[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / runtime / storage / SMcompacting.lc
1 \section[SM-compacting]{Compacting Collector Subroutines}
2
3 This is a collection of C functions used in implementing the compacting
4 collectors.
5
6 The motivation for making this a separate file/section is twofold:
7
8 1) It lets us focus on one thing.
9
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.
12
13 The second is the major motivation.  
14
15 ToDo ADR: trash contents of other semispace after GC in debugging version
16
17 \begin{code} 
18 #if defined(GC1s) || defined(GCdu) || defined(GCap) || defined(GCgn)
19     /* to the end */
20
21 #if defined(GC1s)
22
23 #define  SCAN_REG_DUMP
24 #include "SMinternal.h"
25 REGDUMP(ScanRegDump);
26
27 #else /* GCdu, GCap, GCgn */
28
29 #define SCAV_REG_MAP
30 #include "SMinternal.h"
31 REGDUMP(ScavRegDump);
32
33 #endif
34
35 #include "SMcompacting.h"
36 \end{code}
37
38 \begin{code}
39 void
40 LinkRoots(roots, rootno)
41 P_ roots[];
42 I_ rootno;
43 {
44     I_ root;
45
46     DEBUG_STRING("Linking Roots:");
47     for (root = 0; root < rootno; root++) {
48         LINK_LOCATION_TO_CLOSURE(&(roots[root]));
49     }
50 }
51
52 \end{code}
53
54 \begin{code}
55
56 #ifdef CONCURRENT
57 void
58 LinkSparks(STG_NO_ARGS)
59 {
60     PP_ sparkptr;
61     int pool;
62
63     DEBUG_STRING("Linking Sparks:");
64     for (pool = 0; pool < SPARK_POOLS; pool++) {
65         for (sparkptr = PendingSparksHd[pool]; 
66           sparkptr < PendingSparksTl[pool]; sparkptr++) {
67             LINK_LOCATION_TO_CLOSURE(sparkptr);
68         }
69     }
70 }
71 #endif
72
73 \end{code}
74
75 \begin{code}
76
77 #ifdef PAR
78
79 void
80 LinkLiveGAs(base, bits)
81 P_ base;
82 BitWord *bits;
83 {
84     GALA *gala;
85     GALA *next;
86     GALA *prev;
87     long _hp_word, bit_index, bit;
88
89     DEBUG_STRING("Linking Live GAs:");
90
91     for (gala = liveIndirections, prev = NULL; gala != NULL; gala = next) {
92         next = gala->next;
93         ASSERT(gala->ga.loc.gc.gtid == mytid);
94         if (gala->ga.weight != MAX_GA_WEIGHT) {
95             LINK_LOCATION_TO_CLOSURE(&gala->la);
96             gala->next = prev;
97             prev = gala;
98         } else {
99             /* Since we have all of the weight, this GA is no longer needed */
100             W_ pga = PACK_GA(thisPE, gala->ga.loc.gc.slot);
101
102 #ifdef FREE_DEBUG
103             fprintf(stderr, "Freeing slot %d\n", gala->ga.loc.gc.slot);
104 #endif
105             gala->next = freeIndirections;
106             freeIndirections->next = gala;
107             (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala);
108 #ifdef DEBUG
109             gala->ga.weight = 0x0d0d0d0d;
110             gala->la = (P_) 0xbadbad;
111 #endif
112         }
113     }
114     liveIndirections = prev;
115
116     prepareFreeMsgBuffers();
117
118     for (gala = liveRemoteGAs, prev = NULL; gala != NULL; gala = next) {
119         next = gala->next;
120         ASSERT(gala->ga.loc.gc.gtid != mytid);
121
122         _hp_word = gala->la - base;
123         bit_index = _hp_word / BITS_IN(BitWord);
124         bit = 1L << (_hp_word & (BITS_IN(BitWord) - 1));
125         if (!(bits[bit_index] & bit)) {
126             int pe = taskIDtoPE(gala->ga.loc.gc.gtid);
127             W_ pga = PACK_GA(pe, gala->ga.loc.gc.slot);
128             int i;
129
130             (void) removeHashTable(pGAtoGALAtable, pga, (void *) gala);
131             freeRemoteGA(pe, &(gala->ga));
132             gala->next = freeGALAList;
133             freeGALAList = gala;
134         } else {
135             LINK_LOCATION_TO_CLOSURE(&gala->la);
136             gala->next = prev;
137             prev = gala;
138         }
139     }
140     liveRemoteGAs = prev;
141
142     /* If we have any remaining FREE messages to send off, do so now */
143     sendFreeMessages();
144 }
145
146 #else
147
148 \end{code}
149
150 Note: no \tr{Link[AB]Stack} for ``parallel'' systems, because they
151 don't have a single main stack.
152
153 \begin{code}
154
155 void
156 LinkAStack(stackA, botA)
157 PP_ stackA;
158 PP_ botA;
159 {
160     PP_ stackptr;
161
162     DEBUG_STRING("Linking A Stack:");
163     for (stackptr = stackA;
164       SUBTRACT_A_STK(stackptr, botA) >= 0;
165       stackptr = stackptr + AREL(1)) {
166         LINK_LOCATION_TO_CLOSURE(stackptr);
167     }
168 }
169 #endif /* PAR */
170 \end{code}
171
172 ToDo (Patrick?): Dont explicitly mark & compact unmarked Bstack frames
173
174 \begin{code}   
175 #if ! defined(PAR)
176 void
177 LinkBStack(stackB, botB)
178 P_ stackB;
179 P_ botB;                        /* stackB points to topmost update frame */
180 {
181     P_ updateFramePtr;
182
183     DEBUG_STRING("Linking B Stack:");
184     for (updateFramePtr = stackB;
185       SUBTRACT_B_STK(updateFramePtr, botB) > 0;
186       /* re-initialiser given explicitly */ ) {
187
188         P_ updateClosurePtr = updateFramePtr + BREL(UF_UPDATEE);
189
190         LINK_LOCATION_TO_CLOSURE(updateClosurePtr);
191
192         updateFramePtr = GRAB_SuB(updateFramePtr);
193     }
194 }
195 #endif /* not PAR */
196 \end{code}
197
198 \begin{code}
199 I_
200 CountCAFs(CAFlist)
201 P_ CAFlist;
202 {
203     I_ caf_no = 0;
204
205     for (caf_no = 0; CAFlist != NULL; CAFlist = (P_) IND_CLOSURE_LINK(CAFlist))
206         caf_no++;
207
208     return caf_no;
209 }
210 \end{code}
211
212 \begin{code}
213 void
214 LinkCAFs(CAFlist)
215 P_ CAFlist;
216 {
217     DEBUG_STRING("Linking CAF Ptr Locations:");
218     while(CAFlist != NULL) {
219         DEBUG_LINK_CAF(CAFlist);
220         LINK_LOCATION_TO_CLOSURE(&IND_CLOSURE_PTR(CAFlist));
221         CAFlist = (P_) IND_CLOSURE_LINK(CAFlist);
222     }
223 }
224
225 \end{code}
226
227 \begin{code}
228
229 #ifdef PAR
230
231 #endif /* PAR */
232
233 #endif /* defined(_INFO_COMPACTING) */
234 \end{code}