Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/gc/call-gc.c
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/call-gc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 569 - (view) (download) (as text)

1 : monnier 249 /* call-gc.c
2 :     *
3 :     * COPYRIGHT (c) 1993 by AT&T Bell Laboratories.
4 :     *
5 :     * The main interface between the GC and the rest of the run-time system.
6 :     * These are the routines used to invoke the GC.
7 :     */
8 :    
9 :     #ifdef PAUSE_STATS /* GC pause statistics are UNIX dependent */
10 :     # include "ml-unixdep.h"
11 :     #endif
12 :    
13 :     #include <stdarg.h>
14 :     #include "ml-base.h"
15 :     #include "ml-limits.h"
16 :     #include "memory.h"
17 :     #include "ml-state.h"
18 :     #include "ml-values.h"
19 :     #include "ml-objects.h"
20 :     #include "cntr.h"
21 :     #include "heap.h"
22 :     #include "heap-monitor.h"
23 :     #include "ml-globals.h"
24 :     #include "ml-timer.h"
25 :     #include "gc-stats.h"
26 :     #include "vproc-state.h"
27 :     #include "profile.h"
28 :    
29 :     #ifdef C_CALLS
30 :     /* This is a list of pointers into the C heap locations that hold
31 :     * pointers to ML functions. This list is not part of any ML data
32 :     * structure(s). (also see gc/major-gc.c and c-libs/c-calls/c-calls-fns.c)
33 :     */
34 :     extern ml_val_t CInterfaceRootList;
35 :     #endif
36 :    
37 :    
38 :     /* InvokeGC:
39 :     *
40 :     * Invoke a garbage collection. A garbage collection always involves
41 :     * collecting the allocation space. In addition, if level is greater than
42 :     * 0, or if the first generation is full after the minor collection, then
43 :     * a major collection of one or more generations is performed (at least
44 :     * level generations are collected).
45 :     */
46 :     void InvokeGC (ml_state_t *msp, int level)
47 :     {
48 :     ml_val_t *roots[NUM_GC_ROOTS]; /* registers and globals */
49 :     ml_val_t **rootsPtr = roots;
50 :     heap_t *heap;
51 :     int i;
52 :     #ifdef MP_SUPPORT
53 :     int nProcs;
54 :     #endif
55 :    
56 :     ASSIGN(ProfCurrent, PROF_MINOR_GC);
57 :    
58 :     #ifdef MP_SUPPORT
59 :     #ifdef MP_DEBUG
60 :     SayDebug ("igc %d\n", msp->ml_mpSelf);
61 :     #endif
62 :     if ((nProcs = MP_StartCollect (msp)) == 0) {
63 :     /* a waiting proc */
64 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
65 :     return;
66 :     }
67 :     #endif
68 :    
69 :     START_GC_PAUSE(msp->ml_heap);
70 :    
71 :     #ifdef C_CALLS
72 :     *rootsPtr++ = &CInterfaceRootList;
73 :     #endif
74 :    
75 :     #ifdef MP_SUPPORT
76 :     /* get extra roots from procs that entered through InvokeGCWithRoots */
77 :     for (i = 0; mpExtraRoots[i] != NIL(ml_val_t *); i++)
78 :     *rootsPtr++ = mpExtraRoots[i];
79 :     #endif
80 :    
81 :     /* Gather the roots */
82 :     for (i = 0; i < NumCRoots; i++)
83 :     *rootsPtr++ = CRoots[i];
84 :     #ifdef MP_SUPPORT
85 :     {
86 :     vproc_state_t *vsp;
87 :     ml_state_t *msp;
88 :     int j;
89 :    
90 :     for (j = 0; j < MAX_NUM_PROCS; j++) {
91 :     vsp = VProc[j];
92 :     msp = vsp->vp_state;
93 :     #ifdef MP_DEBUG
94 :     SayDebug ("msp[%d] alloc/limit was %x/%x\n",
95 :     j, msp->ml_allocPtr, msp->ml_limitPtr);
96 :     #endif
97 :     if (vsp->vp_mpState == MP_PROC_RUNNING) {
98 :     *rootsPtr++ = &(msp->ml_arg);
99 :     *rootsPtr++ = &(msp->ml_cont);
100 :     *rootsPtr++ = &(msp->ml_closure);
101 :     *rootsPtr++ = &(msp->ml_exnCont);
102 :     *rootsPtr++ = &(msp->ml_varReg);
103 :     *rootsPtr++ = &(msp->ml_calleeSave[0]);
104 :     *rootsPtr++ = &(msp->ml_calleeSave[1]);
105 :     *rootsPtr++ = &(msp->ml_calleeSave[2]);
106 :     }
107 :     } /* for */
108 :     }
109 :     #else /* !MP_SUPPORT */
110 :     *rootsPtr++ = &(msp->ml_linkReg);
111 :     *rootsPtr++ = &(msp->ml_arg);
112 :     *rootsPtr++ = &(msp->ml_cont);
113 :     *rootsPtr++ = &(msp->ml_closure);
114 :     *rootsPtr++ = &(msp->ml_exnCont);
115 :     *rootsPtr++ = &(msp->ml_varReg);
116 :     *rootsPtr++ = &(msp->ml_calleeSave[0]);
117 :     *rootsPtr++ = &(msp->ml_calleeSave[1]);
118 :     *rootsPtr++ = &(msp->ml_calleeSave[2]);
119 :     #endif /* MP_SUPPORT */
120 :     *rootsPtr = NIL(ml_val_t *);
121 :    
122 :     MinorGC (msp, roots);
123 :    
124 :     heap = msp->ml_heap;
125 :    
126 :     /* Check for major GC */
127 :     if (level == 0) {
128 :     gen_t *gen1 = heap->gen[0];
129 :     Word_t sz = msp->ml_allocArenaSzB;
130 :    
131 :     for (i = 0; i < NUM_ARENAS; i++) {
132 :     arena_t *arena = gen1->arena[i];
133 :     if (isACTIVE(arena) && (AVAIL_SPACE(arena) < sz)) {
134 :     level = 1;
135 :     break;
136 :     }
137 :     }
138 :     }
139 :    
140 :     if (level > 0) {
141 :     #ifdef MP_SUPPORT
142 :     vproc_state_t *vsp;
143 :     ml_state_t *msp;
144 :    
145 :     for (i = 0; i < MAX_NUM_PROCS; i++) {
146 :     vsp = VProc[i];
147 :     msp = vsp->vp_state;
148 :     if (vsp->vp_mpState == MP_PROC_RUNNING)
149 :     *rootsPtr++ = &(msp->ml_linkReg);
150 :     }
151 :     #else
152 :     ASSIGN(ProfCurrent, PROF_MAJOR_GC);
153 :     #endif
154 :     *rootsPtr = NIL(ml_val_t *);
155 :     MajorGC (msp, roots, level);
156 :     }
157 :     else {
158 :     HeapMon_UpdateHeap (heap, 1);
159 :     }
160 :    
161 :     /* reset the allocation space */
162 :     #ifdef MP_SUPPORT
163 :     MP_FinishCollect (msp, nProcs);
164 :     #else
165 :     msp->ml_allocPtr = heap->allocBase;
166 :     #ifdef SOFT_POLL
167 :     ResetPollLimit (msp);
168 :     #else
169 :     msp->ml_limitPtr = HEAP_LIMIT(heap);
170 :     #endif
171 :     #endif
172 :    
173 :     STOP_GC_PAUSE();
174 :    
175 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
176 :    
177 :     } /* end of InvokeGC */
178 :    
179 :    
180 :     /* InvokeGCWithRoots:
181 :     *
182 :     * Invoke a garbage collection with possible additional roots. The list of
183 :     * additional roots should be NIL terminated. A garbage collection always
184 :     * involves collecting the allocation space. In addition, if level is greater
185 :     * than 0, or if the first generation is full after the minor collection, then
186 :     * a major collection of one or more generations is performed (at least level
187 :     * generations are collected).
188 :     *
189 :     * NOTE: the MP version of this may be broken, since if a processor calls this
190 :     * but isn't the collecting process, then the extra roots are lost.
191 :     */
192 :     void InvokeGCWithRoots (ml_state_t *msp, int level, ...)
193 :     {
194 :     ml_val_t *roots[NUM_GC_ROOTS+NUM_EXTRA_ROOTS]; /* registers and globals */
195 :     ml_val_t **rootsPtr = roots, *p;
196 :     heap_t *heap;
197 :     int i;
198 :     va_list ap;
199 :     #ifdef MP_SUPPORT
200 :     int nProcs;
201 :     #endif
202 :    
203 :     ASSIGN(ProfCurrent, PROF_MINOR_GC);
204 :    
205 :     #ifdef MP_SUPPORT
206 :     #ifdef MP_DEBUG
207 :     SayDebug ("igcwr %d\n", msp->ml_mpSelf);
208 :     #endif
209 :     va_start (ap, level);
210 :     nProcs = MP_StartCollectWithRoots (msp, ap);
211 :     va_end(ap);
212 :     if (nProcs == 0)
213 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
214 :     return; /* a waiting proc */
215 :     #endif
216 :    
217 :     START_GC_PAUSE(msp->ml_heap);
218 :    
219 :     #ifdef C_CALLS
220 :     *rootsPtr++ = &CInterfaceRootList;
221 :     #endif
222 :    
223 :     #ifdef MP_SUPPORT
224 :     /* get extra roots from procs that entered through InvokeGCWithRoots.
225 :     * Our extra roots were placed in mpExtraRoots by MP_StartCollectWithRoots.
226 :     */
227 :     for (i = 0; mpExtraRoots[i] != NIL(ml_val_t *); i++)
228 :     *rootsPtr++ = mpExtraRoots[i];
229 :     #else
230 :     /* record extra roots from param list */
231 :     va_start (ap, level);
232 :     while ((p = va_arg(ap, ml_val_t *)) != NIL(ml_val_t *)) {
233 :     *rootsPtr++ = p;
234 :     }
235 :     va_end(ap);
236 :     #endif /* MP_SUPPORT */
237 :    
238 :     /* Gather the roots */
239 :     for (i = 0; i < NumCRoots; i++)
240 :     *rootsPtr++ = CRoots[i];
241 :     #ifdef MP_SUPPORT
242 :     {
243 :     ml_state_t *msp;
244 :     vproc_state_t *vsp;
245 :     int j;
246 :    
247 :     for (j = 0; j < MAX_NUM_PROCS; j++) {
248 :     vsp = VProc[j];
249 :     msp = vsp->vp_state;
250 :     #ifdef MP_DEBUG
251 :     SayDebug ("msp[%d] alloc/limit was %x/%x\n",
252 :     j, msp->ml_allocPtr, msp->ml_limitPtr);
253 :     #endif
254 :     if (vsp->vp_mpState == MP_PROC_RUNNING) {
255 :     *rootsPtr++ = &(msp->ml_arg);
256 :     *rootsPtr++ = &(msp->ml_cont);
257 :     *rootsPtr++ = &(msp->ml_closure);
258 :     *rootsPtr++ = &(msp->ml_exnCont);
259 :     *rootsPtr++ = &(msp->ml_varReg);
260 :     *rootsPtr++ = &(msp->ml_calleeSave[0]);
261 :     *rootsPtr++ = &(msp->ml_calleeSave[1]);
262 :     *rootsPtr++ = &(msp->ml_calleeSave[2]);
263 :     }
264 :     } /* for */
265 :     }
266 :     #else /* !MP_SUPPORT */
267 :     *rootsPtr++ = &(msp->ml_arg);
268 :     *rootsPtr++ = &(msp->ml_cont);
269 :     *rootsPtr++ = &(msp->ml_closure);
270 :     *rootsPtr++ = &(msp->ml_exnCont);
271 :     *rootsPtr++ = &(msp->ml_varReg);
272 :     *rootsPtr++ = &(msp->ml_calleeSave[0]);
273 :     *rootsPtr++ = &(msp->ml_calleeSave[1]);
274 :     *rootsPtr++ = &(msp->ml_calleeSave[2]);
275 :     #endif /* MP_SUPPORT */
276 :     *rootsPtr = NIL(ml_val_t *);
277 :    
278 :     MinorGC (msp, roots);
279 :    
280 :     heap = msp->ml_heap;
281 :    
282 :     /* Check for major GC */
283 :     if (level == 0) {
284 :     gen_t *gen1 = heap->gen[0];
285 :     Word_t sz = msp->ml_allocArenaSzB;
286 :    
287 :     for (i = 0; i < NUM_ARENAS; i++) {
288 :     arena_t *arena = gen1->arena[i];
289 :     if (isACTIVE(arena) && (AVAIL_SPACE(arena) < sz)) {
290 :     level = 1;
291 :     break;
292 :     }
293 :     }
294 :     }
295 :    
296 :     if (level > 0) {
297 :     #ifdef MP_SUPPORT
298 :     vproc_state_t *vsp;
299 :    
300 :     for (i = 0; i < MAX_NUM_PROCS; i++) {
301 :     vsp = VProc[i];
302 :     if (vsp->vp_mpState == MP_PROC_RUNNING)
303 :     *rootsPtr++ = &(vsp->vp_state->ml_linkReg);
304 :     }
305 :     #else
306 :     ASSIGN(ProfCurrent, PROF_MAJOR_GC);
307 :     *rootsPtr++ = &(msp->ml_linkReg);
308 :     *rootsPtr++ = &(msp->ml_pc);
309 :     #endif
310 :     *rootsPtr = NIL(ml_val_t *);
311 :     MajorGC (msp, roots, level);
312 :     }
313 :     else {
314 :     HeapMon_UpdateHeap (heap, 1);
315 :     }
316 :    
317 :     /* reset the allocation space */
318 :     #ifdef MP_SUPPORT
319 :     MP_FinishCollect (msp, nProcs);
320 :     #else
321 :     msp->ml_allocPtr = heap->allocBase;
322 :     #ifdef SOFT_POLL
323 :     ResetPollLimit (msp);
324 :     #else
325 :     msp->ml_limitPtr = HEAP_LIMIT(heap);
326 :     #endif
327 :     #endif
328 :    
329 :     STOP_GC_PAUSE();
330 :    
331 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
332 :    
333 :     } /* end of InvokeGCWithRoots */
334 :    
335 :     /* NeedGC:
336 :     *
337 :     * Check to see if a GC is required, or if there is enough heap space for
338 :     * nbytes worth of allocation. Return TRUE, if GC is required, FALSE
339 :     * otherwise.
340 :     */
341 :     bool_t NeedGC (ml_state_t *msp, Word_t nbytes)
342 :     {
343 :     #if (defined(MP_SUPPORT) && defined(COMMENT_MP_GCPOLL))
344 :     if ((((Addr_t)(msp->ml_allocPtr)+nbytes) >= (Addr_t)(msp->ml_limitPtr))
345 :     || (INT_MLtoC(PollEvent) != 0))
346 :     #elif defined(MP_SUPPORT)
347 :     if (((Addr_t)(msp->ml_allocPtr)+nbytes) >= (Addr_t)(msp->ml_limitPtr))
348 :     #else
349 :     if (((Addr_t)(msp->ml_allocPtr)+nbytes) >= (Addr_t)HEAP_LIMIT(msp->ml_heap))
350 :     #endif
351 :     return TRUE;
352 :     else
353 :     return FALSE;
354 :    
355 :     } /* end of NeedGC */
356 :    
357 :    
358 :     #ifdef SOFT_POLL
359 :     /* ResetPollLimit:
360 :     *
361 :     * Reset the limit pointer according to the current polling frequency.
362 :     */
363 :     void ResetPollLimit (ml_state_t *msp)
364 :     {
365 :     int pollFreq = INT_MLtoC(DEREF(PollFreq));
366 :     heap_t *heap = msp->ml_heap;
367 :    
368 :     /* assumes ml_allocPtr has been reset */
369 :     msp->ml_realLimit = HEAP_LIMIT(heap);
370 :     if (pollFreq > 0) {
371 :     msp->ml_limitPtr = heap->allocBase + pollFreq*POLL_GRAIN_CPSI;
372 :     msp->ml_limitPtr = (msp->ml_limitPtr > msp->ml_realLimit)
373 :     ? msp->ml_realLimit
374 :     : msp->ml_limitPtr;
375 :     }
376 :     else
377 :     msp->ml_limitPtr = msp->ml_realLimit;
378 :    
379 :     } /* end ResetPollLimit */
380 :     #endif /* SOFT_POLL */

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0