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