Mercurial > repos > rhope
comparison runtime/object.c @ 41:1b86a1ee500a
Added faster allocator for small objects
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 10 Oct 2009 16:40:50 -0400 |
parents | 789a146a48e1 |
children | 3e20ed8959c4 b218af069da7 |
comparison
equal
deleted
inserted
replaced
40:789a146a48e1 | 41:1b86a1ee500a |
---|---|
1 #include "object.h" | 1 #include "object.h" |
2 #include "builtin.h" | 2 #include "builtin.h" |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 #include <string.h> | 4 #include <string.h> |
5 #include <stdio.h> | 5 #include <stdio.h> |
6 #include "fixed_alloc.h" | |
6 | 7 |
7 blueprint ** registered_types = NULL; | 8 blueprint ** registered_types = NULL; |
8 uint32_t max_registered_type = 0; | 9 uint32_t max_registered_type = 0; |
9 uint32_t type_storage = 0; | 10 uint32_t type_storage = 0; |
11 | |
12 mem_manager * manager = NULL; | |
10 | 13 |
11 returntype call_method(uint32_t methodid, calldata * params) | 14 returntype call_method(uint32_t methodid, calldata * params) |
12 { | 15 { |
13 int i; | 16 int i; |
14 blueprint * bp = get_blueprint(params->params[0]); | 17 blueprint * bp = get_blueprint(params->params[0]); |
123 return EXCEPTION_RETURN; | 126 return EXCEPTION_RETURN; |
124 } | 127 } |
125 | 128 |
126 object * alloc_object(blueprint * bp) | 129 object * alloc_object(blueprint * bp) |
127 { | 130 { |
128 //TODO: Replace with something more performant | 131 return falloc(bp->boxed_size, manager); |
129 return malloc(bp->boxed_size); | 132 //return malloc(bp->boxed_size); |
130 } | |
131 | |
132 void * alloc_variable(uint32_t size) | |
133 { | |
134 return malloc(size); | |
135 } | 133 } |
136 | 134 |
137 void dealloc_object(blueprint * bp, object * obj) | 135 void dealloc_object(blueprint * bp, object * obj) |
138 { | 136 { |
139 //TODO: Replace with something more performant | 137 ffree(obj, bp->boxed_size, manager); |
140 free(obj); | |
141 } | 138 } |
142 | 139 |
143 object * new_object(uint32_t type) | 140 object * new_object(uint32_t type) |
144 { | 141 { |
145 blueprint * bp; | 142 blueprint * bp; |
170 { | 167 { |
171 blueprint *bp; | 168 blueprint *bp; |
172 multisize * ret; | 169 multisize * ret; |
173 if(type >= max_registered_type || !registered_types[type]) | 170 if(type >= max_registered_type || !registered_types[type]) |
174 return NULL; | 171 return NULL; |
175 ret = alloc_variable(sizeof(multisize) + type); | 172 ret = falloc(sizeof(multisize) + size, manager); |
176 if(ret) | 173 if(ret) |
177 { | 174 { |
178 bp = registered_types[type]; | 175 bp = registered_types[type]; |
179 ret->base.bprint = bp; | 176 ret->base.bprint = bp; |
180 ret->size = size; | 177 ret->size = size; |
193 if(rh_atomic_get(tocopy, refcount) == 1) | 190 if(rh_atomic_get(tocopy, refcount) == 1) |
194 return tocopy; | 191 return tocopy; |
195 bp = get_blueprint(tocopy); | 192 bp = get_blueprint(tocopy); |
196 if(bp->size < 0) { | 193 if(bp->size < 0) { |
197 mtocopy = (multisize *)tocopy; | 194 mtocopy = (multisize *)tocopy; |
198 mcopy = alloc_variable(sizeof(multisize) + mtocopy->size); | 195 mcopy = falloc(sizeof(multisize) + mtocopy->size, manager); |
199 mcopy->size = mtocopy->size; | 196 mcopy->size = mtocopy->size; |
200 memcpy(((char *)mcopy)+sizeof(multisize), ((char *)mtocopy)+sizeof(multisize), mtocopy->size); | 197 memcpy(((char *)mcopy)+sizeof(multisize), ((char *)mtocopy)+sizeof(multisize), mtocopy->size); |
201 copy = (object *)mcopy; | 198 copy = (object *)mcopy; |
202 } else { | 199 } else { |
203 copy = alloc_object(bp); | 200 copy = alloc_object(bp); |
212 | 209 |
213 object * naked_to_boxed(uint32_t type, void * rawdata) | 210 object * naked_to_boxed(uint32_t type, void * rawdata) |
214 { | 211 { |
215 object * dest; | 212 object * dest; |
216 blueprint * bp = get_blueprint_byid(type); | 213 blueprint * bp = get_blueprint_byid(type); |
217 if(!bp->size) | 214 if(!bp->boxed_size) |
218 return NULL; //We don't know how big a naked multi-size object is so we can't do anything with it | 215 return NULL; //We don't know how big a naked multi-size object is so we can't do anything with it |
219 dest = alloc_object(bp); | 216 dest = alloc_object(bp); |
220 memcpy(((char *)dest) + sizeof(object), rawdata, bp->size); | 217 memcpy(((char *)dest) + sizeof(object), rawdata, bp->size); |
221 dest->bprint = bp; | 218 dest->bprint = bp; |
222 rh_atomic_set(dest, refcount, 1); | 219 rh_atomic_set(dest, refcount, 1); |
225 } | 222 } |
226 | 223 |
227 void boxed_to_naked(object * src, void * dest) | 224 void boxed_to_naked(object * src, void * dest) |
228 { | 225 { |
229 blueprint * bp = get_blueprint(src); | 226 blueprint * bp = get_blueprint(src); |
230 if(!bp->size) | 227 if(!bp->boxed_size) |
231 return; //We don't know how big a naked multi-size object is so we can't do anything with it | 228 return; //We don't know how big a naked multi-size object is so we can't do anything with it |
232 memcpy(dest, ((char *)src) + sizeof(object), bp->size); | 229 memcpy(dest, ((char *)src) + sizeof(object), bp->size); |
233 bp->copy(src); | 230 bp->copy(src); |
234 } | 231 } |
235 | 232 |
236 void free_object(object * obj) | |
237 { | |
238 blueprint * bp = get_blueprint(obj); | |
239 if(bp->cleanup) | |
240 bp->cleanup(obj); | |
241 dealloc_object(bp, obj); | |
242 } | |
243 | |
244 void release_ref(object * obj) | 233 void release_ref(object * obj) |
245 { | 234 { |
246 if(rh_atomic_sub_testzero(obj, refcount, 1)) | 235 if(rh_atomic_sub_testzero(obj, refcount, 1)) |
247 free_object(obj); | 236 get_blueprint(obj)->free(obj); |
248 } | 237 } |
249 | 238 |
250 void check_type_storage(type) | 239 void check_type_storage(type) |
251 { | 240 { |
252 uint32_t type_storage_temp; | 241 uint32_t type_storage_temp; |
288 | 277 |
289 void default_action(object * obj) | 278 void default_action(object * obj) |
290 { | 279 { |
291 } | 280 } |
292 | 281 |
282 void normal_free(object * obj) | |
283 { | |
284 blueprint * bp = get_blueprint(obj); | |
285 if(bp->cleanup) | |
286 bp->cleanup(obj); | |
287 ffree(obj, bp->boxed_size, manager); | |
288 } | |
289 | |
290 void multi_free(object * obj) | |
291 { | |
292 multisize * multi = (multisize *)obj; | |
293 blueprint * bp = get_blueprint(obj); | |
294 if(bp->cleanup) | |
295 bp->cleanup(obj); | |
296 ffree(multi, sizeof(multi) + multi->size, manager); | |
297 } | |
298 | |
293 blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup) | 299 blueprint * new_blueprint(uint32_t type, uint32_t size, special_func init, special_func copy, special_func cleanup) |
294 { | 300 { |
295 blueprint * bp = malloc(sizeof(blueprint)); | 301 blueprint * bp = malloc(sizeof(blueprint)); |
302 //dirty hack!, move elsewhere | |
303 if (!manager) { | |
304 fixed_alloc_init(); | |
305 manager = new_mem_manager(); | |
306 } | |
296 if(bp) | 307 if(bp) |
297 { | 308 { |
298 bp->size = size; | 309 bp->size = size; |
299 bp->boxed_size = size >= 0 ? size + sizeof(object) : size; | 310 bp->boxed_size = size >= 0 ? size + sizeof(object) : 0; |
300 bp->method_lookup = bp->getter_lookup = bp->setter_lookup = bp->convert_to = bp->convert_from = NULL; | 311 bp->method_lookup = bp->getter_lookup = bp->setter_lookup = bp->convert_to = bp->convert_from = NULL; |
301 bp->init = init ? init : default_action; | 312 bp->init = init ? init : default_action; |
302 bp->copy = copy ? copy : default_action; | 313 bp->copy = copy ? copy : default_action; |
303 bp->cleanup = cleanup ? cleanup : default_action; | 314 bp->cleanup = cleanup ? cleanup : default_action; |
315 bp->free = size >= 0 ? normal_free : multi_free; | |
304 bp->first_methodid = bp->last_methodid = bp->first_getfieldid = bp->last_getfieldid = bp->first_setfieldid = bp->last_setfieldid = bp->first_convertto = bp->last_convertto = bp->first_convertfrom = bp->last_convertfrom = 0; | 316 bp->first_methodid = bp->last_methodid = bp->first_getfieldid = bp->last_getfieldid = bp->first_setfieldid = bp->last_setfieldid = bp->first_convertto = bp->last_convertto = bp->first_convertfrom = bp->last_convertfrom = 0; |
305 //TODO: Handle names | 317 //TODO: Handle names |
306 bp->name = NULL; | 318 bp->name = NULL; |
307 } | 319 } |
308 return bp; | 320 return bp; |