209 } |
209 } |
210 |
210 |
211 LIRGenerator* gen = access.gen(); |
211 LIRGenerator* gen = access.gen(); |
212 |
212 |
213 DecoratorSet decorators = access.decorators(); |
213 DecoratorSet decorators = access.decorators(); |
214 if ((decorators & IN_NATIVE) != 0) { |
214 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
|
215 |
|
216 if ((decorators & IN_NATIVE) != 0 && !is_traversal_mode) { |
215 assert(access.is_oop(), "IN_NATIVE access only for oop values"); |
217 assert(access.is_oop(), "IN_NATIVE access only for oop values"); |
216 BarrierSetC1::load_at_resolved(access, result); |
218 BarrierSetC1::load_at_resolved(access, result); |
217 LIR_OprList* args = new LIR_OprList(); |
219 LIR_OprList* args = new LIR_OprList(); |
218 LIR_Opr addr = access.resolved_addr(); |
220 LIR_Opr addr = access.resolved_addr(); |
219 addr = ensure_in_register(gen, addr); |
221 addr = ensure_in_register(gen, addr); |
224 signature.append(T_ADDRESS); |
226 signature.append(T_ADDRESS); |
225 LIR_Opr call_result = gen->call_runtime(&signature, args, |
227 LIR_Opr call_result = gen->call_runtime(&signature, args, |
226 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), |
228 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), |
227 objectType, NULL); |
229 objectType, NULL); |
228 __ move(call_result, result); |
230 __ move(call_result, result); |
229 return; |
231 } else { |
230 } |
232 if (ShenandoahLoadRefBarrier) { |
231 |
233 LIR_Opr tmp = gen->new_register(T_OBJECT); |
232 if (ShenandoahLoadRefBarrier) { |
234 BarrierSetC1::load_at_resolved(access, tmp); |
233 LIR_Opr tmp = gen->new_register(T_OBJECT); |
235 tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr()); |
234 BarrierSetC1::load_at_resolved(access, tmp); |
236 __ move(tmp, result); |
235 tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr()); |
237 } else { |
236 __ move(tmp, result); |
238 BarrierSetC1::load_at_resolved(access, result); |
237 } else { |
239 } |
238 BarrierSetC1::load_at_resolved(access, result); |
|
239 } |
240 } |
240 |
241 |
241 if (ShenandoahKeepAliveBarrier) { |
242 if (ShenandoahKeepAliveBarrier) { |
242 bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
243 bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
243 bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
244 bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; |
244 bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; |
245 bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; |
245 if (is_weak || is_phantom || is_anonymous) { |
246 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
|
247 |
|
248 if ((is_weak || is_phantom || is_anonymous) && keep_alive) { |
246 // Register the value in the referent field with the pre-barrier |
249 // Register the value in the referent field with the pre-barrier |
247 LabelObj *Lcont_anonymous; |
250 LabelObj *Lcont_anonymous; |
248 if (is_anonymous) { |
251 if (is_anonymous) { |
249 Lcont_anonymous = new LabelObj(); |
252 Lcont_anonymous = new LabelObj(); |
250 generate_referent_check(access, Lcont_anonymous); |
253 generate_referent_check(access, Lcont_anonymous); |