3 /* Stop-and-copy garbage collection using Cheney's algorithm. */
5 /* #define GC_DEBUG /* */
7 INLINE void gc_debug(char* msg, CELL x) {
9 printf("%s %d\n",msg,x);
13 /* Given a pointer to a pointer to oldspace, copy it to newspace. */
14 CELL copy_untagged_object(CELL pointer, CELL size)
16 CELL newpointer = allot(size);
17 memcpy(newpointer,pointer,size);
23 Given a pointer to a tagged pointer to oldspace, copy it to newspace.
24 If the object has already been copied, return the forwarding
25 pointer address without copying anything; otherwise, install
26 a new forwarding pointer.
28 void copy_object(CELL* handle)
30 CELL pointer = *handle;
31 CELL tag = TAG(pointer);
32 CELL header, newpointer;
34 if(in_zone(active,pointer))
35 critical_error("copy_object given newspace ptr",pointer);
37 if(tag == FIXNUM_TYPE)
43 header = get(UNTAG(pointer));
45 if(TAG(header) == GC_COLLECTED)
47 newpointer = UNTAG(header);
48 gc_debug("FORWARDING",newpointer);
52 gc_debug("copy_object",pointer);
53 newpointer = copy_untagged_object(UNTAG(pointer),
54 object_size(pointer));
55 put(UNTAG(pointer),RETAG(newpointer,GC_COLLECTED));
58 if(tag == GC_COLLECTED)
59 critical_error("installing forwarding pointer in newspace",newpointer);
61 *handle = RETAG(newpointer,tag);
64 void collect_object(void)
66 CELL size = untagged_object_size(scan);
67 gc_debug("collect_object",scan);
68 gc_debug("collect_object size=",size);
70 switch(untag_header(get(scan)))
73 collect_word((WORD*)scan);
76 collect_array((ARRAY*)scan);
79 collect_vector((VECTOR*)scan);
82 collect_sbuf((SBUF*)scan);
85 collect_handle((HANDLE*)scan);
91 void collect_next(void)
93 gc_debug("collect_next",scan);
94 gc_debug("collect_next header",get(scan));
95 switch(TAG(get(scan)))
107 void copy_roots(void)
111 CELL ds_depth = env.ds - UNTAG(env.ds_bot);
112 CELL cs_depth = env.cs - UNTAG(env.cs_bot);
114 gc_debug("collect_roots",scan);
115 /* these three must be the first in the heap */
117 gc_debug("empty",empty);
122 copy_object(&env.dt);
123 copy_object(&env.ds_bot);
124 env.ds = UNTAG(env.ds_bot) + ds_depth;
125 copy_object(&env.cs_bot);
126 env.cs = UNTAG(env.cs_bot) + cs_depth;
127 copy_object(&env.cf);
128 copy_object(&env.boot);
130 for(i = 0; i < USER_ENV; i++)
131 copy_object(&env.user[i]);
134 void primitive_gc(void)
137 scan = active->here = active->base;
139 while(scan < active->here)
141 gc_debug("scan loop",scan);
144 gc_debug("gc done",0);