--- old/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2017-02-13 23:17:53.242256471 +0100 +++ new/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2017-02-13 23:17:53.178256660 +0100 @@ -1664,6 +1664,10 @@ case g1_post_barrier_slow_id: { + // avoid touching CardTableModRefBS if not G1 + // FIXME: This looks like an upstream bug. + if (!UseG1GC) break; + StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments); --- old/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2017-02-13 23:17:53.470255796 +0100 +++ new/src/cpu/x86/vm/stubGenerator_x86_32.cpp 2017-02-13 23:17:53.406255984 +0100 @@ -688,6 +688,7 @@ case BarrierSet::CardTableForRS: case BarrierSet::CardTableExtension: case BarrierSet::ModRef: + case BarrierSet::Epsilon: break; default : ShouldNotReachHere(); @@ -740,6 +741,7 @@ } break; case BarrierSet::ModRef: + case BarrierSet::Epsilon: break; default : ShouldNotReachHere(); --- old/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2017-02-13 23:17:53.718255063 +0100 +++ new/src/cpu/x86/vm/stubGenerator_x86_64.cpp 2017-02-13 23:17:53.654255251 +0100 @@ -1220,6 +1220,7 @@ case BarrierSet::CardTableForRS: case BarrierSet::CardTableExtension: case BarrierSet::ModRef: + case BarrierSet::Epsilon: break; default: ShouldNotReachHere(); @@ -1281,6 +1282,9 @@ __ jcc(Assembler::greaterEqual, L_loop); } break; + case BarrierSet::Epsilon: + // TODO: why are we here at all? + break; default: ShouldNotReachHere(); --- old/src/cpu/x86/vm/templateTable_x86.cpp 2017-02-13 23:17:53.966254333 +0100 +++ new/src/cpu/x86/vm/templateTable_x86.cpp 2017-02-13 23:17:53.902254522 +0100 @@ -216,6 +216,7 @@ } break; case BarrierSet::ModRef: + case BarrierSet::Epsilon: if (val == noreg) { __ store_heap_oop_null(obj); } else { --- old/src/share/vm/c1/c1_LIRGenerator.cpp 2017-02-13 23:17:54.206253621 +0100 +++ new/src/share/vm/c1/c1_LIRGenerator.cpp 2017-02-13 23:17:54.142253810 +0100 @@ -1462,6 +1462,7 @@ // No pre barriers break; case BarrierSet::ModRef: + case BarrierSet::Epsilon: // No pre barriers break; default : @@ -1482,6 +1483,7 @@ CardTableModRef_post_barrier(addr, new_val); break; case BarrierSet::ModRef: + case BarrierSet::Epsilon: // No post barriers break; default : --- old/src/share/vm/gc/shared/barrierSet.hpp 2017-02-13 23:17:54.442252924 +0100 +++ new/src/share/vm/gc/shared/barrierSet.hpp 2017-02-13 23:17:54.382253102 +0100 @@ -52,7 +52,8 @@ CardTableForRS, // CardTableModRefBSForCTRS CardTableExtension, // CardTableExtension G1SATBCT, // G1SATBCardTableModRefBS - G1SATBCTLogging // G1SATBCardTableLoggingModRefBS + G1SATBCTLogging, // G1SATBCardTableLoggingModRefBS + Epsilon, // EpsilonBarrierSet }; protected: --- old/src/share/vm/gc/shared/collectedHeap.hpp 2017-02-13 23:17:54.662252274 +0100 +++ new/src/share/vm/gc/shared/collectedHeap.hpp 2017-02-13 23:17:54.598252463 +0100 @@ -191,7 +191,8 @@ enum Name { GenCollectedHeap, ParallelScavengeHeap, - G1CollectedHeap + G1CollectedHeap, + EpsilonCollectedHeap, }; static inline size_t filler_array_max_size() { --- old/src/share/vm/jvmci/jvmciCompilerToVM.cpp 2017-02-13 23:17:54.882251624 +0100 +++ new/src/share/vm/jvmci/jvmciCompilerToVM.cpp 2017-02-13 23:17:54.822251802 +0100 @@ -174,6 +174,7 @@ break; } case BarrierSet::ModRef: + case BarrierSet::Epsilon: cardtable_start_address = 0; cardtable_shift = 0; // No post barriers --- old/src/share/vm/memory/universe.cpp 2017-02-13 23:17:55.110250952 +0100 +++ new/src/share/vm/memory/universe.cpp 2017-02-13 23:17:55.046251141 +0100 @@ -82,6 +82,8 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" +#include "gc/epsilon/epsilonCollectedHeap.hpp" +#include "gc/epsilon/epsilonCollectorPolicy.hpp" #include "gc/shared/adaptiveSizePolicy.hpp" #endif // INCLUDE_ALL_GCS #if INCLUDE_CDS @@ -733,6 +735,8 @@ #endif } else if (UseSerialGC) { return Universe::create_heap_with_policy(); + } else if (UseEpsilonGC) { + return Universe::create_heap_with_policy(); } ShouldNotReachHere(); --- old/src/share/vm/opto/graphKit.cpp 2017-02-13 23:17:55.338250277 +0100 +++ new/src/share/vm/opto/graphKit.cpp 2017-02-13 23:17:55.274250470 +0100 @@ -1538,6 +1538,7 @@ case BarrierSet::CardTableForRS: case BarrierSet::CardTableExtension: case BarrierSet::ModRef: + case BarrierSet::Epsilon: break; default : @@ -1555,6 +1556,7 @@ case BarrierSet::CardTableForRS: case BarrierSet::CardTableExtension: case BarrierSet::ModRef: + case BarrierSet::Epsilon: return true; // There is no pre-barrier default : @@ -1584,6 +1586,7 @@ break; case BarrierSet::ModRef: + case BarrierSet::Epsilon: break; default : --- old/src/share/vm/runtime/arguments.cpp 2017-02-13 23:17:55.590249533 +0100 +++ new/src/share/vm/runtime/arguments.cpp 2017-02-13 23:17:55.518249747 +0100 @@ -1760,7 +1760,7 @@ bool Arguments::gc_selected() { #if INCLUDE_ALL_GCS - return UseSerialGC || UseParallelGC || UseParallelOldGC || UseConcMarkSweepGC || UseG1GC; + return UseSerialGC || UseParallelGC || UseParallelOldGC || UseConcMarkSweepGC || UseG1GC || UseEpsilonGC; #else return UseSerialGC; #endif // INCLUDE_ALL_GCS @@ -1932,6 +1932,15 @@ log_trace(gc)("MarkStackSize: %uk MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K)); } +void Arguments::set_epsilon_flags() { + assert(UseEpsilonGC, "Error"); + + // Forcefully exit when OOME is detected. Nothing we can do at that point. + if (FLAG_IS_DEFAULT(ExitOnOutOfMemoryError)) { + FLAG_SET_DEFAULT(ExitOnOutOfMemoryError, true); + } +} + void Arguments::set_gc_specific_flags() { #if INCLUDE_ALL_GCS // Set per-collector flags @@ -1941,6 +1950,8 @@ set_cms_and_parnew_gc_flags(); } else if (UseG1GC) { set_g1_gc_flags(); + } else if (UseEpsilonGC) { + set_epsilon_flags(); } if (AssumeMP && !UseSerialGC) { if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) { @@ -2304,6 +2315,7 @@ if (UseConcMarkSweepGC) i++; if (UseParallelGC || UseParallelOldGC) i++; if (UseG1GC) i++; + if (UseEpsilonGC) i++; if (i > 1) { jio_fprintf(defaultStream::error_stream(), "Conflicting collector combinations in option list; " --- old/src/share/vm/runtime/arguments.hpp 2017-02-13 23:17:55.834248813 +0100 +++ new/src/share/vm/runtime/arguments.hpp 2017-02-13 23:17:55.770249002 +0100 @@ -464,6 +464,8 @@ static void set_parallel_gc_flags(); // Garbage-First (UseG1GC) static void set_g1_gc_flags(); + // Epsilon + static void set_epsilon_flags(); // GC ergonomics static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); --- old/src/share/vm/runtime/globals.hpp 2017-02-13 23:17:56.062248139 +0100 +++ new/src/share/vm/runtime/globals.hpp 2017-02-13 23:17:55.990248352 +0100 @@ -1399,6 +1399,9 @@ product(bool, UseParallelOldGC, false, \ "Use the Parallel Old garbage collector") \ \ + experimental(bool, UseEpsilonGC, false, \ + "Use the Epsilon (no-op) garbage collector") \ + \ product(uintx, HeapMaximumCompactionInterval, 20, \ "How often should we maximally compact the heap (not allowing " \ "any dead space)") \ --- old/src/share/vm/services/memoryManager.cpp 2017-02-13 23:17:56.302247431 +0100 +++ new/src/share/vm/services/memoryManager.cpp 2017-02-13 23:17:56.242247608 +0100 @@ -91,6 +91,10 @@ return (GCMemoryManager*) new G1OldGenMemoryManager(); } +GCMemoryManager* MemoryManager::get_epsilon_memory_manager() { + return (GCMemoryManager*) new EpsilonMemoryManager(); +} + instanceOop MemoryManager::get_memory_manager_instance(TRAPS) { // Must do an acquire so as to force ordering of subsequent // loads from anything _memory_mgr_obj points to or implies. --- old/src/share/vm/services/memoryManager.hpp 2017-02-13 23:17:56.518246792 +0100 +++ new/src/share/vm/services/memoryManager.hpp 2017-02-13 23:17:56.458246970 +0100 @@ -83,6 +83,7 @@ static GCMemoryManager* get_psMarkSweep_memory_manager(); static GCMemoryManager* get_g1YoungGen_memory_manager(); static GCMemoryManager* get_g1OldGen_memory_manager(); + static GCMemoryManager* get_epsilon_memory_manager(); }; class CodeCacheMemoryManager : public MemoryManager { @@ -253,4 +254,12 @@ const char* name() { return "G1 Old Generation"; } }; +class EpsilonMemoryManager : public GCMemoryManager { +private: +public: + EpsilonMemoryManager() : GCMemoryManager() {} + + const char* name() { return "Epsilon Generation"; } +}; + #endif // SHARE_VM_SERVICES_MEMORYMANAGER_HPP --- old/src/share/vm/services/memoryService.cpp 2017-02-13 23:17:56.738246142 +0100 +++ new/src/share/vm/services/memoryService.cpp 2017-02-13 23:17:56.674246334 +0100 @@ -99,6 +99,10 @@ add_g1_heap_info(G1CollectedHeap::heap()); break; } + case CollectedHeap::EpsilonCollectedHeap : { + add_epsilon_heap_info(); + break; + } #endif // INCLUDE_ALL_GCS default: { guarantee(false, "Unrecognized kind of heap"); @@ -188,6 +192,18 @@ add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager); add_g1OldGen_memory_pool(g1h, _major_gc_manager); } + +void MemoryService::add_epsilon_heap_info() { + assert(UseEpsilonGC, "sanity"); + + _minor_gc_manager = MemoryManager::get_epsilon_memory_manager(); + _major_gc_manager = MemoryManager::get_epsilon_memory_manager(); + _managers_list->append(_minor_gc_manager); + _managers_list->append(_major_gc_manager); +// TODO: fix these? +// add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager); +// add_g1OldGen_memory_pool(g1h, _major_gc_manager); +} #endif // INCLUDE_ALL_GCS MemoryPool* MemoryService::add_gen(Generation* gen, --- old/src/share/vm/services/memoryService.hpp 2017-02-13 23:17:56.954245507 +0100 +++ new/src/share/vm/services/memoryService.hpp 2017-02-13 23:17:56.894245685 +0100 @@ -116,6 +116,7 @@ static void add_gen_collected_heap_info(GenCollectedHeap* heap); static void add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap); static void add_g1_heap_info(G1CollectedHeap* g1h); + static void add_epsilon_heap_info(); public: static void set_universe_heap(CollectedHeap* heap); --- old/src/share/vm/utilities/vmError.cpp 2017-02-13 23:17:57.178244843 +0100 +++ new/src/share/vm/utilities/vmError.cpp 2017-02-13 23:17:57.114245035 +0100 @@ -246,6 +246,7 @@ if (UseParallelGC) return "parallel gc"; if (UseConcMarkSweepGC) return "concurrent mark sweep gc"; if (UseSerialGC) return "serial gc"; + if (UseEpsilonGC) return "epsilon gc"; return "ERROR in GC mode"; } --- /dev/null 2017-02-09 18:28:35.238523416 +0100 +++ new/src/share/vm/gc/epsilon/epsilonBarrierSet.hpp 2017-02-13 23:17:57.338244370 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. + * + * 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 HOTSPOT_EPSILONBARRIERSET_HPP_H +#define HOTSPOT_EPSILONBARRIERSET_HPP_H + +#include "gc/shared/collectorPolicy.hpp" +#include "gc/shared/barrierSet.hpp" + +// Most are no-ops. +class EpsilonBarrierSet: public ModRefBarrierSet { + friend class VMStructs; + +public: + EpsilonBarrierSet() : + ModRefBarrierSet(BarrierSet::FakeRtti(BarrierSet::Epsilon)) {}; + + virtual bool has_write_ref_barrier() { return false; } + virtual bool has_write_ref_pre_barrier() { return false; } + virtual bool has_write_ref_array_opt() { return true; } // TODO: why? + virtual bool has_write_region_opt() { return true; } // TODO: why? + + virtual bool is_aligned(HeapWord *addr) { return true; } // TODO: Safe? + + virtual void resize_covered_region(MemRegion new_region) {} + virtual void print_on(outputStream *st) const {} + +protected: + virtual void write_ref_field_work(void *field, oop new_val, bool release) {} + virtual void write_ref_array_work(MemRegion mr) {} + virtual void write_region_work(MemRegion mr) {} + +public: + virtual void invalidate(MemRegion mr) {} + virtual void clear(MemRegion mr) {} +}; + +template<> +struct BarrierSet::GetName { + static const BarrierSet::Name value = BarrierSet::Epsilon; +}; + +#endif --- /dev/null 2017-02-09 18:28:35.238523416 +0100 +++ new/src/share/vm/gc/epsilon/epsilonCollectedHeap.cpp 2017-02-13 23:17:57.542243768 +0100 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. + * + * 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 "oops/oop.hpp" +#include "oops/oop.inline.hpp" +#include "utilities/copy.hpp" +#include "gc/shared/collectedHeap.hpp" +#include "epsilonCollectedHeap.hpp" +#include "epsilonBarrierSet.hpp" + +jint EpsilonCollectedHeap::initialize() { + CollectedHeap::pre_initialize(); + + size_t max_byte_size = _policy->max_heap_byte_size(); + size_t align = _policy->heap_alignment(); + + ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, align); + + _start = (HeapWord *) heap_rs.base(); + _current = _start; + _end = (HeapWord *) (heap_rs.base() + heap_rs.size()); + size_t size = pointer_delta(_end, _start); + + initialize_reserved_region(_start, _end); + os::commit_memory((char*)_start, size*HeapWordSize, align, false); + + EpsilonBarrierSet* bs = new EpsilonBarrierSet(); + set_barrier_set(bs); + + log_info(gc)("Initialized with " SIZE_FORMAT "M non-resizable heap.", size*HeapWordSize / M); + + return JNI_OK; +} + +HeapWord* EpsilonCollectedHeap::allocate_work(size_t size) { + do { + HeapWord* obj = (HeapWord *) _current; + if (pointer_delta(_end, obj) >= size) { + HeapWord* new_current = obj + size; + HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_current, &_current, obj); + if (result != obj) { + continue; + } + assert(is_object_aligned((intptr_t)obj), "object is aligned"); + assert(is_object_aligned((intptr_t)new_current), "current is aligned"); + return obj; + } else { + return NULL; + } + } while (true); +} + +HeapWord* EpsilonCollectedHeap::allocate_new_tlab(size_t size) { + return allocate_work(size); +} + +HeapWord* EpsilonCollectedHeap::mem_allocate(size_t size, bool *gc_overhead_limit_was_exceeded) { + *gc_overhead_limit_was_exceeded = false; + return allocate_work(size); +} + +void EpsilonCollectedHeap::collect(GCCause::Cause cause) { + log_warning(gc)("GC was triggered with cause \"%s\". Ignoring.", GCCause::to_string(cause)); +} + +void EpsilonCollectedHeap::do_full_collection(bool clear_all_soft_refs) { + log_warning(gc)("Full GC was triggered. Ignoring."); +} + +void EpsilonCollectedHeap::safe_object_iterate(ObjectClosure *cl) { + HeapWord* mark = _start; + while (mark < _current) { + oop obj = oop(mark); + cl->do_object(obj); + mark += obj->size(); + } +} --- /dev/null 2017-02-09 18:28:35.238523416 +0100 +++ new/src/share/vm/gc/epsilon/epsilonCollectedHeap.hpp 2017-02-13 23:17:57.746243165 +0100 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. + * + * 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 "gc/shared/collectedHeap.hpp" +#include "gc/epsilon/epsilonCollectorPolicy.hpp" +#include "gc/epsilon/epsilonBarrierSet.hpp" + +class EpsilonCollectedHeap : public CollectedHeap { +private: + EpsilonCollectorPolicy* _policy; + HeapWord* _start; + HeapWord* _end; + volatile HeapWord* _current; +public: + EpsilonCollectedHeap(EpsilonCollectorPolicy* p) : _policy(p) {}; + + virtual Name kind() const { + return CollectedHeap::EpsilonCollectedHeap; + } + + virtual const char *name() const { + return "Epsilon GC"; + } + + virtual jint initialize(); + + virtual void post_initialize() {} + + virtual size_t capacity() const { return pointer_delta(_end, _start); } + virtual size_t used() const { return pointer_delta((HeapWord*)_current, _start); } + virtual size_t max_capacity() const { return capacity(); } + + virtual bool is_maximal_no_gc() const { return used() == capacity(); } // TODO: Really? + + virtual bool is_in(const void *p) const { return (_start <= p) && (p < _end); } + + virtual bool is_scavengable(const void *p) { return true; } // TODO: Why? + + virtual HeapWord* mem_allocate(size_t size, bool *gc_overhead_limit_was_exceeded); + virtual HeapWord* allocate_new_tlab(size_t size); + + virtual HeapWord* allocate_work(size_t size); + + // TLAB allocations + 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(); } // TODO: Should probably record the TLAB? + virtual size_t unsafe_max_tlab_alloc(Thread *thr) const { + // TODO: hook up in TLAB policy better. pointer_delta(_current, _end); + return HeapWordSize * 128 * K; + } + + virtual bool can_elide_tlab_store_barriers() const { + return true; // TODO: Really? + } + + virtual bool can_elide_initializing_store_barrier(oop new_obj) { + return true; // TODO: Really? + } + + virtual bool card_mark_must_follow_store() const { + return true; // TODO: Really? + } + + virtual void collect(GCCause::Cause cause); + virtual void do_full_collection(bool clear_all_soft_refs); + + virtual AdaptiveSizePolicy *size_policy() { + // No such thing for Epsilon + return NULL; + } + + virtual CollectorPolicy *collector_policy() const { + return _policy; + } + + virtual void object_iterate(ObjectClosure *cl) { + safe_object_iterate(cl); + } + + virtual void safe_object_iterate(ObjectClosure *cl); + + virtual HeapWord *block_start(const void *addr) const { + Unimplemented(); + return NULL; + } + + virtual size_t block_size(const HeapWord *addr) const { + Unimplemented(); + return 0; + } + + virtual bool block_is_obj(const HeapWord *addr) const { + Unimplemented(); + return false; + } + + virtual jlong millis_since_last_gc() { + return os::elapsed_counter() / NANOSECS_PER_MILLISEC; // since the VM start + } + + virtual void prepare_for_verify() { + // No heap verification. + } + + virtual void print_on(outputStream *st) const { + // Print nothing. + } + + virtual void print_gc_threads_on(outputStream *st) const { + // No GC threads. + } + + virtual void gc_threads_do(ThreadClosure *tc) const { + // No GC threads. + } + + virtual void print_tracing_info() const { + Log(gc) log; + size_t allocated_kb = pointer_delta((HeapWord*)_current, _start) * HeapWordSize / K; + log.info("Total allocated: " SIZE_FORMAT " KB.", + allocated_kb); + log.info("Average allocation rate: " SIZE_FORMAT " KB/sec", + allocated_kb * NANOSECS_PER_SEC / os::elapsed_counter()); + } + + virtual void verify(VerifyOption option) { + // No heap verification for Epsilon. + } + +}; --- /dev/null 2017-02-09 18:28:35.238523416 +0100 +++ new/src/share/vm/gc/epsilon/epsilonCollectorPolicy.hpp 2017-02-13 23:17:57.954242551 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. + * + * 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 HOTSPOT_EPSILONCOLLECTORPOLICY_HPP_H +#define HOTSPOT_EPSILONCOLLECTORPOLICY_HPP_H + +#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