201 const bool patch_before_barrier = access.is_oop() && (access.decorators() & C1_NEEDS_PATCHING) != 0; |
202 const bool patch_before_barrier = access.is_oop() && (access.decorators() & C1_NEEDS_PATCHING) != 0; |
202 return BarrierSetC1::resolve_address(access, resolve_in_register || patch_before_barrier); |
203 return BarrierSetC1::resolve_address(access, resolve_in_register || patch_before_barrier); |
203 } |
204 } |
204 |
205 |
205 void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { |
206 void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { |
|
207 // 1: non-reference load, no additional barrier is needed |
206 if (!access.is_oop()) { |
208 if (!access.is_oop()) { |
207 BarrierSetC1::load_at_resolved(access, result); |
209 BarrierSetC1::load_at_resolved(access, result); |
208 return; |
210 return; |
209 } |
211 } |
210 |
212 |
211 LIRGenerator* gen = access.gen(); |
213 LIRGenerator* gen = access.gen(); |
212 |
|
213 DecoratorSet decorators = access.decorators(); |
214 DecoratorSet decorators = access.decorators(); |
214 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
215 |
215 |
216 // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set |
216 if ((decorators & IN_NATIVE) != 0 && !is_traversal_mode) { |
217 if (ShenandoahLoadRefBarrier) { |
217 assert(access.is_oop(), "IN_NATIVE access only for oop values"); |
218 // Native barrier is for concurrent root processing |
218 BarrierSetC1::load_at_resolved(access, result); |
219 bool in_native = (decorators & IN_NATIVE) != 0; |
219 LIR_OprList* args = new LIR_OprList(); |
220 if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { |
220 LIR_Opr addr = access.resolved_addr(); |
221 BarrierSetC1::load_at_resolved(access, result); |
221 addr = ensure_in_register(gen, addr); |
222 LIR_OprList* args = new LIR_OprList(); |
222 args->append(result); |
223 LIR_Opr addr = access.resolved_addr(); |
223 args->append(addr); |
224 addr = ensure_in_register(gen, addr); |
224 BasicTypeList signature; |
225 args->append(result); |
225 signature.append(T_OBJECT); |
226 args->append(addr); |
226 signature.append(T_ADDRESS); |
227 BasicTypeList signature; |
227 LIR_Opr call_result = gen->call_runtime(&signature, args, |
228 signature.append(T_OBJECT); |
228 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), |
229 signature.append(T_ADDRESS); |
229 objectType, NULL); |
230 LIR_Opr call_result = gen->call_runtime(&signature, args, |
230 __ move(call_result, result); |
231 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), |
231 } else { |
232 objectType, NULL); |
232 if (ShenandoahLoadRefBarrier) { |
233 __ move(call_result, result); |
|
234 } else { |
233 LIR_Opr tmp = gen->new_register(T_OBJECT); |
235 LIR_Opr tmp = gen->new_register(T_OBJECT); |
234 BarrierSetC1::load_at_resolved(access, tmp); |
236 BarrierSetC1::load_at_resolved(access, tmp); |
235 tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr()); |
237 tmp = load_reference_barrier(gen, tmp, access.resolved_addr()); |
236 __ move(tmp, result); |
238 __ move(tmp, result); |
237 } else { |
239 } |
238 BarrierSetC1::load_at_resolved(access, result); |
240 } else { |
239 } |
241 BarrierSetC1::load_at_resolved(access, result); |
240 } |
242 } |
241 |
243 |
|
244 // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set |
242 if (ShenandoahKeepAliveBarrier) { |
245 if (ShenandoahKeepAliveBarrier) { |
243 bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
246 bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
244 bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
247 bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
245 bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; |
248 bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; |
|
249 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
246 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
250 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
247 |
251 |
248 if ((is_weak || is_phantom || is_anonymous) && keep_alive) { |
252 if ((is_weak || is_phantom || is_anonymous) && keep_alive) { |
249 // Register the value in the referent field with the pre-barrier |
253 // Register the value in the referent field with the pre-barrier |
250 LabelObj *Lcont_anonymous; |
254 LabelObj *Lcont_anonymous; |
251 if (is_anonymous) { |
255 if (is_anonymous) { |
252 Lcont_anonymous = new LabelObj(); |
256 Lcont_anonymous = new LabelObj(); |
253 generate_referent_check(access, Lcont_anonymous); |
257 generate_referent_check(access, Lcont_anonymous); |
254 } |
258 } |
255 pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */, |
259 pre_barrier(gen, access.access_emit_info(), decorators, LIR_OprFact::illegalOpr /* addr_opr */, |
256 result /* pre_val */); |
260 result /* pre_val */); |
257 if (is_anonymous) { |
261 if (is_anonymous) { |
258 __ branch_destination(Lcont_anonymous->label()); |
262 __ branch_destination(Lcont_anonymous->label()); |
259 } |
263 } |
260 } |
264 } |
261 } |
265 } |
262 } |
266 } |
263 |
267 |
264 class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure { |
268 class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure { |
265 virtual OopMapSet* generate_code(StubAssembler* sasm) { |
269 virtual OopMapSet* generate_code(StubAssembler* sasm) { |
266 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); |
270 ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); |