93 assert(alloc_region->free() / HeapWordSize < min_word_size_to_fill, |
93 assert(alloc_region->free() / HeapWordSize < min_word_size_to_fill, |
94 "post-condition"); |
94 "post-condition"); |
95 return result; |
95 return result; |
96 } |
96 } |
97 |
97 |
|
98 size_t G1AllocRegion::retire_internal(HeapRegion* alloc_region, bool fill_up) { |
|
99 // We never have to check whether the active region is empty or not, |
|
100 // and potentially free it if it is, given that it's guaranteed that |
|
101 // it will never be empty. |
|
102 size_t waste = 0; |
|
103 assert_alloc_region(!alloc_region->is_empty(), |
|
104 "the alloc region should never be empty"); |
|
105 |
|
106 if (fill_up) { |
|
107 waste = fill_up_remaining_space(alloc_region); |
|
108 } |
|
109 |
|
110 assert_alloc_region(alloc_region->used() >= _used_bytes_before, "invariant"); |
|
111 size_t allocated_bytes = alloc_region->used() - _used_bytes_before; |
|
112 retire_region(alloc_region, allocated_bytes); |
|
113 _used_bytes_before = 0; |
|
114 |
|
115 return waste; |
|
116 } |
|
117 |
98 size_t G1AllocRegion::retire(bool fill_up) { |
118 size_t G1AllocRegion::retire(bool fill_up) { |
99 assert_alloc_region(_alloc_region != NULL, "not initialized properly"); |
119 assert_alloc_region(_alloc_region != NULL, "not initialized properly"); |
100 |
120 |
101 size_t result = 0; |
121 size_t waste = 0; |
102 |
122 |
103 trace("retiring"); |
123 trace("retiring"); |
104 HeapRegion* alloc_region = _alloc_region; |
124 HeapRegion* alloc_region = _alloc_region; |
105 if (alloc_region != _dummy_region) { |
125 if (alloc_region != _dummy_region) { |
106 // We never have to check whether the active region is empty or not, |
126 waste = retire_internal(alloc_region, fill_up); |
107 // and potentially free it if it is, given that it's guaranteed that |
127 reset_alloc_region(); |
108 // it will never be empty. |
|
109 assert_alloc_region(!alloc_region->is_empty(), |
|
110 "the alloc region should never be empty"); |
|
111 |
|
112 if (fill_up) { |
|
113 result = fill_up_remaining_space(alloc_region); |
|
114 } |
|
115 |
|
116 assert_alloc_region(alloc_region->used() >= _used_bytes_before, "invariant"); |
|
117 size_t allocated_bytes = alloc_region->used() - _used_bytes_before; |
|
118 retire_region(alloc_region, allocated_bytes); |
|
119 _used_bytes_before = 0; |
|
120 _alloc_region = _dummy_region; |
|
121 } |
128 } |
122 trace("retired"); |
129 trace("retired"); |
123 |
130 |
124 return result; |
131 return waste; |
125 } |
132 } |
126 |
133 |
127 HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size, |
134 HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size, |
128 bool force) { |
135 bool force) { |
129 assert_alloc_region(_alloc_region == _dummy_region, "pre-condition"); |
136 assert_alloc_region(_alloc_region == _dummy_region, "pre-condition"); |
243 #endif // PRODUCT |
250 #endif // PRODUCT |
244 |
251 |
245 G1AllocRegion::G1AllocRegion(const char* name, |
252 G1AllocRegion::G1AllocRegion(const char* name, |
246 bool bot_updates) |
253 bool bot_updates) |
247 : _name(name), _bot_updates(bot_updates), |
254 : _name(name), _bot_updates(bot_updates), |
248 _alloc_region(NULL), _count(0), _used_bytes_before(0) { } |
255 _alloc_region(NULL), _count(0), |
|
256 _used_bytes_before(0) { } |
249 |
257 |
250 |
258 |
251 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size, |
259 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size, |
252 bool force) { |
260 bool force) { |
253 return _g1h->new_mutator_alloc_region(word_size, force); |
261 return _g1h->new_mutator_alloc_region(word_size, force); |
254 } |
262 } |
255 |
263 |
256 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region, |
264 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region, |
257 size_t allocated_bytes) { |
265 size_t allocated_bytes) { |
258 _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes); |
266 _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes); |
|
267 } |
|
268 |
|
269 void MutatorAllocRegion::init() { |
|
270 assert(_retained_alloc_region == NULL, "Pre-condition"); |
|
271 G1AllocRegion::init(); |
|
272 _wasted_bytes = 0; |
|
273 } |
|
274 |
|
275 bool MutatorAllocRegion::should_retain(HeapRegion* region) { |
|
276 size_t free_bytes = region->free(); |
|
277 if (free_bytes < MinTLABSize) { |
|
278 return false; |
|
279 } |
|
280 |
|
281 if (_retained_alloc_region != NULL && |
|
282 free_bytes < _retained_alloc_region->free()) { |
|
283 return false; |
|
284 } |
|
285 |
|
286 return true; |
|
287 } |
|
288 |
|
289 size_t MutatorAllocRegion::retire(bool fill_up) { |
|
290 size_t waste = 0; |
|
291 trace("retiring"); |
|
292 HeapRegion* current_region = get(); |
|
293 if (current_region != NULL) { |
|
294 // Retain the current region if it fits a TLAB and has more |
|
295 // free than the currently retained region. |
|
296 if (should_retain(current_region)) { |
|
297 trace("mutator retained"); |
|
298 if (_retained_alloc_region != NULL) { |
|
299 waste = retire_internal(_retained_alloc_region, true); |
|
300 } |
|
301 _retained_alloc_region = current_region; |
|
302 } else { |
|
303 waste = retire_internal(current_region, fill_up); |
|
304 } |
|
305 reset_alloc_region(); |
|
306 } |
|
307 |
|
308 _wasted_bytes += waste; |
|
309 trace("retired"); |
|
310 return waste; |
|
311 } |
|
312 |
|
313 size_t MutatorAllocRegion::used_in_alloc_regions() { |
|
314 size_t used = 0; |
|
315 HeapRegion* hr = get(); |
|
316 if (hr != NULL) { |
|
317 used += hr->used(); |
|
318 } |
|
319 |
|
320 hr = _retained_alloc_region; |
|
321 if (hr != NULL) { |
|
322 used += hr->used(); |
|
323 } |
|
324 return used; |
|
325 } |
|
326 |
|
327 HeapRegion* MutatorAllocRegion::release() { |
|
328 HeapRegion* ret = G1AllocRegion::release(); |
|
329 |
|
330 // The retained alloc region must be retired and this must be |
|
331 // done after the above call to release the mutator alloc region, |
|
332 // since it might update the _retained_alloc_region member. |
|
333 if (_retained_alloc_region != NULL) { |
|
334 _wasted_bytes += retire_internal(_retained_alloc_region, false); |
|
335 _retained_alloc_region = NULL; |
|
336 } |
|
337 log_debug(gc, alloc, region)("Mutator Allocation stats, regions: %u, wasted size: " SIZE_FORMAT "%s (%4.1f%%)", |
|
338 count(), |
|
339 byte_size_in_proper_unit(_wasted_bytes), |
|
340 proper_unit_for_byte_size(_wasted_bytes), |
|
341 percent_of(_wasted_bytes, count() * HeapRegion::GrainBytes)); |
|
342 return ret; |
259 } |
343 } |
260 |
344 |
261 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size, |
345 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size, |
262 bool force) { |
346 bool force) { |
263 assert(!force, "not supported for GC alloc regions"); |
347 assert(!force, "not supported for GC alloc regions"); |