gc.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * -------- classes of data types --------
  3. *
  4. * ATOMIC:
  5. * bools, null, integers, symbols, characters
  6. *
  7. * DATA:
  8. * strings
  9. *
  10. * COMPLEX:
  11. * boxes, conses, vectors, closures, records
  12. *
  13. *
  14. * -------- data layout of complex types --------
  15. *
  16. * box: skip=0
  17. * [SCM]
  18. *
  19. * cons: skip=0
  20. * [SCM][SCM]
  21. *
  22. * vector: skip=1
  23. * [LEN][SCM][SCM]...[SCM]
  24. *
  25. * closure: skip=2
  26. * [LEN][LBL][SCM][SCM]...[SCM]
  27. *
  28. * record: skip=2
  29. * [LEN][TAG][SCM]...[SCM]
  30. *
  31. *
  32. * Note: LEN is the number of SCM's, the total size of the object
  33. * is skips+LEN
  34. *
  35. *
  36. * -------- tagging --------
  37. *
  38. * The tags are organized into 3 sets:
  39. * [immediates] < [data] < [complex]
  40. *
  41. * this enables us to quickly test what sort of
  42. * object we have
  43. *
  44. * further, for complex data the 2 bits of the
  45. * tag will give you the number of skips for
  46. * that object.
  47. *
  48. */
  49. word gc_obj(word *o) {
  50. word tag, skips, len;
  51. word ptr, to_ptr;
  52. tag = TAG(*o);
  53. if(ATOMIC_TAG(tag)) {
  54. return *o;
  55. }
  56. else if(GC_MARK_TAG(tag)) {
  57. ptr = PTR(*o);
  58. return FROM_HEAP_REF(ptr);
  59. }
  60. else if(DATA_TAG(tag)) {
  61. ptr = PTR(*o);
  62. skips = FROM_HEAP_REF(ptr);
  63. len = 0;
  64. }
  65. else {
  66. ptr = PTR(*o);
  67. skip = SKIPS(*o);
  68. len = FROM_HEAP_REF(ptr);
  69. }
  70. // we need to allocate space in the "to" heap
  71. // - mark this object as dead so recursion wont loop
  72. // or make spurious copies
  73. // - then copy the 'skips' amount of raw data across
  74. // - then copy each of the children into the space
  75. to_ptr = heap_alloc(skips + len);
  76. *o = OBJECT_TAG_PTR(tag_dead, to_ptr);
  77. memcpy(TO_HEAP(to_ptr), FROM_HEAP(ptr), skips*WORDSIZE);
  78. for(i = 0; i < len; i++) {
  79. TO_HEAP_REF(to_ptr + skip + i) = gc_obj(FROM_HEAP_REF(to_ptr + skip + i));
  80. }
  81. return OBJECT_TAG_PTR(tag, to_ptr);
  82. }