diff options
Diffstat (limited to 'lgc.h')
-rw-r--r-- | lgc.h | 44 |
1 files changed, 41 insertions, 3 deletions
@@ -123,6 +123,43 @@ | |||
123 | #define changeage(o,f,t) \ | 123 | #define changeage(o,f,t) \ |
124 | check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) | 124 | check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) |
125 | 125 | ||
126 | /* | ||
127 | ** In generational mode, objects are created 'new'. After surviving one | ||
128 | ** cycle, they become 'survival'. Both 'new' and 'survival' can point | ||
129 | ** to any other object, as they are traversed at the end of the cycle. | ||
130 | ** We call them both 'young' objects. | ||
131 | ** If a survival object survives another cycle, it becomes 'old1'. | ||
132 | ** 'old1' objects can still point to survival objects (but not to | ||
133 | ** new objects), so they still must be traversed. After another cycle | ||
134 | ** (that, being old, 'old1' objects will "survive" no matter what) | ||
135 | ** finally the 'old1' object becomes really 'old', and then they | ||
136 | ** are no more traversed. | ||
137 | ** | ||
138 | ** To keep its invariants, the generational mode uses the same barriers | ||
139 | ** also used by the incremental mode. If a young object is caught in a | ||
140 | ** foward barrier, it cannot become old immediately, because it can | ||
141 | ** still point to other young objects. Instead, it becomes 'old0', | ||
142 | ** which in the next cycle becomes 'old1'. So, 'old0' objects is | ||
143 | ** old but can point to new and survival objects; 'old1' is old | ||
144 | ** but cannot point to new objects; and 'old' cannot point to any | ||
145 | ** young object. | ||
146 | ** | ||
147 | ** If any old object ('old0', 'old1', 'old') is caught in a back | ||
148 | ** barrier, it becomes 'touched1' and goes into a gray list, to be | ||
149 | ** visited at the end of the cycle. There it evolves to 'touched2', | ||
150 | ** which can point to survivals but not to new objects. In yet another | ||
151 | ** cycle then it becomes 'old' again. | ||
152 | ** | ||
153 | ** The generational mode must also control the colors of objects, | ||
154 | ** because of the barriers. While the mutator is running, young objects | ||
155 | ** are kept white. 'old', 'old1', and 'touched2' objects are kept black, | ||
156 | ** as they cannot point to new objects; exceptions are threads and open | ||
157 | ** upvalues, which age to 'old1' and 'old' but are kept gray. 'old0' | ||
158 | ** objects may be gray or black, as in the incremental mode. 'touched1' | ||
159 | ** objects are kept gray, as they must be visited again at the end of | ||
160 | ** the cycle. | ||
161 | */ | ||
162 | |||
126 | 163 | ||
127 | /* Default Values for GC parameters */ | 164 | /* Default Values for GC parameters */ |
128 | 165 | ||
@@ -161,9 +198,10 @@ | |||
161 | ** (value * original parameter / 100). | 198 | ** (value * original parameter / 100). |
162 | ** | 199 | ** |
163 | ** For most parameters, which are typically larger than 100%, 2^n is | 200 | ** For most parameters, which are typically larger than 100%, 2^n is |
164 | ** 16 (2^4), allowing maximum values up to 1599. For the minor | 201 | ** 16 (2^4), allowing maximum values up to ~1500%, with a granularity |
165 | ** multiplier, which is typically smaller, 2^n is 64 (2^6) to allow more | 202 | ** of ~6%. For the minor multiplier, which is typically smaller, |
166 | ** precision. | 203 | ** 2^n is 64 (2^6) to allow more precision. In that case, the maximum |
204 | ** value is ~400%, with a granularity of ~1.5%. | ||
167 | */ | 205 | */ |
168 | #define gcparamshift(p) \ | 206 | #define gcparamshift(p) \ |
169 | (offsetof(global_State, p) == offsetof(global_State, genminormul) ? 6 : 4) | 207 | (offsetof(global_State, p) == offsetof(global_State, genminormul) ? 6 : 4) |