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 2 - (view) (download) (as text)

1 : monnier 2 /* 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 :     #ifdef COUNT_REG_MASKS
38 :     #define NUM_MASKS 64
39 :     PVT struct {
40 :     Word_t mask;
41 :     int count;
42 :     } Masks[NUM_MASKS];
43 :     PVT NumMasks = 0;
44 :     PVT NumOthers = 0;
45 :    
46 :     PVT void RecordMask (Word_t m)
47 :     {
48 :     int i;
49 :    
50 :     for (i = 0; (i < NumMasks) && (Masks[i].mask != m); i++)
51 :     continue;
52 :     if (i < NumMasks)
53 :     Masks[i].count++;
54 :     else if (i < NUM_MASKS) {
55 :     NumMasks++;
56 :     Masks[i].mask = m;
57 :     Masks[i].count = 1;
58 :     }
59 :     else
60 :     NumOthers++;
61 :     }
62 :    
63 :     void DumpMasks ()
64 :     {
65 :     int i;
66 :    
67 :     SayDebug ("GC Masks:\n");
68 :     for (i = 0; i < NumMasks; i++) {
69 :     SayDebug (" %#8x: %5d\n", Masks[i].mask, Masks[i].count);
70 :     }
71 :     if (NumOthers > 0)
72 :     SayDebug (" ????????: %5d\n", NumOthers);
73 :     }
74 :     #endif /* COUNT_REG_MASKS */
75 :    
76 :    
77 :    
78 :     /* InvokeGC:
79 :     *
80 :     * Invoke a garbage collection. A garbage collection always involves
81 :     * collecting the allocation space. In addition, if level is greater than
82 :     * 0, or if the first generation is full after the minor collection, then
83 :     * a major collection of one or more generations is performed (at least
84 :     * level generations are collected).
85 :     */
86 :     void InvokeGC (ml_state_t *msp, int level)
87 :     {
88 :     ml_val_t *roots[NUM_GC_ROOTS]; /* registers and globals */
89 :     ml_val_t **rootsPtr = roots;
90 :     heap_t *heap;
91 :     Word_t mask;
92 :     int i;
93 :     #ifdef MP_SUPPORT
94 :     int nProcs;
95 :     #endif
96 :    
97 :     ASSIGN(ProfCurrent, PROF_MINOR_GC);
98 :    
99 :     #ifdef MP_SUPPORT
100 :     #ifdef MP_DEBUG
101 :     SayDebug ("igc %d\n", msp->ml_mpSelf);
102 :     #endif
103 :     if ((nProcs = MP_StartCollect (msp)) == 0) {
104 :     /* a waiting proc */
105 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
106 :     return;
107 :     }
108 :     #endif
109 :    
110 :     START_GC_PAUSE(msp->ml_heap);
111 :    
112 :     #ifdef C_CALLS
113 :     *rootsPtr++ = &CInterfaceRootList;
114 :     #endif
115 :    
116 :     #ifdef MP_SUPPORT
117 :     /* get extra roots from procs that entered through InvokeGCWithRoots */
118 :     for (i = 0; mpExtraRoots[i] != NIL(ml_val_t *); i++)
119 :     *rootsPtr++ = mpExtraRoots[i];
120 :     #endif
121 :    
122 :     /* Gather the roots */
123 :     for (i = 0; i < NumCRoots; i++)
124 :     *rootsPtr++ = CRoots[i];
125 :     #ifdef MP_SUPPORT
126 :     {
127 :     vproc_state_t *vsp;
128 :     ml_state_t *msp;
129 :     int j;
130 :    
131 :     for (j = 0; j < MAX_NUM_PROCS; j++) {
132 :     vsp = VProc[j];
133 :     msp = vsp->vp_state;
134 :     #ifdef MP_DEBUG
135 :     SayDebug ("msp[%d] alloc/limit was %x/%x\n",
136 :     j, msp->ml_allocPtr, msp->ml_limitPtr);
137 :     #endif
138 :     if (vsp->vp_mpState == MP_PROC_RUNNING) {
139 :     *rootsPtr++ = &(msp->ml_exnCont);
140 :     *rootsPtr++ = &(msp->ml_varReg);
141 :     #ifdef BASE_INDX
142 :     *rootsPtr++ = &(msp->ml_baseReg);
143 :     #endif
144 :     mask = msp->ml_liveRegMask;
145 :     for (i = 0; mask != 0; i++, mask >>= 1) {
146 :     if ((mask & 1) != 0)
147 :     *rootsPtr++ = &(msp->ml_roots[ArgRegMap[i]]);
148 :     } /* for */
149 :     #ifdef N_PSEUDO_REGS
150 :     for (i = 0; i < N_PSEUDO_REGS; i++)
151 :     *rootsPtr++ = &(msp->ml_pseudoRegs[i]);
152 :     #endif
153 :     }
154 :     } /* for */
155 :     }
156 :     #else /* !MP_SUPPORT */
157 :     *rootsPtr++ = &(msp->ml_exnCont);
158 :     *rootsPtr++ = &(msp->ml_varReg);
159 :     #ifdef BASE_INDX
160 :     *rootsPtr++ = &(msp->ml_baseReg);
161 :     #endif
162 :     mask = msp->ml_liveRegMask;
163 :     #ifdef COUNT_REG_MASKS
164 :     RecordMask (mask);
165 :     #endif
166 :     for (i = 0; mask != 0; i++, mask >>= 1) {
167 :     if ((mask & 1) != 0)
168 :     *rootsPtr++ = &(msp->ml_roots[ArgRegMap[i]]);
169 :     }
170 :     #ifdef N_PSEUDO_REGS
171 :     for (i = 0; i < N_PSEUDO_REGS; i++)
172 :     *rootsPtr++ = &(msp->ml_pseudoRegs[i]);
173 :     #endif
174 :     #endif /* MP_SUPPORT */
175 :     *rootsPtr = NIL(ml_val_t *);
176 :    
177 :     MinorGC (msp, roots);
178 :    
179 :     heap = msp->ml_heap;
180 :    
181 :     /* Check for major GC */
182 :     if (level == 0) {
183 :     gen_t *gen1 = heap->gen[0];
184 :     Word_t sz = msp->ml_allocArenaSzB;
185 :    
186 :     for (i = 0; i < NUM_ARENAS; i++) {
187 :     arena_t *arena = gen1->arena[i];
188 :     if (isACTIVE(arena) && (AVAIL_SPACE(arena) < sz)) {
189 :     level = 1;
190 :     break;
191 :     }
192 :     }
193 :     }
194 :    
195 :     if (level > 0) {
196 :     #ifdef MP_SUPPORT
197 :     vproc_state_t *vsp;
198 :     ml_state_t *msp;
199 :    
200 :     for (i = 0; i < MAX_NUM_PROCS; i++) {
201 :     vsp = VProc[i];
202 :     msp = vsp->vp_state;
203 :     if (vsp->vp_mpState == MP_PROC_RUNNING)
204 :     *rootsPtr++ = &(msp->ml_pc);
205 :     }
206 :     #else
207 :     ASSIGN(ProfCurrent, PROF_MAJOR_GC);
208 :     *rootsPtr++ = &(msp->ml_pc);
209 :     #endif
210 :     *rootsPtr = NIL(ml_val_t *);
211 :     MajorGC (msp, roots, level);
212 :     }
213 :     else {
214 :     HeapMon_UpdateHeap (heap, 1);
215 :     }
216 :    
217 :     /* reset the allocation space */
218 :     #ifdef MP_SUPPORT
219 :     MP_FinishCollect (msp, nProcs);
220 :     #else
221 :     msp->ml_allocPtr = heap->allocBase;
222 :     #ifdef SOFT_POLL
223 :     ResetPollLimit (msp);
224 :     #else
225 :     msp->ml_limitPtr = HEAP_LIMIT(heap);
226 :     #endif
227 :     #endif
228 :    
229 :     STOP_GC_PAUSE();
230 :    
231 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
232 :    
233 :     } /* end of InvokeGC */
234 :    
235 :    
236 :     /* InvokeGCWithRoots:
237 :     *
238 :     * Invoke a garbage collection with possible additional roots. The list of
239 :     * additional roots should be NIL terminated. A garbage collection always
240 :     * involves collecting the allocation space. In addition, if level is greater
241 :     * than 0, or if the first generation is full after the minor collection, then
242 :     * a major collection of one or more generations is performed (at least level
243 :     * generations are collected).
244 :     *
245 :     * NOTE: the MP version of this may be broken, since if a processor calls this
246 :     * but isn't the collecting process, then the extra roots are lost.
247 :     */
248 :     void InvokeGCWithRoots (ml_state_t *msp, int level, ...)
249 :     {
250 :     ml_val_t *roots[NUM_GC_ROOTS+NUM_EXTRA_ROOTS]; /* registers and globals */
251 :     ml_val_t **rootsPtr = roots, *p;
252 :     heap_t *heap;
253 :     Word_t mask;
254 :     int i;
255 :     va_list ap;
256 :     #ifdef MP_SUPPORT
257 :     int nProcs;
258 :     #endif
259 :    
260 :     ASSIGN(ProfCurrent, PROF_MINOR_GC);
261 :    
262 :     #ifdef MP_SUPPORT
263 :     #ifdef MP_DEBUG
264 :     SayDebug ("igcwr %d\n", msp->ml_mpSelf);
265 :     #endif
266 :     va_start (ap, level);
267 :     nProcs = MP_StartCollectWithRoots (msp, ap);
268 :     va_end(ap);
269 :     if (nProcs == 0)
270 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
271 :     return; /* a waiting proc */
272 :     #endif
273 :    
274 :     START_GC_PAUSE(msp->ml_heap);
275 :    
276 :     #ifdef C_CALLS
277 :     *rootsPtr++ = &CInterfaceRootList;
278 :     #endif
279 :    
280 :     #ifdef MP_SUPPORT
281 :     /* get extra roots from procs that entered through InvokeGCWithRoots.
282 :     * Our extra roots were placed in mpExtraRoots by MP_StartCollectWithRoots.
283 :     */
284 :     for (i = 0; mpExtraRoots[i] != NIL(ml_val_t *); i++)
285 :     *rootsPtr++ = mpExtraRoots[i];
286 :     #else
287 :     /* record extra roots from param list */
288 :     va_start (ap, level);
289 :     while ((p = va_arg(ap, ml_val_t *)) != NIL(ml_val_t *)) {
290 :     *rootsPtr++ = p;
291 :     }
292 :     va_end(ap);
293 :     #endif /* MP_SUPPORT */
294 :    
295 :     /* Gather the roots */
296 :     for (i = 0; i < NumCRoots; i++)
297 :     *rootsPtr++ = CRoots[i];
298 :     #ifdef MP_SUPPORT
299 :     {
300 :     ml_state_t *msp;
301 :     vproc_state_t *vsp;
302 :     int j;
303 :    
304 :     for (j = 0; j < MAX_NUM_PROCS; j++) {
305 :     vsp = VProc[j];
306 :     msp = vsp->vp_state;
307 :     #ifdef MP_DEBUG
308 :     SayDebug ("msp[%d] alloc/limit was %x/%x\n",
309 :     j, msp->ml_allocPtr, msp->ml_limitPtr);
310 :     #endif
311 :     if (vsp->vp_mpState == MP_PROC_RUNNING) {
312 :     *rootsPtr++ = &(msp->ml_exnCont);
313 :     *rootsPtr++ = &(msp->ml_varReg);
314 :     #ifdef BASE_INDX
315 :     *rootsPtr++ = &(msp->ml_baseReg);
316 :     #endif
317 :     mask = msp->ml_liveRegMask;
318 :     for (i = 0; mask != 0; i++, mask >>= 1) {
319 :     if ((mask & 1) != 0)
320 :     *rootsPtr++ = &(msp->ml_roots[ArgRegMap[i]]);
321 :     } /* for */
322 :     #ifdef N_PSEUDO_REGS
323 :     for (i = 0; i < N_PSEUDO_REGS; i++)
324 :     *rootsPtr++ = &(msp->ml_pseudoRegs[i]);
325 :     #endif
326 :     }
327 :     } /* for */
328 :     }
329 :     #else /* !MP_SUPPORT */
330 :     *rootsPtr++ = &(msp->ml_exnCont);
331 :     *rootsPtr++ = &(msp->ml_varReg);
332 :     #ifdef BASE_INDX
333 :     *rootsPtr++ = &(msp->ml_baseReg);
334 :     #endif
335 :     mask = msp->ml_liveRegMask;
336 :     for (i = 0; mask != 0; i++, mask >>= 1) {
337 :     if ((mask & 1) != 0)
338 :     *rootsPtr++ = &(msp->ml_roots[ArgRegMap[i]]);
339 :     }
340 :     #ifdef N_PSEUDO_REGS
341 :     for (i = 0; i < N_PSEUDO_REGS; i++)
342 :     *rootsPtr++ = &(msp->ml_pseudoRegs[i]);
343 :     #endif
344 :     #endif /* MP_SUPPORT */
345 :     *rootsPtr = NIL(ml_val_t *);
346 :    
347 :     MinorGC (msp, roots);
348 :    
349 :     heap = msp->ml_heap;
350 :    
351 :     /* Check for major GC */
352 :     if (level == 0) {
353 :     gen_t *gen1 = heap->gen[0];
354 :     Word_t sz = msp->ml_allocArenaSzB;
355 :    
356 :     for (i = 0; i < NUM_ARENAS; i++) {
357 :     arena_t *arena = gen1->arena[i];
358 :     if (isACTIVE(arena) && (AVAIL_SPACE(arena) < sz)) {
359 :     level = 1;
360 :     break;
361 :     }
362 :     }
363 :     }
364 :    
365 :     if (level > 0) {
366 :     #ifdef MP_SUPPORT
367 :     vproc_state_t *vsp;
368 :    
369 :     for (i = 0; i < MAX_NUM_PROCS; i++) {
370 :     vsp = VProc[i];
371 :     if (vsp->vp_mpState == MP_PROC_RUNNING)
372 :     *rootsPtr++ = &(vsp->vp_state->ml_pc);
373 :     }
374 :     #else
375 :     ASSIGN(ProfCurrent, PROF_MAJOR_GC);
376 :     *rootsPtr++ = &(msp->ml_pc);
377 :     #endif
378 :     *rootsPtr = NIL(ml_val_t *);
379 :     MajorGC (msp, roots, level);
380 :     }
381 :     else {
382 :     HeapMon_UpdateHeap (heap, 1);
383 :     }
384 :    
385 :     /* reset the allocation space */
386 :     #ifdef MP_SUPPORT
387 :     MP_FinishCollect (msp, nProcs);
388 :     #else
389 :     msp->ml_allocPtr = heap->allocBase;
390 :     #ifdef SOFT_POLL
391 :     ResetPollLimit (msp);
392 :     #else
393 :     msp->ml_limitPtr = HEAP_LIMIT(heap);
394 :     #endif
395 :     #endif
396 :    
397 :     STOP_GC_PAUSE();
398 :    
399 :     ASSIGN(ProfCurrent, PROF_RUNTIME);
400 :    
401 :     } /* end of InvokeGCWithRoots */
402 :    
403 :     /* NeedGC:
404 :     *
405 :     * Check to see if a GC is required, or if there is enough heap space for
406 :     * nbytes worth of allocation. Return TRUE, if GC is required, FALSE
407 :     * otherwise.
408 :     */
409 :     bool_t NeedGC (ml_state_t *msp, Word_t nbytes)
410 :     {
411 :     #if (defined(MP_SUPPORT) && defined(COMMENT_MP_GCPOLL))
412 :     if ((((Addr_t)(msp->ml_allocPtr)+nbytes) >= (Addr_t)(msp->ml_limitPtr))
413 :     || (INT_MLtoC(PollEvent) != 0))
414 :     #elif defined(MP_SUPPORT)
415 :     if (((Addr_t)(msp->ml_allocPtr)+nbytes) >= (Addr_t)(msp->ml_limitPtr))
416 :     #else
417 :     if (((Addr_t)(msp->ml_allocPtr)+nbytes) >= (Addr_t)HEAP_LIMIT(msp->ml_heap))
418 :     #endif
419 :     return TRUE;
420 :     else
421 :     return FALSE;
422 :    
423 :     } /* end of NeedGC */
424 :    
425 :    
426 :     #ifdef SOFT_POLL
427 :     /* ResetPollLimit:
428 :     *
429 :     * Reset the limit pointer according to the current polling frequency.
430 :     */
431 :     void ResetPollLimit (ml_state_t *msp)
432 :     {
433 :     int pollFreq = INT_MLtoC(DEREF(PollFreq));
434 :     heap_t *heap = msp->ml_heap;
435 :    
436 :     /* assumes ml_allocPtr has been reset */
437 :     msp->ml_realLimit = HEAP_LIMIT(heap);
438 :     if (pollFreq > 0) {
439 :     msp->ml_limitPtr = heap->allocBase + pollFreq*POLL_GRAIN_CPSI;
440 :     msp->ml_limitPtr = (msp->ml_limitPtr > msp->ml_realLimit)
441 :     ? msp->ml_realLimit
442 :     : msp->ml_limitPtr;
443 :     }
444 :     else
445 :     msp->ml_limitPtr = msp->ml_realLimit;
446 :    
447 :     } /* end ResetPollLimit */
448 :     #endif /* SOFT_POLL */

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