--- old/make/autoconf/hotspot.m4 2018-06-11 09:34:11.026997116 +0200 +++ new/make/autoconf/hotspot.m4 2018-06-11 09:34:10.802996497 +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 jfr" # Deprecated JVM features (these are ignored, but with a warning) @@ -410,7 +410,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 --- old/make/hotspot/lib/JvmFeatures.gmk 2018-06-11 09:34:11.306997890 +0200 +++ new/make/hotspot/lib/JvmFeatures.gmk 2018-06-11 09:34:11.094997305 +0200 @@ -155,6 +155,11 @@ 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 --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonArguments.cpp 2018-06-11 09:34:11.378998090 +0200 @@ -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(); +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonArguments.hpp 2018-06-11 09:34:11.682998931 +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 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp 2018-06-11 09:34:11.974999737 +0200 @@ -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(), + make_barrier_set_c1(), + make_barrier_set_c2(), + 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 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonBarrierSet.hpp 2018-06-11 09:34:12.267000545 +0200 @@ -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 + class AccessBarrier: public BarrierSet::AccessBarrier {}; +}; + +template<> +struct BarrierSet::GetName { + static const BarrierSet::Name value = BarrierSet::EpsilonBarrierSet; +}; + +template<> +struct BarrierSet::GetType { + typedef ::EpsilonBarrierSet type; +}; + +#endif // SHARE_VM_GC_EPSILON_BARRIERSET_HPP --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonCollectorPolicy.hpp 2018-06-11 09:34:12.559001352 +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 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonHeap.cpp 2018-06-11 09:34:12.851002160 +0200 @@ -0,0 +1,284 @@ +/* + * 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(); + + // Initialize backing storage + ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, _policy->heap_alignment()); + _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(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 EpsilonHeap::memory_managers() { + GrowableArray memory_managers(1); + memory_managers.append(&_memory_manager); + return memory_managers; +} + +GrowableArray EpsilonHeap::memory_pools() { + GrowableArray 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())); +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonHeap.hpp 2018-06-11 09:34:13.151002989 +0200 @@ -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 memory_managers(); + virtual GrowableArray 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 --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonMemoryPool.cpp 2018-06-11 09:34:13.455003830 +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 "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); +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonMemoryPool.hpp 2018-06-11 09:34:13.743004627 +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_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 --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp 2018-06-11 09:34:14.039005445 +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 { + 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 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.hpp 2018-06-11 09:34:14.331006251 +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 { +private: + GenerationCounters* _heap_counters; + EpsilonSpaceCounters* _space_counters; + +public: + EpsilonMonitoringSupport(EpsilonHeap* heap); + void update_counters(); +}; + +#endif // SHARE_VM_GC_EPSILON_EPSILONMONITORINGSUPPORT_HPP + --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilonThreadLocalData.hpp 2018-06-11 09:34:14.639007103 +0200 @@ -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(); + } + +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 --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/epsilon_globals.hpp 2018-06-11 09:34:14.931007910 +0200 @@ -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 --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/hotspot/share/gc/epsilon/vmStructs_epsilon.hpp 2018-06-11 09:34:15.231008740 +0200 @@ -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 --- old/src/hotspot/share/gc/shared/barrierSetConfig.hpp 2018-06-11 09:34:15.739010144 +0200 +++ new/src/hotspot/share/gc/shared/barrierSetConfig.hpp 2018-06-11 09:34:15.519009536 +0200 @@ -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) \ --- old/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp 2018-06-11 09:34:16.031010952 +0200 +++ new/src/hotspot/share/gc/shared/barrierSetConfig.inline.hpp 2018-06-11 09:34:15.815010356 +0200 @@ -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 --- old/src/hotspot/share/gc/shared/collectedHeap.hpp 2018-06-11 09:34:16.327011770 +0200 +++ new/src/hotspot/share/gc/shared/collectedHeap.hpp 2018-06-11 09:34:16.103011151 +0200 @@ -206,7 +206,8 @@ Serial, Parallel, CMS, - G1 + G1, + Epsilon, }; static inline size_t filler_array_max_size() { --- old/src/hotspot/share/gc/shared/gcConfig.cpp 2018-06-11 09:34:16.623012589 +0200 +++ new/src/hotspot/share/gc/shared/gcConfig.cpp 2018-06-11 09:34:16.407011992 +0200 @@ -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 @@ }; 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 @@ // 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 @@ } 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)); --- old/src/hotspot/share/gc/shared/gc_globals.hpp 2018-06-11 09:34:16.911013385 +0200 +++ new/src/hotspot/share/gc/shared/gc_globals.hpp 2018-06-11 09:34:16.699012800 +0200 @@ -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) \ --- old/src/hotspot/share/gc/shared/vmStructs_gc.hpp 2018-06-11 09:34:17.211014215 +0200 +++ new/src/hotspot/share/gc/shared/vmStructs_gc.hpp 2018-06-11 09:34:16.995013618 +0200 @@ -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, \ --- old/src/hotspot/share/utilities/macros.hpp 2018-06-11 09:34:17.503015023 +0200 +++ new/src/hotspot/share/utilities/macros.hpp 2018-06-11 09:34:17.275014392 +0200 @@ -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 --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java 2018-06-11 09:34:17.791015819 +0200 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java 2018-06-11 09:34:17.571015210 +0200 @@ -33,6 +33,7 @@ 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 @@ anno = "PSOldGen "; bad = false; } + } else if (collHeap instanceof EpsilonHeap) { + anno = "Epsilon "; + bad = false; } else { // Optimistically assume the oop isn't bad anno = "[Unknown generation] "; --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/epsilon/EpsilonHeap.java 2018-06-11 09:34:17.871016039 +0200 @@ -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() + "]"); + } + +} --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java 2018-06-11 09:34:18.367017411 +0200 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeapName.java 2018-06-11 09:34:18.155016824 +0200 @@ -35,6 +35,7 @@ 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; --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java 2018-06-11 09:34:18.651018196 +0200 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/Universe.java 2018-06-11 09:34:18.435017599 +0200 @@ -31,6 +31,7 @@ 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 @@ 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"); --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java 2018-06-11 09:34:18.951019026 +0200 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java 2018-06-11 09:34:18.715018373 +0200 @@ -34,6 +34,7 @@ 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 @@ } 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()); } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java 2018-06-11 09:34:19.239019822 +0200 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java 2018-06-11 09:34:19.023019224 +0200 @@ -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 @@ 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 @@ return; } + l = getFlagValue("UseEpsilonGC", flagMap); + if (l == 1L) { + System.out.println("Epsilon (no-op) GC"); + return; + } + System.out.println("Mark Sweep Compact GC"); } --- old/test/hotspot/jtreg/TEST.ROOT 2018-06-11 09:34:19.531020629 +0200 +++ new/test/hotspot/jtreg/TEST.ROOT 2018-06-11 09:34:19.311020021 +0200 @@ -45,6 +45,7 @@ vm.gc.Serial \ vm.gc.Parallel \ vm.gc.ConcMarkSweep \ + vm.gc.Epsilon \ vm.jvmci \ vm.emulatedClient \ vm.cpu.features \ --- old/test/hotspot/jtreg/TEST.groups 2018-06-11 09:34:19.803021381 +0200 +++ new/test/hotspot/jtreg/TEST.groups 2018-06-11 09:34:19.583020773 +0200 @@ -174,12 +174,14 @@ -: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 \ --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestAlwaysPretouch.java 2018-06-11 09:34:19.891021624 +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 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 + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestByteArrays.java 2018-06-11 09:34:20.175022409 +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 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); + } + } + } + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestDieDefault.java 2018-06-11 09:34:20.471023229 +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 + * @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(); + } + } + } + +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestDieWithHeapDump.java 2018-06-11 09:34:20.763024035 +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 + * @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(); + } + } + } + +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestDieWithOnError.java 2018-06-11 09:34:21.059024853 +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 + * @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(); + } + } + } + +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestElasticTLAB.java 2018-06-11 09:34:21.351025661 +0200 @@ -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); + } + } + } + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestElasticTLABDecay.java 2018-06-11 09:34:21.651026491 +0200 @@ -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); + } + } + } + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestEpsilonEnabled.java 2018-06-11 09:34:21.951027320 +0200 @@ -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; + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestHelloWorld.java 2018-06-11 09:34:22.239028116 +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 + * @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"); + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestLogTrace.java 2018-06-11 09:34:22.523028901 +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 + * @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"); + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestManyThreads.java 2018-06-11 09:34:22.823029730 +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 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; + } + } + +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestMemoryMXBeans.java 2018-06-11 09:34:23.111030527 +0200 @@ -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 + "]"); + } + } + +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestMemoryPools.java 2018-06-11 09:34:23.403031334 +0200 @@ -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 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 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestObjects.java 2018-06-11 09:34:23.687032119 +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 + * @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; + } + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestPrintHeapSteps.java 2018-06-11 09:34:23.983032937 +0200 @@ -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"); + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestRefArrays.java 2018-06-11 09:34:24.275033745 +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 + * @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; + } + } +} --- /dev/null 2018-06-10 19:57:01.244702788 +0200 +++ new/test/hotspot/jtreg/gc/epsilon/TestUpdateCountersSteps.java 2018-06-11 09:34:24.571034563 +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. + */ + +/** + * @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"); + } +} --- old/test/hotspot/jtreg/serviceability/sa/TestUniverse.java 2018-06-11 09:34:25.067035935 +0200 +++ new/test/hotspot/jtreg/serviceability/sa/TestUniverse.java 2018-06-11 09:34:24.859035360 +0200 @@ -106,13 +106,19 @@ 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 vmArgs = new ArrayList(); + 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 @@ if (!Compiler.isGraalEnabled()) { // Graal does not support CMS test("-XX:+UseConcMarkSweepGC"); } + test("-XX:+UseEpsilonGC"); } catch (Exception e) { throw new Error("Test failed with " + e); } --- old/test/lib/sun/hotspot/gc/GC.java 2018-06-11 09:34:25.359036742 +0200 +++ new/test/lib/sun/hotspot/gc/GC.java 2018-06-11 09:34:25.143036145 +0200 @@ -36,7 +36,8 @@ Serial(1), Parallel(2), ConcMarkSweep(3), - G1(4); + G1(4), + Epsilon(5); private static final WhiteBox WB = WhiteBox.getWhiteBox();