提交 50a69aab 编写于 作者: T tschatzl

8028710: G1 does not retire allocation buffers after reference processing work

Summary: G1 does not retire allocation buffers after reference processing work when -XX:+ParallelRefProcEnabled is enabled. This causes wrong calculation of PLAB sizes, as the amount of space wasted is not updated correctly.
Reviewed-by: brutisso
上级 0e0ee0c9
...@@ -4571,7 +4571,7 @@ HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, ...@@ -4571,7 +4571,7 @@ HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose,
} }
G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : 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) G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
: _g1h(g1h), : _g1h(g1h),
...@@ -4935,8 +4935,6 @@ void G1ParEvacuateFollowersClosure::do_void() { ...@@ -4935,8 +4935,6 @@ void G1ParEvacuateFollowersClosure::do_void() {
pss->trim_queue(); pss->trim_queue();
} }
} while (!offer_termination()); } while (!offer_termination());
pss->retire_alloc_buffers();
} }
class G1KlassScanClosure : public KlassClosure { class G1KlassScanClosure : public KlassClosure {
...@@ -5776,10 +5774,8 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) { ...@@ -5776,10 +5774,8 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) {
} }
_gc_tracer_stw->report_gc_reference_stats(stats); _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 // We have completed copying any necessary live referent objects.
// retire any active alloc buffers
pss.retire_alloc_buffers();
assert(pss.refs()->is_empty(), "both queue and overflow should be empty"); assert(pss.refs()->is_empty(), "both queue and overflow should be empty");
double ref_proc_time = os::elapsedTime() - ref_proc_start; double ref_proc_time = os::elapsedTime() - ref_proc_start;
......
...@@ -1691,15 +1691,19 @@ private: ...@@ -1691,15 +1691,19 @@ private:
public: public:
G1ParGCAllocBuffer(size_t gclab_word_size); 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); ParGCAllocBuffer::set_buf(buf);
_retired = false; _retired = false;
} }
void retire(bool end_of_gc, bool retain) { virtual void retire(bool end_of_gc, bool retain) {
if (_retired) if (_retired) {
return; return;
}
ParGCAllocBuffer::retire(end_of_gc, retain); ParGCAllocBuffer::retire(end_of_gc, retain);
_retired = true; _retired = true;
} }
...@@ -1769,6 +1773,7 @@ public: ...@@ -1769,6 +1773,7 @@ public:
G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp); G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp);
~G1ParScanThreadState() { ~G1ParScanThreadState() {
retire_alloc_buffers();
FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC); FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
} }
...@@ -1879,6 +1884,7 @@ public: ...@@ -1879,6 +1884,7 @@ public:
return _surviving_young_words; return _surviving_young_words;
} }
private:
void retire_alloc_buffers() { void retire_alloc_buffers() {
for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
size_t waste = _alloc_buffers[ap]->words_remaining(); size_t waste = _alloc_buffers[ap]->words_remaining();
...@@ -1888,8 +1894,8 @@ public: ...@@ -1888,8 +1894,8 @@ public:
false /* retain */); false /* retain */);
} }
} }
private:
#define G1_PARTIAL_ARRAY_MASK 0x2 #define G1_PARTIAL_ARRAY_MASK 0x2
inline bool has_partial_array_mask(oop* ref) const { inline bool has_partial_array_mask(oop* ref) const {
return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK; return ((uintptr_t)ref & G1_PARTIAL_ARRAY_MASK) == G1_PARTIAL_ARRAY_MASK;
......
...@@ -60,6 +60,7 @@ public: ...@@ -60,6 +60,7 @@ public:
// Initializes the buffer to be empty, but with the given "word_sz". // Initializes the buffer to be empty, but with the given "word_sz".
// Must get initialized with "set_buf" for an allocation to succeed. // Must get initialized with "set_buf" for an allocation to succeed.
ParGCAllocBuffer(size_t word_sz); ParGCAllocBuffer(size_t word_sz);
virtual ~ParGCAllocBuffer() {}
static const size_t min_size() { static const size_t min_size() {
return ThreadLocalAllocBuffer::min_size(); return ThreadLocalAllocBuffer::min_size();
...@@ -113,7 +114,7 @@ public: ...@@ -113,7 +114,7 @@ public:
} }
// Sets the space of the buffer to be [buf, space+word_sz()). // 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; _bottom = buf;
_top = _bottom; _top = _bottom;
_hard_end = _bottom + word_sz(); _hard_end = _bottom + word_sz();
...@@ -158,7 +159,7 @@ public: ...@@ -158,7 +159,7 @@ public:
// Fills in the unallocated portion of the buffer with a garbage object. // 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" // 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. // 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; void print() PRODUCT_RETURN;
}; };
...@@ -238,14 +239,14 @@ public: ...@@ -238,14 +239,14 @@ public:
void undo_allocation(HeapWord* obj, size_t word_sz); 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); ParGCAllocBuffer::set_buf(buf_start);
_true_end = _hard_end; _true_end = _hard_end;
_bt.set_region(MemRegion(buf_start, word_sz())); _bt.set_region(MemRegion(buf_start, word_sz()));
_bt.initialize_threshold(); _bt.initialize_threshold();
} }
void retire(bool end_of_gc, bool retain); virtual void retire(bool end_of_gc, bool retain);
MemRegion range() { MemRegion range() {
return MemRegion(_top, _true_end); return MemRegion(_top, _true_end);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册