114 assert(verify(), "cache should be consistent"); |
114 assert(verify(), "cache should be consistent"); |
115 return ret; |
115 return ret; |
116 } else { |
116 } else { |
117 return NULL; |
117 return NULL; |
118 } |
118 } |
119 } |
|
120 |
|
121 // this is a bit expensive... but we expect that it should not be called |
|
122 // to often. |
|
123 void CSetChooserCache::remove(HeapRegion *hr) { |
|
124 assert(_occupancy > 0, "cache should not be empty"); |
|
125 assert(hr->sort_index() < -1, "should already be in the cache"); |
|
126 int index = get_index(hr->sort_index()); |
|
127 assert(_cache[index] == hr, "index should be correct"); |
|
128 int next_index = trim_index(index + 1); |
|
129 int last_index = trim_index(_first + _occupancy - 1); |
|
130 while (index != last_index) { |
|
131 assert(_cache[next_index] != NULL, "should not be null"); |
|
132 _cache[index] = _cache[next_index]; |
|
133 _cache[index]->set_sort_index(get_sort_index(index)); |
|
134 |
|
135 index = next_index; |
|
136 next_index = trim_index(next_index+1); |
|
137 } |
|
138 assert(index == last_index, "should have reached the last one"); |
|
139 _cache[index] = NULL; |
|
140 hr->set_sort_index(-1); |
|
141 --_occupancy; |
|
142 assert(verify(), "cache should be consistent"); |
|
143 } |
119 } |
144 |
120 |
145 static inline int orderRegions(HeapRegion* hr1, HeapRegion* hr2) { |
121 static inline int orderRegions(HeapRegion* hr1, HeapRegion* hr2) { |
146 if (hr1 == NULL) { |
122 if (hr1 == NULL) { |
147 if (hr2 == NULL) return 0; |
123 if (hr2 == NULL) return 0; |
195 "all entries before _curMarkedIndex should be NULL"); |
171 "all entries before _curMarkedIndex should be NULL"); |
196 } |
172 } |
197 HeapRegion *prev = NULL; |
173 HeapRegion *prev = NULL; |
198 while (index < _numMarkedRegions) { |
174 while (index < _numMarkedRegions) { |
199 HeapRegion *curr = _markedRegions.at(index++); |
175 HeapRegion *curr = _markedRegions.at(index++); |
200 if (curr != NULL) { |
176 guarantee(curr != NULL, "Regions in _markedRegions array cannot be NULL"); |
201 int si = curr->sort_index(); |
177 int si = curr->sort_index(); |
202 guarantee(!curr->is_young(), "should not be young!"); |
178 guarantee(!curr->is_young(), "should not be young!"); |
203 guarantee(si > -1 && si == (index-1), "sort index invariant"); |
179 guarantee(si > -1 && si == (index-1), "sort index invariant"); |
204 if (prev != NULL) { |
180 if (prev != NULL) { |
205 guarantee(orderRegions(prev, curr) != 1, "regions should be sorted"); |
181 guarantee(orderRegions(prev, curr) != 1, "regions should be sorted"); |
206 } |
182 } |
207 prev = curr; |
183 prev = curr; |
208 } |
|
209 } |
184 } |
210 return _cache.verify(); |
185 return _cache.verify(); |
211 } |
186 } |
212 #endif |
187 #endif |
213 |
188 |
214 bool |
189 void |
215 CollectionSetChooser::addRegionToCache() { |
190 CollectionSetChooser::fillCache() { |
216 assert(!_cache.is_full(), "cache should not be full"); |
191 while (!_cache.is_full() && (_curMarkedIndex < _numMarkedRegions)) { |
217 |
192 HeapRegion* hr = _markedRegions.at(_curMarkedIndex); |
218 HeapRegion *hr = NULL; |
193 assert(hr != NULL, |
219 while (hr == NULL && _curMarkedIndex < _numMarkedRegions) { |
194 err_msg("Unexpected NULL hr in _markedRegions at index %d", |
220 hr = _markedRegions.at(_curMarkedIndex++); |
195 _curMarkedIndex)); |
221 } |
196 _curMarkedIndex += 1; |
222 if (hr == NULL) |
197 assert(!hr->is_young(), "should not be young!"); |
223 return false; |
198 assert(hr->sort_index() == _curMarkedIndex-1, "sort_index invariant"); |
224 assert(!hr->is_young(), "should not be young!"); |
199 _markedRegions.at_put(hr->sort_index(), NULL); |
225 assert(hr->sort_index() == _curMarkedIndex-1, "sort_index invariant"); |
200 _cache.insert(hr); |
226 _markedRegions.at_put(hr->sort_index(), NULL); |
201 assert(!_cache.is_empty(), "cache should not be empty"); |
227 _cache.insert(hr); |
202 } |
228 assert(!_cache.is_empty(), "cache should not be empty"); |
|
229 assert(verify(), "cache should be consistent"); |
203 assert(verify(), "cache should be consistent"); |
230 return false; |
|
231 } |
|
232 |
|
233 void |
|
234 CollectionSetChooser::fillCache() { |
|
235 while (!_cache.is_full() && addRegionToCache()) { |
|
236 } |
|
237 } |
204 } |
238 |
205 |
239 void |
206 void |
240 CollectionSetChooser::sortMarkedHeapRegions() { |
207 CollectionSetChooser::sortMarkedHeapRegions() { |
241 guarantee(_cache.is_empty(), "cache should be empty"); |
208 guarantee(_cache.is_empty(), "cache should be empty"); |
330 }; |
297 }; |
331 |
298 |
332 void |
299 void |
333 CollectionSetChooser::updateAfterFullCollection() { |
300 CollectionSetChooser::updateAfterFullCollection() { |
334 clearMarkedHeapRegions(); |
301 clearMarkedHeapRegions(); |
335 } |
|
336 |
|
337 void CollectionSetChooser::removeRegion(HeapRegion *hr) { |
|
338 int si = hr->sort_index(); |
|
339 assert(si == -1 || hr->is_marked(), "Sort index not valid."); |
|
340 if (si > -1) { |
|
341 assert(_markedRegions.at(si) == hr, "Sort index not valid." ); |
|
342 _markedRegions.at_put(si, NULL); |
|
343 } else if (si < -1) { |
|
344 assert(_cache.region_in_cache(hr), "should be in the cache"); |
|
345 _cache.remove(hr); |
|
346 assert(hr->sort_index() == -1, "sort index invariant"); |
|
347 } |
|
348 hr->set_sort_index(-1); |
|
349 } |
302 } |
350 |
303 |
351 // if time_remaining < 0.0, then this method should try to return |
304 // if time_remaining < 0.0, then this method should try to return |
352 // a region, whether it fits within the remaining time or not |
305 // a region, whether it fits within the remaining time or not |
353 HeapRegion* |
306 HeapRegion* |