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