@@ -3629,13 +3629,33 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3629
3629
3630
3630
__ verify_oop (obj);
3631
3631
3632
- if (tmp != obj) {
3633
- __ mov (tmp, obj);
3632
+ #ifdef ASSERT
3633
+ if (obj == tmp) {
3634
+ #ifdef _LP64
3635
+ assert_different_registers (obj, rscratch1, mdo_addr.base (), mdo_addr.index ());
3636
+ #else
3637
+ assert_different_registers (obj, mdo_addr.base (), mdo_addr.index ());
3638
+ #endif
3639
+ } else {
3640
+ #ifdef _LP64
3641
+ assert_different_registers (obj, tmp, rscratch1, mdo_addr.base (), mdo_addr.index ());
3642
+ #else
3643
+ assert_different_registers (obj, tmp, mdo_addr.base (), mdo_addr.index ());
3644
+ #endif
3634
3645
}
3646
+ #endif
3635
3647
if (do_null) {
3636
- __ testptr (tmp, tmp );
3648
+ __ testptr (obj, obj );
3637
3649
__ jccb (Assembler::notZero, update);
3638
3650
if (!TypeEntries::was_null_seen (current_klass)) {
3651
+ __ testptr (mdo_addr, TypeEntries::null_seen);
3652
+ #ifndef ASSERT
3653
+ __ jccb (Assembler::notZero, next); // already set
3654
+ #else
3655
+ __ jcc (Assembler::notZero, next); // already set
3656
+ #endif
3657
+ // atomic update to prevent overwriting Klass* with 0
3658
+ __ lock ();
3639
3659
__ orptr (mdo_addr, TypeEntries::null_seen);
3640
3660
}
3641
3661
if (do_update) {
@@ -3646,7 +3666,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3646
3666
__ jmp (next);
3647
3667
}
3648
3668
} else {
3649
- __ testptr (tmp, tmp );
3669
+ __ testptr (obj, obj );
3650
3670
__ jcc (Assembler::notZero, update);
3651
3671
__ stop (" unexpected null obj" );
3652
3672
#endif
@@ -3658,7 +3678,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3658
3678
#ifdef ASSERT
3659
3679
if (exact_klass != nullptr ) {
3660
3680
Label ok;
3661
- __ load_klass (tmp, tmp , tmp_load_klass);
3681
+ __ load_klass (tmp, obj , tmp_load_klass);
3662
3682
__ push (tmp);
3663
3683
__ mov_metadata (tmp, exact_klass->constant_encoding ());
3664
3684
__ cmpptr (tmp, Address (rsp, 0 ));
@@ -3673,9 +3693,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3673
3693
if (exact_klass != nullptr ) {
3674
3694
__ mov_metadata (tmp, exact_klass->constant_encoding ());
3675
3695
} else {
3676
- __ load_klass (tmp, tmp , tmp_load_klass);
3696
+ __ load_klass (tmp, obj , tmp_load_klass);
3677
3697
}
3678
-
3698
+ #ifdef _LP64
3699
+ __ mov (rscratch1, tmp); // save original value before XOR
3700
+ #endif
3679
3701
__ xorptr (tmp, mdo_addr);
3680
3702
__ testptr (tmp, TypeEntries::type_klass_mask);
3681
3703
// klass seen before, nothing to do. The unknown bit may have been
@@ -3686,23 +3708,23 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3686
3708
__ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
3687
3709
3688
3710
if (TypeEntries::is_type_none (current_klass)) {
3689
- __ cmpptr (mdo_addr, 0 );
3690
- __ jccb (Assembler::equal, none);
3691
- __ cmpptr (mdo_addr, TypeEntries::null_seen);
3692
- __ jccb (Assembler::equal, none);
3711
+ __ testptr (mdo_addr, TypeEntries::type_mask);
3712
+ __ jccb (Assembler::zero, none);
3713
+ #ifdef _LP64
3693
3714
// There is a chance that the checks above (re-reading profiling
3694
3715
// data from memory) fail if another thread has just set the
3695
3716
// profiling to this obj's klass
3717
+ __ mov (tmp, rscratch1); // get back original value before XOR
3696
3718
__ xorptr (tmp, mdo_addr);
3697
3719
__ testptr (tmp, TypeEntries::type_klass_mask);
3698
3720
__ jccb (Assembler::zero, next);
3721
+ #endif
3699
3722
}
3700
3723
} else {
3701
3724
assert (ciTypeEntries::valid_ciklass (current_klass) != nullptr &&
3702
3725
ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " conflict only" );
3703
3726
3704
- __ movptr (tmp, mdo_addr);
3705
- __ testptr (tmp, TypeEntries::type_unknown);
3727
+ __ testptr (mdo_addr, TypeEntries::type_unknown);
3706
3728
__ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
3707
3729
}
3708
3730
@@ -3715,6 +3737,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3715
3737
__ bind (none);
3716
3738
// first time here. Set profile type.
3717
3739
__ movptr (mdo_addr, tmp);
3740
+ #ifdef ASSERT
3741
+ __ andptr (tmp, TypeEntries::type_klass_mask);
3742
+ __ verify_klass_ptr (tmp);
3743
+ #endif
3718
3744
}
3719
3745
} else {
3720
3746
// There's a single possible klass at this profile point
@@ -3729,10 +3755,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3729
3755
{
3730
3756
Label ok;
3731
3757
__ push (tmp);
3732
- __ cmpptr (mdo_addr, 0 );
3733
- __ jcc (Assembler::equal, ok);
3734
- __ cmpptr (mdo_addr, TypeEntries::null_seen);
3735
- __ jcc (Assembler::equal, ok);
3758
+ __ testptr (mdo_addr, TypeEntries::type_mask);
3759
+ __ jcc (Assembler::zero, ok);
3736
3760
// may have been set by another thread
3737
3761
__ mov_metadata (tmp, exact_klass->constant_encoding ());
3738
3762
__ xorptr (tmp, mdo_addr);
@@ -3748,20 +3772,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
3748
3772
#endif
3749
3773
// first time here. Set profile type.
3750
3774
__ movptr (mdo_addr, tmp);
3775
+ #ifdef ASSERT
3776
+ __ andptr (tmp, TypeEntries::type_klass_mask);
3777
+ __ verify_klass_ptr (tmp);
3778
+ #endif
3751
3779
} else {
3752
3780
assert (ciTypeEntries::valid_ciklass (current_klass) != nullptr &&
3753
3781
ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " inconsistent" );
3754
3782
3755
- __ movptr (tmp, mdo_addr);
3756
- __ testptr (tmp, TypeEntries::type_unknown);
3783
+ __ testptr (mdo_addr, TypeEntries::type_unknown);
3757
3784
__ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
3758
3785
3759
3786
__ orptr (mdo_addr, TypeEntries::type_unknown);
3760
3787
}
3761
3788
}
3762
-
3763
- __ bind (next);
3764
3789
}
3790
+ __ bind (next);
3765
3791
}
3766
3792
3767
3793
void LIR_Assembler::emit_delay (LIR_OpDelay*) {
0 commit comments