1 /* 2 * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved. 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 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_INLINE_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_INLINE_HPP 26 27 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp" 28 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" 29 #include "gc_implementation/shenandoah/shenandoahPacer.inline.hpp" 30 #include "runtime/atomic.hpp" 31 32 HeapWord* ShenandoahHeapRegion::allocate(size_t size, ShenandoahAllocRequest::Type type) { 33 shenandoah_assert_heaplocked_or_safepoint(); 34 35 assert(is_object_aligned((intptr_t)size), err_msg("alloc size breaks alignment: " SIZE_FORMAT, size)); 36 37 HeapWord* obj = top(); 38 if (pointer_delta(end(), obj) >= size) { 39 make_regular_allocation(); 40 adjust_alloc_metadata(type, size); 41 42 HeapWord* new_top = obj + size; 43 set_top(new_top); 44 45 assert(is_object_aligned((intptr_t)new_top), err_msg("new top breaks alignment: " PTR_FORMAT, p2i(new_top))); 46 assert(is_object_aligned((intptr_t)obj), err_msg("obj is not aligned: " PTR_FORMAT, p2i(obj))); 47 48 return obj; 49 } else { 50 return NULL; 51 } 52 } 53 54 inline void ShenandoahHeapRegion::adjust_alloc_metadata(ShenandoahAllocRequest::Type type, size_t size) { 55 switch (type) { 56 case ShenandoahAllocRequest::_alloc_shared: 57 case ShenandoahAllocRequest::_alloc_shared_gc: 58 // Counted implicitly by tlab/gclab allocs 59 break; 60 case ShenandoahAllocRequest::_alloc_tlab: 61 _tlab_allocs += size; 62 break; 63 case ShenandoahAllocRequest::_alloc_gclab: 64 _gclab_allocs += size; 65 break; 66 default: 67 ShouldNotReachHere(); 68 } 69 } 70 71 void ShenandoahHeapRegion::clear_live_data() { 72 OrderAccess::release_store_fence((volatile jint*)&_live_data, 0); 73 } 74 75 inline void ShenandoahHeapRegion::increase_live_data_alloc_words(size_t s) { 76 internal_increase_live_data(s); 77 } 78 79 inline void ShenandoahHeapRegion::increase_live_data_gc_words(size_t s) { 80 internal_increase_live_data(s); 81 if (ShenandoahPacing) { 82 ShenandoahHeap::heap()->pacer()->report_mark(s); 83 } 84 } 85 86 inline void ShenandoahHeapRegion::internal_increase_live_data(size_t s) { 87 assert(s < (size_t)max_jint, "sanity"); 88 size_t new_live_data = (size_t)(Atomic::add((jint)s, &_live_data)); 89 #ifdef ASSERT 90 size_t live_bytes = new_live_data * HeapWordSize; 91 size_t used_bytes = used(); 92 assert(live_bytes <= used_bytes, 93 err_msg("can't have more live data than used: " SIZE_FORMAT ", " SIZE_FORMAT, live_bytes, used_bytes)); 94 #endif 95 } 96 97 size_t ShenandoahHeapRegion::get_live_data_words() const { 98 jint v = OrderAccess::load_acquire((volatile jint*)&_live_data); 99 assert(v >= 0, "sanity"); 100 return (size_t)v; 101 } 102 103 size_t ShenandoahHeapRegion::get_live_data_bytes() const { 104 return get_live_data_words() * HeapWordSize; 105 } 106 107 bool ShenandoahHeapRegion::has_live() const { 108 return get_live_data_words() != 0; 109 } 110 111 size_t ShenandoahHeapRegion::garbage() const { 112 assert(used() >= get_live_data_bytes(), err_msg("Live Data must be a subset of used() live: " SIZE_FORMAT " used: " SIZE_FORMAT, 113 get_live_data_bytes(), used())); 114 size_t result = used() - get_live_data_bytes(); 115 return result; 116 } 117 118 inline HeapWord* ShenandoahHeapRegion::get_update_watermark() const { 119 HeapWord* watermark = (HeapWord*)OrderAccess::load_ptr_acquire(&_update_watermark); 120 assert(bottom() <= watermark && watermark <= top(), "within bounds"); 121 return watermark; 122 } 123 124 inline void ShenandoahHeapRegion::set_update_watermark(HeapWord* w) { 125 assert(bottom() <= w && w <= top(), "within bounds"); 126 OrderAccess::release_store_ptr(&_update_watermark, w); 127 } 128 129 // Fast version that avoids synchronization, only to be used at safepoints. 130 inline void ShenandoahHeapRegion::set_update_watermark_at_safepoint(HeapWord* w) { 131 assert(bottom() <= w && w <= top(), "within bounds"); 132 assert(SafepointSynchronize::is_at_safepoint(), "Should be at Shenandoah safepoint"); 133 _update_watermark = w; 134 } 135 136 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHHEAPREGION_INLINE_HPP