1 /* 2 * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "oops/oop.hpp" 25 #include "oops/oop.inline.hpp" 26 #include "utilities/copy.hpp" 27 #include "gc/shared/collectedHeap.hpp" 28 #include "epsilonCollectedHeap.hpp" 29 #include "epsilonBarrierSet.hpp" 30 31 jint EpsilonCollectedHeap::initialize() { 32 CollectedHeap::pre_initialize(); 33 34 size_t max_byte_size = _policy->max_heap_byte_size(); 35 size_t align = _policy->heap_alignment(); 36 37 ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, align); 38 39 _start = (HeapWord *) heap_rs.base(); 40 _current = _start; 41 _end = (HeapWord *) (heap_rs.base() + heap_rs.size()); 42 size_t size = pointer_delta(_end, _start); 43 44 initialize_reserved_region(_start, _end); 45 os::commit_memory((char*)_start, size*HeapWordSize, align, false); 46 if (AlwaysPreTouch) { 47 // TODO: Use shared code instead of this. Also pick up large pages, if available. 48 os::pretouch_memory(_start, _end); 49 } 50 51 EpsilonBarrierSet* bs = new EpsilonBarrierSet(); 52 set_barrier_set(bs); 53 54 log_info(gc)("Initialized with " SIZE_FORMAT "M non-resizable heap.", size*HeapWordSize / M); 55 if (UseTLAB) { 56 log_info(gc)("Using " SIZE_FORMAT "K TLABs.", EpsilonTLABSize / K); 57 } else { 58 log_info(gc)("Not using TLAB allocation."); 59 } 60 61 return JNI_OK; 62 } 63 64 HeapWord* EpsilonCollectedHeap::allocate_work(size_t size) { 65 do { 66 HeapWord* obj = (HeapWord *) _current; 67 if (pointer_delta(_end, obj) >= size) { 68 HeapWord* new_current = obj + size; 69 HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_current, &_current, obj); 70 if (result != obj) { 71 continue; 72 } 73 assert(is_object_aligned((intptr_t)obj), "object is aligned"); 74 assert(is_object_aligned((intptr_t)new_current), "current is aligned"); 75 return obj; 76 } else { 77 return NULL; 78 } 79 } while (true); 80 } 81 82 HeapWord* EpsilonCollectedHeap::allocate_new_tlab(size_t size) { 83 return allocate_work(size); 84 } 85 86 HeapWord* EpsilonCollectedHeap::mem_allocate(size_t size, bool *gc_overhead_limit_was_exceeded) { 87 *gc_overhead_limit_was_exceeded = false; 88 return allocate_work(size); 89 } 90 91 void EpsilonCollectedHeap::collect(GCCause::Cause cause) { 92 log_warning(gc)("GC was triggered with cause \"%s\". Ignoring.", GCCause::to_string(cause)); 93 } 94 95 void EpsilonCollectedHeap::do_full_collection(bool clear_all_soft_refs) { 96 log_warning(gc)("Full GC was triggered. Ignoring."); 97 } 98 99 void EpsilonCollectedHeap::safe_object_iterate(ObjectClosure *cl) { 100 HeapWord* mark = _start; 101 while (mark < _current) { 102 oop obj = oop(mark); 103 cl->do_object(obj); 104 mark += obj->size(); 105 } 106 }