--- old/src/share/vm/gc_implementation/shared/plab.hpp 2015-04-17 19:08:41.226783967 +0300 +++ new/src/share/vm/gc_implementation/shared/plab.hpp 2015-04-17 19:08:41.150782780 +0300 @@ -45,6 +45,7 @@ // In support of ergonomic sizing of PLAB's size_t _allocated; // in HeapWord units size_t _wasted; // in HeapWord units + size_t _undo_wasted; char tail[32]; static size_t AlignmentReserve; @@ -62,6 +63,19 @@ // the amount of remaining space. size_t retire_internal(); + void add_undo_waste(HeapWord* obj, size_t word_sz) { + CollectedHeap::fill_with_object(obj, word_sz); + _undo_wasted += word_sz; + } + + // Undo the last allocation in the buffer, which is required to be of the + // "obj" of the given "word_sz". + void undo_last_allocation(HeapWord* obj, size_t word_sz) { + assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo"); + assert(pointer_delta(_top, obj) == word_sz, "Bad undo"); + _top = obj; + } + public: // Initializes the buffer to be empty, but with the given "word_sz". // Must get initialized with "set_buf" for an allocation to succeed. @@ -90,18 +104,26 @@ // Allocate the object aligned to "alignment_in_bytes". HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes); - // Undo the last allocation in the buffer, which is required to be of the + // Undo any allocation in the buffer, which is required to be of the // "obj" of the given "word_sz". void undo_allocation(HeapWord* obj, size_t word_sz) { - assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo"); - assert(pointer_delta(_top, obj) == word_sz, "Bad undo"); - _top = obj; + // Is the alloc in the current alloc buffer? + if (contains(obj)) { + assert(contains(obj + word_sz - 1), + "should contain whole object"); + undo_last_allocation(obj, word_sz); + } else { + add_undo_waste(obj, word_sz); + } } // The total (word) size of the buffer, including both allocated and // unallocated space. size_t word_sz() { return _word_sz; } + size_t waste() { return _wasted; } + size_t undo_waste() { return _undo_wasted; } + // Should only be done if we are about to reset with a new buffer of the // given size. void set_word_size(size_t new_word_sz) { @@ -146,20 +168,23 @@ class PLABStats VALUE_OBJ_CLASS_SPEC { size_t _allocated; // Total allocated size_t _wasted; // of which wasted (internal fragmentation) + size_t _undo_wasted; // of which wasted on undo (is not used for calculation of PLAB size) size_t _unused; // Unused in last buffer size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized AdaptiveWeightedAverage _filter; // Integrator with decay void reset() { - _allocated = 0; - _wasted = 0; - _unused = 0; + _allocated = 0; + _wasted = 0; + _undo_wasted = 0; + _unused = 0; } public: PLABStats(size_t desired_plab_sz_, unsigned wt) : _allocated(0), _wasted(0), + _undo_wasted(0), _unused(0), _desired_plab_sz(desired_plab_sz_), _filter(wt) @@ -192,6 +217,10 @@ void add_wasted(size_t v) { Atomic::add_ptr(v, &_wasted); } + + void add_undo_wasted(size_t v) { + Atomic::add_ptr(v, &_undo_wasted); + } }; #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP