1 /* 2 * Copyright (c) 2013, 2015, 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 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP 26 27 #include "gc/shared/accessBarrierSupport.hpp" 28 #include "gc/shenandoah/shenandoahBaseBarrierSet.hpp" 29 30 class ShenandoahBarrierSet: public ShenandoahBaseBarrierSet { 31 32 public: 33 34 ShenandoahBarrierSet(ShenandoahHeap* heap); 35 36 void print_on(outputStream* st) const; 37 38 bool is_a(BarrierSet::Name bsn); 39 40 // We export this to make it available in cases where the static 41 // type of the barrier set is known. Note that it is non-virtual. 42 template <class T> inline void inline_write_ref_field_pre(T* field, oop new_val); 43 44 // These are the more general virtual versions. 45 void write_ref_field_pre_work(oop* field, oop new_val); 46 void write_ref_field_pre_work(narrowOop* field, oop new_val); 47 void write_ref_field_pre_work(void* field, oop new_val); 48 49 void write_ref_field_work(void* v, oop o, bool release = false); 50 51 public: 52 // Callbacks for runtime accesses. 53 template <DecoratorSet decorators, typename BarrierSetT = ShenandoahBarrierSet> 54 class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> { 55 typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw; 56 57 public: 58 // Primitive heap accesses. These accessors get resolved when 59 // IN_HEAP is set (e.g. when using the HeapAccess API), it is 60 // not an oop_* overload, and the barrier strength is AS_NORMAL. 61 template <typename T> 62 static T load_in_heap(T* addr) { 63 ShouldNotReachHere(); 64 return Raw::template load<T>(addr); 65 } 66 67 template <typename T> 68 static T load_in_heap_at(oop base, ptrdiff_t offset) { 69 base = ShenandoahBaseBarrierSet::resolve_forwarded(base); 70 return Raw::template load_at<T>(base, offset); 71 } 72 73 template <typename T> 74 static void store_in_heap(T* addr, T value) { 75 ShouldNotReachHere(); 76 Raw::store(addr, value); 77 } 78 79 template <typename T> 80 static void store_in_heap_at(oop base, ptrdiff_t offset, T value) { 81 base = ShenandoahBaseBarrierSet::barrier_set()->write_barrier(base); 82 Raw::store_at(base, offset, value); 83 } 84 85 template <typename T> 86 static T atomic_cmpxchg_in_heap(T new_value, T* addr, T compare_value) { 87 ShouldNotReachHere(); 88 return Raw::atomic_cmpxchg(new_value, addr, compare_value); 89 } 90 91 template <typename T> 92 static T atomic_cmpxchg_in_heap_at(T new_value, oop base, ptrdiff_t offset, T compare_value) { 93 base = ShenandoahBaseBarrierSet::barrier_set()->write_barrier(base); 94 return Raw::atomic_cmpxchg_at(new_value, base, offset, compare_value); 95 } 96 97 template <typename T> 98 static T atomic_xchg_in_heap(T new_value, T* addr) { 99 ShouldNotReachHere(); 100 return Raw::atomic_xchg(new_value, addr); 101 } 102 103 template <typename T> 104 static T atomic_xchg_in_heap_at(T new_value, oop base, ptrdiff_t offset) { 105 base = ShenandoahBaseBarrierSet::barrier_set()->write_barrier(base); 106 return Raw::atomic_xchg_at(new_value, base, offset); 107 } 108 109 template <typename T> 110 static void arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, 111 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, 112 size_t length); 113 114 // Heap oop accesses. These accessors get resolved when 115 // IN_HEAP is set (e.g. when using the HeapAccess API), it is 116 // an oop_* overload, and the barrier strength is AS_NORMAL. 117 template <typename T> 118 static oop oop_load_in_heap(T* addr) { 119 // ShouldNotReachHere(); 120 oop value = Raw::template oop_load<oop>(addr); 121 keep_alive_if_weak(decorators, value); 122 return value; 123 } 124 125 static oop oop_load_in_heap_at(oop base, ptrdiff_t offset) { 126 base = ShenandoahBaseBarrierSet::resolve_forwarded(base); 127 oop value = Raw::template oop_load_at<oop>(base, offset); 128 keep_alive_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value); 129 return value; 130 } 131 132 template <typename T> 133 static void oop_store_in_heap(T* addr, oop value) { 134 ShenandoahBaseBarrierSet::barrier_set()->write_ref_field_pre_work(addr, value); 135 Raw::oop_store(addr, value); 136 } 137 138 static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) { 139 base = ShenandoahBaseBarrierSet::barrier_set()->write_barrier(base); 140 value = ShenandoahBaseBarrierSet::barrier_set()->storeval_barrier(value); 141 142 oop_store_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), value); 143 } 144 145 template <typename T> 146 static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value); 147 148 static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) { 149 base = ShenandoahBaseBarrierSet::barrier_set()->write_barrier(base); 150 new_value = ShenandoahBaseBarrierSet::barrier_set()->storeval_barrier(new_value); 151 return oop_atomic_cmpxchg_in_heap(new_value, AccessInternal::oop_field_addr<decorators>(base, offset), compare_value); 152 } 153 154 template <typename T> 155 static oop oop_atomic_xchg_in_heap(oop new_value, T* addr); 156 157 static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) { 158 base = ShenandoahBaseBarrierSet::barrier_set()->write_barrier(base); 159 new_value = ShenandoahBaseBarrierSet::barrier_set()->storeval_barrier(new_value); 160 return oop_atomic_xchg_in_heap(new_value, AccessInternal::oop_field_addr<decorators>(base, offset)); 161 } 162 163 template <typename T> 164 static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw, 165 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, 166 size_t length); 167 168 // Clone barrier support 169 static void clone_in_heap(oop src, oop dst, size_t size); 170 171 // Needed for loads on non-heap weak references 172 template <typename T> 173 static oop oop_load_not_in_heap(T* addr) { 174 oop value = Raw::oop_load_not_in_heap(addr); 175 keep_alive_if_weak(decorators, value); 176 return value; 177 } 178 179 static oop resolve(oop obj) { 180 return ShenandoahBaseBarrierSet::barrier_set()->write_barrier(obj); 181 } 182 183 static bool equals(oop o1, oop o2) { 184 return ShenandoahBaseBarrierSet::barrier_set()->obj_equals(o1, o2); 185 } 186 187 }; 188 189 }; 190 191 template<> 192 struct BarrierSet::GetName<ShenandoahBarrierSet> { 193 static const BarrierSet::Name value = BarrierSet::Shenandoah; 194 }; 195 196 template<> 197 struct BarrierSet::GetType<BarrierSet::Shenandoah> { 198 typedef ::ShenandoahBarrierSet type; 199 }; 200 201 #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP