8204180: Implementation: JEP 318: Epsilon, A No-Op Garbage Collector
Introduce Epsilon GC Reviewed-by: rkennke, ihse, pliden, eosterlund, lmesnik, jgeorge, stefank
This commit is contained in:
parent
2c389ccbac
commit
a1518ac9b2
make
src
hotspot/share
gc
epsilon
epsilonArguments.cppepsilonArguments.hppepsilonBarrierSet.cppepsilonBarrierSet.hppepsilonCollectorPolicy.hppepsilonHeap.cppepsilonHeap.hppepsilonMemoryPool.cppepsilonMemoryPool.hppepsilonMonitoringSupport.cppepsilonMonitoringSupport.hppepsilonThreadLocalData.hppepsilon_globals.hppvmStructs_epsilon.hpp
shared
utilities
jdk.hotspot.agent/share/classes/sun/jvm/hotspot
test
hotspot/jtreg
TEST.ROOTTEST.groups
gc/epsilon
TestAlwaysPretouch.javaTestByteArrays.javaTestDieDefault.javaTestDieWithHeapDump.javaTestDieWithOnError.javaTestElasticTLAB.javaTestElasticTLABDecay.javaTestEpsilonEnabled.javaTestHelloWorld.javaTestLogTrace.javaTestManyThreads.javaTestMemoryMXBeans.javaTestMemoryPools.javaTestObjects.javaTestPrintHeapSteps.javaTestRefArrays.javaTestUpdateCountersSteps.java
serviceability/sa
lib/sun/hotspot/gc
@ -25,7 +25,7 @@
|
||||
|
||||
# All valid JVM features, regardless of platform
|
||||
VALID_JVM_FEATURES="compiler1 compiler2 zero minimal dtrace jvmti jvmci \
|
||||
graal vm-structs jni-check services management cmsgc g1gc parallelgc serialgc nmt cds \
|
||||
graal vm-structs jni-check services management cmsgc g1gc parallelgc serialgc epsilongc nmt cds \
|
||||
static-build link-time-opt aot jfr"
|
||||
|
||||
# Deprecated JVM features (these are ignored, but with a warning)
|
||||
@ -410,7 +410,7 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
|
||||
fi
|
||||
|
||||
# All variants but minimal (and custom) get these features
|
||||
NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cmsgc g1gc parallelgc serialgc jni-check jvmti management nmt services vm-structs"
|
||||
NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cmsgc g1gc parallelgc serialgc epsilongc jni-check jvmti management nmt services vm-structs"
|
||||
if test "x$ENABLE_CDS" = "xtrue"; then
|
||||
NON_MINIMAL_FEATURES="$NON_MINIMAL_FEATURES cds"
|
||||
fi
|
||||
|
@ -155,6 +155,11 @@ ifneq ($(call check-jvm-feature, serialgc), true)
|
||||
JVM_EXCLUDE_FILES += psMarkSweep.cpp psMarkSweepDecorator.cpp
|
||||
endif
|
||||
|
||||
ifneq ($(call check-jvm-feature, epsilongc), true)
|
||||
JVM_CFLAGS_FEATURES += -DINCLUDE_EPSILONGC=0
|
||||
JVM_EXCLUDE_PATTERNS += gc/epsilon
|
||||
endif
|
||||
|
||||
ifneq ($(call check-jvm-feature, jfr), true)
|
||||
JVM_CFLAGS_FEATURES += -DINCLUDE_JFR=0
|
||||
JVM_EXCLUDE_PATTERNS += jfr
|
||||
|
72
src/hotspot/share/gc/epsilon/epsilonArguments.cpp
Normal file
72
src/hotspot/share/gc/epsilon/epsilonArguments.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/epsilon/epsilonArguments.hpp"
|
||||
#include "gc/epsilon/epsilonHeap.hpp"
|
||||
#include "gc/epsilon/epsilonCollectorPolicy.hpp"
|
||||
#include "gc/shared/gcArguments.inline.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/globals_extension.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
size_t EpsilonArguments::conservative_max_heap_alignment() {
|
||||
return UseLargePages ? os::large_page_size() : os::vm_page_size();
|
||||
}
|
||||
|
||||
void EpsilonArguments::initialize() {
|
||||
GCArguments::initialize();
|
||||
|
||||
assert(UseEpsilonGC, "Sanity");
|
||||
|
||||
// Forcefully exit when OOME is detected. Nothing we can do at that point.
|
||||
if (FLAG_IS_DEFAULT(ExitOnOutOfMemoryError)) {
|
||||
FLAG_SET_DEFAULT(ExitOnOutOfMemoryError, true);
|
||||
}
|
||||
|
||||
if (EpsilonMaxTLABSize < MinTLABSize) {
|
||||
warning("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
|
||||
EpsilonMaxTLABSize = MinTLABSize;
|
||||
}
|
||||
|
||||
if (!EpsilonElasticTLAB && EpsilonElasticTLABDecay) {
|
||||
warning("Disabling EpsilonElasticTLABDecay because EpsilonElasticTLAB is disabled");
|
||||
FLAG_SET_DEFAULT(EpsilonElasticTLABDecay, false);
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
// Enable loop strip mining: there are still non-GC safepoints, no need to make it worse
|
||||
if (FLAG_IS_DEFAULT(UseCountedLoopSafepoints)) {
|
||||
FLAG_SET_DEFAULT(UseCountedLoopSafepoints, true);
|
||||
if (FLAG_IS_DEFAULT(LoopStripMiningIter)) {
|
||||
FLAG_SET_DEFAULT(LoopStripMiningIter, 1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CollectedHeap* EpsilonArguments::create_heap() {
|
||||
return create_heap_with_policy<EpsilonHeap, EpsilonCollectorPolicy>();
|
||||
}
|
39
src/hotspot/share/gc/epsilon/epsilonArguments.hpp
Normal file
39
src/hotspot/share/gc/epsilon/epsilonArguments.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_EPSILON_EPSILONARGUMENTS_HPP
|
||||
#define SHARE_GC_EPSILON_EPSILONARGUMENTS_HPP
|
||||
|
||||
#include "gc/shared/gcArguments.hpp"
|
||||
|
||||
class CollectedHeap;
|
||||
|
||||
class EpsilonArguments : public GCArguments {
|
||||
public:
|
||||
virtual void initialize();
|
||||
virtual size_t conservative_max_heap_alignment();
|
||||
virtual CollectedHeap* create_heap();
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_EPSILON_EPSILONARGUMENTS_HPP
|
51
src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp
Normal file
51
src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "gc/epsilon/epsilonBarrierSet.hpp"
|
||||
#include "gc/epsilon/epsilonThreadLocalData.hpp"
|
||||
#include "gc/shared/collectorPolicy.hpp"
|
||||
#include "gc/shared/barrierSet.hpp"
|
||||
#include "gc/shared/barrierSetAssembler.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#ifdef COMPILER1
|
||||
#include "gc/shared/c1/barrierSetC1.hpp"
|
||||
#endif
|
||||
#ifdef COMPILER2
|
||||
#include "gc/shared/c2/barrierSetC2.hpp"
|
||||
#endif
|
||||
|
||||
EpsilonBarrierSet::EpsilonBarrierSet() : BarrierSet(
|
||||
make_barrier_set_assembler<BarrierSetAssembler>(),
|
||||
make_barrier_set_c1<BarrierSetC1>(),
|
||||
make_barrier_set_c2<BarrierSetC2>(),
|
||||
BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {};
|
||||
|
||||
void EpsilonBarrierSet::on_thread_create(Thread *thread) {
|
||||
EpsilonThreadLocalData::create(thread);
|
||||
}
|
||||
|
||||
void EpsilonBarrierSet::on_thread_destroy(Thread *thread) {
|
||||
EpsilonThreadLocalData::destroy(thread);
|
||||
}
|
57
src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp
Normal file
57
src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_BARRIERSET_HPP
|
||||
#define SHARE_VM_GC_EPSILON_BARRIERSET_HPP
|
||||
|
||||
#include "gc/shared/barrierSetAssembler.hpp"
|
||||
#include "gc/shared/barrierSet.hpp"
|
||||
|
||||
// No interaction with application is required for Epsilon, and therefore
|
||||
// the barrier set is empty.
|
||||
class EpsilonBarrierSet: public BarrierSet {
|
||||
friend class VMStructs;
|
||||
|
||||
public:
|
||||
EpsilonBarrierSet();
|
||||
|
||||
virtual void print_on(outputStream *st) const {}
|
||||
|
||||
virtual void on_thread_create(Thread* thread);
|
||||
virtual void on_thread_destroy(Thread* thread);
|
||||
|
||||
template <DecoratorSet decorators, typename BarrierSetT = EpsilonBarrierSet>
|
||||
class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> {};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BarrierSet::GetName<EpsilonBarrierSet> {
|
||||
static const BarrierSet::Name value = BarrierSet::EpsilonBarrierSet;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct BarrierSet::GetType<BarrierSet::EpsilonBarrierSet> {
|
||||
typedef ::EpsilonBarrierSet type;
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_BARRIERSET_HPP
|
42
src/hotspot/share/gc/epsilon/epsilonCollectorPolicy.hpp
Normal file
42
src/hotspot/share/gc/epsilon/epsilonCollectorPolicy.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_COLLECTORPOLICY_HPP
|
||||
#define SHARE_VM_GC_EPSILON_COLLECTORPOLICY_HPP
|
||||
|
||||
#include "gc/shared/collectorPolicy.hpp"
|
||||
|
||||
class EpsilonCollectorPolicy: public CollectorPolicy {
|
||||
protected:
|
||||
virtual void initialize_alignments() {
|
||||
size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
|
||||
size_t align = MAX2((size_t)os::vm_allocation_granularity(), page_size);
|
||||
_space_alignment = align;
|
||||
_heap_alignment = align;
|
||||
}
|
||||
|
||||
public:
|
||||
EpsilonCollectorPolicy() : CollectorPolicy() {};
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_COLLECTORPOLICY_HPP
|
285
src/hotspot/share/gc/epsilon/epsilonHeap.cpp
Normal file
285
src/hotspot/share/gc/epsilon/epsilonHeap.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/epsilon/epsilonHeap.hpp"
|
||||
#include "gc/epsilon/epsilonMemoryPool.hpp"
|
||||
#include "gc/epsilon/epsilonThreadLocalData.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
|
||||
jint EpsilonHeap::initialize() {
|
||||
size_t align = _policy->heap_alignment();
|
||||
size_t init_byte_size = align_up(_policy->initial_heap_byte_size(), align);
|
||||
size_t max_byte_size = align_up(_policy->max_heap_byte_size(), align);
|
||||
|
||||
// Initialize backing storage
|
||||
ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, align);
|
||||
_virtual_space.initialize(heap_rs, init_byte_size);
|
||||
|
||||
MemRegion committed_region((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high());
|
||||
MemRegion reserved_region((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary());
|
||||
|
||||
initialize_reserved_region(reserved_region.start(), reserved_region.end());
|
||||
|
||||
_space = new ContiguousSpace();
|
||||
_space->initialize(committed_region, /* clear_space = */ true, /* mangle_space = */ true);
|
||||
|
||||
// Precompute hot fields
|
||||
_max_tlab_size = MIN2(CollectedHeap::max_tlab_size(), EpsilonMaxTLABSize / HeapWordSize);
|
||||
_step_counter_update = MIN2<size_t>(max_byte_size / 16, EpsilonUpdateCountersStep);
|
||||
_step_heap_print = (EpsilonPrintHeapSteps == 0) ? SIZE_MAX : (max_byte_size / EpsilonPrintHeapSteps);
|
||||
_decay_time_ns = (int64_t) EpsilonTLABDecayTime * NANOSECS_PER_MILLISEC;
|
||||
|
||||
// Enable monitoring
|
||||
_monitoring_support = new EpsilonMonitoringSupport(this);
|
||||
_last_counter_update = 0;
|
||||
_last_heap_print = 0;
|
||||
|
||||
// Install barrier set
|
||||
BarrierSet::set_barrier_set(new EpsilonBarrierSet());
|
||||
|
||||
// All done, print out the configuration
|
||||
if (init_byte_size != max_byte_size) {
|
||||
log_info(gc)("Resizeable heap; starting at " SIZE_FORMAT "M, max: " SIZE_FORMAT "M, step: " SIZE_FORMAT "M",
|
||||
init_byte_size / M, max_byte_size / M, EpsilonMinHeapExpand / M);
|
||||
} else {
|
||||
log_info(gc)("Non-resizeable heap; start/max: " SIZE_FORMAT "M", init_byte_size / M);
|
||||
}
|
||||
|
||||
if (UseTLAB) {
|
||||
log_info(gc)("Using TLAB allocation; max: " SIZE_FORMAT "K", _max_tlab_size * HeapWordSize / K);
|
||||
if (EpsilonElasticTLAB) {
|
||||
log_info(gc)("Elastic TLABs enabled; elasticity: %.2fx", EpsilonTLABElasticity);
|
||||
}
|
||||
if (EpsilonElasticTLABDecay) {
|
||||
log_info(gc)("Elastic TLABs decay enabled; decay time: " SIZE_FORMAT "ms", EpsilonTLABDecayTime);
|
||||
}
|
||||
} else {
|
||||
log_info(gc)("Not using TLAB allocation");
|
||||
}
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
void EpsilonHeap::post_initialize() {
|
||||
CollectedHeap::post_initialize();
|
||||
}
|
||||
|
||||
void EpsilonHeap::initialize_serviceability() {
|
||||
_pool = new EpsilonMemoryPool(this);
|
||||
_memory_manager.add_pool(_pool);
|
||||
}
|
||||
|
||||
GrowableArray<GCMemoryManager*> EpsilonHeap::memory_managers() {
|
||||
GrowableArray<GCMemoryManager*> memory_managers(1);
|
||||
memory_managers.append(&_memory_manager);
|
||||
return memory_managers;
|
||||
}
|
||||
|
||||
GrowableArray<MemoryPool*> EpsilonHeap::memory_pools() {
|
||||
GrowableArray<MemoryPool*> memory_pools(1);
|
||||
memory_pools.append(_pool);
|
||||
return memory_pools;
|
||||
}
|
||||
|
||||
size_t EpsilonHeap::unsafe_max_tlab_alloc(Thread* thr) const {
|
||||
// Return max allocatable TLAB size, and let allocation path figure out
|
||||
// the actual TLAB allocation size.
|
||||
return _max_tlab_size;
|
||||
}
|
||||
|
||||
EpsilonHeap* EpsilonHeap::heap() {
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
assert(heap != NULL, "Uninitialized access to EpsilonHeap::heap()");
|
||||
assert(heap->kind() == CollectedHeap::Epsilon, "Not an Epsilon heap");
|
||||
return (EpsilonHeap*)heap;
|
||||
}
|
||||
|
||||
HeapWord* EpsilonHeap::allocate_work(size_t size) {
|
||||
HeapWord* res = _space->par_allocate(size);
|
||||
|
||||
while (res == NULL) {
|
||||
// Allocation failed, attempt expansion, and retry:
|
||||
MutexLockerEx ml(Heap_lock);
|
||||
|
||||
size_t space_left = max_capacity() - capacity();
|
||||
size_t want_space = MAX2(size, EpsilonMinHeapExpand);
|
||||
|
||||
if (want_space < space_left) {
|
||||
// Enough space to expand in bulk:
|
||||
bool expand = _virtual_space.expand_by(want_space);
|
||||
assert(expand, "Should be able to expand");
|
||||
} else if (size < space_left) {
|
||||
// No space to expand in bulk, and this allocation is still possible,
|
||||
// take all the remaining space:
|
||||
bool expand = _virtual_space.expand_by(space_left);
|
||||
assert(expand, "Should be able to expand");
|
||||
} else {
|
||||
// No space left:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_space->set_end((HeapWord *) _virtual_space.high());
|
||||
res = _space->par_allocate(size);
|
||||
}
|
||||
|
||||
size_t used = _space->used();
|
||||
|
||||
// Allocation successful, update counters
|
||||
{
|
||||
size_t last = _last_counter_update;
|
||||
if ((used - last >= _step_counter_update) && Atomic::cmpxchg(used, &_last_counter_update, last) == last) {
|
||||
_monitoring_support->update_counters();
|
||||
}
|
||||
}
|
||||
|
||||
// ...and print the occupancy line, if needed
|
||||
{
|
||||
size_t last = _last_heap_print;
|
||||
if ((used - last >= _step_heap_print) && Atomic::cmpxchg(used, &_last_heap_print, last) == last) {
|
||||
log_info(gc)("Heap: " SIZE_FORMAT "M reserved, " SIZE_FORMAT "M (%.2f%%) committed, " SIZE_FORMAT "M (%.2f%%) used",
|
||||
max_capacity() / M,
|
||||
capacity() / M,
|
||||
capacity() * 100.0 / max_capacity(),
|
||||
used / M,
|
||||
used * 100.0 / max_capacity());
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
HeapWord* EpsilonHeap::allocate_new_tlab(size_t min_size,
|
||||
size_t requested_size,
|
||||
size_t* actual_size) {
|
||||
Thread* thread = Thread::current();
|
||||
|
||||
// Defaults in case elastic paths are not taken
|
||||
bool fits = true;
|
||||
size_t size = requested_size;
|
||||
size_t ergo_tlab = requested_size;
|
||||
int64_t time = 0;
|
||||
|
||||
if (EpsilonElasticTLAB) {
|
||||
ergo_tlab = EpsilonThreadLocalData::ergo_tlab_size(thread);
|
||||
|
||||
if (EpsilonElasticTLABDecay) {
|
||||
int64_t last_time = EpsilonThreadLocalData::last_tlab_time(thread);
|
||||
time = (int64_t) os::javaTimeNanos();
|
||||
|
||||
assert(last_time <= time, "time should be monotonic");
|
||||
|
||||
// If the thread had not allocated recently, retract the ergonomic size.
|
||||
// This conserves memory when the thread had initial burst of allocations,
|
||||
// and then started allocating only sporadically.
|
||||
if (last_time != 0 && (time - last_time > _decay_time_ns)) {
|
||||
ergo_tlab = 0;
|
||||
EpsilonThreadLocalData::set_ergo_tlab_size(thread, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// If we can fit the allocation under current TLAB size, do so.
|
||||
// Otherwise, we want to elastically increase the TLAB size.
|
||||
fits = (requested_size <= ergo_tlab);
|
||||
if (!fits) {
|
||||
size = (size_t) (ergo_tlab * EpsilonTLABElasticity);
|
||||
}
|
||||
}
|
||||
|
||||
// Always honor boundaries
|
||||
size = MAX2(min_size, MIN2(_max_tlab_size, size));
|
||||
|
||||
if (log_is_enabled(Trace, gc)) {
|
||||
ResourceMark rm;
|
||||
log_trace(gc)("TLAB size for \"%s\" (Requested: " SIZE_FORMAT "K, Min: " SIZE_FORMAT
|
||||
"K, Max: " SIZE_FORMAT "K, Ergo: " SIZE_FORMAT "K) -> " SIZE_FORMAT "K",
|
||||
thread->name(),
|
||||
requested_size * HeapWordSize / K,
|
||||
min_size * HeapWordSize / K,
|
||||
_max_tlab_size * HeapWordSize / K,
|
||||
ergo_tlab * HeapWordSize / K,
|
||||
size * HeapWordSize / K);
|
||||
}
|
||||
|
||||
// All prepared, let's do it!
|
||||
HeapWord* res = allocate_work(size);
|
||||
|
||||
if (res != NULL) {
|
||||
// Allocation successful
|
||||
*actual_size = size;
|
||||
if (EpsilonElasticTLABDecay) {
|
||||
EpsilonThreadLocalData::set_last_tlab_time(thread, time);
|
||||
}
|
||||
if (EpsilonElasticTLAB && !fits) {
|
||||
// If we requested expansion, this is our new ergonomic TLAB size
|
||||
EpsilonThreadLocalData::set_ergo_tlab_size(thread, size);
|
||||
}
|
||||
} else {
|
||||
// Allocation failed, reset ergonomics to try and fit smaller TLABs
|
||||
if (EpsilonElasticTLAB) {
|
||||
EpsilonThreadLocalData::set_ergo_tlab_size(thread, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
HeapWord* EpsilonHeap::mem_allocate(size_t size, bool *gc_overhead_limit_was_exceeded) {
|
||||
*gc_overhead_limit_was_exceeded = false;
|
||||
return allocate_work(size);
|
||||
}
|
||||
|
||||
void EpsilonHeap::collect(GCCause::Cause cause) {
|
||||
log_info(gc)("GC request for \"%s\" is ignored", GCCause::to_string(cause));
|
||||
_monitoring_support->update_counters();
|
||||
}
|
||||
|
||||
void EpsilonHeap::do_full_collection(bool clear_all_soft_refs) {
|
||||
log_info(gc)("Full GC request for \"%s\" is ignored", GCCause::to_string(gc_cause()));
|
||||
_monitoring_support->update_counters();
|
||||
}
|
||||
|
||||
void EpsilonHeap::safe_object_iterate(ObjectClosure *cl) {
|
||||
_space->safe_object_iterate(cl);
|
||||
}
|
||||
|
||||
void EpsilonHeap::print_on(outputStream *st) const {
|
||||
st->print_cr("Epsilon Heap");
|
||||
|
||||
// Cast away constness:
|
||||
((VirtualSpace)_virtual_space).print_on(st);
|
||||
|
||||
st->print_cr("Allocation space:");
|
||||
_space->print_on(st);
|
||||
}
|
||||
|
||||
void EpsilonHeap::print_tracing_info() const {
|
||||
Log(gc) log;
|
||||
size_t allocated_kb = used() / K;
|
||||
log.info("Total allocated: " SIZE_FORMAT " KB",
|
||||
allocated_kb);
|
||||
log.info("Average allocation rate: " SIZE_FORMAT " KB/sec",
|
||||
(size_t)(allocated_kb * NANOSECS_PER_SEC / os::elapsed_counter()));
|
||||
}
|
147
src/hotspot/share/gc/epsilon/epsilonHeap.hpp
Normal file
147
src/hotspot/share/gc/epsilon/epsilonHeap.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_COLLECTEDHEAP_HPP
|
||||
#define SHARE_VM_GC_EPSILON_COLLECTEDHEAP_HPP
|
||||
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "gc/shared/softRefPolicy.hpp"
|
||||
#include "gc/shared/space.hpp"
|
||||
#include "services/memoryManager.hpp"
|
||||
#include "gc/epsilon/epsilonCollectorPolicy.hpp"
|
||||
#include "gc/epsilon/epsilonMonitoringSupport.hpp"
|
||||
#include "gc/epsilon/epsilonBarrierSet.hpp"
|
||||
#include "gc/epsilon/epsilon_globals.hpp"
|
||||
|
||||
class EpsilonHeap : public CollectedHeap {
|
||||
friend class VMStructs;
|
||||
private:
|
||||
EpsilonCollectorPolicy* _policy;
|
||||
SoftRefPolicy _soft_ref_policy;
|
||||
EpsilonMonitoringSupport* _monitoring_support;
|
||||
MemoryPool* _pool;
|
||||
GCMemoryManager _memory_manager;
|
||||
ContiguousSpace* _space;
|
||||
VirtualSpace _virtual_space;
|
||||
size_t _max_tlab_size;
|
||||
size_t _step_counter_update;
|
||||
size_t _step_heap_print;
|
||||
int64_t _decay_time_ns;
|
||||
volatile size_t _last_counter_update;
|
||||
volatile size_t _last_heap_print;
|
||||
|
||||
public:
|
||||
static EpsilonHeap* heap();
|
||||
|
||||
EpsilonHeap(EpsilonCollectorPolicy* p) :
|
||||
_policy(p),
|
||||
_memory_manager("Epsilon Heap", "") {};
|
||||
|
||||
virtual Name kind() const {
|
||||
return CollectedHeap::Epsilon;
|
||||
}
|
||||
|
||||
virtual const char* name() const {
|
||||
return "Epsilon";
|
||||
}
|
||||
|
||||
virtual CollectorPolicy* collector_policy() const {
|
||||
return _policy;
|
||||
}
|
||||
|
||||
virtual SoftRefPolicy* soft_ref_policy() {
|
||||
return &_soft_ref_policy;
|
||||
}
|
||||
|
||||
virtual jint initialize();
|
||||
virtual void post_initialize();
|
||||
virtual void initialize_serviceability();
|
||||
|
||||
virtual GrowableArray<GCMemoryManager*> memory_managers();
|
||||
virtual GrowableArray<MemoryPool*> memory_pools();
|
||||
|
||||
virtual size_t max_capacity() const { return _virtual_space.reserved_size(); }
|
||||
virtual size_t capacity() const { return _virtual_space.committed_size(); }
|
||||
virtual size_t used() const { return _space->used(); }
|
||||
|
||||
virtual bool is_in(const void* p) const {
|
||||
return _space->is_in(p);
|
||||
}
|
||||
|
||||
virtual bool is_scavengable(oop obj) {
|
||||
// No GC is going to happen, therefore no objects ever move.
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool is_maximal_no_gc() const {
|
||||
// No GC is going to happen. Return "we are at max", when we are about to fail.
|
||||
return used() == capacity();
|
||||
}
|
||||
|
||||
// Allocation
|
||||
HeapWord* allocate_work(size_t size);
|
||||
virtual HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded);
|
||||
virtual HeapWord* allocate_new_tlab(size_t min_size,
|
||||
size_t requested_size,
|
||||
size_t* actual_size);
|
||||
|
||||
// TLAB allocation
|
||||
virtual bool supports_tlab_allocation() const { return true; }
|
||||
virtual size_t tlab_capacity(Thread* thr) const { return capacity(); }
|
||||
virtual size_t tlab_used(Thread* thr) const { return used(); }
|
||||
virtual size_t max_tlab_size() const { return _max_tlab_size; }
|
||||
virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
|
||||
|
||||
virtual void collect(GCCause::Cause cause);
|
||||
virtual void do_full_collection(bool clear_all_soft_refs);
|
||||
|
||||
// Heap walking support
|
||||
virtual void safe_object_iterate(ObjectClosure* cl);
|
||||
virtual void object_iterate(ObjectClosure* cl) {
|
||||
safe_object_iterate(cl);
|
||||
}
|
||||
|
||||
// No support for block parsing.
|
||||
virtual HeapWord* block_start(const void* addr) const { return NULL; }
|
||||
virtual size_t block_size(const HeapWord* addr) const { return 0; }
|
||||
virtual bool block_is_obj(const HeapWord* addr) const { return false; }
|
||||
|
||||
// No GC threads
|
||||
virtual void print_gc_threads_on(outputStream* st) const {}
|
||||
virtual void gc_threads_do(ThreadClosure* tc) const {}
|
||||
|
||||
// No heap verification
|
||||
virtual void prepare_for_verify() {}
|
||||
virtual void verify(VerifyOption option) {}
|
||||
|
||||
virtual jlong millis_since_last_gc() {
|
||||
// Report time since the VM start
|
||||
return os::elapsed_counter() / NANOSECS_PER_MILLISEC;
|
||||
}
|
||||
|
||||
virtual void print_on(outputStream* st) const;
|
||||
virtual void print_tracing_info() const;
|
||||
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_COLLECTEDHEAP_HPP
|
45
src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp
Normal file
45
src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/epsilon/epsilonHeap.hpp"
|
||||
#include "gc/epsilon/epsilonMemoryPool.hpp"
|
||||
|
||||
EpsilonMemoryPool::EpsilonMemoryPool(EpsilonHeap* heap) :
|
||||
_heap(heap),
|
||||
CollectedMemoryPool("Epsilon Heap",
|
||||
heap->capacity(),
|
||||
heap->max_capacity(),
|
||||
false) {
|
||||
assert(UseEpsilonGC, "sanity");
|
||||
}
|
||||
|
||||
MemoryUsage EpsilonMemoryPool::get_memory_usage() {
|
||||
size_t initial_sz = initial_size();
|
||||
size_t max_sz = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = committed_in_bytes();
|
||||
|
||||
return MemoryUsage(initial_sz, used, committed, max_sz);
|
||||
}
|
44
src/hotspot/share/gc/epsilon/epsilonMemoryPool.hpp
Normal file
44
src/hotspot/share/gc/epsilon/epsilonMemoryPool.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_EPSILONMEMORYPOOL_HPP
|
||||
#define SHARE_VM_GC_EPSILON_EPSILONMEMORYPOOL_HPP
|
||||
|
||||
#include "gc/epsilon/epsilonHeap.hpp"
|
||||
#include "services/memoryPool.hpp"
|
||||
#include "services/memoryUsage.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class EpsilonMemoryPool : public CollectedMemoryPool {
|
||||
private:
|
||||
EpsilonHeap* _heap;
|
||||
|
||||
public:
|
||||
EpsilonMemoryPool(EpsilonHeap* heap);
|
||||
size_t committed_in_bytes() { return _heap->capacity(); }
|
||||
size_t used_in_bytes() { return _heap->used(); }
|
||||
size_t max_size() const { return _heap->max_capacity(); }
|
||||
MemoryUsage get_memory_usage();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_EPSILONMEMORYPOOL_HPP
|
118
src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp
Normal file
118
src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/epsilon/epsilonMonitoringSupport.hpp"
|
||||
#include "gc/epsilon/epsilonHeap.hpp"
|
||||
#include "gc/shared/generationCounters.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/metaspaceCounters.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "services/memoryService.hpp"
|
||||
|
||||
class EpsilonSpaceCounters: public CHeapObj<mtGC> {
|
||||
friend class VMStructs;
|
||||
|
||||
private:
|
||||
PerfVariable* _capacity;
|
||||
PerfVariable* _used;
|
||||
char* _name_space;
|
||||
|
||||
public:
|
||||
EpsilonSpaceCounters(const char* name,
|
||||
int ordinal,
|
||||
size_t max_size,
|
||||
size_t initial_capacity,
|
||||
GenerationCounters* gc) {
|
||||
if (UsePerfData) {
|
||||
EXCEPTION_MARK;
|
||||
ResourceMark rm;
|
||||
|
||||
const char* cns = PerfDataManager::name_space(gc->name_space(), "space", ordinal);
|
||||
|
||||
_name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
|
||||
strcpy(_name_space, cns);
|
||||
|
||||
const char* cname = PerfDataManager::counter_name(_name_space, "name");
|
||||
PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK);
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
|
||||
PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, (jlong)max_size, CHECK);
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "capacity");
|
||||
_capacity = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, initial_capacity, CHECK);
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "used");
|
||||
_used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, (jlong) 0, CHECK);
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "initCapacity");
|
||||
PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, initial_capacity, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
~EpsilonSpaceCounters() {
|
||||
if (_name_space != NULL) {
|
||||
FREE_C_HEAP_ARRAY(char, _name_space);
|
||||
}
|
||||
}
|
||||
|
||||
inline void update_all(size_t capacity, size_t used) {
|
||||
_capacity->set_value(capacity);
|
||||
_used->set_value(used);
|
||||
}
|
||||
};
|
||||
|
||||
class EpsilonGenerationCounters : public GenerationCounters {
|
||||
private:
|
||||
EpsilonHeap* _heap;
|
||||
public:
|
||||
EpsilonGenerationCounters(EpsilonHeap* heap) :
|
||||
GenerationCounters("Heap", 1, 1, 0, heap->max_capacity(), heap->capacity()),
|
||||
_heap(heap)
|
||||
{};
|
||||
|
||||
virtual void update_all() {
|
||||
_current_size->set_value(_heap->capacity());
|
||||
}
|
||||
};
|
||||
|
||||
EpsilonMonitoringSupport::EpsilonMonitoringSupport(EpsilonHeap* heap) {
|
||||
_heap_counters = new EpsilonGenerationCounters(heap);
|
||||
_space_counters = new EpsilonSpaceCounters("Heap", 0, heap->max_capacity(), 0, _heap_counters);
|
||||
}
|
||||
|
||||
void EpsilonMonitoringSupport::update_counters() {
|
||||
MemoryService::track_memory_usage();
|
||||
|
||||
if (UsePerfData) {
|
||||
EpsilonHeap* heap = EpsilonHeap::heap();
|
||||
size_t used = heap->used();
|
||||
size_t capacity = heap->capacity();
|
||||
_heap_counters->update_all();
|
||||
_space_counters->update_all(capacity, used);
|
||||
MetaspaceCounters::update_performance_counters();
|
||||
CompressedClassSpaceCounters::update_performance_counters();
|
||||
}
|
||||
}
|
||||
|
44
src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp
Normal file
44
src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_EPSILONMONITORINGSUPPORT_HPP
|
||||
#define SHARE_VM_GC_EPSILON_EPSILONMONITORINGSUPPORT_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class GenerationCounters;
|
||||
class EpsilonSpaceCounters;
|
||||
class EpsilonHeap;
|
||||
|
||||
class EpsilonMonitoringSupport : public CHeapObj<mtGC> {
|
||||
private:
|
||||
GenerationCounters* _heap_counters;
|
||||
EpsilonSpaceCounters* _space_counters;
|
||||
|
||||
public:
|
||||
EpsilonMonitoringSupport(EpsilonHeap* heap);
|
||||
void update_counters();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_EPSILONMONITORINGSUPPORT_HPP
|
||||
|
70
src/hotspot/share/gc/epsilon/epsilonThreadLocalData.hpp
Normal file
70
src/hotspot/share/gc/epsilon/epsilonThreadLocalData.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_EPSILONTHREADLOCALDATA_HPP
|
||||
#define SHARE_VM_GC_EPSILON_EPSILONTHREADLOCALDATA_HPP
|
||||
|
||||
#include "runtime/thread.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
class EpsilonThreadLocalData {
|
||||
private:
|
||||
size_t _ergo_tlab_size;
|
||||
int64_t _last_tlab_time;
|
||||
|
||||
EpsilonThreadLocalData() :
|
||||
_ergo_tlab_size(0),
|
||||
_last_tlab_time(0) {}
|
||||
|
||||
static EpsilonThreadLocalData* data(Thread* thread) {
|
||||
assert(UseEpsilonGC, "Sanity");
|
||||
return thread->gc_data<EpsilonThreadLocalData>();
|
||||
}
|
||||
|
||||
public:
|
||||
static void create(Thread* thread) {
|
||||
new (data(thread)) EpsilonThreadLocalData();
|
||||
}
|
||||
|
||||
static void destroy(Thread* thread) {
|
||||
data(thread)->~EpsilonThreadLocalData();
|
||||
}
|
||||
|
||||
static size_t ergo_tlab_size(Thread *thread) {
|
||||
return data(thread)->_ergo_tlab_size;
|
||||
}
|
||||
|
||||
static int64_t last_tlab_time(Thread *thread) {
|
||||
return data(thread)->_last_tlab_time;
|
||||
}
|
||||
|
||||
static void set_ergo_tlab_size(Thread *thread, size_t val) {
|
||||
data(thread)->_ergo_tlab_size = val;
|
||||
}
|
||||
|
||||
static void set_last_tlab_time(Thread *thread, int64_t time) {
|
||||
data(thread)->_last_tlab_time = time;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_EPSILONTHREADLOCALDATA_HPP
|
96
src/hotspot/share/gc/epsilon/epsilon_globals.hpp
Normal file
96
src/hotspot/share/gc/epsilon/epsilon_globals.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_EPSILON_GLOBALS_HPP
|
||||
#define SHARE_VM_GC_EPSILON_GLOBALS_HPP
|
||||
|
||||
#include "runtime/globals.hpp"
|
||||
//
|
||||
// Defines all globals flags used by the Epsilon GC.
|
||||
//
|
||||
|
||||
#define GC_EPSILON_FLAGS(develop, \
|
||||
develop_pd, \
|
||||
product, \
|
||||
product_pd, \
|
||||
diagnostic, \
|
||||
diagnostic_pd, \
|
||||
experimental, \
|
||||
notproduct, \
|
||||
manageable, \
|
||||
product_rw, \
|
||||
lp64_product, \
|
||||
range, \
|
||||
constraint, \
|
||||
writeable) \
|
||||
\
|
||||
experimental(size_t, EpsilonPrintHeapSteps, 20, \
|
||||
"Print heap occupancy stats with this number of steps. " \
|
||||
"0 turns the printing off.") \
|
||||
range(0, max_intx) \
|
||||
\
|
||||
experimental(size_t, EpsilonUpdateCountersStep, 1 * M, \
|
||||
"Update heap occupancy counters after allocating this much " \
|
||||
"memory. Higher values would make allocations faster at " \
|
||||
"the expense of lower resolution in heap counters.") \
|
||||
range(1, max_intx) \
|
||||
\
|
||||
experimental(size_t, EpsilonMaxTLABSize, 4 * M, \
|
||||
"Max TLAB size to use with Epsilon GC. Larger value improves " \
|
||||
"performance at the expense of per-thread memory waste. This " \
|
||||
"asks TLAB machinery to cap TLAB sizes at this value.") \
|
||||
range(1, max_intx) \
|
||||
\
|
||||
experimental(bool, EpsilonElasticTLAB, true, \
|
||||
"Use elastic policy to manage TLAB sizes. This conserves memory " \
|
||||
"for non-actively allocating threads, even when they request " \
|
||||
"large TLABs for themselves. Active threads would experience " \
|
||||
"smaller TLABs until policy catches up.") \
|
||||
\
|
||||
experimental(bool, EpsilonElasticTLABDecay, true, \
|
||||
"Use timed decays to shrik TLAB sizes. This conserves memory " \
|
||||
"for the threads that allocate in bursts of different sizes, " \
|
||||
"for example the small/rare allocations coming after the initial "\
|
||||
"large burst.") \
|
||||
\
|
||||
experimental(double, EpsilonTLABElasticity, 1.1, \
|
||||
"Multiplier to use when deciding on next TLAB size. Larger value "\
|
||||
"improves performance at the expense of per-thread memory waste. "\
|
||||
"Lower value improves memory footprint, but penalizes actively " \
|
||||
"allocating threads.") \
|
||||
range(1, max_intx) \
|
||||
\
|
||||
experimental(size_t, EpsilonTLABDecayTime, 1000, \
|
||||
"TLAB sizing policy decays to initial size after thread had not " \
|
||||
"allocated for this long. Time is in milliseconds. Lower value " \
|
||||
"improves memory footprint, but penalizes actively allocating " \
|
||||
"threads.") \
|
||||
range(1, max_intx) \
|
||||
\
|
||||
experimental(size_t, EpsilonMinHeapExpand, 128 * M, \
|
||||
"Min expansion step for heap. Larger value improves performance " \
|
||||
"at the potential expense of memory waste.") \
|
||||
range(1, max_intx)
|
||||
|
||||
#endif // SHARE_VM_GC_EPSILON_GLOBALS_HPP
|
46
src/hotspot/share/gc/epsilon/vmStructs_epsilon.hpp
Normal file
46
src/hotspot/share/gc/epsilon/vmStructs_epsilon.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_EPSILON_VMSTRUCTS_HPP
|
||||
#define SHARE_GC_EPSILON_VMSTRUCTS_HPP
|
||||
|
||||
#include "gc/epsilon/epsilonHeap.hpp"
|
||||
#include "gc/shared/space.hpp"
|
||||
#include "memory/virtualspace.hpp"
|
||||
|
||||
#define VM_STRUCTS_EPSILONGC(nonstatic_field, \
|
||||
volatile_nonstatic_field, \
|
||||
static_field) \
|
||||
nonstatic_field(EpsilonHeap, _virtual_space, VirtualSpace) \
|
||||
nonstatic_field(EpsilonHeap, _space, ContiguousSpace*)
|
||||
|
||||
#define VM_TYPES_EPSILONGC(declare_type, \
|
||||
declare_toplevel_type, \
|
||||
declare_integer_type) \
|
||||
declare_type(EpsilonHeap, CollectedHeap)
|
||||
|
||||
#define VM_INT_CONSTANTS_EPSILONGC(declare_constant, \
|
||||
declare_constant_with_value)
|
||||
|
||||
#endif // SHARE_GC_EPSILON_VMSTRUCTS_HPP
|
@ -30,6 +30,7 @@
|
||||
// Do something for each concrete barrier set part of the build.
|
||||
#define FOR_EACH_CONCRETE_BARRIER_SET_DO(f) \
|
||||
f(CardTableBarrierSet) \
|
||||
EPSILONGC_ONLY(f(EpsilonBarrierSet)) \
|
||||
G1GC_ONLY(f(G1BarrierSet))
|
||||
|
||||
#define FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "gc/shared/modRefBarrierSet.inline.hpp"
|
||||
#include "gc/shared/cardTableBarrierSet.inline.hpp"
|
||||
|
||||
#if INCLUDE_EPSILONGC
|
||||
#include "gc/epsilon/epsilonBarrierSet.hpp" // Epsilon support
|
||||
#endif
|
||||
#if INCLUDE_G1GC
|
||||
#include "gc/g1/g1BarrierSet.inline.hpp" // G1 support
|
||||
#endif
|
||||
|
@ -206,7 +206,8 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
Serial,
|
||||
Parallel,
|
||||
CMS,
|
||||
G1
|
||||
G1,
|
||||
Epsilon
|
||||
};
|
||||
|
||||
static inline size_t filler_array_max_size() {
|
||||
|
@ -31,6 +31,9 @@
|
||||
#if INCLUDE_CMSGC
|
||||
#include "gc/cms/cmsArguments.hpp"
|
||||
#endif
|
||||
#if INCLUDE_EPSILONGC
|
||||
#include "gc/epsilon/epsilonArguments.hpp"
|
||||
#endif
|
||||
#if INCLUDE_G1GC
|
||||
#include "gc/g1/g1Arguments.hpp"
|
||||
#endif
|
||||
@ -52,6 +55,7 @@ struct SupportedGC {
|
||||
};
|
||||
|
||||
CMSGC_ONLY(static CMSArguments cmsArguments;)
|
||||
EPSILONGC_ONLY(static EpsilonArguments epsilonArguments;)
|
||||
G1GC_ONLY(static G1Arguments g1Arguments;)
|
||||
PARALLELGC_ONLY(static ParallelArguments parallelArguments;)
|
||||
SERIALGC_ONLY(static SerialArguments serialArguments;)
|
||||
@ -60,6 +64,7 @@ PARALLELGC_ONLY(static ParallelArguments parallelArguments;)
|
||||
// line flag, CollectedHeap::Name and GCArguments instance.
|
||||
static const SupportedGC SupportedGCs[] = {
|
||||
CMSGC_ONLY_ARG(SupportedGC(UseConcMarkSweepGC, CollectedHeap::CMS, cmsArguments, "concurrent mark sweep gc"))
|
||||
EPSILONGC_ONLY_ARG(SupportedGC(UseEpsilonGC, CollectedHeap::Epsilon, epsilonArguments, "epsilon gc"))
|
||||
G1GC_ONLY_ARG(SupportedGC(UseG1GC, CollectedHeap::G1, g1Arguments, "g1 gc"))
|
||||
PARALLELGC_ONLY_ARG(SupportedGC(UseParallelGC, CollectedHeap::Parallel, parallelArguments, "parallel gc"))
|
||||
PARALLELGC_ONLY_ARG(SupportedGC(UseParallelOldGC, CollectedHeap::Parallel, parallelArguments, "parallel gc"))
|
||||
@ -88,6 +93,7 @@ void GCConfig::select_gc_ergonomically() {
|
||||
}
|
||||
|
||||
NOT_CMSGC( UNSUPPORTED_OPTION(UseConcMarkSweepGC));
|
||||
NOT_EPSILONGC( UNSUPPORTED_OPTION(UseEpsilonGC);)
|
||||
NOT_G1GC( UNSUPPORTED_OPTION(UseG1GC);)
|
||||
NOT_PARALLELGC(UNSUPPORTED_OPTION(UseParallelGC);)
|
||||
NOT_PARALLELGC(UNSUPPORTED_OPTION(UseParallelOldGC));
|
||||
|
@ -29,6 +29,9 @@
|
||||
#if INCLUDE_CMSGC
|
||||
#include "gc/cms/cms_globals.hpp"
|
||||
#endif
|
||||
#if INCLUDE_EPSILONGC
|
||||
#include "gc/epsilon/epsilon_globals.hpp"
|
||||
#endif
|
||||
#if INCLUDE_G1GC
|
||||
#include "gc/g1/g1_globals.hpp"
|
||||
#endif
|
||||
@ -70,6 +73,22 @@
|
||||
constraint, \
|
||||
writeable)) \
|
||||
\
|
||||
EPSILONGC_ONLY(GC_EPSILON_FLAGS( \
|
||||
develop, \
|
||||
develop_pd, \
|
||||
product, \
|
||||
product_pd, \
|
||||
diagnostic, \
|
||||
diagnostic_pd, \
|
||||
experimental, \
|
||||
notproduct, \
|
||||
manageable, \
|
||||
product_rw, \
|
||||
lp64_product, \
|
||||
range, \
|
||||
constraint, \
|
||||
writeable)) \
|
||||
\
|
||||
G1GC_ONLY(GC_G1_FLAGS( \
|
||||
develop, \
|
||||
develop_pd, \
|
||||
@ -135,6 +154,9 @@
|
||||
product(bool, UseParallelOldGC, false, \
|
||||
"Use the Parallel Old garbage collector") \
|
||||
\
|
||||
experimental(bool, UseEpsilonGC, false, \
|
||||
"Use the Epsilon (no-op) garbage collector") \
|
||||
\
|
||||
product(uint, ParallelGCThreads, 0, \
|
||||
"Number of parallel threads parallel gc will use") \
|
||||
constraint(ParallelGCThreadsConstraintFunc,AfterErgo) \
|
||||
|
@ -37,6 +37,9 @@
|
||||
#if INCLUDE_CMSGC
|
||||
#include "gc/cms/vmStructs_cms.hpp"
|
||||
#endif
|
||||
#if INCLUDE_EPSILONGC
|
||||
#include "gc/epsilon/vmStructs_epsilon.hpp"
|
||||
#endif
|
||||
#if INCLUDE_G1GC
|
||||
#include "gc/g1/vmStructs_g1.hpp"
|
||||
#endif
|
||||
@ -55,6 +58,9 @@
|
||||
CMSGC_ONLY(VM_STRUCTS_CMSGC(nonstatic_field, \
|
||||
volatile_nonstatic_field, \
|
||||
static_field)) \
|
||||
EPSILONGC_ONLY(VM_STRUCTS_EPSILONGC(nonstatic_field, \
|
||||
volatile_nonstatic_field, \
|
||||
static_field)) \
|
||||
G1GC_ONLY(VM_STRUCTS_G1GC(nonstatic_field, \
|
||||
volatile_nonstatic_field, \
|
||||
static_field)) \
|
||||
@ -153,6 +159,9 @@
|
||||
CMSGC_ONLY(VM_TYPES_CMSGC(declare_type, \
|
||||
declare_toplevel_type, \
|
||||
declare_integer_type)) \
|
||||
EPSILONGC_ONLY(VM_TYPES_EPSILONGC(declare_type, \
|
||||
declare_toplevel_type, \
|
||||
declare_integer_type)) \
|
||||
G1GC_ONLY(VM_TYPES_G1GC(declare_type, \
|
||||
declare_toplevel_type, \
|
||||
declare_integer_type)) \
|
||||
@ -225,6 +234,8 @@
|
||||
declare_constant_with_value) \
|
||||
CMSGC_ONLY(VM_INT_CONSTANTS_CMSGC(declare_constant, \
|
||||
declare_constant_with_value)) \
|
||||
EPSILONGC_ONLY(VM_INT_CONSTANTS_EPSILONGC(declare_constant, \
|
||||
declare_constant_with_value)) \
|
||||
G1GC_ONLY(VM_INT_CONSTANTS_G1GC(declare_constant, \
|
||||
declare_constant_with_value)) \
|
||||
PARALLELGC_ONLY(VM_INT_CONSTANTS_PARALLELGC(declare_constant, \
|
||||
|
@ -149,6 +149,24 @@
|
||||
#define NOT_CMSGC_RETURN_(code) { return code; }
|
||||
#endif // INCLUDE_CMSGC
|
||||
|
||||
#ifndef INCLUDE_EPSILONGC
|
||||
#define INCLUDE_EPSILONGC 1
|
||||
#endif // INCLUDE_EPSILONGC
|
||||
|
||||
#if INCLUDE_EPSILONGC
|
||||
#define EPSILONGC_ONLY(x) x
|
||||
#define EPSILONGC_ONLY_ARG(arg) arg,
|
||||
#define NOT_EPSILONGC(x)
|
||||
#define NOT_EPSILONGC_RETURN /* next token must be ; */
|
||||
#define NOT_EPSILONGC_RETURN_(code) /* next token must be ; */
|
||||
#else
|
||||
#define EPSILONGC_ONLY(x)
|
||||
#define EPSILONGC_ONLY_ARG(arg)
|
||||
#define NOT_EPSILONGC(x) x
|
||||
#define NOT_EPSILONGC_RETURN {}
|
||||
#define NOT_EPSILONGC_RETURN_(code) { return code; }
|
||||
#endif // INCLUDE_EPSILONGC
|
||||
|
||||
#ifndef INCLUDE_G1GC
|
||||
#define INCLUDE_G1GC 1
|
||||
#endif // INCLUDE_G1GC
|
||||
@ -203,7 +221,7 @@
|
||||
#define NOT_SERIALGC_RETURN_(code) { return code; }
|
||||
#endif // INCLUDE_SERIALGC
|
||||
|
||||
#if INCLUDE_CMSGC || INCLUDE_G1GC || INCLUDE_PARALLELGC
|
||||
#if INCLUDE_CMSGC || INCLUDE_EPSILONGC || INCLUDE_G1GC || INCLUDE_PARALLELGC
|
||||
#define INCLUDE_NOT_ONLY_SERIALGC 1
|
||||
#else
|
||||
#define INCLUDE_NOT_ONLY_SERIALGC 0
|
||||
|
@ -33,6 +33,7 @@ import java.util.*;
|
||||
import sun.jvm.hotspot.code.*;
|
||||
import sun.jvm.hotspot.compiler.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.gc.epsilon.*;
|
||||
import sun.jvm.hotspot.gc.parallel.*;
|
||||
import sun.jvm.hotspot.gc.shared.*;
|
||||
import sun.jvm.hotspot.gc.g1.*;
|
||||
@ -1108,6 +1109,9 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
|
||||
anno = "PSOldGen ";
|
||||
bad = false;
|
||||
}
|
||||
} else if (collHeap instanceof EpsilonHeap) {
|
||||
anno = "Epsilon ";
|
||||
bad = false;
|
||||
} else {
|
||||
// Optimistically assume the oop isn't bad
|
||||
anno = "[Unknown generation] ";
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
|
||||
* 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 sun.jvm.hotspot.gc.epsilon;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import sun.jvm.hotspot.gc.shared.*;
|
||||
import sun.jvm.hotspot.code.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
|
||||
public class EpsilonHeap extends CollectedHeap {
|
||||
|
||||
private static AddressField spaceField;
|
||||
private static Field virtualSpaceField;
|
||||
private ContiguousSpace space;
|
||||
private VirtualSpace virtualSpace;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("EpsilonHeap");
|
||||
spaceField = type.getAddressField("_space");
|
||||
virtualSpaceField = type.getField("_virtual_space");
|
||||
}
|
||||
|
||||
public EpsilonHeap(Address addr) {
|
||||
super(addr);
|
||||
space = new ContiguousSpace(spaceField.getValue(addr));
|
||||
virtualSpace = new VirtualSpace(addr.addOffsetTo(virtualSpaceField.getOffset()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectedHeapName kind() {
|
||||
return CollectedHeapName.EPSILON;
|
||||
}
|
||||
|
||||
public ContiguousSpace space() {
|
||||
return space;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printOn(PrintStream tty) {
|
||||
MemRegion mr = reservedRegion();
|
||||
tty.println("Epsilon heap");
|
||||
tty.println(" reserved: [" + mr.start() + ", " + mr.end() + "]");
|
||||
tty.println(" committed: [" + virtualSpace.low() + ", " + virtualSpace.high() + "]");
|
||||
tty.println(" used: [" + space.bottom() + ", " + space.top() + "]");
|
||||
}
|
||||
|
||||
}
|
@ -35,6 +35,7 @@ public class CollectedHeapName {
|
||||
public static final CollectedHeapName PARALLEL = new CollectedHeapName("Parallel");
|
||||
public static final CollectedHeapName CMS = new CollectedHeapName("CMS");
|
||||
public static final CollectedHeapName G1 = new CollectedHeapName("G1");
|
||||
public static final CollectedHeapName EPSILON = new CollectedHeapName("Epsilon");
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
|
@ -31,6 +31,7 @@ import sun.jvm.hotspot.gc.cms.CMSHeap;
|
||||
import sun.jvm.hotspot.gc.serial.SerialHeap;
|
||||
import sun.jvm.hotspot.gc.shared.*;
|
||||
import sun.jvm.hotspot.gc.g1.G1CollectedHeap;
|
||||
import sun.jvm.hotspot.gc.epsilon.EpsilonHeap;
|
||||
import sun.jvm.hotspot.gc.parallel.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
@ -82,6 +83,7 @@ public class Universe {
|
||||
heapConstructor.addMapping("SerialHeap", SerialHeap.class);
|
||||
heapConstructor.addMapping("ParallelScavengeHeap", ParallelScavengeHeap.class);
|
||||
heapConstructor.addMapping("G1CollectedHeap", G1CollectedHeap.class);
|
||||
heapConstructor.addMapping("EpsilonHeap", EpsilonHeap.class);
|
||||
|
||||
mainThreadGroupField = type.getOopField("_main_thread_group");
|
||||
systemThreadGroupField = type.getOopField("_system_thread_group");
|
||||
|
@ -34,6 +34,7 @@ import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.gc.cms.*;
|
||||
import sun.jvm.hotspot.gc.shared.*;
|
||||
import sun.jvm.hotspot.gc.epsilon.*;
|
||||
import sun.jvm.hotspot.gc.g1.*;
|
||||
import sun.jvm.hotspot.gc.parallel.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
@ -438,11 +439,13 @@ public class ObjectHeap {
|
||||
} else if (heap instanceof G1CollectedHeap) {
|
||||
G1CollectedHeap g1h = (G1CollectedHeap) heap;
|
||||
g1h.heapRegionIterate(lrc);
|
||||
} else if (heap instanceof EpsilonHeap) {
|
||||
EpsilonHeap eh = (EpsilonHeap) heap;
|
||||
liveRegions.add(eh.space().top());
|
||||
liveRegions.add(eh.space().bottom());
|
||||
} else {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(false, "Expecting GenCollectedHeap, G1CollectedHeap, " +
|
||||
"or ParallelScavengeHeap, but got " +
|
||||
heap.getClass().getName());
|
||||
Assert.that(false, "Unexpected CollectedHeap type: " + heap.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
package sun.jvm.hotspot.tools;
|
||||
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.gc.epsilon.*;
|
||||
import sun.jvm.hotspot.gc.g1.*;
|
||||
import sun.jvm.hotspot.gc.parallel.*;
|
||||
import sun.jvm.hotspot.gc.serial.*;
|
||||
@ -124,6 +125,9 @@ public class HeapSummary extends Tool {
|
||||
printValMB("used = ", oldGen.used());
|
||||
printValMB("free = ", oldFree);
|
||||
System.out.println(alignment + (double)oldGen.used() * 100.0 / oldGen.capacity() + "% used");
|
||||
} else if (heap instanceof EpsilonHeap) {
|
||||
EpsilonHeap eh = (EpsilonHeap) heap;
|
||||
printSpace(eh.space());
|
||||
} else {
|
||||
throw new RuntimeException("unknown CollectedHeap type : " + heap.getClass());
|
||||
}
|
||||
@ -161,6 +165,12 @@ public class HeapSummary extends Tool {
|
||||
return;
|
||||
}
|
||||
|
||||
l = getFlagValue("UseEpsilonGC", flagMap);
|
||||
if (l == 1L) {
|
||||
System.out.println("Epsilon (no-op) GC");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Mark Sweep Compact GC");
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ requires.properties= \
|
||||
vm.gc.Serial \
|
||||
vm.gc.Parallel \
|
||||
vm.gc.ConcMarkSweep \
|
||||
vm.gc.Epsilon \
|
||||
vm.jvmci \
|
||||
vm.emulatedClient \
|
||||
vm.cpu.features \
|
||||
|
@ -174,12 +174,14 @@ hotspot_not_fast_gc = \
|
||||
-:tier1_gc
|
||||
|
||||
tier1_gc_1 = \
|
||||
gc/epsilon/ \
|
||||
gc/g1/ \
|
||||
-gc/g1/ihop/TestIHOPErgo.java
|
||||
|
||||
tier1_gc_2 = \
|
||||
sanity/ExecuteInternalVMTests.java \
|
||||
gc/ \
|
||||
-gc/epsilon/ \
|
||||
-gc/g1/ \
|
||||
-gc/logging/TestUnifiedLoggingSwitchStress.java \
|
||||
-gc/stress \
|
||||
|
36
test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java
Normal file
36
test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestAlwaysPretouch
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Basic sanity test for Epsilon
|
||||
* @run main/othervm -Xmx1g -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestAlwaysPretouch
|
||||
*/
|
||||
|
||||
public class TestAlwaysPretouch {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// everything should happen before entry point
|
||||
}
|
||||
}
|
78
test/hotspot/jtreg/gc/epsilon/TestByteArrays.java
Normal file
78
test/hotspot/jtreg/gc/epsilon/TestByteArrays.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestByteArrays
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon is able to allocate arrays, and does not corrupt their state
|
||||
*
|
||||
* @run main/othervm -Xmx1g -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
*
|
||||
* @run main/othervm -Xmx1g -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestByteArrays
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TestByteArrays {
|
||||
|
||||
static long SEED = Long.getLong("seed", System.nanoTime());
|
||||
static int COUNT = Integer.getInteger("count", 3000); // ~500 MB allocation
|
||||
|
||||
static byte[][] arr;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Random r = new Random(SEED);
|
||||
|
||||
arr = new byte[COUNT * 100][];
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
arr[c] = new byte[c * 100];
|
||||
for (int v = 0; v < c; v++) {
|
||||
arr[c][v] = (byte)(r.nextInt(255) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
r = new Random(SEED);
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
byte[] b = arr[c];
|
||||
if (b.length != (c * 100)) {
|
||||
throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
|
||||
}
|
||||
for (int v = 0; v < c; v++) {
|
||||
byte actual = b[v];
|
||||
byte expected = (byte)(r.nextInt(255) & 0xFF);
|
||||
if (actual != expected) {
|
||||
throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
108
test/hotspot/jtreg/gc/epsilon/TestDieDefault.java
Normal file
108
test/hotspot/jtreg/gc/epsilon/TestDieDefault.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestDieDefault
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon GC should die on heap exhaustion
|
||||
* @library /test/lib
|
||||
* @run main TestDieDefault
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
public class TestDieDefault {
|
||||
|
||||
public static void passWith(String... args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
out.shouldNotContain("OutOfMemoryError");
|
||||
out.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
public static void failWith(String... args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
out.shouldContain("OutOfMemoryError");
|
||||
if (out.getExitValue() == 0) {
|
||||
throw new IllegalStateException("Should have failed with non-zero exit code");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
passWith("-Xmx128m",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-Dcount=1",
|
||||
TestDieDefault.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
TestDieDefault.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xint",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
TestDieDefault.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
TestDieDefault.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:TieredStopAtLevel=1",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
TestDieDefault.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
TestDieDefault.Workload.class.getName());
|
||||
}
|
||||
|
||||
public static class Workload {
|
||||
static int COUNT = Integer.getInteger("count", 1_000_000_000); // ~24 GB allocation
|
||||
|
||||
static volatile Object sink;
|
||||
|
||||
public static void main(String... args) {
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
sink = new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
120
test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java
Normal file
120
test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestDieWithHeapDump
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon GC should die on heap exhaustion with error handler attached
|
||||
* @library /test/lib
|
||||
* @run main TestDieWithHeapDump
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
public class TestDieWithHeapDump {
|
||||
|
||||
public static void passWith(String... args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
out.shouldNotContain("OutOfMemoryError");
|
||||
out.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
public static void failWith(String... args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
Process p = pb.start();
|
||||
OutputAnalyzer out = new OutputAnalyzer(p);
|
||||
out.shouldContain("OutOfMemoryError");
|
||||
if (out.getExitValue() == 0) {
|
||||
throw new IllegalStateException("Should have failed with non-zero exit code");
|
||||
}
|
||||
String heapDump = "java_pid" + p.pid() + ".hprof";
|
||||
if (!new File(heapDump).exists()) {
|
||||
throw new IllegalStateException("Should have produced the heap dump at: " + heapDump);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
passWith("-Xmx128m",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-Dcount=1",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
TestDieWithHeapDump.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
TestDieWithHeapDump.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xint",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
TestDieWithHeapDump.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
TestDieWithHeapDump.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:TieredStopAtLevel=1",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
TestDieWithHeapDump.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
TestDieWithHeapDump.Workload.class.getName());
|
||||
}
|
||||
|
||||
public static class Workload {
|
||||
static int COUNT = Integer.getInteger("count", 1_000_000_000); // ~24 GB allocation
|
||||
|
||||
static volatile Object sink;
|
||||
|
||||
public static void main(String... args) {
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
sink = new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
118
test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java
Normal file
118
test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestDieWithOnError
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon GC should die on heap exhaustion with error handler attached
|
||||
* @library /test/lib
|
||||
* @run main TestDieWithOnError
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
public class TestDieWithOnError {
|
||||
|
||||
static String ON_ERR_MSG = "Epsilon error handler message";
|
||||
|
||||
public static void passWith(String... args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
out.shouldNotContain("OutOfMemoryError");
|
||||
out.stdoutShouldNotMatch("^" + ON_ERR_MSG);
|
||||
out.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
public static void failWith(String... args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
out.shouldContain("OutOfMemoryError");
|
||||
if (out.getExitValue() == 0) {
|
||||
throw new IllegalStateException("Should have failed with non-zero exit code");
|
||||
}
|
||||
out.stdoutShouldMatch("^" + ON_ERR_MSG);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
passWith("-Xmx128m",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-Dcount=1",
|
||||
"-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
|
||||
TestDieWithOnError.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
|
||||
TestDieWithOnError.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xint",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
|
||||
TestDieWithOnError.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
|
||||
TestDieWithOnError.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:TieredStopAtLevel=1",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
|
||||
TestDieWithOnError.Workload.class.getName());
|
||||
|
||||
failWith("-Xmx128m",
|
||||
"-Xbatch",
|
||||
"-Xcomp",
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UnlockExperimentalVMOptions",
|
||||
"-XX:+UseEpsilonGC",
|
||||
"-XX:OnOutOfMemoryError=echo " + ON_ERR_MSG,
|
||||
TestDieWithOnError.Workload.class.getName());
|
||||
}
|
||||
|
||||
public static class Workload {
|
||||
static int COUNT = Integer.getInteger("count", 1_000_000_000); // ~24 GB allocation
|
||||
|
||||
static volatile Object sink;
|
||||
|
||||
public static void main(String... args) {
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
sink = new Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
73
test/hotspot/jtreg/gc/epsilon/TestElasticTLAB.java
Normal file
73
test/hotspot/jtreg/gc/epsilon/TestElasticTLAB.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestElasticTLAB
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon is able to work with/without elastic TLABs
|
||||
*
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:-EpsilonElasticTLAB TestElasticTLAB
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=1 TestElasticTLAB
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=1.1 TestElasticTLAB
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=2.0 TestElasticTLAB
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=42 TestElasticTLAB
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:EpsilonTLABElasticity=100 TestElasticTLAB
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TestElasticTLAB {
|
||||
|
||||
static long SEED = Long.getLong("seed", System.nanoTime());
|
||||
static int COUNT = Integer.getInteger("count", 3000); // ~500 MB allocation
|
||||
|
||||
static byte[][] arr;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Random r = new Random(SEED);
|
||||
|
||||
arr = new byte[COUNT * 100][];
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
arr[c] = new byte[c * 100];
|
||||
for (int v = 0; v < c; v++) {
|
||||
arr[c][v] = (byte)(r.nextInt(255) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
r = new Random(SEED);
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
byte[] b = arr[c];
|
||||
if (b.length != (c * 100)) {
|
||||
throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
|
||||
}
|
||||
for (int v = 0; v < c; v++) {
|
||||
byte actual = b[v];
|
||||
byte expected = (byte)(r.nextInt(255) & 0xFF);
|
||||
if (actual != expected) {
|
||||
throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
71
test/hotspot/jtreg/gc/epsilon/TestElasticTLABDecay.java
Normal file
71
test/hotspot/jtreg/gc/epsilon/TestElasticTLABDecay.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestElasticTLABDecay
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon is able to work with/without elastic TLABs
|
||||
*
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:-EpsilonElasticTLABDecay TestElasticTLABDecay
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:+EpsilonElasticTLABDecay -XX:EpsilonTLABDecayTime=1 TestElasticTLABDecay
|
||||
* @run main/othervm -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+EpsilonElasticTLAB -XX:+EpsilonElasticTLABDecay -XX:EpsilonTLABDecayTime=100 TestElasticTLABDecay
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TestElasticTLABDecay {
|
||||
|
||||
static long SEED = Long.getLong("seed", System.nanoTime());
|
||||
static int COUNT = Integer.getInteger("count", 3000); // ~500 MB allocation
|
||||
|
||||
static byte[][] arr;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Random r = new Random(SEED);
|
||||
|
||||
arr = new byte[COUNT * 100][];
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
arr[c] = new byte[c * 100];
|
||||
for (int v = 0; v < c; v++) {
|
||||
arr[c][v] = (byte)(r.nextInt(255) & 0xFF);
|
||||
}
|
||||
Thread.sleep(5);
|
||||
}
|
||||
|
||||
r = new Random(SEED);
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
byte[] b = arr[c];
|
||||
if (b.length != (c * 100)) {
|
||||
throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
|
||||
}
|
||||
for (int v = 0; v < c; v++) {
|
||||
byte actual = b[v];
|
||||
byte expected = (byte)(r.nextInt(255) & 0xFF);
|
||||
if (actual != expected) {
|
||||
throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
test/hotspot/jtreg/gc/epsilon/TestEpsilonEnabled.java
Normal file
52
test/hotspot/jtreg/gc/epsilon/TestEpsilonEnabled.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestAlwaysPretouch
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Basic sanity test for Epsilon
|
||||
* @library /test/lib
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestEpsilonEnabled
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
public class TestEpsilonEnabled {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (!isEpsilonEnabled()) {
|
||||
throw new IllegalStateException("Debug builds should have Epsilon enabled");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEpsilonEnabled() {
|
||||
for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
|
||||
if (bean.getName().contains("Epsilon")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
36
test/hotspot/jtreg/gc/epsilon/TestHelloWorld.java
Normal file
36
test/hotspot/jtreg/gc/epsilon/TestHelloWorld.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestHelloWorld
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Basic sanity test for Epsilon
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestHelloWorld
|
||||
*/
|
||||
|
||||
public class TestHelloWorld {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
36
test/hotspot/jtreg/gc/epsilon/TestLogTrace.java
Normal file
36
test/hotspot/jtreg/gc/epsilon/TestLogTrace.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestLogTrace
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Test that tracing does not crash Epsilon
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc*=trace TestLogTrace
|
||||
*/
|
||||
|
||||
public class TestLogTrace {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
79
test/hotspot/jtreg/gc/epsilon/TestManyThreads.java
Normal file
79
test/hotspot/jtreg/gc/epsilon/TestManyThreads.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestManyThreads
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Test allocations from many threads
|
||||
*
|
||||
* @run main/othervm -Xmx128m -Xss512k -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
*
|
||||
* @run main/othervm -Xmx128m -Xss512k -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
* @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestManyThreads
|
||||
*/
|
||||
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
public class TestManyThreads {
|
||||
|
||||
static int COUNT = Integer.getInteger("count", 128); // 128 * 4M max tlabs = 512M, would overflow without TLAB sizing
|
||||
|
||||
static volatile Object sink;
|
||||
static volatile Throwable failed;
|
||||
static final AtomicInteger allocated = new AtomicInteger();
|
||||
|
||||
public static void workload() {
|
||||
try {
|
||||
sink = new Object();
|
||||
allocated.incrementAndGet();
|
||||
Thread.sleep(3600 * 1000);
|
||||
} catch (Throwable e) {
|
||||
failed = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
Thread t = new Thread(TestManyThreads::workload);
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
while ((failed == null) && (allocated.get() != COUNT)) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
|
||||
if (failed != null) {
|
||||
throw failed;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
95
test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java
Normal file
95
test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestMemoryMXBeans
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Test JMX memory beans
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xmx1g TestMemoryMXBeans -1 1024
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xms1g -Xmx1g TestMemoryMXBeans 1024 1024
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xms128m -Xmx1g TestMemoryMXBeans 128 1024
|
||||
*/
|
||||
|
||||
import java.lang.management.*;
|
||||
import java.util.*;
|
||||
|
||||
public class TestMemoryMXBeans {
|
||||
|
||||
static volatile Object sink;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new IllegalStateException("Should provide expected heap sizes");
|
||||
}
|
||||
|
||||
long initSize = 1L * Integer.parseInt(args[0]) * 1024 * 1024;
|
||||
long maxSize = 1L * Integer.parseInt(args[1]) * 1024 * 1024;
|
||||
|
||||
testMemoryBean(initSize, maxSize);
|
||||
testAllocs();
|
||||
}
|
||||
|
||||
public static void testMemoryBean(long initSize, long maxSize) {
|
||||
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
|
||||
long heapInit = memoryMXBean.getHeapMemoryUsage().getInit();
|
||||
long heapMax = memoryMXBean.getHeapMemoryUsage().getMax();
|
||||
long nonHeapInit = memoryMXBean.getNonHeapMemoryUsage().getInit();
|
||||
long nonHeapMax = memoryMXBean.getNonHeapMemoryUsage().getMax();
|
||||
|
||||
if (initSize > 0 && heapInit != initSize) {
|
||||
throw new IllegalStateException("Init heap size is wrong: " + heapInit + " vs " + initSize);
|
||||
}
|
||||
if (maxSize > 0 && heapMax != maxSize) {
|
||||
throw new IllegalStateException("Max heap size is wrong: " + heapMax + " vs " + maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testAllocs() {
|
||||
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
|
||||
|
||||
// Do lazy inits first:
|
||||
long heapUsed1 = memoryMXBean.getHeapMemoryUsage().getUsed();
|
||||
sink = new int[1024*1024];
|
||||
long heapUsed2 = memoryMXBean.getHeapMemoryUsage().getUsed();
|
||||
|
||||
// Compute how much we waste during the calls themselves:
|
||||
heapUsed1 = memoryMXBean.getHeapMemoryUsage().getUsed();
|
||||
heapUsed2 = memoryMXBean.getHeapMemoryUsage().getUsed();
|
||||
long adj = heapUsed2 - heapUsed1;
|
||||
|
||||
heapUsed1 = memoryMXBean.getHeapMemoryUsage().getUsed();
|
||||
sink = new int[1024*1024];
|
||||
heapUsed2 = memoryMXBean.getHeapMemoryUsage().getUsed();
|
||||
|
||||
long diff = heapUsed2 - heapUsed1 - adj;
|
||||
long min = 8 + 4*1024*1024;
|
||||
long max = 16 + 4*1024*1024;
|
||||
if (!(min <= diff && diff <= max)) {
|
||||
throw new IllegalStateException("Allocation did not change used space right: " + diff + " should be in [" + min + ", " + max + "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
66
test/hotspot/jtreg/gc/epsilon/TestMemoryPools.java
Normal file
66
test/hotspot/jtreg/gc/epsilon/TestMemoryPools.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestMemoryPools
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Test JMX memory pools
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xmx1g -Xms1g TestMemoryPools
|
||||
*/
|
||||
|
||||
import java.lang.management.*;
|
||||
import java.util.*;
|
||||
|
||||
public class TestMemoryPools {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
List<MemoryManagerMXBean> mms = ManagementFactory.getMemoryManagerMXBeans();
|
||||
if (mms == null) {
|
||||
throw new RuntimeException("getMemoryManagerMXBeans is null");
|
||||
}
|
||||
if (mms.isEmpty()) {
|
||||
throw new RuntimeException("getMemoryManagerMXBeans is empty");
|
||||
}
|
||||
for (MemoryManagerMXBean mmBean : mms) {
|
||||
String[] names = mmBean.getMemoryPoolNames();
|
||||
if (names == null) {
|
||||
throw new RuntimeException("getMemoryPoolNames() is null");
|
||||
}
|
||||
if (names.length == 0) {
|
||||
throw new RuntimeException("getMemoryPoolNames() is empty");
|
||||
}
|
||||
for (String name : names) {
|
||||
if (name == null) {
|
||||
throw new RuntimeException("pool name is null");
|
||||
}
|
||||
if (name.length() == 0) {
|
||||
throw new RuntimeException("pool name is empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
79
test/hotspot/jtreg/gc/epsilon/TestObjects.java
Normal file
79
test/hotspot/jtreg/gc/epsilon/TestObjects.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestObjects
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon is able to allocate objects, and does not corrupt their state
|
||||
*
|
||||
* @run main/othervm -Xmx128m -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
*
|
||||
* @run main/othervm -Xmx128m -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
* @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestObjects
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TestObjects {
|
||||
|
||||
static long SEED = Long.getLong("seed", System.nanoTime());
|
||||
static int COUNT = Integer.getInteger("count", 1_000_000); // ~24 MB allocation
|
||||
|
||||
static MyObject[] arr;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Random r = new Random(SEED);
|
||||
|
||||
arr = new MyObject[COUNT];
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
arr[c] = new MyObject(r.nextInt());
|
||||
}
|
||||
|
||||
r = new Random(SEED);
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
int expected = r.nextInt();
|
||||
int actual = arr[c].id();
|
||||
if (expected != actual) {
|
||||
throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyObject {
|
||||
int id;
|
||||
public MyObject(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public int id() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
38
test/hotspot/jtreg/gc/epsilon/TestPrintHeapSteps.java
Normal file
38
test/hotspot/jtreg/gc/epsilon/TestPrintHeapSteps.java
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestPrintSteps
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Tests -XX:EpsilonPrintHeapSteps works
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=0 TestPrintHeapSteps
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=1 TestPrintHeapSteps
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=1000 TestPrintHeapSteps
|
||||
*/
|
||||
|
||||
public class TestPrintHeapSteps {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
89
test/hotspot/jtreg/gc/epsilon/TestRefArrays.java
Normal file
89
test/hotspot/jtreg/gc/epsilon/TestRefArrays.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestRefArrays
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Epsilon is able to allocate arrays, and does not corrupt their state
|
||||
* @library /test/lib
|
||||
*
|
||||
* @run main/othervm -Xmx1g -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
*
|
||||
* @run main/othervm -Xmx1g -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
* @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-TieredCompilation -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC TestRefArrays
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class TestRefArrays {
|
||||
|
||||
static long SEED = Long.getLong("seed", System.nanoTime());
|
||||
static int COUNT = Integer.getInteger("count", 1000); // ~500 MB allocation
|
||||
|
||||
static MyObject[][] arr;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Random r = new Random(SEED);
|
||||
|
||||
arr = new MyObject[COUNT * 100][];
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
arr[c] = new MyObject[c * 100];
|
||||
for (int v = 0; v < c; v++) {
|
||||
arr[c][v] = new MyObject(r.nextInt());
|
||||
}
|
||||
}
|
||||
|
||||
r = new Random(SEED);
|
||||
for (int c = 0; c < COUNT; c++) {
|
||||
MyObject[] b = arr[c];
|
||||
if (b.length != (c * 100)) {
|
||||
throw new IllegalStateException("Failure: length = " + b.length + ", need = " + (c*100));
|
||||
}
|
||||
for (int v = 0; v < c; v++) {
|
||||
int actual = b[v].id();
|
||||
int expected = r.nextInt();
|
||||
if (actual != expected) {
|
||||
throw new IllegalStateException("Failure: expected = " + expected + ", actual = " + actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyObject {
|
||||
int id;
|
||||
public MyObject(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public int id() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
39
test/hotspot/jtreg/gc/epsilon/TestUpdateCountersSteps.java
Normal file
39
test/hotspot/jtreg/gc/epsilon/TestUpdateCountersSteps.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test TestUpdateCountersSteps
|
||||
* @key gc
|
||||
* @requires vm.gc.Epsilon
|
||||
* @summary Test EpsilonUpdateCountersStep works
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=1 TestUpdateCountersSteps
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=10 TestUpdateCountersSteps
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=100 TestUpdateCountersSteps
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonUpdateCountersStep=1000 TestUpdateCountersSteps
|
||||
*/
|
||||
|
||||
public class TestUpdateCountersSteps {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Hello World");
|
||||
}
|
||||
}
|
@ -106,13 +106,19 @@ public class TestUniverse {
|
||||
output.shouldContain("PSYoungGen");
|
||||
output.shouldContain("eden");
|
||||
}
|
||||
|
||||
if (gc.contains("UseEpsilonGC")) {
|
||||
output.shouldContain("Epsilon heap");
|
||||
output.shouldContain("reserved");
|
||||
output.shouldContain("committed");
|
||||
output.shouldContain("used");
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(String gc) throws Exception {
|
||||
LingeredApp app = null;
|
||||
try {
|
||||
List<String> vmArgs = new ArrayList<String>();
|
||||
vmArgs.add("-XX:+UnlockExperimentalVMOptions"); // unlock experimental GCs
|
||||
vmArgs.add(gc);
|
||||
app = LingeredApp.startApp(vmArgs);
|
||||
System.out.println ("Started LingeredApp with the GC option " + gc +
|
||||
@ -139,6 +145,7 @@ public class TestUniverse {
|
||||
if (!Compiler.isGraalEnabled()) { // Graal does not support CMS
|
||||
test("-XX:+UseConcMarkSweepGC");
|
||||
}
|
||||
test("-XX:+UseEpsilonGC");
|
||||
} catch (Exception e) {
|
||||
throw new Error("Test failed with " + e);
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ public enum GC {
|
||||
Serial(1),
|
||||
Parallel(2),
|
||||
ConcMarkSweep(3),
|
||||
G1(4);
|
||||
G1(4),
|
||||
Epsilon(5);
|
||||
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user