78 if (dummy != NULL) {
79 // If the allocation was successful we should fill in the space.
80 CollectedHeap::fill_with_object(dummy, free_word_size);
81 alloc_region->set_pre_dummy_top(dummy);
82 result += free_word_size * HeapWordSize;
83 break;
84 }
85
86 free_word_size = alloc_region->free() / HeapWordSize;
87 // It's also possible that someone else beats us to the
88 // allocation and they fill up the region. In that case, we can
89 // just get out of the loop.
90 }
91 result += alloc_region->free();
92
93 assert(alloc_region->free() / HeapWordSize < min_word_size_to_fill,
94 "post-condition");
95 return result;
96 }
97
98 size_t G1AllocRegion::retire(bool fill_up) {
99 assert_alloc_region(_alloc_region != NULL, "not initialized properly");
100
101 size_t result = 0;
102
103 trace("retiring");
104 HeapRegion* alloc_region = _alloc_region;
105 if (alloc_region != _dummy_region) {
106 // We never have to check whether the active region is empty or not,
107 // and potentially free it if it is, given that it's guaranteed that
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 }
122 trace("retired");
123
124 return result;
125 }
126
127 HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size,
128 bool force) {
129 assert_alloc_region(_alloc_region == _dummy_region, "pre-condition");
130 assert_alloc_region(_used_bytes_before == 0, "pre-condition");
131
132 trace("attempting region allocation");
133 HeapRegion* new_alloc_region = allocate_new_region(word_size, force);
134 if (new_alloc_region != NULL) {
135 new_alloc_region->reset_pre_dummy_top();
136 // Need to do this before the allocation
137 _used_bytes_before = new_alloc_region->used();
138 HeapWord* result = allocate(new_alloc_region, word_size);
139 assert_alloc_region(result != NULL, "the allocation should succeeded");
140
141 OrderAccess::storestore();
142 // Note that we first perform the allocation and then we store the
143 // region in _alloc_region. This is the reason why an active region
144 // can never be empty.
228 }
229
230 out->print(" : %s", str);
231
232 if (detailed_info) {
233 if (result != NULL) {
234 out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT,
235 min_word_size, desired_word_size, actual_word_size, p2i(result));
236 } else if (min_word_size != 0) {
237 out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size);
238 }
239 }
240 out->cr();
241 }
242 }
243 #endif // PRODUCT
244
245 G1AllocRegion::G1AllocRegion(const char* name,
246 bool bot_updates)
247 : _name(name), _bot_updates(bot_updates),
248 _alloc_region(NULL), _count(0), _used_bytes_before(0) { }
249
250
251 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
252 bool force) {
253 return _g1h->new_mutator_alloc_region(word_size, force);
254 }
255
256 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
257 size_t allocated_bytes) {
258 _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes);
259 }
260
261 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size,
262 bool force) {
263 assert(!force, "not supported for GC alloc regions");
264 return _g1h->new_gc_alloc_region(word_size, _purpose);
265 }
266
267 void G1GCAllocRegion::retire_region(HeapRegion* alloc_region,
268 size_t allocated_bytes) {
269 _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, _purpose);
270 }
271
272 size_t G1GCAllocRegion::retire(bool fill_up) {
273 HeapRegion* retired = get();
274 size_t end_waste = G1AllocRegion::retire(fill_up);
275 // Do not count retirement of the dummy allocation region.
276 if (retired != NULL) {
277 _stats->add_region_end_waste(end_waste / HeapWordSize);
278 }
|
78 if (dummy != NULL) {
79 // If the allocation was successful we should fill in the space.
80 CollectedHeap::fill_with_object(dummy, free_word_size);
81 alloc_region->set_pre_dummy_top(dummy);
82 result += free_word_size * HeapWordSize;
83 break;
84 }
85
86 free_word_size = alloc_region->free() / HeapWordSize;
87 // It's also possible that someone else beats us to the
88 // allocation and they fill up the region. In that case, we can
89 // just get out of the loop.
90 }
91 result += alloc_region->free();
92
93 assert(alloc_region->free() / HeapWordSize < min_word_size_to_fill,
94 "post-condition");
95 return result;
96 }
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
118 size_t G1AllocRegion::retire(bool fill_up) {
119 assert_alloc_region(_alloc_region != NULL, "not initialized properly");
120
121 size_t waste = 0;
122
123 trace("retiring");
124 HeapRegion* alloc_region = _alloc_region;
125 if (alloc_region != _dummy_region) {
126 waste = retire_internal(alloc_region, fill_up);
127 reset_alloc_region();
128 }
129 trace("retired");
130
131 return waste;
132 }
133
134 HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size,
135 bool force) {
136 assert_alloc_region(_alloc_region == _dummy_region, "pre-condition");
137 assert_alloc_region(_used_bytes_before == 0, "pre-condition");
138
139 trace("attempting region allocation");
140 HeapRegion* new_alloc_region = allocate_new_region(word_size, force);
141 if (new_alloc_region != NULL) {
142 new_alloc_region->reset_pre_dummy_top();
143 // Need to do this before the allocation
144 _used_bytes_before = new_alloc_region->used();
145 HeapWord* result = allocate(new_alloc_region, word_size);
146 assert_alloc_region(result != NULL, "the allocation should succeeded");
147
148 OrderAccess::storestore();
149 // Note that we first perform the allocation and then we store the
150 // region in _alloc_region. This is the reason why an active region
151 // can never be empty.
235 }
236
237 out->print(" : %s", str);
238
239 if (detailed_info) {
240 if (result != NULL) {
241 out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT " actual " SIZE_FORMAT " " PTR_FORMAT,
242 min_word_size, desired_word_size, actual_word_size, p2i(result));
243 } else if (min_word_size != 0) {
244 out->print(" min " SIZE_FORMAT " desired " SIZE_FORMAT, min_word_size, desired_word_size);
245 }
246 }
247 out->cr();
248 }
249 }
250 #endif // PRODUCT
251
252 G1AllocRegion::G1AllocRegion(const char* name,
253 bool bot_updates)
254 : _name(name), _bot_updates(bot_updates),
255 _alloc_region(NULL), _count(0),
256 _used_bytes_before(0) { }
257
258
259 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
260 bool force) {
261 return _g1h->new_mutator_alloc_region(word_size, force);
262 }
263
264 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region,
265 size_t 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;
343 }
344
345 HeapRegion* G1GCAllocRegion::allocate_new_region(size_t word_size,
346 bool force) {
347 assert(!force, "not supported for GC alloc regions");
348 return _g1h->new_gc_alloc_region(word_size, _purpose);
349 }
350
351 void G1GCAllocRegion::retire_region(HeapRegion* alloc_region,
352 size_t allocated_bytes) {
353 _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, _purpose);
354 }
355
356 size_t G1GCAllocRegion::retire(bool fill_up) {
357 HeapRegion* retired = get();
358 size_t end_waste = G1AllocRegion::retire(fill_up);
359 // Do not count retirement of the dummy allocation region.
360 if (retired != NULL) {
361 _stats->add_region_end_waste(end_waste / HeapWordSize);
362 }
|