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;