comparison runtime/object.c @ 186:ba35ab624ec2

Add support for raw C function output from C backend as well as an option to use Boehm-GC instead of reference counting
author Mike Pavone <pavone@retrodev.com>
date Fri, 07 Oct 2011 00:10:02 -0700
parents a68e6828d896
children
comparison
equal deleted inserted replaced
185:4580c08fd4e8 186:ba35ab624ec2
1 #include "object.h" 1 #include "object.h"
2 #include "builtin.h" 2 #include "builtin.h"
3 #ifdef USE_GC
4 #include <gc/gc.h>
5 #else
3 #include <stdlib.h> 6 #include <stdlib.h>
7 #ifndef USE_MALLOC
8 #include "fixed_alloc.h"
9 #endif
10 #endif
4 #include <string.h> 11 #include <string.h>
5 #include <stdio.h> 12 #include <stdio.h>
6 #include "fixed_alloc.h"
7 13
8 blueprint ** registered_types = NULL; 14 blueprint ** registered_types = NULL;
9 uint32_t max_registered_type = 0; 15 uint32_t max_registered_type = 0;
10 uint32_t type_storage = 0; 16 uint32_t type_storage = 0;
11 17
127 return EXCEPTION_RETURN; 133 return EXCEPTION_RETURN;
128 }*/ 134 }*/
129 135
130 object * alloc_object(blueprint * bp) 136 object * alloc_object(blueprint * bp)
131 { 137 {
138 #ifdef USE_GC
139 return GC_malloc(bp->boxed_size);
140 #else
141 #ifdef USE_MALLOC
142 return malloc(bp->boxed_size);
143 #else
132 return falloc(bp->boxed_size, manager); 144 return falloc(bp->boxed_size, manager);
133 //return malloc(bp->boxed_size); 145 #endif
134 } 146 #endif
135 147 }
148
149 #ifndef USE_GC
136 void dealloc_object(blueprint * bp, object * obj) 150 void dealloc_object(blueprint * bp, object * obj)
137 { 151 {
152 #ifdef USE_MALLOC
153 free(obj);
154 #else
138 ffree(obj, bp->boxed_size, manager); 155 ffree(obj, bp->boxed_size, manager);
139 } 156 #endif
157 }
158 #endif
140 159
141 object * new_object(uint32_t type) 160 object * new_object(uint32_t type)
142 { 161 {
143 blueprint * bp; 162 blueprint * bp;
144 object * ret; 163 object * ret;
153 object * ret; 172 object * ret;
154 ret = alloc_object(bp); 173 ret = alloc_object(bp);
155 if(ret) 174 if(ret)
156 { 175 {
157 ret->bprint = bp; 176 ret->bprint = bp;
177 #ifndef USE_GC
158 rh_atomic_set(ret, refcount, 1); 178 rh_atomic_set(ret, refcount, 1);
179 #endif
159 memset(((char *)ret) + sizeof(object), '\0', bp->size); 180 memset(((char *)ret) + sizeof(object), '\0', bp->size);
160 bp->init(ret); 181 bp->init(ret);
161 } else { 182 } else {
162 fprintf(stderr, "Could not allocate new object with size %d\n", bp->boxed_size); 183 fprintf(stderr, "Could not allocate new object with size %d\n", bp->boxed_size);
163 } 184 }
168 { 189 {
169 blueprint *bp; 190 blueprint *bp;
170 multisize * ret; 191 multisize * ret;
171 if(type >= max_registered_type || !registered_types[type]) 192 if(type >= max_registered_type || !registered_types[type])
172 return NULL; 193 return NULL;
194 #ifdef USE_GC
195 ret = GC_malloc(sizeof(multisize) + size);
196 #else
197 #ifdef USE_MALLOC
198 ret = malloc(sizeof(multisize) + size);
199 #else
173 ret = falloc(sizeof(multisize) + size, manager); 200 ret = falloc(sizeof(multisize) + size, manager);
201 #endif
202 #endif
174 if(ret) 203 if(ret)
175 { 204 {
176 bp = registered_types[type]; 205 bp = registered_types[type];
177 ret->base.bprint = bp; 206 ret->base.bprint = bp;
178 ret->size = size; 207 ret->size = size;
208 #ifndef USE_GC
179 rh_atomic_set(&(ret->base), refcount, 1); 209 rh_atomic_set(&(ret->base), refcount, 1);
210 #endif
180 memset(((char *)ret) + sizeof(multisize), '\0', size); 211 memset(((char *)ret) + sizeof(multisize), '\0', size);
181 bp->init((object *)ret); 212 bp->init((object *)ret);
182 } 213 }
183 return ret; 214 return ret;
184 } 215 }
186 object * copy_object(object * tocopy) 217 object * copy_object(object * tocopy)
187 { 218 {
188 object * copy; 219 object * copy;
189 multisize * mcopy, *mtocopy; 220 multisize * mcopy, *mtocopy;
190 blueprint * bp; 221 blueprint * bp;
222 #ifndef USE_GC
191 if(rh_atomic_get(tocopy, refcount) == 1) 223 if(rh_atomic_get(tocopy, refcount) == 1)
192 return tocopy; 224 return tocopy;
225 #endif
193 bp = get_blueprint(tocopy); 226 bp = get_blueprint(tocopy);
194 if(bp->size < 0) { 227 if(bp->size < 0) {
195 mtocopy = (multisize *)tocopy; 228 mtocopy = (multisize *)tocopy;
229 #ifdef USE_GC
230 mcopy = GC_malloc(sizeof(multisize) + mtocopy->size);
231 #else
232 #ifdef USE_MALLOC
233 mcopy = malloc(sizeof(multisize) + mtocopy->size);
234 #else
196 mcopy = falloc(sizeof(multisize) + mtocopy->size, manager); 235 mcopy = falloc(sizeof(multisize) + mtocopy->size, manager);
236 #endif
237 #endif
197 mcopy->size = mtocopy->size; 238 mcopy->size = mtocopy->size;
198 memcpy(((char *)mcopy)+sizeof(multisize), ((char *)mtocopy)+sizeof(multisize), mtocopy->size); 239 memcpy(((char *)mcopy)+sizeof(multisize), ((char *)mtocopy)+sizeof(multisize), mtocopy->size);
199 copy = (object *)mcopy; 240 copy = (object *)mcopy;
200 } else { 241 } else {
201 copy = alloc_object(bp); 242 copy = alloc_object(bp);
202 memcpy(((char *)copy) + sizeof(object), ((char *)tocopy)+sizeof(object), bp->size); 243 memcpy(((char *)copy) + sizeof(object), ((char *)tocopy)+sizeof(object), bp->size);
203 } 244 }
204 copy->bprint = bp; 245 copy->bprint = bp;
246 #ifndef USE_GC
205 rh_atomic_set(copy, refcount, 1); 247 rh_atomic_set(copy, refcount, 1);
248 #endif
206 bp->copy(copy); 249 bp->copy(copy);
207 release_ref(tocopy); 250 release_ref(tocopy);
208 return copy; 251 return copy;
209 } 252 }
210 253
215 if(!bp->boxed_size) 258 if(!bp->boxed_size)
216 return NULL; //We don't know how big a naked multi-size object is so we can't do anything with it 259 return NULL; //We don't know how big a naked multi-size object is so we can't do anything with it
217 dest = alloc_object(bp); 260 dest = alloc_object(bp);
218 memcpy(((char *)dest) + sizeof(object), rawdata, bp->size); 261 memcpy(((char *)dest) + sizeof(object), rawdata, bp->size);
219 dest->bprint = bp; 262 dest->bprint = bp;
263 #ifndef USE_GC
220 rh_atomic_set(dest, refcount, 1); 264 rh_atomic_set(dest, refcount, 1);
265 #endif
221 bp->copy(dest); 266 bp->copy(dest);
222 return dest; 267 return dest;
223 } 268 }
224 269
225 void boxed_to_naked(object * src, void * dest) 270 void boxed_to_naked(object * src, void * dest)
229 return; //We don't know how big a naked multi-size object is so we can't do anything with it 274 return; //We don't know how big a naked multi-size object is so we can't do anything with it
230 memcpy(dest, ((char *)src) + sizeof(object), bp->size); 275 memcpy(dest, ((char *)src) + sizeof(object), bp->size);
231 bp->copy(src); 276 bp->copy(src);
232 } 277 }
233 278
279 #ifndef USE_GC
234 void release_ref(object * obj) 280 void release_ref(object * obj)
235 { 281 {
236 if(rh_atomic_sub_testzero(obj, refcount, 1)) 282 if(rh_atomic_sub_testzero(obj, refcount, 1))
237 get_blueprint(obj)->free(obj); 283 get_blueprint(obj)->free(obj);
238 } 284 }
285 #endif
239 286
240 void check_type_storage(type) 287 void check_type_storage(type)
241 { 288 {
242 uint32_t type_storage_temp; 289 uint32_t type_storage_temp;
243 blueprint ** temp; 290 blueprint ** temp;
244 if(type >= type_storage) 291 if(type >= type_storage)
245 if(type_storage) 292 if(type_storage)
246 { 293 {
247 type_storage_temp = (type + (type_storage >> 1)); 294 type_storage_temp = (type + (type_storage >> 1));
295 #ifdef USE_GC
296 temp = GC_realloc(registered_types, type_storage_temp * sizeof(blueprint *));
297 #else
248 temp = realloc(registered_types, type_storage_temp * sizeof(blueprint *)); 298 temp = realloc(registered_types, type_storage_temp * sizeof(blueprint *));
299 #endif
249 if(temp) 300 if(temp)
250 { 301 {
251 registered_types = temp; 302 registered_types = temp;
252 memset(registered_types + type_storage, '\0', (type_storage_temp - type_storage) * sizeof(blueprint *)); 303 memset(registered_types + type_storage, '\0', (type_storage_temp - type_storage) * sizeof(blueprint *));
253 type_storage = type_storage_temp; 304 type_storage = type_storage_temp;
254 } 305 }
255 else 306 else
256 { 307 {
308 #ifndef USE_GC
257 free(registered_types); 309 free(registered_types);
310 #endif
258 fprintf(stderr, "Couldn't allocate %d bytes for type storage array\n", type_storage_temp * sizeof(blueprint *)); 311 fprintf(stderr, "Couldn't allocate %d bytes for type storage array\n", type_storage_temp * sizeof(blueprint *));
259 exit(-1); 312 exit(-1);
260 } 313 }
261 } else { 314 } else {
262 315
263 if(type < INITIAL_TYPE_STORAGE) 316 if(type < INITIAL_TYPE_STORAGE)
264 type_storage =INITIAL_TYPE_STORAGE; 317 type_storage =INITIAL_TYPE_STORAGE;
265 else 318 else
266 type_storage = type + 8; 319 type_storage = type + 8;
320 #ifdef USE_GC
321 registered_types = GC_malloc(type_storage * sizeof(blueprint *));
322 #else
267 registered_types = malloc(type_storage * sizeof(blueprint *)); 323 registered_types = malloc(type_storage * sizeof(blueprint *));
324 #endif
325
268 if(registered_types) 326 if(registered_types)
269 memset(registered_types, '\0', type_storage * sizeof(blueprint *)); 327 memset(registered_types, '\0', type_storage * sizeof(blueprint *));
270 else 328 else
271 { 329 {
272 fprintf(stderr, "Couldn't allocate %d bytes for type storage array\n", type_storage * sizeof(blueprint *)); 330 fprintf(stderr, "Couldn't allocate %d bytes for type storage array\n", type_storage * sizeof(blueprint *));
283 void normal_free(object * obj) 341 void normal_free(object * obj)
284 { 342 {
285 blueprint * bp = get_blueprint(obj); 343 blueprint * bp = get_blueprint(obj);
286 if(bp->cleanup) 344 if(bp->cleanup)
287 bp->cleanup(obj); 345 bp->cleanup(obj);
346 #ifndef USE_GC
288 ffree(obj, bp->boxed_size, manager); 347 ffree(obj, bp->boxed_size, manager);
348 #endif
289 } 349 }
290 350
291 void multi_free(object * obj) 351 void multi_free(object * obj)
292 { 352 {
293 multisize * multi = (multisize *)obj; 353 multisize * multi = (multisize *)obj;
294 blueprint * bp = get_blueprint(obj); 354 blueprint * bp = get_blueprint(obj);
295 if(bp->cleanup) 355 if(bp->cleanup)
296 bp->cleanup(obj); 356 bp->cleanup(obj);
357 #ifndef USE_GC
297 ffree(multi, sizeof(multisize) + multi->size, manager); 358 ffree(multi, sizeof(multisize) + multi->size, manager);
359 #endif
298 } 360 }
299 361
300 blueprint * new_blueprint(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup) 362 blueprint * new_blueprint(uint32_t type, int32_t size, special_func init, special_func copy, special_func cleanup)
301 { 363 {
364 #ifdef USE_GC
365 blueprint * bp = GC_malloc(sizeof(blueprint));
366 #else
302 blueprint * bp = malloc(sizeof(blueprint)); 367 blueprint * bp = malloc(sizeof(blueprint));
368
303 //dirty hack!, move elsewhere 369 //dirty hack!, move elsewhere
304 if (!manager) { 370 if (!manager) {
305 fixed_alloc_init(); 371 fixed_alloc_init();
306 manager = new_mem_manager(); 372 manager = new_mem_manager();
307 } 373 }
374 #endif
308 if(bp) 375 if(bp)
309 { 376 {
310 bp->size = size; 377 bp->size = size;
311 bp->boxed_size = size >= 0 ? size + sizeof(object) : 0; 378 bp->boxed_size = size >= 0 ? size + sizeof(object) : 0;
312 bp->method_lookup = bp->getter_lookup = bp->setter_lookup = bp->convert_to = bp->convert_from = NULL; 379 bp->method_lookup = bp->getter_lookup = bp->setter_lookup = bp->convert_to = bp->convert_from = NULL;
341 blueprint * register_type(int32_t size, special_func init, special_func copy, special_func cleanup) 408 blueprint * register_type(int32_t size, special_func init, special_func copy, special_func cleanup)
342 { 409 {
343 return register_type_byid(max_registered_type, size, init, copy, cleanup); 410 return register_type_byid(max_registered_type, size, init, copy, cleanup);
344 } 411 }
345 412
413 /*
346 void add_method(blueprint * bp, uint32_t methodid, rhope_func impl) 414 void add_method(blueprint * bp, uint32_t methodid, rhope_func impl)
347 { 415 {
348 rhope_func * temp; 416 rhope_func * temp;
349 if(methodid < 1) { 417 if(methodid < 1) {
350 fputs("Attempt to add a method with an ID < 1\n", stderr); 418 fputs("Attempt to add a method with an ID < 1\n", stderr);
487 bp->last_setfieldid = setfieldid+1; 555 bp->last_setfieldid = setfieldid+1;
488 } 556 }
489 } 557 }
490 bp->setter_lookup[setfieldid-bp->first_setfieldid] = impl; 558 bp->setter_lookup[setfieldid-bp->first_setfieldid] = impl;
491 } 559 }
560 */
492 561
493 blueprint * get_blueprint_byid(uint32_t type) 562 blueprint * get_blueprint_byid(uint32_t type)
494 { 563 {
495 if(type >= max_registered_type) 564 if(type >= max_registered_type)
496 return NULL; 565 return NULL;