home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Em / gc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  4.1 KB  |  171 lines

  1. /* 
  2.  * @(#)gc.c    1.7  4/5/89
  3.  */
  4.  
  5. /* Copyright 1986 Eric Jul.  May not be used for any purpose without    */
  6. /* written permission from the author.                            */
  7. /* The Emerald kernel for the Emerald programming language.             */
  8.  
  9. /* Version 1.0 started 1986-12-06, eric                                 */
  10.  
  11. /* This file contains the implementation of the Emerald kernel garbage  */
  12. /* collector                                                            */
  13.  
  14. #include <stdio.h>
  15.  
  16. #include "Kernel/h/system.h"
  17. #include "Kernel/h/assert.h"
  18. #include "Kernel/h/macros.h"
  19. #include "Kernel/h/errMsgs.h"
  20. #include "Kernel/h/emTypes.h"
  21. #include "Kernel/h/kmdTypes.h"
  22. #include "Kernel/h/kEvents.h"
  23. #include "Kernel/h/emkDefs.h"
  24. #include "Kernel/h/hotsTypes.h"
  25. #include "Kernel/h/map.h"
  26. #include "Kernel/h/set.h"
  27. #include "Kernel/h/utils.h"
  28. #include "Kernel/h/builtins.h"
  29.  
  30. extern EmLocation           thisNodeLocation;
  31.  
  32. /**********************************************************************/
  33. /*      GC                                                            */
  34. /**********************************************************************/
  35.  
  36. #ifdef RICEGC
  37. /* Snapshot */
  38. void GC()
  39. {
  40.   extern int ok_to_expand;
  41.   KMDPrint("Garbage Collection, starting\n");
  42.   ok_to_expand = 0;
  43.   gcollect();
  44.   ok_to_expand = 1;
  45.   KMDPrint("Garbage Collection, done\n");  
  46. }
  47. #else RICEGC
  48. /* Snapshot */
  49. void GC()
  50. {
  51.   KMDPrint("Garbage Collection not implemented\n");
  52. }
  53.  
  54. #endif RICEGC
  55. extern int OTSize;
  56.  
  57. #ifdef RICEGC
  58.  
  59. /*
  60.  * Go through the object table, Xoring all references with -1.
  61.  */
  62. gc_before()
  63. {
  64.   register ODP *p, *limit;
  65.   register OID id;
  66.   ODTag tag;
  67.   KMDTrace("GC", 1, "GC starting\n");
  68.   for (p = &OT[0], limit = &OT[OTSize]; p < limit; p++) {
  69.     if (!*p) continue;
  70.     tag = (*p)->G.tag;
  71.     id = (*p)->G.ownOID;
  72.     if (tag.tag == CodeODTag) {
  73.       KMDTrace("GC", 5, "Not Xoring Code ODP 0x%X OID 0x%X\n", *p, id);
  74.       continue;
  75.     }
  76.     if (tag.xref) {
  77.       KMDTrace("GC", 5, "Not Xoring externally referenced ODP 0x%X OID 0x%X\n", *p, id);
  78.       continue;
  79.     }
  80.     if (id >= (unsigned)BUILTINOBJECTBASE && 
  81.     id <= (unsigned)(INSTCTOFBUILTINOBJECTBASE+0x20)) {
  82.       KMDTrace("GC", 5, "Not Xoring 0x%X OID 0x%X\n", *p, id);
  83.       continue;
  84.     }
  85.     KMDTrace("GC", 3, "Xoring 0x%X OID 0x%X\n", *p, id);
  86.     *(int *)p ^= (-1);
  87.   }
  88. }
  89.  
  90. extern int nOT;
  91. #define OTDelete(P) { (*(P)) = (ODP) -1; nOT--; }
  92.  
  93. /*
  94.  * Go through the object table, and for each non referencable object,
  95.  * delete it from the OT.
  96.  */
  97. gc_during()
  98. {
  99.   register ODP *p, *limit;
  100.   register int isreachable;
  101.   extern void OTFinishDelete();
  102.   for (p = &OT[0], limit = &OT[OTSize]; p < limit; p++) {
  103.     if (!((int)*p & 0x80000000)) continue;
  104.     *(int *)p ^= (-1);
  105.     KMDTrace("GC", 5, "Checking 0x%X OID 0x%X\n", *p, (*p)->G.ownOID);
  106.     isreachable = gc_ismarked(*p);
  107.     KMDTrace("GC", 3, "0x%X OID 0x%X is %sreachable\n", *p, (*p)->G.ownOID,
  108.       isreachable?"":"not ");
  109.     if (!isreachable) OTDelete(p);
  110.   }
  111.   OTFinishDelete();
  112. }
  113.  
  114. gc_after()
  115. {
  116.   KMDTrace("GC", 1, "GC Done\n");
  117. }
  118.  
  119. struct pcs {
  120.   int (*pc[5])();
  121. };
  122.  
  123. #ifdef DEBUGGC
  124. gc_each(b, p)
  125. ODP b;
  126. struct pcs p;
  127. {
  128.   char *PPCodePtr(), *PPODTag();
  129.   if (!ok_to_expand) {
  130.     /* during a snapshot */
  131.     if (b->G.tag.otherstuff == OBSCUREVALUE) {
  132.       if (b->G.tag.tag == GODataTag || b->G.tag.tag == LOTag) {
  133.     KMDPrint("freed %x tag %s %s\n",
  134.       b,
  135.       PPODTag(b->G.tag),
  136.       PPCodePtr(((LODataPtr)b)->myCodePtr));
  137.       } else if(b->G.tag.tag == GODTag) {
  138.     KMDPrint("freed %x tag %s id %x dataPtr %x %s\n",
  139.       b,
  140.       PPODTag(b->G.tag),
  141.       b->G.ownOID,
  142.       b->G.dataPtr,
  143.       b->G.dataPtr == 0 || b->G.dataPtr == EMNIL ? "" : PPCodePtr(b->G.dataPtr->myCodePtr));
  144.       }
  145.     
  146.     }
  147.   }
  148. }
  149. #endif DEBUGGC
  150.  
  151. #endif RICEGC
  152.  
  153. /**********************************************************************/
  154. /*      GCInit                                                        */
  155. /**********************************************************************/
  156. void GCInit()
  157. {
  158. #ifdef RICEGC
  159. #ifdef DEBUGGC
  160.     gc_init(gc_before, gc_during, gc_after, gc_each);
  161. #else
  162.     gc_init(gc_before, gc_during, gc_after, 0);
  163. #endif DEBUGGC
  164.     expand_hp((1024 - 64) / 4);
  165. #endif RICEGC
  166.     KMDSetSnap(GC);
  167.     KMDSetTrace(GC);
  168. }
  169.  
  170. /* Copyright 1986 Eric Jul */
  171.