357 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
358 }
359
360 // 3: apply keep-alive barrier if needed
361 if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
362 __ enter(/*strip_ret_addr*/true);
363 __ push_call_clobbered_registers();
364 satb_write_barrier_pre(masm /* masm */,
365 noreg /* obj */,
366 dst /* pre_val */,
367 rthread /* thread */,
368 tmp1 /* tmp */,
369 true /* tosca_live */,
370 true /* expand_call */);
371 __ pop_call_clobbered_registers();
372 __ leave();
373 }
374 }
375
376 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
377 Address dst, Register val, Register tmp1, Register tmp2) {
378 bool on_oop = is_reference_type(type);
379 if (!on_oop) {
380 BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
381 return;
382 }
383
384 // flatten object address if needed
385 if (dst.index() == noreg && dst.offset() == 0) {
386 if (dst.base() != r3) {
387 __ mov(r3, dst.base());
388 }
389 } else {
390 __ lea(r3, dst);
391 }
392
393 shenandoah_write_barrier_pre(masm,
394 r3 /* obj */,
395 tmp2 /* pre_val */,
396 rthread /* thread */,
397 tmp1 /* tmp */,
398 val != noreg /* tosca_live */,
399 false /* expand_call */);
400
401 if (val == noreg) {
402 BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), noreg, noreg, noreg);
403 } else {
404 iu_barrier(masm, val, tmp1);
405 // G1 barrier needs uncompressed oop for region cross check.
406 Register new_val = val;
407 if (UseCompressedOops) {
408 new_val = rscratch2;
409 __ mov(new_val, val);
410 }
411 BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), val, noreg, noreg);
412 }
413
414 }
415
416 void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
417 Register obj, Register tmp, Label& slowpath) {
418 Label done;
419 // Resolve jobject
420 BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, obj, tmp, slowpath);
421
422 // Check for null.
423 __ cbz(obj, done);
424
425 assert(obj != rscratch2, "need rscratch2");
426 Address gc_state(jni_env, ShenandoahThreadLocalData::gc_state_offset() - JavaThread::jni_environment_offset());
427 __ lea(rscratch2, gc_state);
428 __ ldrb(rscratch2, Address(rscratch2));
429
430 // Check for heap in evacuation phase
431 __ tbnz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, slowpath);
|
357 BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
358 }
359
360 // 3: apply keep-alive barrier if needed
361 if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
362 __ enter(/*strip_ret_addr*/true);
363 __ push_call_clobbered_registers();
364 satb_write_barrier_pre(masm /* masm */,
365 noreg /* obj */,
366 dst /* pre_val */,
367 rthread /* thread */,
368 tmp1 /* tmp */,
369 true /* tosca_live */,
370 true /* expand_call */);
371 __ pop_call_clobbered_registers();
372 __ leave();
373 }
374 }
375
376 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
377 Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
378 bool on_oop = is_reference_type(type);
379 if (!on_oop) {
380 BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
381 return;
382 }
383
384 // flatten object address if needed
385 if (dst.index() == noreg && dst.offset() == 0) {
386 if (dst.base() != r3) {
387 __ mov(r3, dst.base());
388 }
389 } else {
390 __ lea(r3, dst);
391 }
392
393 shenandoah_write_barrier_pre(masm,
394 r3 /* obj */,
395 tmp2 /* pre_val */,
396 rthread /* thread */,
397 tmp1 /* tmp */,
398 val != noreg /* tosca_live */,
399 false /* expand_call */);
400
401 if (val == noreg) {
402 BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), noreg, noreg, noreg, noreg);
403 } else {
404 iu_barrier(masm, val, tmp1);
405 // G1 barrier needs uncompressed oop for region cross check.
406 Register new_val = val;
407 if (UseCompressedOops) {
408 new_val = rscratch2;
409 __ mov(new_val, val);
410 }
411 BarrierSetAssembler::store_at(masm, decorators, type, Address(r3, 0), val, noreg, noreg, noreg);
412 }
413
414 }
415
416 void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
417 Register obj, Register tmp, Label& slowpath) {
418 Label done;
419 // Resolve jobject
420 BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, obj, tmp, slowpath);
421
422 // Check for null.
423 __ cbz(obj, done);
424
425 assert(obj != rscratch2, "need rscratch2");
426 Address gc_state(jni_env, ShenandoahThreadLocalData::gc_state_offset() - JavaThread::jni_environment_offset());
427 __ lea(rscratch2, gc_state);
428 __ ldrb(rscratch2, Address(rscratch2));
429
430 // Check for heap in evacuation phase
431 __ tbnz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, slowpath);
|