diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 1e9de0dad39bbb3d6b1a65457f37fa54b1d1bd95..83521899d0dde92fc3662adf67b118ea2d202068 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -4571,7 +4571,7 @@ HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, } G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : - ParGCAllocBuffer(gclab_word_size), _retired(false) { } + ParGCAllocBuffer(gclab_word_size), _retired(true) { } G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp) : _g1h(g1h), @@ -4935,8 +4935,6 @@ void G1ParEvacuateFollowersClosure::do_void() { pss->trim_queue(); } } while (!offer_termination()); - - pss->retire_alloc_buffers(); } class G1KlassScanClosure : public KlassClosure { @@ -5776,10 +5774,8 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) { } _gc_tracer_stw->report_gc_reference_stats(stats); - // We have completed copying any necessary live referent objects - // (that were not copied during the actual pause) so we can - // retire any active alloc buffers - pss.retire_alloc_buffers(); + + // We have completed copying any necessary live referent objects. assert(pss.refs()->is_empty(), "both queue and overflow should be empty"); double ref_proc_time = os::elapsedTime() - ref_proc_start; diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 0daffe7aade6a80b4c6ab4d8ff0760b0ad08b476..06b6d61da34cfae648b66c352a0326c2012c58f8 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -1691,15 +1691,19 @@ private: public: G1ParGCAllocBuffer(size_t gclab_word_size); + virtual ~G1ParGCAllocBuffer() { + guarantee(_retired, "Allocation buffer has not been retired"); + } - void set_buf(HeapWord* buf) { + virtual void set_buf(HeapWord* buf) { ParGCAllocBuffer::set_buf(buf); _retired = false; } - void retire(bool end_of_gc, bool retain) { - if (_retired) + virtual void retire(bool end_of_gc, bool retain) { + if (_retired) { return; + } ParGCAllocBuffer::retire(end_of_gc, retain); _retired = true; } @@ -1769,6 +1773,7 @@ public: G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp); ~G1ParScanThreadState() { + retire_alloc_buffers(); FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC); } @@ -1879,6 +1884,7 @@ public: return _surviving_young_words; } +private: void retire_alloc_buffers() { for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { size_t waste = _alloc_buffers[ap]->words_remaining(); @@ -1888,8 +1894,8 @@ public: false /* retain */); } } -private: - #define G1_PARTIAL_ARRAY_MASK 0x2 + +#define G1_PARTIAL_ARRAY_MASK 0x2 inline bool has_partial_array_mask(oop* ref) const { return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK; diff --git a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp index aac3e9815cc02adb68a1f98e5d278c5388cd841a..63f3213ce2d4bff2e5d4415140323c82d73dbe79 100644 --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp @@ -60,6 +60,7 @@ public: // Initializes the buffer to be empty, but with the given "word_sz". // Must get initialized with "set_buf" for an allocation to succeed. ParGCAllocBuffer(size_t word_sz); + virtual ~ParGCAllocBuffer() {} static const size_t min_size() { return ThreadLocalAllocBuffer::min_size(); @@ -113,7 +114,7 @@ public: } // Sets the space of the buffer to be [buf, space+word_sz()). - void set_buf(HeapWord* buf) { + virtual void set_buf(HeapWord* buf) { _bottom = buf; _top = _bottom; _hard_end = _bottom + word_sz(); @@ -158,7 +159,7 @@ public: // Fills in the unallocated portion of the buffer with a garbage object. // If "end_of_gc" is TRUE, is after the last use in the GC. IF "retain" // is true, attempt to re-use the unused portion in the next GC. - void retire(bool end_of_gc, bool retain); + virtual void retire(bool end_of_gc, bool retain); void print() PRODUCT_RETURN; }; @@ -238,14 +239,14 @@ public: void undo_allocation(HeapWord* obj, size_t word_sz); - void set_buf(HeapWord* buf_start) { + virtual void set_buf(HeapWord* buf_start) { ParGCAllocBuffer::set_buf(buf_start); _true_end = _hard_end; _bt.set_region(MemRegion(buf_start, word_sz())); _bt.initialize_threshold(); } - void retire(bool end_of_gc, bool retain); + virtual void retire(bool end_of_gc, bool retain); MemRegion range() { return MemRegion(_top, _true_end);