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/flip.c
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/flip.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 249 - (view) (download) (as text)
Original Path: sml/branches/SMLNJ/src/runtime/gc/flip.c

1 : monnier 249 /* flip.c
2 :     *
3 :     * COPYRIGHT (c) 1993 by AT&T Bell Laboratories.
4 :     *
5 :     * This code determines which generations to flip and what the
6 :     * to-space sizes should be.
7 :     */
8 :    
9 :     #include "ml-base.h"
10 :     #include "ml-limits.h"
11 :     #include "ml-state.h"
12 :     #include "heap.h"
13 :     #include "heap-monitor.h"
14 :    
15 :     #if defined(VERBOSE)
16 :     extern char *ArenaName[NUM_ARENAS+1];
17 :     #endif
18 :    
19 :    
20 :     /* Flip:
21 :     *
22 :     * Determine which generations need to be flipped and flip them. Return
23 :     * the number of flipped generations (which will be at least min_gc_level).
24 :     * It is assumed that the fist generation is always flipped (i.e., that
25 :     * min_gc_level > 1).
26 :     */
27 :     int Flip (heap_t *heap, int min_gc_level)
28 :     {
29 :     int i, j, prevGC, numGCs;
30 :     Addr_t totSz, newSz, prevOldSz[NUM_ARENAS], minSize[NUM_ARENAS];
31 :     arena_t *ap;
32 :    
33 :     #ifdef VERBOSE
34 :     SayDebug ("Flip: min_gc_level = %d\n", min_gc_level);
35 :     #endif
36 :     for (i = 0; i < NUM_ARENAS; i++)
37 :     prevOldSz[i] = heap->allocSzB;
38 :    
39 :     prevGC = heap->numMinorGCs;
40 :     for (i = 0; i < heap->numGens; i++) {
41 :     gen_t *g = heap->gen[i];
42 :    
43 :     /* Check to see if generation (i+1) should be flipped */
44 :     #ifdef VERBOSE
45 :     SayDebug ("checking generation %d\n", i+1);
46 :     #endif
47 :     if (i >= min_gc_level) {
48 :     for (j = 0; j < NUM_ARENAS; j++) {
49 :     arena_t *ap = g->arena[j];
50 :     #ifdef VERBOSE
51 :     SayDebug (" %s: avail = %d, prev = %d\n",
52 :     ArenaName[j+1], (isACTIVE(ap) ? AVAIL_SPACE(ap) : 0), prevOldSz[j]);
53 :     #endif
54 :     if ((isACTIVE(ap) ? AVAIL_SPACE(ap) : 0) < prevOldSz[j])
55 :     goto flip;
56 :     }
57 :     /* Here we don't need to flip gen[i] */
58 :     return i;
59 :     }
60 :     flip:; /* Here we need to flip gen[i] */
61 :    
62 :     numGCs = prevGC - g->lastPrevGC;
63 :     #ifdef VERBOSE
64 :     SayDebug ("Flip generation %d: (%d GCs)\n", i+1, numGCs);
65 :     #endif
66 :     /* Compute the space requirements for this generation, make the old
67 :     * to-space into from-space, and allocate a new to-space.
68 :     */
69 :     for (j = 0; j < NUM_ARENAS; j++) {
70 :     Addr_t minSz, thisMinSz;
71 :     ap = g->arena[j];
72 :     if (isACTIVE(ap)) {
73 :     FLIP_ARENA(ap);
74 :     HeapMon_MarkFromSp (heap, ap->frspBase, ap->frspSizeB);
75 :     thisMinSz = ((Addr_t)(ap->frspTop) - (Addr_t)(ap->oldTop));
76 :     }
77 :     else {
78 :     ap->frspSizeB = 0; /* to insure accurate stats */
79 :     if ((ap->reqSizeB == 0) && (prevOldSz[j] == 0))
80 :     continue;
81 :     else
82 :     thisMinSz = 0;
83 :     }
84 :     minSz = prevOldSz[j] + thisMinSz + ap->reqSizeB;
85 :     if (j == PAIR_INDX)
86 :     /* first slot isn't used, but may need the space for poly = */
87 :     minSz += 2*WORD_SZB;
88 :     minSize[j] = minSz;
89 :    
90 :     #ifdef OLD_POLICY
91 :     /* The desired size is the minimum size times the ratio for the arena,
92 :     * but it shouldn't exceed the maximum size for the arena (unless
93 :     * minSz > maxSizeB).
94 :     */
95 :     newSz = (ap->ratio * minSz) / RATIO_UNIT;
96 :     if (newSz < minSz+ap->reqSizeB)
97 :     newSz = minSz+ap->reqSizeB;
98 :     #endif
99 :     /* The desired size is one that will allow "ratio" GCs of the
100 :     * previous generation before this has to be collected again.
101 :     * We approximate this as ((f*ratio) / n), where
102 :     * f == # of bytes forwarded since the last collection of this generation
103 :     * n == # of collections of the previous generation since the last
104 :     * collection of this generation
105 :     * We also need to allow space for young objects in this generation,
106 :     * but the new size shouldn't exceed the maximum size for the arena
107 :     * (unless minSz > maxSizeB).
108 :     */
109 :     newSz = minSz + ((thisMinSz * (g->ratio-1)) / numGCs);
110 :     #ifdef VERBOSE
111 :     SayDebug (" %s: min = %d, prev = %d, thisMin = %d, req = %d, new = %d, max = %d\n",
112 :     ArenaName[j+1], minSz, prevOldSz[j], thisMinSz, ap->reqSizeB, newSz, ap->maxSizeB);
113 :     #endif
114 :     if (newSz > ap->maxSizeB)
115 :     newSz = (minSz > ap->maxSizeB) ? minSz : ap->maxSizeB;
116 :     ap->reqSizeB = 0;
117 :    
118 :     if (newSz > 0) {
119 :     ap->tospSizeB = RND_MEMOBJ_SZB(newSz);
120 :     #ifdef VERBOSE
121 :     SayDebug (" alloc %d\n", ap->tospSizeB);
122 :     #endif
123 :     }
124 :     else {
125 :     ap->nextw = NIL(ml_val_t *);
126 :     ap->tospTop = NIL(ml_val_t *);
127 :     ap->tospSizeB = 0;
128 :     }
129 :     /* Note: any data between ap->oldTop and ap->nextw is "young", and
130 :     * should stay in this generation.
131 :     */
132 :     if (ap->frspSizeB > 0)
133 :     prevOldSz[j] = (Addr_t)(ap->oldTop) - (Addr_t)(ap->frspBase);
134 :     else
135 :     prevOldSz[j] = 0;
136 :     }
137 :    
138 :     g->lastPrevGC = prevGC;
139 :     g->numGCs++;
140 :     prevGC = g->numGCs;
141 :     g->fromObj = g->toObj;
142 :     if (NewGeneration(g) == FAILURE) {
143 :     /* try to allocate the minimum size */
144 :     Error ("unable to allocate to-space for generation %d; trying smaller size\n", i+1);
145 :     for (j = 0; j < NUM_ARENAS; j++) {
146 :     g->arena[j]->tospSizeB = RND_MEMOBJ_SZB(minSize[j]);
147 :     }
148 :     if (NewGeneration(g) == FAILURE)
149 :     Die("unable to allocate minimum size\n");
150 :     }
151 :     #ifdef TOSPACE_ID
152 :     for (j = 0; j < NUM_ARENAS; j++) {
153 :     arena_t *ap = g->arena[j];
154 :     if (isACTIVE(ap))
155 :     MarkRegion (BIBOP, ap->tospBase, ap->tospSizeB, TOSPACE_AID(i+1));
156 :     }
157 :     #endif
158 :    
159 :     if (isACTIVE(g->arena[ARRAY_INDX]))
160 :     NewDirtyVector(g);
161 :     }
162 :    
163 :     return heap->numGens;
164 :    
165 :     } /* end of Flip */

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