97 slow = new ShenandoahPreBarrierStub(pre_val);
98 }
99
100 __ branch(lir_cond_notEqual, T_INT, slow);
101 __ branch_destination(slow->continuation());
102 }
103
104 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj) {
105 if (ShenandoahLoadRefBarrier) {
106 return load_reference_barrier_impl(gen, obj);
107 } else {
108 return obj;
109 }
110 }
111
112 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj) {
113 assert(ShenandoahLoadRefBarrier, "Should be enabled");
114
115 obj = ensure_in_register(gen, obj);
116 assert(obj->is_register(), "must be a register at this point");
117 LIR_Opr result = gen->new_register(T_OBJECT);
118 __ move(obj, result);
119
120 LIR_Opr thrd = gen->getThreadPointer();
121 LIR_Address* active_flag_addr =
122 new LIR_Address(thrd,
123 in_bytes(ShenandoahThreadLocalData::gc_state_offset()),
124 T_BYTE);
125 // Read and check the gc-state-flag.
126 LIR_Opr flag_val = gen->new_register(T_INT);
127 __ load(active_flag_addr, flag_val);
128 LIR_Opr mask = LIR_OprFact::intConst(ShenandoahHeap::HAS_FORWARDED |
129 ShenandoahHeap::EVACUATION |
130 ShenandoahHeap::TRAVERSAL);
131 LIR_Opr mask_reg = gen->new_register(T_INT);
132 __ move(mask, mask_reg);
133
134 if (TwoOperandLIRForm) {
135 __ logical_and(flag_val, mask_reg, flag_val);
136 } else {
137 LIR_Opr masked_flag = gen->new_register(T_INT);
138 __ logical_and(flag_val, mask_reg, masked_flag);
139 flag_val = masked_flag;
140 }
141 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
142
143 CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result);
144 __ branch(lir_cond_notEqual, T_INT, slow);
145 __ branch_destination(slow->continuation());
146
147 return result;
148 }
149
150 LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRGenerator* gen, LIR_Opr obj) {
151 if (!obj->is_register()) {
152 LIR_Opr obj_reg = gen->new_register(T_OBJECT);
153 if (obj->is_constant()) {
154 __ move(obj, obj_reg);
155 } else {
156 __ leal(obj, obj_reg);
157 }
158 obj = obj_reg;
159 }
160 return obj;
161 }
162
163 LIR_Opr ShenandoahBarrierSetC1::storeval_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, DecoratorSet decorators) {
221 Lcont_anonymous = new LabelObj();
222 generate_referent_check(access, Lcont_anonymous);
223 }
224 pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */,
225 result /* pre_val */);
226 if (is_anonymous) {
227 __ branch_destination(Lcont_anonymous->label());
228 }
229 }
230 }
231 }
232
233 class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
234 virtual OopMapSet* generate_code(StubAssembler* sasm) {
235 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
236 bs->generate_c1_pre_barrier_runtime_stub(sasm);
237 return NULL;
238 }
239 };
240
241 void ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob) {
242 C1ShenandoahPreBarrierCodeGenClosure pre_code_gen_cl;
243 _pre_barrier_c1_runtime_code_blob = Runtime1::generate_blob(buffer_blob, -1,
244 "shenandoah_pre_barrier_slow",
245 false, &pre_code_gen_cl);
246 }
247
248 const char* ShenandoahBarrierSetC1::rtcall_name_for_address(address entry) {
249 if (entry == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)) {
250 return "ShenandoahRuntime::load_reference_barrier_native";
251 }
252 return NULL;
253 }
|
97 slow = new ShenandoahPreBarrierStub(pre_val);
98 }
99
100 __ branch(lir_cond_notEqual, T_INT, slow);
101 __ branch_destination(slow->continuation());
102 }
103
104 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj) {
105 if (ShenandoahLoadRefBarrier) {
106 return load_reference_barrier_impl(gen, obj);
107 } else {
108 return obj;
109 }
110 }
111
112 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj) {
113 assert(ShenandoahLoadRefBarrier, "Should be enabled");
114
115 obj = ensure_in_register(gen, obj);
116 assert(obj->is_register(), "must be a register at this point");
117 LIR_Opr result = gen->result_register_for(obj->value_type());
118 __ move(obj, result);
119 LIR_Opr tmp1 = gen->new_register(T_OBJECT);
120 LIR_Opr tmp2 = gen->new_register(T_OBJECT);
121
122 LIR_Opr thrd = gen->getThreadPointer();
123 LIR_Address* active_flag_addr =
124 new LIR_Address(thrd,
125 in_bytes(ShenandoahThreadLocalData::gc_state_offset()),
126 T_BYTE);
127 // Read and check the gc-state-flag.
128 LIR_Opr flag_val = gen->new_register(T_INT);
129 __ load(active_flag_addr, flag_val);
130 LIR_Opr mask = LIR_OprFact::intConst(ShenandoahHeap::HAS_FORWARDED |
131 ShenandoahHeap::EVACUATION |
132 ShenandoahHeap::TRAVERSAL);
133 LIR_Opr mask_reg = gen->new_register(T_INT);
134 __ move(mask, mask_reg);
135
136 if (TwoOperandLIRForm) {
137 __ logical_and(flag_val, mask_reg, flag_val);
138 } else {
139 LIR_Opr masked_flag = gen->new_register(T_INT);
140 __ logical_and(flag_val, mask_reg, masked_flag);
141 flag_val = masked_flag;
142 }
143 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
144
145 CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result, tmp1, tmp2);
146 __ branch(lir_cond_notEqual, T_INT, slow);
147 __ branch_destination(slow->continuation());
148
149 return result;
150 }
151
152 LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRGenerator* gen, LIR_Opr obj) {
153 if (!obj->is_register()) {
154 LIR_Opr obj_reg = gen->new_register(T_OBJECT);
155 if (obj->is_constant()) {
156 __ move(obj, obj_reg);
157 } else {
158 __ leal(obj, obj_reg);
159 }
160 obj = obj_reg;
161 }
162 return obj;
163 }
164
165 LIR_Opr ShenandoahBarrierSetC1::storeval_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, DecoratorSet decorators) {
223 Lcont_anonymous = new LabelObj();
224 generate_referent_check(access, Lcont_anonymous);
225 }
226 pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */,
227 result /* pre_val */);
228 if (is_anonymous) {
229 __ branch_destination(Lcont_anonymous->label());
230 }
231 }
232 }
233 }
234
235 class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
236 virtual OopMapSet* generate_code(StubAssembler* sasm) {
237 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
238 bs->generate_c1_pre_barrier_runtime_stub(sasm);
239 return NULL;
240 }
241 };
242
243 class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
244 virtual OopMapSet* generate_code(StubAssembler* sasm) {
245 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
246 bs->generate_c1_load_reference_barrier_runtime_stub(sasm);
247 return NULL;
248 }
249 };
250
251 void ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob) {
252 C1ShenandoahPreBarrierCodeGenClosure pre_code_gen_cl;
253 _pre_barrier_c1_runtime_code_blob = Runtime1::generate_blob(buffer_blob, -1,
254 "shenandoah_pre_barrier_slow",
255 false, &pre_code_gen_cl);
256 if (ShenandoahLoadRefBarrier) {
257 C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_code_gen_cl;
258 _load_reference_barrier_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1,
259 "shenandoah_load_reference_barrier_slow",
260 false, &lrb_code_gen_cl);
261 }
262 }
263
264 const char* ShenandoahBarrierSetC1::rtcall_name_for_address(address entry) {
265 if (entry == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)) {
266 return "ShenandoahRuntime::load_reference_barrier_native";
267 }
268 return NULL;
269 }
|