--- /dev/null 2017-03-08 12:03:25.330745819 +0100 +++ new/src/share/vm/gc/epsilon/epsilonCollectedHeap.cpp 2017-03-12 11:11:20.430844368 +0100 @@ -0,0 +1,106 @@ +/* + * 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); + if (AlwaysPreTouch) { + // TODO: Use shared code instead of this. Also pick up large pages, if available. + os::pretouch_memory(_start, _end); + } + + EpsilonBarrierSet* bs = new EpsilonBarrierSet(); + set_barrier_set(bs); + + log_info(gc)("Initialized with " SIZE_FORMAT "M non-resizable heap.", size*HeapWordSize / M); + if (UseTLAB) { + log_info(gc)("Using " SIZE_FORMAT "K TLABs.", EpsilonTLABSize / K); + } else { + log_info(gc)("Not using TLAB allocation."); + } + + 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(); + } +}