void G1AllocRegion::setup(G1CollectedHeap* g1h, HeapRegion* dummy_region) { assert(_dummy_region == NULL, "should be set once"); assert(dummy_region != NULL, "pre-condition"); assert(dummy_region->free() == 0, "pre-condition"); // Make sure that any allocation attempt on this region will fail // and will not trigger any asserts. assert(allocate(dummy_region, 1, false) == NULL, "should fail"); assert(par_allocate(dummy_region, 1, false) == NULL, "should fail"); assert(allocate(dummy_region, 1, true) == NULL, "should fail"); assert(par_allocate(dummy_region, 1, true) == NULL, "should fail"); _g1h = g1h; _dummy_region = dummy_region; }
/** * 并发分配 */ inline HeapWord* G1AllocRegion::attempt_allocation(size_t word_size, bool bot_updates) { assert(bot_updates == _bot_updates, ar_ext_msg(this, "pre-condition")); HeapRegion* alloc_region = _alloc_region; assert(alloc_region != NULL, ar_ext_msg(this, "not initialized properly")); HeapWord* result = par_allocate(alloc_region, word_size, bot_updates); if (result != NULL) { trace("alloc", word_size, result); return result; } trace("alloc failed", word_size); return NULL; }
void G1AllocRegion::fill_up_remaining_space(HeapRegion* alloc_region, bool bot_updates) { assert(alloc_region != NULL && alloc_region != _dummy_region, "pre-condition"); // Other threads might still be trying to allocate using a CAS out // of the region we are trying to retire, as they can do so without // holding the lock. So, we first have to make sure that noone else // can allocate out of it by doing a maximal allocation. Even if our // CAS attempt fails a few times, we'll succeed sooner or later // given that failed CAS attempts mean that the region is getting // closed to being full. size_t free_word_size = alloc_region->free() / HeapWordSize; // This is the minimum free chunk we can turn into a dummy // object. If the free space falls below this, then noone can // allocate in this region anyway (all allocation requests will be // of a size larger than this) so we won't have to perform the dummy // allocation. size_t min_word_size_to_fill = CollectedHeap::min_fill_size(); while (free_word_size >= min_word_size_to_fill) { HeapWord* dummy = par_allocate(alloc_region, free_word_size, bot_updates); if (dummy != NULL) { // If the allocation was successful we should fill in the space. CollectedHeap::fill_with_object(dummy, free_word_size); alloc_region->set_pre_dummy_top(dummy); break; } free_word_size = alloc_region->free() / HeapWordSize; // It's also possible that someone else beats us to the // allocation and they fill up the region. In that case, we can // just get out of the loop. } assert(alloc_region->free() / HeapWordSize < min_word_size_to_fill, "post-condition"); }