12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /*
- * -------- classes of data types --------
- *
- * ATOMIC:
- * bools, null, integers, symbols, characters
- *
- * DATA:
- * strings
- *
- * COMPLEX:
- * boxes, conses, vectors, closures, records
- *
- *
- * -------- data layout of complex types --------
- *
- * box: skip=0
- * [SCM]
- *
- * cons: skip=0
- * [SCM][SCM]
- *
- * vector: skip=1
- * [LEN][SCM][SCM]...[SCM]
- *
- * closure: skip=2
- * [LEN][LBL][SCM][SCM]...[SCM]
- *
- * record: skip=2
- * [LEN][TAG][SCM]...[SCM]
- *
- *
- * Note: LEN is the number of SCM's, the total size of the object
- * is skips+LEN
- *
- *
- * -------- tagging --------
- *
- * The tags are organized into 3 sets:
- * [immediates] < [data] < [complex]
- *
- * this enables us to quickly test what sort of
- * object we have
- *
- * further, for complex data the 2 bits of the
- * tag will give you the number of skips for
- * that object.
- *
- */
- word gc_obj(word *o) {
- word tag, skips, len;
- word ptr, to_ptr;
- tag = TAG(*o);
-
- if(ATOMIC_TAG(tag)) {
- return *o;
- }
- else if(GC_MARK_TAG(tag)) {
- ptr = PTR(*o);
- return FROM_HEAP_REF(ptr);
- }
- else if(DATA_TAG(tag)) {
- ptr = PTR(*o);
- skips = FROM_HEAP_REF(ptr);
- len = 0;
- }
- else {
- ptr = PTR(*o);
- skip = SKIPS(*o);
- len = FROM_HEAP_REF(ptr);
- }
- // we need to allocate space in the "to" heap
- // - mark this object as dead so recursion wont loop
- // or make spurious copies
- // - then copy the 'skips' amount of raw data across
- // - then copy each of the children into the space
-
- to_ptr = heap_alloc(skips + len);
- *o = OBJECT_TAG_PTR(tag_dead, to_ptr);
-
- memcpy(TO_HEAP(to_ptr), FROM_HEAP(ptr), skips*WORDSIZE);
-
- for(i = 0; i < len; i++) {
- TO_HEAP_REF(to_ptr + skip + i) = gc_obj(FROM_HEAP_REF(to_ptr + skip + i));
- }
-
- return OBJECT_TAG_PTR(tag, to_ptr);
- }
|