--- a/make/autoconf/hotspot.m4 Mon May 07 14:42:10 2018 +0200
+++ b/make/autoconf/hotspot.m4 Mon May 07 16:41:38 2018 +0200
@@ -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"
# All valid JVM variants
@@ -391,7 +391,7 @@
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
--- a/make/hotspot/lib/JvmFeatures.gmk Mon May 07 14:42:10 2018 +0200
+++ b/make/hotspot/lib/JvmFeatures.gmk Mon May 07 16:41:38 2018 +0200
@@ -153,6 +153,11 @@
# If serial is disabled, we cannot use serial as OldGC in parallel
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
################################################################################
ifeq ($(call check-jvm-feature, link-time-opt), true)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,68 @@
+/*
+ * 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"
+
+size_t EpsilonArguments::conservative_max_heap_alignment() {
+ return UseLargePages ? os::large_page_size() : os::vm_page_size();
+}
+
+void EpsilonArguments::initialize() {
+ GCArguments::initialize();
+
+ assert(UseEpsilonGC, "Error");
+
+ // Forcefully exit when OOME is detected. Nothing we can do at that point.
+ if (FLAG_IS_DEFAULT(ExitOnOutOfMemoryError)) {
+ FLAG_SET_DEFAULT(ExitOnOutOfMemoryError, true);
+ }
+
+#if INCLUDE_EPSILONGC
+ if (EpsilonMaxTLABSize < MinTLABSize) {
+ warning("EpsilonMaxTLABSize < MinTLABSize, adjusting it to " SIZE_FORMAT, MinTLABSize);
+ EpsilonMaxTLABSize = MinTLABSize;
+ }
+#endif
+
+#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>();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonArguments.hpp Mon May 07 16:41:38 2018 +0200
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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"
+#ifdef COMPILER1
+#include "gc/shared/c1/barrierSetC1.hpp"
+#endif
+
+EpsilonBarrierSet::EpsilonBarrierSet() : BarrierSet(
+ make_barrier_set_assembler<BarrierSetAssembler>(),
+ make_barrier_set_c1<BarrierSetC1>(),
+ BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {};
+
+void EpsilonBarrierSet::on_thread_create(Thread *thread) {
+ EpsilonThreadLocalData::create(thread);
+}
+
+void EpsilonBarrierSet::on_thread_destroy(Thread *thread) {
+ EpsilonThreadLocalData::destroy(thread);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,58 @@
+/*
+ * 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/collectorPolicy.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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonCollectorPolicy.hpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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();
+ _space_alignment = page_size;
+ _heap_alignment = page_size;
+ }
+
+public:
+ EpsilonCollectorPolicy() : CollectorPolicy() {};
+};
+
+#endif // SHARE_VM_GC_EPSILON_COLLECTORPOLICY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,232 @@
+/*
+ * 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 init_byte_size = _policy->initial_heap_byte_size();
+ size_t max_byte_size = _policy->max_heap_byte_size();
+ size_t align = _policy->heap_alignment();
+
+ 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, true, true);
+
+ BarrierSet::set_barrier_set(new EpsilonBarrierSet());
+
+ _max_tlab_size = MIN2(CollectedHeap::max_tlab_size(), EpsilonMaxTLABSize / HeapWordSize);
+
+ _monitoring_support = new EpsilonMonitoringSupport(this);
+ _last_counter_update = 0;
+ _last_heap_print = 0;
+
+ _step_counter_update = MIN2<size_t>(max_byte_size / 16, EpsilonUpdateCountersStep);
+ _step_heap_print = (EpsilonPrintHeapStep == 0) ? SIZE_MAX : (max_byte_size / EpsilonPrintHeapStep);
+
+ if (init_byte_size != max_byte_size) {
+ log_info(gc)("Initialized with " SIZE_FORMAT "M heap, resizeable to up to " SIZE_FORMAT "M heap with " SIZE_FORMAT "M steps",
+ init_byte_size / M, max_byte_size / M, EpsilonMinHeapExpand / M);
+ } else {
+ log_info(gc)("Initialized with " SIZE_FORMAT "M non-resizeable heap", init_byte_size / M);
+ }
+ if (UseTLAB) {
+ log_info(gc)("Using TLAB allocation; max: " SIZE_FORMAT "K, elasticity %.2f",
+ _max_tlab_size * HeapWordSize / K,
+ EpsilonTLABElasticity);
+ } 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 space left:
+ 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();
+ if (used - _last_counter_update >= _step_counter_update) {
+ _last_counter_update = used;
+ _monitoring_support->update_counters();
+ }
+
+ if (used - _last_heap_print >= _step_heap_print) {
+ log_info(gc)("Heap: " SIZE_FORMAT "M reserved, " SIZE_FORMAT "M committed, " SIZE_FORMAT "M used",
+ max_capacity() / M, capacity() / M, used / M);
+ _last_heap_print = used;
+ }
+
+ return res;
+}
+
+HeapWord* EpsilonHeap::allocate_new_tlab(size_t min_size,
+ size_t requested_size,
+ size_t* actual_size) {
+ size_t ergo_tlab = EpsilonThreadLocalData::ergo_tlab_size(Thread::current());
+
+ bool fits = (requested_size <= ergo_tlab);
+
+ // If we can fit the allocation under current TLAB size, do so.
+ // Otherwise, we want to elastically increase the TLAB size.
+ size_t size = fits ? requested_size : (size_t)(ergo_tlab * EpsilonTLABElasticity);
+
+ // 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::current()->name(),
+ requested_size * HeapWordSize / K,
+ min_size * HeapWordSize / K,
+ _max_tlab_size * HeapWordSize / K,
+ ergo_tlab * HeapWordSize / K,
+ size * HeapWordSize / K);
+ }
+
+ HeapWord* res = allocate_work(size);
+ if (res != NULL) {
+ *actual_size = size;
+
+ // Allocation successful, this our new TLAB size, if we requested expansion
+ if (!fits) {
+ EpsilonThreadLocalData::set_ergo_tlab_size(Thread::current(), size);
+ }
+ } else {
+ // Allocation failed, reset ergonomics to try an fit smaller TLABs
+ EpsilonThreadLocalData::set_ergo_tlab_size(Thread::current(), 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()));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,145 @@
+/*
+ * 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 {
+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 _last_counter_update;
+ size_t _last_heap_print;
+ size_t _step_counter_update;
+ size_t _step_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 UseTLAB; }
+ 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp Mon May 07 16:41:38 2018 +0200
@@ -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 "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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMemoryPool.hpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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 "utilities/macros.hpp"
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilonHeap.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryUsage.hpp"
+#endif // INCLUDE_EPSILONGC
+
+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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp Mon May 07 16:41:38 2018 +0200
@@ -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();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp Mon May 07 16:41:38 2018 +0200
@@ -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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilonThreadLocalData.hpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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
+
+class EpsilonThreadLocalData {
+private:
+ size_t _ergo_tlab_size;
+
+ EpsilonThreadLocalData() :
+ _ergo_tlab_size(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 void set_ergo_tlab_size(Thread *thread, size_t val) {
+ data(thread)->_ergo_tlab_size = val;
+ }
+};
+
+#endif // SHARE_VM_GC_EPSILON_EPSILONTHREADLOCALDATA_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/epsilon/epsilon_globals.hpp Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,77 @@
+/*
+ * 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, EpsilonPrintHeapStep, 100, \
+ "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 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(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, especially for rarely " \
+ "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
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp Mon May 07 16:41:38 2018 +0200
@@ -30,7 +30,8 @@
// Do something for each concrete barrier set part of the build.
#define FOR_EACH_CONCRETE_BARRIER_SET_DO(f) \
f(CardTableBarrierSet) \
- G1GC_ONLY(f(G1BarrierSet))
+ G1GC_ONLY(f(G1BarrierSet)) \
+ EPSILONGC_ONLY(f(EpsilonBarrierSet))
#define FOR_EACH_ABSTRACT_BARRIER_SET_DO(f) \
f(ModRef)
--- a/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp Mon May 07 16:41:38 2018 +0200
@@ -33,5 +33,8 @@
#if INCLUDE_G1GC
#include "gc/g1/g1BarrierSet.inline.hpp" // G1 support
#endif
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilonBarrierSet.hpp" // Epsilon support
+#endif
#endif // SHARE_VM_GC_SHARED_BARRIERSETCONFIG_INLINE_HPP
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Mon May 07 16:41:38 2018 +0200
@@ -196,7 +196,8 @@
Serial,
Parallel,
CMS,
- G1
+ G1,
+ Epsilon,
};
static inline size_t filler_array_max_size() {
--- a/src/hotspot/share/gc/shared/gcConfig.cpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp Mon May 07 16:41:38 2018 +0200
@@ -40,6 +40,9 @@
#if INCLUDE_SERIALGC
#include "gc/serial/serialArguments.hpp"
#endif
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilonArguments.hpp"
+#endif
struct SupportedGC {
bool& _flag;
@@ -55,6 +58,7 @@
G1GC_ONLY(static G1Arguments g1Arguments;)
PARALLELGC_ONLY(static ParallelArguments parallelArguments;)
SERIALGC_ONLY(static SerialArguments serialArguments;)
+ EPSILONGC_ONLY(static EpsilonArguments epsilonArguments;)
// Table of supported GCs, for translating between command
// line flag, CollectedHeap::Name and GCArguments instance.
@@ -64,6 +68,7 @@
PARALLELGC_ONLY_ARG(SupportedGC(UseParallelGC, CollectedHeap::Parallel, parallelArguments, "parallel gc"))
PARALLELGC_ONLY_ARG(SupportedGC(UseParallelOldGC, CollectedHeap::Parallel, parallelArguments, "parallel gc"))
SERIALGC_ONLY_ARG(SupportedGC(UseSerialGC, CollectedHeap::Serial, serialArguments, "serial gc"))
+ EPSILONGC_ONLY_ARG(SupportedGC(UseEpsilonGC, CollectedHeap::Epsilon, epsilonArguments, "epsilon gc"))
};
#define FOR_EACH_SUPPORTED_GC(var) \
@@ -92,6 +97,7 @@
NOT_PARALLELGC(UNSUPPORTED_OPTION(UseParallelGC);)
NOT_PARALLELGC(UNSUPPORTED_OPTION(UseParallelOldGC));
NOT_SERIALGC( UNSUPPORTED_OPTION(UseSerialGC);)
+ NOT_EPSILONGC( UNSUPPORTED_OPTION(UseEpsilonGC);)
}
bool GCConfig::is_no_gc_selected() {
--- a/src/hotspot/share/gc/shared/gc_globals.hpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp Mon May 07 16:41:38 2018 +0200
@@ -38,6 +38,9 @@
#if INCLUDE_SERIALGC
#include "gc/serial/serial_globals.hpp"
#endif
+#if INCLUDE_EPSILONGC
+#include "gc/epsilon/epsilon_globals.hpp"
+#endif
#define GC_FLAGS(develop, \
develop_pd, \
@@ -118,6 +121,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)) \
+ \
/* gc */ \
\
product(bool, UseConcMarkSweepGC, false, \
@@ -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) \
--- a/src/hotspot/share/opto/graphKit.cpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/opto/graphKit.cpp Mon May 07 16:41:38 2018 +0200
@@ -1571,6 +1571,11 @@
break;
#endif
+#if INCLUDE_EPSILONGC
+ case BarrierSet::EpsilonBarrierSet:
+ break;
+#endif
+
case BarrierSet::CardTableBarrierSet:
break;
@@ -1589,6 +1594,11 @@
return true; // Can move it if no safepoint
#endif
+#if INCLUDE_EPSILONGC
+ case BarrierSet::EpsilonBarrierSet:
+ return true; // There is no pre-barrier
+#endif
+
case BarrierSet::CardTableBarrierSet:
return true; // There is no pre-barrier
@@ -1615,6 +1625,11 @@
break;
#endif
+#if INCLUDE_EPSILONGC
+ case BarrierSet::EpsilonBarrierSet:
+ break;
+#endif
+
case BarrierSet::CardTableBarrierSet:
write_barrier_post(store, obj, adr, adr_idx, val, use_precise);
break;
--- a/src/hotspot/share/utilities/macros.hpp Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/utilities/macros.hpp Mon May 07 16:41:38 2018 +0200
@@ -203,7 +203,25 @@
#define NOT_SERIALGC_RETURN_(code) { return code; }
#endif // INCLUDE_SERIALGC
-#if INCLUDE_CMSGC || INCLUDE_G1GC || INCLUDE_PARALLELGC
+#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
+
+#if INCLUDE_CMSGC || INCLUDE_G1GC || INCLUDE_PARALLELGC || INCLUDE_EPSILONGC
#define INCLUDE_NOT_ONLY_SERIALGC 1
#else
#define INCLUDE_NOT_ONLY_SERIALGC 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/AbstractEpsilonTest.java Mon May 07 16:41:38 2018 +0200
@@ -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.
+ */
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+
+public class AbstractEpsilonTest {
+ public static boolean isEpsilonEnabled() {
+ for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
+ if (bean.getName().contains("Epsilon")) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * @summary Basic sanity test for Epsilon
+ * @run main/othervm -Xmx1g -XX:+AlwaysPreTouch -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestAlwaysPretouch
+ */
+
+public class TestAlwaysPretouch {
+ public static void main(String[] args) throws Exception {
+ // everything should happen before entry point
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestByteArrays.java Mon May 07 16:41:38 2018 +0200
@@ -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 TestByteArrays
+ * @library /test/lib
+ * @summary Epsilon is able to allocate arrays, and does not corrupt their state
+ *
+ * @run main/othervm -Xmx1g -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ *
+ * @run main/othervm -Xmx1g -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestByteArrays
+ */
+
+import java.util.Random;
+
+public class TestByteArrays extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @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 extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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:TieredStopAtLevel=4",
+ "-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();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @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 extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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:TieredStopAtLevel=4",
+ "-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();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @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 extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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:TieredStopAtLevel=4",
+ "-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();
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestEpsilonEnabled.java Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * @library /test/lib
+ * @summary Basic sanity test for Epsilon
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestEpsilonEnabled
+ */
+
+import jdk.test.lib.Platform;
+
+public class TestEpsilonEnabled extends AbstractEpsilonTest {
+ public static void main(String[] args) throws Exception {
+ if (Platform.isDebugBuild() && !isEpsilonEnabled()) {
+ throw new IllegalStateException("Debug builds should have Epsilon enabled");
+ }
+ if (!Platform.isDebugBuild() && !isEpsilonEnabled()) {
+ throw new IllegalStateException("Non-debug builds should have Epsilon enabled");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestHelloWorld.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @summary Basic sanity test for Epsilon
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestHelloWorld
+ */
+
+import java.util.LinkedList;
+
+public class TestHelloWorld {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestLogTrace.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @summary Basic sanity test for Epsilon
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc=trace TestLogTrace
+ */
+
+import java.util.LinkedList;
+
+public class TestLogTrace {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestManyThreads.java Mon May 07 16:41:38 2018 +0200
@@ -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 TestManyThreads
+ *
+ * @run main/othervm -Xmx128m -Xss512k -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ *
+ * @run main/othervm -Xmx128m -Xss512k -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ * @run main/othervm -Xmx128m -Xss512k -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestManyThreads
+ */
+
+import java.util.concurrent.atomic.*;
+
+public class TestManyThreads extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,96 @@
+/*
+ * 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
+ * @summary Test JMX memory beans
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xmx1g TestMemoryMXBeans -1 1024
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xms1g -Xmx1g TestMemoryMXBeans 1024 1024
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xms128m -Xmx1g TestMemoryMXBeans 128 1024
+ */
+
+import java.lang.management.*;
+import java.util.*;
+
+public class TestMemoryMXBeans extends AbstractEpsilonTest {
+
+ static volatile Object sink;
+
+ public static void main(String[] args) throws Exception {
+ if (!isEpsilonEnabled()) return;
+
+ 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 + "]");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestMemoryPools.java Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,67 @@
+/*
+ * 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
+ * @summary Test JMX memory pools
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xmx1g -Xms1g TestMemoryPools
+ */
+
+import java.lang.management.*;
+import java.util.*;
+
+public class TestMemoryPools extends AbstractEpsilonTest {
+
+ public static void main(String[] args) throws Exception {
+ if (!isEpsilonEnabled()) return;
+
+ 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");
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestObjects.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @summary Epsilon is able to allocate objects, and does not corrupt their state
+ *
+ * @run main/othervm -Xmx128m -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ *
+ * @run main/othervm -Xmx128m -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ * @run main/othervm -Xmx128m -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestObjects
+ */
+
+import java.util.Random;
+
+public class TestObjects extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestPrintHeapSteps.java Mon May 07 16:41:38 2018 +0200
@@ -0,0 +1,35 @@
+/*
+ * 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
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=0 TestPrintHeapSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=1 TestPrintHeapSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonPrintHeapSteps=1000 TestPrintHeapSteps
+ */
+
+public class TestPrintHeapSteps {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestRefArrays.java Mon May 07 16:41:38 2018 +0200
@@ -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
+ * @library /test/lib
+ * @summary Epsilon is able to allocate arrays, and does not corrupt their state
+ *
+ * @run main/othervm -Xmx1g -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xint -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:+UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ *
+ * @run main/othervm -Xmx1g -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xint -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ * @run main/othervm -Xmx1g -Xbatch -Xcomp -XX:TieredStopAtLevel=4 -XX:-UseTLAB -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC TestRefArrays
+ */
+
+import java.util.Random;
+
+public class TestRefArrays extends AbstractEpsilonTest {
+
+ 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 {
+ if (!isEpsilonEnabled()) return;
+
+ 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;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/epsilon/TestUpdateCountersSteps.java Mon May 07 16:41:38 2018 +0200
@@ -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 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonTestUpdateCountersSteps=1 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonTestUpdateCountersSteps=10 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonTestUpdateCountersSteps=100 TestUpdateCountersSteps
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+UseEpsilonGC -Xlog:gc -XX:EpsilonTestUpdateCountersSteps=1000 TestUpdateCountersSteps
+ */
+
+public class TestUpdateCountersSteps {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Hello World");
+ }
+}