HeapRegion* OldGCAllocRegion::release() { HeapRegion* cur = get(); if (cur != NULL) { // Determine how far we are from the next card boundary. If it is smaller than // the minimum object size we can allocate into, expand into the next card. HeapWord* top = cur->top(); HeapWord* aligned_top = (HeapWord*)align_ptr_up(top, G1BlockOffsetSharedArray::N_bytes); size_t to_allocate_words = pointer_delta(aligned_top, top, HeapWordSize); if (to_allocate_words != 0) { // We are not at a card boundary. Fill up, possibly into the next, taking the // end of the region and the minimum object size into account. to_allocate_words = MIN2(pointer_delta(cur->end(), cur->top(), HeapWordSize), MAX2(to_allocate_words, G1CollectedHeap::min_fill_size())); // Skip allocation if there is not enough space to allocate even the smallest // possible object. In this case this region will not be retained, so the // original problem cannot occur. if (to_allocate_words >= G1CollectedHeap::min_fill_size()) { HeapWord* dummy = attempt_allocation(to_allocate_words, true /* bot_updates */); CollectedHeap::fill_with_object(dummy, to_allocate_words); } } } return G1AllocRegion::release(); }
inline HeapWord* G1AllocRegion::attempt_allocation_locked(size_t word_size, bool bot_updates) { // First we have to tedo the allocation, assuming we're holding the // appropriate lock, in case another thread changed the region while // we were waiting to get the lock. HeapWord* result = attempt_allocation(word_size, bot_updates); if (result != NULL) { return result; } retire(true /* fill_up */); result = new_alloc_region_and_allocate(word_size, false /* force */); if (result != NULL) { trace("alloc locked (second attempt)", word_size, result); return result; } trace("alloc locked failed", word_size); return NULL; }