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/shenandoah/shenandoahHeap.hpp" 28 #include "gc/shared/barrierSet.hpp" 29 30 class ShenandoahBarrierSet: public BarrierSet { 31 private: 32 33 static inline oop get_shenandoah_forwardee_helper(oop p) { 34 assert(UseShenandoahGC, "must only be called when Shenandoah is used."); 35 assert(Universe::heap()->is_in(p), "We shouldn't be calling this on objects not in the heap"); 36 oop forwardee; 37 #ifdef ASSERT 38 if (ShenandoahVerifyReadsToFromSpace) { 39 ShenandoahHeap* heap = (ShenandoahHeap *) Universe::heap(); 40 ShenandoahHeapRegion* region = heap->heap_region_containing(p); 41 { 42 region->memProtectionOff(); 43 forwardee = oop( *((HeapWord**) ((HeapWord*) p) - 1)); 44 region->memProtectionOn(); 45 } 46 } else { 47 forwardee = oop( *((HeapWord**) ((HeapWord*) p) - 1)); 48 } 49 #else 50 forwardee = oop( *((HeapWord**) ((HeapWord*) p) - 1)); 51 #endif 52 return forwardee; 53 } 54 55 public: 56 57 ShenandoahBarrierSet(); 58 59 void print_on(outputStream* st) const; 60 61 bool is_a(BarrierSet::Name bsn); 62 63 bool has_read_prim_array_opt(); 64 bool has_read_prim_barrier(); 65 bool has_read_ref_array_opt(); 66 bool has_read_ref_barrier(); 67 bool has_read_region_opt(); 68 bool has_write_prim_array_opt(); 69 bool has_write_prim_barrier(); 70 bool has_write_ref_array_opt(); 71 bool has_write_ref_barrier(); 72 bool has_write_ref_pre_barrier(); 73 bool has_write_region_opt(); 74 bool is_aligned(HeapWord* hw); 75 void read_prim_array(MemRegion mr); 76 void read_prim_field(HeapWord* hw, size_t s); 77 bool read_prim_needs_barrier(HeapWord* hw, size_t s); 78 void read_ref_array(MemRegion mr); 79 80 void read_ref_field(void* v); 81 82 bool read_ref_needs_barrier(void* v); 83 void read_region(MemRegion mr); 84 void resize_covered_region(MemRegion mr); 85 void write_prim_array(MemRegion mr); 86 void write_prim_field(HeapWord* hw, size_t s , juint x, juint y); 87 bool write_prim_needs_barrier(HeapWord* hw, size_t s, juint x, juint y); 88 void write_ref_array_work(MemRegion mr); 89 90 template <class T> void 91 write_ref_array_pre_work(T* dst, int count); 92 93 void write_ref_array_pre(oop* dst, int count, bool dest_uninitialized); 94 95 void write_ref_array_pre(narrowOop* dst, int count, bool dest_uninitialized); 96 97 98 template <class T> static void write_ref_field_pre_static(T* field, oop newVal); 99 100 // We export this to make it available in cases where the static 101 // type of the barrier set is known. Note that it is non-virtual. 102 template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal); 103 104 // These are the more general virtual versions. 105 void write_ref_field_pre_work(oop* field, oop new_val); 106 void write_ref_field_pre_work(narrowOop* field, oop new_val); 107 void write_ref_field_pre_work(void* field, oop new_val); 108 109 void write_ref_field_work(void* v, oop o, bool release = false); 110 void write_region_work(MemRegion mr); 111 112 virtual oop read_barrier(oop src); 113 114 template <class T> 115 static inline oop resolve_and_update_oop_static(T p, oop obj) { 116 oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj); 117 if (forw != obj) { 118 obj = forw; 119 oopDesc::encode_store_heap_oop_not_null(p, obj); 120 } 121 return obj; 122 } 123 124 static inline oop resolve_oop_static_not_null(oop p) { 125 assert(p != NULL, "Must be NULL checked"); 126 127 oop result = get_shenandoah_forwardee_helper(p); 128 129 if (result != NULL) { 130 #ifdef ASSERT 131 if (result != p) { 132 oop second_forwarding = get_shenandoah_forwardee_helper(result); 133 134 // We should never be forwarded more than once. 135 if (result != second_forwarding) { 136 ShenandoahHeap* sh = (ShenandoahHeap*) Universe::heap(); 137 tty->print("first reference "PTR_FORMAT" is in heap region:\n", p2i((HeapWord*) p)); 138 sh->heap_region_containing(p)->print(); 139 tty->print("first_forwarding "PTR_FORMAT" is in heap region:\n", p2i((HeapWord*) result)); 140 sh->heap_region_containing(result)->print(); 141 tty->print("final reference "PTR_FORMAT" is in heap region:\n", p2i((HeapWord*) second_forwarding)); 142 sh->heap_region_containing(second_forwarding)->print(); 143 assert(get_shenandoah_forwardee_helper(result) == result, "Only one fowarding per customer"); 144 } 145 } 146 #endif 147 if (! ShenandoahVerifyReadsToFromSpace) { 148 // is_oop() would trigger a SEGFAULT when we're checking from-space-access. 149 assert(ShenandoahHeap::heap()->is_in(result) && result->is_oop(), "resolved oop must be a valid oop in the heap"); 150 } 151 } 152 return result; 153 } 154 155 static inline oop resolve_oop_static(oop p) { 156 if (((HeapWord*) p) != NULL) { 157 return resolve_oop_static_not_null(p); 158 } else { 159 return p; 160 } 161 } 162 163 static inline oop resolve_oop_static_no_check(oop p) { 164 if (((HeapWord*) p) != NULL) { 165 return get_shenandoah_forwardee_helper(p); 166 } else { 167 return p; 168 } 169 } 170 171 172 oop resolve_and_maybe_copy_oopHelper(oop src); 173 oop resolve_and_maybe_copy_oop_work(oop src); 174 oop resolve_and_maybe_copy_oop_work2(oop src); 175 virtual oop write_barrier(oop src); 176 177 static oopDesc* resolve_and_maybe_copy_oop_c2(oopDesc* src); 178 static oopDesc* resolve_and_maybe_copy_oop_interp(oopDesc* src); 179 static oopDesc* resolve_and_maybe_copy_oop_c1(JavaThread* thread, oopDesc* src); 180 181 private: 182 bool need_update_refs_barrier(); 183 184 #ifndef CC_INTERP 185 public: 186 virtual void interpreter_read_barrier(MacroAssembler* masm, Register dst); 187 virtual void interpreter_read_barrier_not_null(MacroAssembler* masm, Register dst); 188 void interpreter_write_barrier(MacroAssembler* masm, Register dst); 189 190 private: 191 void compile_resolve_oop_runtime(MacroAssembler* masm, Register dst); 192 193 #endif 194 }; 195 196 #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP