8071462: Remove G1ParGCAllocator::alloc_buffer_waste
Summary: Removed G1ParGCAllocator::alloc_buffer_waste, added method to obtain waste
Reviewed-by: tschatzl, sjohanss
Contributed-by: Michail Chernov <michail.chernov@oracle.com>
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Wed Apr 22 17:05:00 2015 +0200
@@ -119,7 +119,6 @@
size_t gclab_word_size = _g1h->desired_plab_sz(dest);
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
G1PLAB* alloc_buf = alloc_buffer(dest, context);
- add_to_alloc_buffer_waste(alloc_buf->words_remaining());
alloc_buf->retire();
HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context);
@@ -153,8 +152,19 @@
for (uint state = 0; state < InCSetState::Num; state++) {
G1PLAB* const buf = _alloc_buffers[state];
if (buf != NULL) {
- add_to_alloc_buffer_waste(buf->words_remaining());
buf->flush_and_retire_stats(_g1h->alloc_buffer_stats(state));
}
}
}
+
+void G1DefaultParGCAllocator::waste(size_t& wasted, size_t& undo_wasted) {
+ wasted = 0;
+ undo_wasted = 0;
+ for (uint state = 0; state < InCSetState::Num; state++) {
+ G1PLAB * const buf = _alloc_buffers[state];
+ if (buf != NULL) {
+ wasted += buf->waste();
+ undo_wasted += buf->undo_waste();
+ }
+ }
+}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Wed Apr 22 17:05:00 2015 +0200
@@ -188,12 +188,6 @@
// architectures have a special compare against zero instructions.
const uint _survivor_alignment_bytes;
- size_t _alloc_buffer_waste;
- size_t _undo_waste;
-
- void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
- void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
-
virtual void retire_alloc_buffers() = 0;
virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
@@ -213,15 +207,12 @@
public:
G1ParGCAllocator(G1CollectedHeap* g1h) :
- _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()),
- _alloc_buffer_waste(0), _undo_waste(0) {
- }
+ _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()) { }
virtual ~G1ParGCAllocator() { }
static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
- size_t alloc_buffer_waste() { return _alloc_buffer_waste; }
- size_t undo_waste() {return _undo_waste; }
+ virtual void waste(size_t& wasted, size_t& undo_wasted) = 0;
// Allocate word_sz words in dest, either directly into the regions or by
// allocating a new PLAB. Returns the address of the allocated memory, NULL if
@@ -253,14 +244,7 @@
}
void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
- if (alloc_buffer(dest, context)->contains(obj)) {
- assert(alloc_buffer(dest, context)->contains(obj + word_sz - 1),
- "should contain whole object");
- alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
- } else {
- CollectedHeap::fill_with_object(obj, word_sz);
- add_to_undo_waste(word_sz);
- }
+ alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
}
};
@@ -280,7 +264,9 @@
return _alloc_buffers[dest.value()];
}
- virtual void retire_alloc_buffers() ;
+ virtual void retire_alloc_buffers();
+
+ virtual void waste(size_t& wasted, size_t& undo_wasted);
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ALLOCATOR_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Wed Apr 22 17:05:00 2015 +0200
@@ -95,8 +95,9 @@
const double elapsed_ms = elapsed_time() * 1000.0;
const double s_roots_ms = strong_roots_time() * 1000.0;
const double term_ms = term_time() * 1000.0;
- const size_t alloc_buffer_waste = _g1_par_allocator->alloc_buffer_waste();
- const size_t undo_waste = _g1_par_allocator->undo_waste();
+ size_t alloc_buffer_waste = 0;
+ size_t undo_waste = 0;
+ _g1_par_allocator->waste(alloc_buffer_waste, undo_waste);
st->print_cr("%3d %9.2f %9.2f %6.2f "
"%9.2f %6.2f " SIZE_FORMAT_W(8) " "
SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp Wed Apr 22 17:05:00 2015 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,9 +54,6 @@
uint _tenuring_threshold;
G1ParScanClosure _scanner;
- size_t _alloc_buffer_waste;
- size_t _undo_waste;
-
OopsInHeapRegionClosure* _evac_failure_cl;
int _hash_seed;
@@ -78,9 +75,6 @@
#define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
- void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; }
- void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
-
DirtyCardQueue& dirty_card_queue() { return _dcq; }
G1SATBCardTableModRefBS* ctbs() { return _ct_bs; }
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Apr 22 17:05:00 2015 +0200
@@ -272,16 +272,8 @@
}
-void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
- size_t word_sz) {
- // Is the alloc in the current alloc buffer?
- if (to_space_alloc_buffer()->contains(obj)) {
- assert(to_space_alloc_buffer()->contains(obj + word_sz - 1),
- "Should contain whole object.");
- to_space_alloc_buffer()->undo_allocation(obj, word_sz);
- } else {
- CollectedHeap::fill_with_object(obj, word_sz);
- }
+void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj, size_t word_sz) {
+ to_space_alloc_buffer()->undo_allocation(obj, word_sz);
}
void ParScanThreadState::print_promotion_failure_size() {
--- a/hotspot/src/share/vm/gc_implementation/shared/plab.cpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.cpp Wed Apr 22 17:05:00 2015 +0200
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc_implementation/shared/plab.hpp"
+#include "gc_interface/collectedHeap.hpp"
#include "memory/threadLocalAllocBuffer.hpp"
#include "oops/arrayOop.hpp"
#include "oops/oop.inline.hpp"
@@ -39,7 +40,7 @@
PLAB::PLAB(size_t desired_plab_sz_) :
_word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
- _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
+ _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0), _undo_wasted(0)
{
// ArrayOopDesc::header_size depends on command line initialization.
AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
@@ -62,13 +63,15 @@
// Now flush the statistics.
stats->add_allocated(_allocated);
stats->add_wasted(_wasted);
+ stats->add_undo_wasted(_undo_wasted);
stats->add_unused(unused);
// Since we have flushed the stats we need to clear the _allocated and _wasted
// fields in case somebody retains an instance of this over GCs. Not doing so
// will artifically inflate the values in the statistics.
- _allocated = 0;
- _wasted = 0;
+ _allocated = 0;
+ _wasted = 0;
+ _undo_wasted = 0;
}
void PLAB::retire() {
@@ -84,6 +87,28 @@
return result;
}
+void PLAB::add_undo_waste(HeapWord* obj, size_t word_sz) {
+ CollectedHeap::fill_with_object(obj, word_sz);
+ _undo_wasted += word_sz;
+}
+
+void PLAB::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;
+}
+
+void PLAB::undo_allocation(HeapWord* obj, size_t word_sz) {
+ // 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);
+ }
+}
+
// Compute desired plab size and latch result for later
// use. This should be called once at the end of parallel
// scavenge; it clears the sensor accumulators.
@@ -98,8 +123,9 @@
err_msg("Inconsistency in PLAB stats: "
"_allocated: "SIZE_FORMAT", "
"_wasted: "SIZE_FORMAT", "
- "_unused: "SIZE_FORMAT,
- _allocated, _wasted, _unused));
+ "_unused: "SIZE_FORMAT", "
+ "_undo_wasted: "SIZE_FORMAT,
+ _allocated, _wasted, _unused, _undo_wasted));
_allocated = 1;
}
--- a/hotspot/src/share/vm/gc_implementation/shared/plab.hpp Mon Apr 27 09:08:07 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.hpp Wed Apr 22 17:05:00 2015 +0200
@@ -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,12 @@
// the amount of remaining space.
size_t retire_internal();
+ void add_undo_waste(HeapWord* obj, size_t 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);
+
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 +97,17 @@
// 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;
- }
+ void undo_allocation(HeapWord* obj, size_t 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 +152,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 +201,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