mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8373941: Epsilon: Robust counter updates in early VM phases
Reviewed-by: stefank, tschatzl
This commit is contained in:
parent
c8c6e7007a
commit
47e19353cd
@ -77,6 +77,7 @@ jint EpsilonHeap::initialize() {
|
||||
void EpsilonHeap::initialize_serviceability() {
|
||||
_pool = new EpsilonMemoryPool(this);
|
||||
_memory_manager.add_pool(_pool);
|
||||
_monitoring_support->mark_ready();
|
||||
}
|
||||
|
||||
GrowableArray<GCMemoryManager*> EpsilonHeap::memory_managers() {
|
||||
@ -101,7 +102,7 @@ EpsilonHeap* EpsilonHeap::heap() {
|
||||
return named_heap<EpsilonHeap>(CollectedHeap::Epsilon);
|
||||
}
|
||||
|
||||
HeapWord* EpsilonHeap::allocate_work(size_t size, bool verbose) {
|
||||
HeapWord* EpsilonHeap::allocate_work(size_t size) {
|
||||
assert(is_object_aligned(size), "Allocation size should be aligned: %zu", size);
|
||||
|
||||
HeapWord* res = nullptr;
|
||||
@ -151,19 +152,23 @@ HeapWord* EpsilonHeap::allocate_work(size_t size, bool verbose) {
|
||||
|
||||
size_t used = _space->used();
|
||||
|
||||
// Allocation successful, update counters
|
||||
if (verbose) {
|
||||
size_t last = _last_counter_update;
|
||||
if ((used - last >= _step_counter_update) && AtomicAccess::cmpxchg(&_last_counter_update, last, used) == last) {
|
||||
// Allocation successful, update counters and print status.
|
||||
// At this point, some diagnostic subsystems might not yet be initialized.
|
||||
// We pretend the printout happened either way. This keeps allocation path
|
||||
// from obsessively checking the subsystems' status on every allocation.
|
||||
size_t last_counter = AtomicAccess::load(&_last_counter_update);
|
||||
if ((used - last_counter >= _step_counter_update) &&
|
||||
AtomicAccess::cmpxchg(&_last_counter_update, last_counter, used) == last_counter) {
|
||||
if (_monitoring_support->is_ready()) {
|
||||
_monitoring_support->update_counters();
|
||||
}
|
||||
}
|
||||
|
||||
// ...and print the occupancy line, if needed
|
||||
if (verbose) {
|
||||
size_t last = _last_heap_print;
|
||||
if ((used - last >= _step_heap_print) && AtomicAccess::cmpxchg(&_last_heap_print, last, used) == last) {
|
||||
print_heap_info(used);
|
||||
size_t last_heap = AtomicAccess::load(&_last_heap_print);
|
||||
if ((used - last_heap >= _step_heap_print) &&
|
||||
AtomicAccess::cmpxchg(&_last_heap_print, last_heap, used) == last_heap) {
|
||||
print_heap_info(used);
|
||||
if (Metaspace::initialized()) {
|
||||
print_metaspace_info();
|
||||
}
|
||||
}
|
||||
@ -265,8 +270,7 @@ HeapWord* EpsilonHeap::mem_allocate(size_t size) {
|
||||
}
|
||||
|
||||
HeapWord* EpsilonHeap::allocate_loaded_archive_space(size_t size) {
|
||||
// Cannot use verbose=true because Metaspace is not initialized
|
||||
return allocate_work(size, /* verbose = */false);
|
||||
return allocate_work(size);
|
||||
}
|
||||
|
||||
void EpsilonHeap::collect(GCCause::Cause cause) {
|
||||
|
||||
@ -83,7 +83,7 @@ public:
|
||||
bool requires_barriers(stackChunkOop obj) const override { return false; }
|
||||
|
||||
// Allocation
|
||||
HeapWord* allocate_work(size_t size, bool verbose = true);
|
||||
HeapWord* allocate_work(size_t size);
|
||||
HeapWord* mem_allocate(size_t size) override;
|
||||
HeapWord* allocate_new_tlab(size_t min_size,
|
||||
size_t requested_size,
|
||||
|
||||
@ -96,9 +96,11 @@ public:
|
||||
EpsilonMonitoringSupport::EpsilonMonitoringSupport(EpsilonHeap* heap) {
|
||||
_heap_counters = new EpsilonGenerationCounters(heap);
|
||||
_space_counters = new EpsilonSpaceCounters("Heap", 0, heap->max_capacity(), 0, _heap_counters);
|
||||
_ready = false;
|
||||
}
|
||||
|
||||
void EpsilonMonitoringSupport::update_counters() {
|
||||
assert(is_ready(), "Must be ready");
|
||||
MemoryService::track_memory_usage();
|
||||
|
||||
if (UsePerfData) {
|
||||
@ -110,3 +112,11 @@ void EpsilonMonitoringSupport::update_counters() {
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
||||
bool EpsilonMonitoringSupport::is_ready() {
|
||||
return AtomicAccess::load_acquire(&_ready);
|
||||
}
|
||||
|
||||
void EpsilonMonitoringSupport::mark_ready() {
|
||||
return AtomicAccess::release_store(&_ready, true);
|
||||
}
|
||||
|
||||
@ -35,9 +35,12 @@ class EpsilonMonitoringSupport : public CHeapObj<mtGC> {
|
||||
private:
|
||||
EpsilonGenerationCounters* _heap_counters;
|
||||
EpsilonSpaceCounters* _space_counters;
|
||||
volatile bool _ready;
|
||||
|
||||
public:
|
||||
EpsilonMonitoringSupport(EpsilonHeap* heap);
|
||||
bool is_ready();
|
||||
void mark_ready();
|
||||
void update_counters();
|
||||
};
|
||||
|
||||
|
||||
76
test/hotspot/jtreg/gc/epsilon/TestInitAllocs.java
Normal file
76
test/hotspot/jtreg/gc/epsilon/TestInitAllocs.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.epsilon;
|
||||
|
||||
/**
|
||||
* @test TestInitAllocs
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Test that allocation path taken in early JVM phases works
|
||||
*
|
||||
* @run main/othervm -Xmx256m
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
|
||||
* gc.epsilon.TestInitAllocs
|
||||
*
|
||||
* @run main/othervm -Xmx256m
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
|
||||
* -XX:+UseTLAB
|
||||
* -XX:+UseCompressedOops
|
||||
* -XX:EpsilonMinHeapExpand=1024
|
||||
* -XX:EpsilonUpdateCountersStep=1
|
||||
* -XX:EpsilonPrintHeapSteps=1000000
|
||||
* gc.epsilon.TestInitAllocs
|
||||
*
|
||||
* @run main/othervm -Xmx256m
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
|
||||
* -XX:+UseTLAB
|
||||
* -XX:-UseCompressedOops
|
||||
* -XX:EpsilonMinHeapExpand=1024
|
||||
* -XX:EpsilonUpdateCountersStep=1
|
||||
* -XX:EpsilonPrintHeapSteps=1000000
|
||||
* gc.epsilon.TestInitAllocs
|
||||
*
|
||||
* @run main/othervm -Xmx256m
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
|
||||
* -XX:-UseTLAB
|
||||
* -XX:+UseCompressedOops
|
||||
* -XX:EpsilonMinHeapExpand=1024
|
||||
* -XX:EpsilonUpdateCountersStep=1
|
||||
* -XX:EpsilonPrintHeapSteps=1000000
|
||||
* gc.epsilon.TestInitAllocs
|
||||
*
|
||||
* @run main/othervm -Xmx256m
|
||||
* -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
|
||||
* -XX:-UseTLAB
|
||||
* -XX:-UseCompressedOops
|
||||
* -XX:EpsilonMinHeapExpand=1024
|
||||
* -XX:EpsilonUpdateCountersStep=1
|
||||
* -XX:EpsilonPrintHeapSteps=1000000
|
||||
* gc.epsilon.TestInitAllocs
|
||||
*/
|
||||
|
||||
public class TestInitAllocs {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user