1 \section[SM-copying]{Copying Collector Subroutines}
3 This is a collection of C functions used in implementing the copying
6 The motivation for making this a separate file/section is twofold:
8 1) It lets us focus on one thing.
10 2) If we don't do this, there will be a huge amount of repetition
11 between the various GC schemes --- a maintenance nightmare.
13 The second is the major motivation.
17 #if defined(GC2s) || defined(GCdu) || defined(GCap) || defined(GCgn)
21 #include "SMinternal.h"
24 #include "SMcopying.h"
27 Comment stolen from SMscav.lc: When doing a new generation copy
28 collection for Appel's collector only evacuate references that point
29 to the new generation. OldGen must be set to point to the end of old
35 #define MAYBE_EVACUATE_CLOSURE( closure ) \
37 P_ evac = (P_) (closure); \
38 if (evac > OldGen) { \
39 (closure) = EVACUATE_CLOSURE(evac); \
45 #define MAYBE_EVACUATE_CLOSURE( closure ) \
47 P_ evac = (P_) (closure); \
48 (closure) = EVACUATE_CLOSURE(evac); \
56 SetCAFInfoTables( CAFlist )
61 /* Set CAF info tables for evacuation */
62 DEBUG_STRING("Setting Evac & Upd CAFs:");
63 for (CAFptr = CAFlist;
65 CAFptr = (P_) IND_CLOSURE_LINK(CAFptr) ) {
66 INFO_PTR(CAFptr) = (W_) Caf_Evac_Upd_info;
73 EvacuateRoots( roots, rootno )
79 DEBUG_STRING("Evacuate (Reg) Roots:");
80 for (root = 0; root < rootno; root++) {
81 MAYBE_EVACUATE_CLOSURE( roots[root] );
89 EvacuateSparks(STG_NO_ARGS)
95 DEBUG_STRING("Evacuate Sparks:");
96 for (pool = 0; pool < SPARK_POOLS; pool++) {
97 for (sparkptr = PendingSparksHd[pool];
98 sparkptr < PendingSparksTl[pool]; sparkptr++) {
99 MAYBE_EVACUATE_CLOSURE(*((PP_) sparkptr));
106 Note: no \tr{evacuate[AB]Stack} for ``parallel'' systems, because they
107 don't have a single main stack.
112 EvacuateAStack( stackA, botA )
114 PP_ botA; /* botA points to bottom-most word */
118 DEBUG_STRING("Evacuate A Stack:");
119 for (stackptr = stackA;
120 SUBTRACT_A_STK(stackptr, botA) >= 0;
121 stackptr = stackptr + AREL(1)) {
122 MAYBE_EVACUATE_CLOSURE( *((PP_) stackptr) );
128 ToDo: Optimisation which squeezes out update frames which point to
131 Perform collection first
133 Then process B stack removing update frames (bot to top via pointer
134 reversal) that reference garbage closues (test infoptr !=
137 Otherwise closure is live update reference to to-space address
142 EvacuateBStack( stackB, botB, roots )
144 P_ botB; /* botB points to bottom-most word */
151 DEBUG_STRING("Evacuate B Stack:");
153 for (updateFramePtr = stackB; /* stackB points to topmost update frame */
154 SUBTRACT_B_STK(updateFramePtr, botB) > 0;
155 updateFramePtr = GRAB_SuB(updateFramePtr)) {
157 /* Evacuate the thing to be updated */
158 updatee = GRAB_UPDATEE(updateFramePtr);
159 MAYBE_EVACUATE_CLOSURE(updatee);
160 PUSH_UPDATEE(updateFramePtr, updatee);
168 When we do a copying collection, we want to evacuate all of the local entries
169 in the GALA table for which there are outstanding remote pointers (i.e. for
170 which the weight is not MAX_GA_WEIGHT.)
177 EvacuateLocalGAs(full)
184 for (gala = liveIndirections; gala != NULL; gala = next) {
186 ASSERT(gala->ga.loc.gc.gtid == mytid);
187 if (gala->ga.weight != MAX_GA_WEIGHT) {
188 /* Remote references exist, so we must evacuate the local closure */
190 MAYBE_EVACUATE_CLOSURE(gala->la);
191 if (!full && gala->preferred && gala->la != old) {
192 (void) removeHashTable(LAtoGALAtable, (W_) old, (void *) gala);
193 insertHashTable(LAtoGALAtable, (W_) gala->la, (void *) gala);
198 /* Since we have all of the weight, this GA is no longer needed */
199 W_ pga = PACK_GA(thisPE, gala->ga.loc.gc.slot);
202 fprintf(stderr, "Freeing slot %d\n", gala->ga.loc.gc.slot);
204 gala->next = freeIndirections;
205 freeIndirections = gala;
206 (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala);
207 if (!full && gala->preferred)
208 (void) removeHashTable(LAtoGALAtable, (W_) gala->la, (void *) gala);
210 gala->ga.weight = 0x0d0d0d0d;
211 gala->la = (P_) 0xbadbad;
215 liveIndirections = prev;
222 EXTDATA_RO(Forward_Ref_info);
225 RebuildGAtables(full)
233 prepareFreeMsgBuffers();
235 for (gala = liveRemoteGAs, prev = NULL; gala != NULL; gala = next) {
237 ASSERT(gala->ga.loc.gc.gtid != mytid);
242 * If the old closure has not been forwarded, we let go. Note that this
243 * approach also drops global aliases for PLCs.
246 #if defined(GCgn) || defined(GCap)
247 if (closure > OldGen) {
249 if (!full && gala->preferred)
250 (void) removeHashTable(LAtoGALAtable, (W_) gala->la, (void *) gala);
252 /* Follow indirection chains to the end, just in case */
253 while (IS_INDIRECTION(INFO_PTR(closure)))
254 closure = (P_) IND_CLOSURE_PTR(closure);
256 /* Change later to incorporate a _FO bit in the INFO_TYPE for GCgn */
258 fall over, until _FO bits are added
260 if (INFO_PTR(closure) != (W_) Forward_Ref_info) {
261 int pe = taskIDtoPE(gala->ga.loc.gc.gtid);
262 W_ pga = PACK_GA(pe, gala->ga.loc.gc.slot);
265 (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala);
266 freeRemoteGA(pe, &(gala->ga));
267 gala->next = freeGALAList;
270 /* Find the new space object */
271 closure = (P_) FORWARD_ADDRESS(closure);
274 if (!full && gala->preferred)
275 insertHashTable(LAtoGALAtable, (W_) gala->la, (void *) gala);
279 #if defined(GCgn) || defined(GCap)
281 /* Old generation, minor collection; just keep it */
287 liveRemoteGAs = prev;
289 /* If we have any remaining FREE messages to send off, do so now */
304 DEBUG_SCAN("Scavenging Start", Scav, "ToHp", ToHp);
305 while (Scav <= ToHp) (SCAV_CODE(INFO_PTR(Scav)))();
306 DEBUG_SCAN("Scavenging End", Scav, "ToHp", ToHp);
314 EvacuateCAFs( CAFlist )
319 DEBUG_STRING("Evacuate CAFs:");
320 for (CAFptr = CAFlist;
322 CAFptr = (P_) IND_CLOSURE_LINK(CAFptr)) {
323 EVACUATE_CLOSURE(CAFptr); /* evac & upd OR return */
327 /* ToDo: put GCap EvacuateCAFs code here */
332 EvacAndScavengeCAFs( CAFlist, extra_words, roots )
341 DEBUG_STRING("Evacuate & Scavenge CAFs:");
342 for (CAFptr = CAFlist;
344 CAFptr = (P_) IND_CLOSURE_LINK(CAFptr)) {
346 EVACUATE_CLOSURE(CAFptr); /* evac & upd OR return */
349 DEBUG_SCAN("Scavenging CAF", Scav, "ToHp", ToHp);
350 while (Scav <= ToHp) (SCAV_CODE(INFO_PTR(Scav)))();
351 DEBUG_SCAN("Scavenging End", Scav, "ToHp", ToHp);
353 /* this_extra_caf_words = ToHp - this_caf_start; */
354 /* ToDo: Report individual CAF space */
356 *extra_words = ToHp - caf_start;
362 #endif /* defined(_INFO_COPYING) */