< prev index next >

src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp

Print this page

 574     assert_different_registers(dst, tmp1, tmp_thread);
 575     if (!thread->is_valid()) {
 576       thread = rdx;
 577     }
 578     NOT_LP64(__ get_thread(thread));
 579     // Generate the SATB pre-barrier code to log the value of
 580     // the referent field in an SATB buffer.
 581     shenandoah_write_barrier_pre(masm /* masm */,
 582                                  noreg /* obj */,
 583                                  dst /* pre_val */,
 584                                  thread /* thread */,
 585                                  tmp1 /* tmp */,
 586                                  true /* tosca_live */,
 587                                  true /* expand_call */);
 588 
 589     restore_machine_state(masm, /* handle_gpr = */ true, /* handle_fp = */ true);
 590   }
 591 }
 592 
 593 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
 594               Address dst, Register val, Register tmp1, Register tmp2) {
 595 
 596   bool on_oop = is_reference_type(type);
 597   bool in_heap = (decorators & IN_HEAP) != 0;
 598   bool as_normal = (decorators & AS_NORMAL) != 0;
 599   if (on_oop && in_heap) {
 600     bool needs_pre_barrier = as_normal;
 601 
 602     Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
 603     Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
 604     // flatten object address if needed
 605     // We do it regardless of precise because we need the registers
 606     if (dst.index() == noreg && dst.disp() == 0) {
 607       if (dst.base() != tmp1) {
 608         __ movptr(tmp1, dst.base());
 609       }
 610     } else {
 611       __ lea(tmp1, dst);
 612     }
 613 
 614     assert_different_registers(val, tmp1, tmp2, tmp3, rthread);
 615 
 616 #ifndef _LP64
 617     __ get_thread(rthread);
 618     InterpreterMacroAssembler *imasm = static_cast<InterpreterMacroAssembler*>(masm);
 619     imasm->save_bcp();
 620 #endif
 621 
 622     if (needs_pre_barrier) {
 623       shenandoah_write_barrier_pre(masm /*masm*/,
 624                                    tmp1 /* obj */,
 625                                    tmp2 /* pre_val */,
 626                                    rthread /* thread */,
 627                                    tmp3  /* tmp */,
 628                                    val != noreg /* tosca_live */,
 629                                    false /* expand_call */);
 630     }
 631     if (val == noreg) {
 632       BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp1, 0), val, noreg, noreg);
 633     } else {
 634       iu_barrier(masm, val, tmp3);
 635       BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp1, 0), val, noreg, noreg);
 636     }
 637     NOT_LP64(imasm->restore_bcp());
 638   } else {
 639     BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2);
 640   }
 641 }
 642 
 643 void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
 644                                                                   Register obj, Register tmp, Label& slowpath) {
 645   Label done;
 646   // Resolve jobject
 647   BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, obj, tmp, slowpath);
 648 
 649   // Check for null.
 650   __ testptr(obj, obj);
 651   __ jcc(Assembler::zero, done);
 652 
 653   Address gc_state(jni_env, ShenandoahThreadLocalData::gc_state_offset() - JavaThread::jni_environment_offset());
 654   __ testb(gc_state, ShenandoahHeap::EVACUATION);
 655   __ jccb(Assembler::notZero, slowpath);
 656   __ bind(done);
 657 }
 658 
 659 // Special Shenandoah CAS implementation that handles false negatives

 574     assert_different_registers(dst, tmp1, tmp_thread);
 575     if (!thread->is_valid()) {
 576       thread = rdx;
 577     }
 578     NOT_LP64(__ get_thread(thread));
 579     // Generate the SATB pre-barrier code to log the value of
 580     // the referent field in an SATB buffer.
 581     shenandoah_write_barrier_pre(masm /* masm */,
 582                                  noreg /* obj */,
 583                                  dst /* pre_val */,
 584                                  thread /* thread */,
 585                                  tmp1 /* tmp */,
 586                                  true /* tosca_live */,
 587                                  true /* expand_call */);
 588 
 589     restore_machine_state(masm, /* handle_gpr = */ true, /* handle_fp = */ true);
 590   }
 591 }
 592 
 593 void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
 594               Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
 595 
 596   bool on_oop = is_reference_type(type);
 597   bool in_heap = (decorators & IN_HEAP) != 0;
 598   bool as_normal = (decorators & AS_NORMAL) != 0;
 599   if (on_oop && in_heap) {
 600     bool needs_pre_barrier = as_normal;
 601 
 602     Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
 603     Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
 604     // flatten object address if needed
 605     // We do it regardless of precise because we need the registers
 606     if (dst.index() == noreg && dst.disp() == 0) {
 607       if (dst.base() != tmp1) {
 608         __ movptr(tmp1, dst.base());
 609       }
 610     } else {
 611       __ lea(tmp1, dst);
 612     }
 613 
 614     assert_different_registers(val, tmp1, tmp2, tmp3, rthread);
 615 
 616 #ifndef _LP64
 617     __ get_thread(rthread);
 618     InterpreterMacroAssembler *imasm = static_cast<InterpreterMacroAssembler*>(masm);
 619     imasm->save_bcp();
 620 #endif
 621 
 622     if (needs_pre_barrier) {
 623       shenandoah_write_barrier_pre(masm /*masm*/,
 624                                    tmp1 /* obj */,
 625                                    tmp2 /* pre_val */,
 626                                    rthread /* thread */,
 627                                    tmp3  /* tmp */,
 628                                    val != noreg /* tosca_live */,
 629                                    false /* expand_call */);
 630     }
 631     if (val == noreg) {
 632       BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp1, 0), val, noreg, noreg, noreg);
 633     } else {
 634       iu_barrier(masm, val, tmp3);
 635       BarrierSetAssembler::store_at(masm, decorators, type, Address(tmp1, 0), val, noreg, noreg, noreg);
 636     }
 637     NOT_LP64(imasm->restore_bcp());
 638   } else {
 639     BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
 640   }
 641 }
 642 
 643 void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
 644                                                                   Register obj, Register tmp, Label& slowpath) {
 645   Label done;
 646   // Resolve jobject
 647   BarrierSetAssembler::try_resolve_jobject_in_native(masm, jni_env, obj, tmp, slowpath);
 648 
 649   // Check for null.
 650   __ testptr(obj, obj);
 651   __ jcc(Assembler::zero, done);
 652 
 653   Address gc_state(jni_env, ShenandoahThreadLocalData::gc_state_offset() - JavaThread::jni_environment_offset());
 654   __ testb(gc_state, ShenandoahHeap::EVACUATION);
 655   __ jccb(Assembler::notZero, slowpath);
 656   __ bind(done);
 657 }
 658 
 659 // Special Shenandoah CAS implementation that handles false negatives
< prev index next >