45 void ShenandoahLoadReferenceBarrierStub::emit_code(LIR_Assembler* ce) { |
45 void ShenandoahLoadReferenceBarrierStub::emit_code(LIR_Assembler* ce) { |
46 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); |
46 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); |
47 bs->gen_load_reference_barrier_stub(ce, this); |
47 bs->gen_load_reference_barrier_stub(ce, this); |
48 } |
48 } |
49 |
49 |
|
50 ShenandoahBarrierSetC1::ShenandoahBarrierSetC1() : |
|
51 _pre_barrier_c1_runtime_code_blob(NULL), |
|
52 _load_reference_barrier_rt_code_blob(NULL) {} |
|
53 |
50 void ShenandoahBarrierSetC1::pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val) { |
54 void ShenandoahBarrierSetC1::pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val) { |
51 // First we test whether marking is in progress. |
55 // First we test whether marking is in progress. |
52 BasicType flag_type; |
56 BasicType flag_type; |
53 bool patch = (decorators & C1_NEEDS_PATCHING) != 0; |
57 bool patch = (decorators & C1_NEEDS_PATCHING) != 0; |
54 bool do_load = pre_val == LIR_OprFact::illegalOpr; |
58 bool do_load = pre_val == LIR_OprFact::illegalOpr; |
112 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj) { |
116 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj) { |
113 assert(ShenandoahLoadRefBarrier, "Should be enabled"); |
117 assert(ShenandoahLoadRefBarrier, "Should be enabled"); |
114 |
118 |
115 obj = ensure_in_register(gen, obj); |
119 obj = ensure_in_register(gen, obj); |
116 assert(obj->is_register(), "must be a register at this point"); |
120 assert(obj->is_register(), "must be a register at this point"); |
117 LIR_Opr result = gen->new_register(T_OBJECT); |
121 LIR_Opr result = gen->result_register_for(obj->value_type()); |
118 __ move(obj, result); |
122 __ move(obj, result); |
|
123 LIR_Opr tmp1 = gen->new_register(T_OBJECT); |
|
124 LIR_Opr tmp2 = gen->new_register(T_OBJECT); |
119 |
125 |
120 LIR_Opr thrd = gen->getThreadPointer(); |
126 LIR_Opr thrd = gen->getThreadPointer(); |
121 LIR_Address* active_flag_addr = |
127 LIR_Address* active_flag_addr = |
122 new LIR_Address(thrd, |
128 new LIR_Address(thrd, |
123 in_bytes(ShenandoahThreadLocalData::gc_state_offset()), |
129 in_bytes(ShenandoahThreadLocalData::gc_state_offset()), |
138 __ logical_and(flag_val, mask_reg, masked_flag); |
144 __ logical_and(flag_val, mask_reg, masked_flag); |
139 flag_val = masked_flag; |
145 flag_val = masked_flag; |
140 } |
146 } |
141 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); |
147 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); |
142 |
148 |
143 CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result); |
149 CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result, tmp1, tmp2); |
144 __ branch(lir_cond_notEqual, T_INT, slow); |
150 __ branch(lir_cond_notEqual, T_INT, slow); |
145 __ branch_destination(slow->continuation()); |
151 __ branch_destination(slow->continuation()); |
146 |
152 |
147 return result; |
153 return result; |
148 } |
154 } |
236 bs->generate_c1_pre_barrier_runtime_stub(sasm); |
242 bs->generate_c1_pre_barrier_runtime_stub(sasm); |
237 return NULL; |
243 return NULL; |
238 } |
244 } |
239 }; |
245 }; |
240 |
246 |
|
247 class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure { |
|
248 virtual OopMapSet* generate_code(StubAssembler* sasm) { |
|
249 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); |
|
250 bs->generate_c1_load_reference_barrier_runtime_stub(sasm); |
|
251 return NULL; |
|
252 } |
|
253 }; |
|
254 |
241 void ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob) { |
255 void ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob) { |
242 C1ShenandoahPreBarrierCodeGenClosure pre_code_gen_cl; |
256 C1ShenandoahPreBarrierCodeGenClosure pre_code_gen_cl; |
243 _pre_barrier_c1_runtime_code_blob = Runtime1::generate_blob(buffer_blob, -1, |
257 _pre_barrier_c1_runtime_code_blob = Runtime1::generate_blob(buffer_blob, -1, |
244 "shenandoah_pre_barrier_slow", |
258 "shenandoah_pre_barrier_slow", |
245 false, &pre_code_gen_cl); |
259 false, &pre_code_gen_cl); |
|
260 if (ShenandoahLoadRefBarrier) { |
|
261 C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_code_gen_cl; |
|
262 _load_reference_barrier_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1, |
|
263 "shenandoah_load_reference_barrier_slow", |
|
264 false, &lrb_code_gen_cl); |
|
265 } |
246 } |
266 } |
247 |
267 |
248 const char* ShenandoahBarrierSetC1::rtcall_name_for_address(address entry) { |
268 const char* ShenandoahBarrierSetC1::rtcall_name_for_address(address entry) { |
249 if (entry == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)) { |
269 if (entry == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)) { |
250 return "ShenandoahRuntime::load_reference_barrier_native"; |
270 return "ShenandoahRuntime::load_reference_barrier_native"; |