--- old/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp 2014-06-25 13:43:35.811525370 +0200 +++ new/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp 2014-06-25 13:43:35.707521129 +0200 @@ -31,38 +31,43 @@ #include "memory/space.hpp" #include "runtime/atomic.inline.hpp" -inline HeapWord* G1OffsetTableContigSpace::cas_allocate_inner(size_t size) { +// This version requires locking. +inline HeapWord* G1OffsetTableContigSpace::allocate_impl(size_t size, + HeapWord* const end_value) { HeapWord* obj = top(); + if (pointer_delta(end_value, obj) >= size) { + HeapWord* new_top = obj + size; + set_top(new_top); + assert(is_aligned(obj) && is_aligned(new_top), "checking alignment"); + return obj; + } else { + return NULL; + } +} + +// This version is lock-free. +inline HeapWord* G1OffsetTableContigSpace::par_allocate_impl(size_t size, + HeapWord* const end_value) { do { - if (pointer_delta(end(), obj) >= size) { + HeapWord* obj = top(); + if (pointer_delta(end_value, obj) >= size) { HeapWord* new_top = obj + size; - HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, &_top, obj); + 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"); return obj; } - obj = result; } else { - break; + return NULL; } } while (true); - return NULL; } -inline HeapWord* G1OffsetTableContigSpace::allocate_inner(size_t size) { - HeapWord* obj = top(); - if (pointer_delta(end(), obj) >= size) { - HeapWord* new_top = obj + size; - assert(is_aligned(obj) && is_aligned(new_top), "checking alignment"); - set_top(new_top); - return obj; - } - return NULL; -} - - inline HeapWord* G1OffsetTableContigSpace::allocate(size_t size) { - HeapWord* res = allocate_inner(size); + HeapWord* res = allocate_impl(size, end()); if (res != NULL) { _offsets.alloc_block(res, size); } @@ -104,12 +109,12 @@ inline HeapWord* HeapRegion::par_allocate_no_bot_updates(size_t word_size) { assert(is_young(), "we can only skip BOT updates on young regions"); - return cas_allocate_inner(word_size); + return par_allocate_impl(word_size, end()); } inline HeapWord* HeapRegion::allocate_no_bot_updates(size_t word_size) { assert(is_young(), "we can only skip BOT updates on young regions"); - return allocate_inner(word_size); + return allocate_impl(word_size, end()); } inline void HeapRegion::note_start_of_marking() {