@@ -3632,13 +3632,33 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36323632
36333633 __ verify_oop (obj);
36343634
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
36373648 }
3649+ #endif
36383650 if (do_null) {
3639- __ testptr (tmp, tmp );
3651+ __ testptr (obj, obj );
36403652 __ jccb (Assembler::notZero, update);
36413653 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 ();
36423662 __ orptr (mdo_addr, TypeEntries::null_seen);
36433663 }
36443664 if (do_update) {
@@ -3649,7 +3669,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36493669 __ jmp (next);
36503670 }
36513671 } else {
3652- __ testptr (tmp, tmp );
3672+ __ testptr (obj, obj );
36533673 __ jcc (Assembler::notZero, update);
36543674 __ stop (" unexpect null obj" );
36553675#endif
@@ -3661,7 +3681,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36613681#ifdef ASSERT
36623682 if (exact_klass != NULL ) {
36633683 Label ok;
3664- __ load_klass (tmp, tmp , tmp_load_klass);
3684+ __ load_klass (tmp, obj , tmp_load_klass);
36653685 __ push (tmp);
36663686 __ mov_metadata (tmp, exact_klass->constant_encoding ());
36673687 __ cmpptr (tmp, Address (rsp, 0 ));
@@ -3676,9 +3696,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36763696 if (exact_klass != NULL ) {
36773697 __ mov_metadata (tmp, exact_klass->constant_encoding ());
36783698 } else {
3679- __ load_klass (tmp, tmp , tmp_load_klass);
3699+ __ load_klass (tmp, obj , tmp_load_klass);
36803700 }
3681-
3701+ #ifdef _LP64
3702+ __ mov (rscratch1, tmp); // save original value before XOR
3703+ #endif
36823704 __ xorptr (tmp, mdo_addr);
36833705 __ testptr (tmp, TypeEntries::type_klass_mask);
36843706 // 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) {
36893711 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
36903712
36913713 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
36963717 // There is a chance that the checks above (re-reading profiling
36973718 // data from memory) fail if another thread has just set the
36983719 // profiling to this obj's klass
3720+ __ mov (tmp, rscratch1); // get back original value before XOR
36993721 __ xorptr (tmp, mdo_addr);
37003722 __ testptr (tmp, TypeEntries::type_klass_mask);
37013723 __ jccb (Assembler::zero, next);
3724+ #endif
37023725 }
37033726 } else {
37043727 assert (ciTypeEntries::valid_ciklass (current_klass) != NULL &&
37053728 ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " conflict only" );
37063729
3707- __ movptr (tmp, mdo_addr);
3708- __ testptr (tmp, TypeEntries::type_unknown);
3730+ __ testptr (mdo_addr, TypeEntries::type_unknown);
37093731 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
37103732 }
37113733
@@ -3718,6 +3740,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37183740 __ bind (none);
37193741 // first time here. Set profile type.
37203742 __ movptr (mdo_addr, tmp);
3743+ #ifdef ASSERT
3744+ __ andptr (tmp, TypeEntries::type_klass_mask);
3745+ __ verify_klass_ptr (tmp);
3746+ #endif
37213747 }
37223748 } else {
37233749 // There's a single possible klass at this profile point
@@ -3732,10 +3758,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37323758 {
37333759 Label ok;
37343760 __ 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);
37393763 // may have been set by another thread
37403764 __ mov_metadata (tmp, exact_klass->constant_encoding ());
37413765 __ xorptr (tmp, mdo_addr);
@@ -3751,20 +3775,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37513775#endif
37523776 // first time here. Set profile type.
37533777 __ movptr (mdo_addr, tmp);
3778+ #ifdef ASSERT
3779+ __ andptr (tmp, TypeEntries::type_klass_mask);
3780+ __ verify_klass_ptr (tmp);
3781+ #endif
37543782 } else {
37553783 assert (ciTypeEntries::valid_ciklass (current_klass) != NULL &&
37563784 ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " inconsistent" );
37573785
3758- __ movptr (tmp, mdo_addr);
3759- __ testptr (tmp, TypeEntries::type_unknown);
3786+ __ testptr (mdo_addr, TypeEntries::type_unknown);
37603787 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
37613788
37623789 __ orptr (mdo_addr, TypeEntries::type_unknown);
37633790 }
37643791 }
3765-
3766- __ bind (next);
37673792 }
3793+ __ bind (next);
37683794}
37693795
37703796void LIR_Assembler::emit_delay (LIR_OpDelay*) {
0 commit comments