--- old/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp 2015-03-05 15:35:43.647616161 +0100 +++ new/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp 2015-03-05 15:35:43.577614080 +0100 @@ -33,32 +33,40 @@ #include "runtime/atomic.inline.hpp" // This version requires locking. -inline HeapWord* G1OffsetTableContigSpace::allocate_impl(size_t size, - HeapWord* const end_value) { +inline HeapWord* G1OffsetTableContigSpace::allocate_impl(size_t min_word_size, + size_t& size, + HeapWord* const end_value) { HeapWord* obj = top(); - if (pointer_delta(end_value, obj) >= size) { - HeapWord* new_top = obj + size; + size_t available = pointer_delta(end_value, obj); + size_t want_to_allocate = MIN2(available, size); + if (want_to_allocate >= min_word_size) { + HeapWord* new_top = obj + want_to_allocate; set_top(new_top); assert(is_aligned(obj) && is_aligned(new_top), "checking alignment"); - return obj; + size = want_to_allocate; + return obj; } else { return NULL; } } // This version is lock-free. -inline HeapWord* G1OffsetTableContigSpace::par_allocate_impl(size_t size, - HeapWord* const end_value) { +inline HeapWord* G1OffsetTableContigSpace::par_allocate_impl(size_t min_word_size, + size_t& size, + HeapWord* const end_value) { do { HeapWord* obj = top(); - if (pointer_delta(end_value, obj) >= size) { - HeapWord* new_top = obj + size; + size_t available = pointer_delta(end_value, obj); + size_t want_to_allocate = MIN2(available, size); + if (want_to_allocate >= min_word_size) { + HeapWord* new_top = obj + want_to_allocate; HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj); // result can be one of two: // the old top value: the exchange succeeded // otherwise: the new value of the top is returned. if (result == obj) { assert(is_aligned(obj) && is_aligned(new_top), "checking alignment"); + size = want_to_allocate; return obj; } } else { @@ -67,8 +75,8 @@ } while (true); } -inline HeapWord* G1OffsetTableContigSpace::allocate(size_t size) { - HeapWord* res = allocate_impl(size, end()); +inline HeapWord* G1OffsetTableContigSpace::allocate(size_t min_word_size, size_t& size) { + HeapWord* res = allocate_impl(min_word_size, size, end()); if (res != NULL) { _offsets.alloc_block(res, size); } @@ -78,9 +86,9 @@ // Because of the requirement of keeping "_offsets" up to date with the // allocations, we sequentialize these with a lock. Therefore, best if // this is used for larger LAB allocations only. -inline HeapWord* G1OffsetTableContigSpace::par_allocate(size_t size) { +inline HeapWord* G1OffsetTableContigSpace::par_allocate(size_t min_word_size, size_t& size) { MutexLocker x(&_par_alloc_lock); - return allocate(size); + return allocate(min_word_size, size); } inline HeapWord* G1OffsetTableContigSpace::block_start(const void* p) { @@ -128,14 +136,14 @@ return pointer_delta(next, addr); } -inline HeapWord* HeapRegion::par_allocate_no_bot_updates(size_t word_size) { +inline HeapWord* HeapRegion::par_allocate_no_bot_updates(size_t min_word_size, size_t& word_size) { assert(is_young(), "we can only skip BOT updates on young regions"); - return par_allocate_impl(word_size, end()); + return par_allocate_impl(min_word_size, word_size, end()); } -inline HeapWord* HeapRegion::allocate_no_bot_updates(size_t word_size) { +inline HeapWord* HeapRegion::allocate_no_bot_updates(size_t min_word_size, size_t& word_size) { assert(is_young(), "we can only skip BOT updates on young regions"); - return allocate_impl(word_size, end()); + return allocate_impl(min_word_size, word_size, end()); } inline void HeapRegion::note_start_of_marking() {