[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / ghc / runtime / storage / SMmarking.lc
1 /*************************************************************************
2                            MARKING OF ROOTS
3 *************************************************************************/
4
5 [Something needed here to explain what this is doing.  KH]
6
7 \begin{code}
8
9 #define MARK_REG_MAP
10 #include "SMinternal.h"
11
12 #if defined(_INFO_MARKING)
13
14 #if defined (__STG_GCC_REGS__) /* If we are using registers load _SAVE */
15
16 /* If we are using registers load _SAVE */
17 #define Mark     SAVE_Mark
18 #define MRoot    SAVE_MRoot
19 #define MStack   SAVE_MStack
20 #define BitArray SAVE_BitArray
21 #define HeapBase SAVE_HeapBase
22 #define HeapLim  SAVE_HeapLim
23
24 #endif /* registerized */
25
26 /* These in SMmark.lhc -- need to be in .hc file */
27 EXTFUN(_startMarkWorld);
28
29 EXTFUN(_PRMarking_MarkNextRoot);
30 EXTFUN(_PRMarking_MarkNextCAF);
31 EXTDATA(_PRMarking_MarkNextRoot_closure);
32 EXTDATA(_PRMarking_MarkNextCAF_closure);
33
34 #ifdef CONCURRENT
35 EXTFUN(_PRMarking_MarkNextSpark);
36 EXTDATA(_PRMarking_MarkNextSpark_closure);
37 #endif
38
39 #if defined(GRAN)
40 EXTFUN(_PRMarking_MarkNextEvent);
41 EXTDATA(_PRMarking_MarkNextEvent_closure);
42 EXTFUN(_PRMarking_MarkNextClosureInFetchBuffer);
43 EXTDATA(_PRMarking_MarkNextClosureInFetchBuffer_closure);
44 #endif
45
46 #ifdef PAR
47 EXTFUN(_PRMarking_MarkNextGA);
48 EXTDATA(_PRMarking_MarkNextGA_closure);
49 #else
50 EXTFUN(_PRMarking_MarkNextAStack);
51 EXTFUN(_PRMarking_MarkNextBStack);
52 EXTDATA(_PRMarking_MarkNextAStack_closure);
53 EXTDATA(_PRMarking_MarkNextBStack_closure);
54 #endif /* not parallel */
55
56 P_ sm_roots_end;
57 #if defined(GRAN)
58 P_ ret_MRoot, ret_Mark;
59 #endif
60
61 I_
62 markHeapRoots(sm, cafs1, cafs2, base, lim, bit_array)
63     smInfo *sm;
64     P_ cafs1, cafs2;  /* Pointer to CAF lists */
65     P_ base;          /* Heap closure in range only tested for by GCgn */
66     P_ lim;
67     BitWord *bit_array;
68 {
69 #ifdef CONCURRENT
70     int pool;
71 #endif
72 #if defined(GRAN)
73     PROC proc;
74     eventq event;
75     sparkq spark;
76     rtsBool found = rtsFalse;
77 #endif
78
79     BitArray = bit_array;
80     HeapBase = base;
81     HeapLim = lim;
82
83     DEBUG_STRING("Marking Roots:");
84     if (sm->rootno > 0) {
85         sm_roots_end = (P_) &sm->roots[sm->rootno];
86         MRoot = (P_) sm->roots;
87         Mark = (P_) *MRoot;
88         MStack = (P_) _PRMarking_MarkNextRoot_closure;
89
90         miniInterpret((StgFunPtr)_startMarkWorld);
91     }
92
93 #if defined(GRAN)
94     DEBUG_STRING("Marking Events (GRAN): ");
95     MRoot = (P_) EventHd;
96     found = rtsFalse;
97     do { 
98       if (MRoot != NULL) {
99         /* inlined version of MarkNextEvent */
100         switch (EVENT_TYPE( ((eventq) MRoot) )) {
101           case CONTINUETHREAD:
102           case STARTTHREAD:
103           case RESUMETHREAD:
104           case MOVETHREAD:
105              EVENT_GC_INFO( ((eventq) MRoot) ) = 0;
106              Mark = (P_) EVENT_TSO( ((eventq) MRoot) );
107              MStack = (P_) _PRMarking_MarkNextEvent_closure;
108              miniInterpret((StgFunPtr)_startMarkWorld);
109              found = rtsTrue;
110              break;
111           case MOVESPARK:
112              EVENT_GC_INFO( ((eventq) MRoot) ) = 0;
113              Mark = (P_) SPARK_NODE(EVENT_SPARK( ((eventq) MRoot) ));
114              MStack = (P_) _PRMarking_MarkNextEvent_closure;
115              miniInterpret((StgFunPtr)_startMarkWorld);
116              found = rtsTrue;
117              break;
118           case FETCHNODE:
119              EVENT_GC_INFO( ((eventq) MRoot) ) = 0;
120              Mark = (P_) EVENT_TSO( ((eventq) MRoot) );
121              MStack = (P_) _PRMarking_MarkNextEvent_closure;
122              miniInterpret((StgFunPtr)_startMarkWorld);
123              found = rtsTrue;
124              break;
125           case FETCHREPLY:
126              EVENT_GC_INFO( ((eventq) MRoot) ) = 0;
127              Mark = (P_) EVENT_TSO( ((eventq) MRoot) );
128              MStack = (P_) _PRMarking_MarkNextEvent_closure;
129              miniInterpret((StgFunPtr)_startMarkWorld);
130              found = rtsTrue;
131              break;
132            case GLOBALBLOCK:
133              EVENT_GC_INFO( ((eventq) MRoot) ) = 0;
134              Mark = (P_) EVENT_TSO( ((eventq) MRoot) );
135              MStack = (P_) _PRMarking_MarkNextEvent_closure;
136              miniInterpret((StgFunPtr)_startMarkWorld);
137              found = rtsTrue;
138              break;
139           case UNBLOCKTHREAD:
140              Mark = (P_) EVENT_TSO( ((eventq) MRoot) );
141              MStack = (P_) _PRMarking_MarkNextEvent_closure;
142              miniInterpret((StgFunPtr)_startMarkWorld);
143              found = rtsTrue;
144              break;
145           case FINDWORK:
146              MRoot = (P_) EVENT_NEXT( ((eventq) MRoot) );
147              found = rtsFalse;
148              break;
149           default:
150              fprintf(stderr,"Unknown event type %d (event @ %#x) in SMmarking_NextEvent\n",
151                               EVENT_TYPE( ((eventq) MRoot) ), MRoot);
152                EXIT(EXIT_FAILURE);
153         }
154       }
155     } while (!found && MRoot != NULL);
156
157     DEBUG_STRING("Marking Sparks (GRAN):");
158     for(proc = 0; proc < RTSflags.GranFlags.proc; ++proc) {
159       for(pool = 0; pool < SPARK_POOLS; pool++) {
160          MRoot = (P_) PendingSparksHd[proc][pool];
161          if (MRoot != NULL) {
162            Mark = (P_) SPARK_NODE( ((sparkq) MRoot) );
163            MStack = (P_) _PRMarking_MarkNextSpark_closure;
164            miniInterpret((StgFunPtr)_startMarkWorld);
165          }
166       }    /* forall pool ..   */
167     }     /* forall proc ...  */
168 #endif /* GRAN */
169
170 #if defined(CONCURRENT) && !defined(GRAN)
171     for(pool = 0; pool < SPARK_POOLS; pool++) {
172         if (PendingSparksHd[pool] < PendingSparksTl[pool]) {
173             sm_roots_end = (P_) PendingSparksTl[pool];
174             MRoot = (P_) PendingSparksHd[pool];
175             Mark = (P_) *MRoot;
176             MStack = (P_) _PRMarking_MarkNextSpark_closure;
177
178             miniInterpret((StgFunPtr)_startMarkWorld);
179         }
180     }
181 #endif
182
183 #ifdef PAR
184     DEBUG_STRING("Marking GA Roots:");
185     MRoot = (P_) liveIndirections;
186     while(MRoot != NULL && ((GALA *)MRoot)->ga.weight == MAX_GA_WEIGHT)
187         MRoot = (P_) ((GALA *)MRoot)->next;
188     if (MRoot != NULL) {
189         Mark = ((GALA *)MRoot)->la;
190         MStack = (P_) _PRMarking_MarkNextGA_closure;
191
192         miniInterpret((StgFunPtr) _startMarkWorld);
193     }
194 #else
195     /* Note: no *external* stacks in parallel/concurrent world */
196
197     DEBUG_STRING("Marking A Stack:");
198     if (SUBTRACT_A_STK(MAIN_SpA, stackInfo.botA) >= 0) {
199         MRoot = (P_) MAIN_SpA;
200         Mark = (P_) *MRoot;
201         MStack = (P_) _PRMarking_MarkNextAStack_closure;
202
203         miniInterpret((StgFunPtr)_startMarkWorld);
204     }
205
206     DEBUG_STRING("Marking B Stack:");
207     if (SUBTRACT_B_STK(MAIN_SuB, stackInfo.botB) > 0) {
208         MRoot = MAIN_SuB;
209         Mark = GRAB_UPDATEE(MRoot);
210         MStack = (P_) _PRMarking_MarkNextBStack_closure;
211         miniInterpret((StgFunPtr)_startMarkWorld);
212     }
213 #endif /* PAR */
214
215     DEBUG_STRING("Marking & Updating CAFs:");
216     if (cafs1) {
217         MRoot  = cafs1;
218         Mark   = (P_) IND_CLOSURE_PTR(MRoot);
219         MStack = (P_) _PRMarking_MarkNextCAF_closure;
220
221         miniInterpret((StgFunPtr)_startMarkWorld);
222     }
223
224     if (cafs2) {
225         MRoot  = cafs2;
226         Mark   = (P_) IND_CLOSURE_PTR(MRoot);
227         MStack = (P_) _PRMarking_MarkNextCAF_closure;
228
229         miniInterpret((StgFunPtr)_startMarkWorld);
230     }
231
232     return 0;
233 }
234
235 #endif /* _INFO_MARKING */
236 \end{code}
237
238
239 CODE REQUIRED (expressed as a loop):
240
241 MARK ROOTS
242
243     MStack = _PRMarking_MarkNextRoot_closure;
244     for (MRoot = (P_) sm->roots;
245          MRoot < (P_) &sm->roots[sm->rootno];
246          MRoot++) {
247         Mark = (P_) *MRoot;
248         (PRMARK_CODE(INFO_PTR(Mark)))();
249 _PRMarking_MarkNextRoot:
250         *MRoot = (W_) Mark;
251     }
252
253
254 MARK AStack
255
256     MStack = _PRMarking_MarkNextAStack_closure;
257     for (MRoot = MAIN_SpA;
258          SUBTRACT_A_STK(MRoot, stackInfo.botA) >= 0;
259          MRoot = MRoot + AREL(1)) {
260         Mark = (P_) *MRoot;
261         (PRMARK_CODE(INFO_PTR(Mark)))();
262 _PRMarking_MarkNextAStack:
263         *MRoot = (W_) Mark;
264     }
265
266
267 MARK BStack
268
269     MStack = _PRMarking_MarkNextBStack_closure;
270     for (MRoot = MAIN_SuB;  --- Topmost Update Frame
271          SUBTRACT_B_STK(MRoot, stackInfo.botB) > 0;
272          MRoot = GRAB_SuB(MRoot)) {
273
274         Mark = GRAB_UPDATEE(MRoot);
275         (PRMARK_CODE(INFO_PTR(Mark)))();
276 _PRMarking_MarkNextBStack:
277         PUSH_UPDATEE(MRoot, Mark);
278     }
279
280
281 MARK CAFs
282
283     MStack = _PRMarking_MarkNextCAF_closure;
284     for (MRoot = sm->CAFlist;
285          MRoot;
286          MRoot = (P_) IND_CLOSURE_LINK(MRoot))
287
288         Mark = IND_CLOSURE_PTR(MRoot);
289         (PRMARK_CODE(INFO_PTR(Mark)))();
290 _PRMarking_MarkNextCAF:
291         IND_CLOSURE_PTR(MRoot) = (W_) Mark;
292     }