@@ -3640,13 +3640,33 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36403640
36413641 __ verify_oop (obj);
36423642
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
36453656 }
3657+ #endif
36463658 if (do_null) {
3647- __ testptr (tmp, tmp );
3659+ __ testptr (obj, obj );
36483660 __ jccb (Assembler::notZero, update);
36493661 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 ();
36503670 __ orptr (mdo_addr, TypeEntries::null_seen);
36513671 }
36523672 if (do_update) {
@@ -3657,7 +3677,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36573677 __ jmp (next);
36583678 }
36593679 } else {
3660- __ testptr (tmp, tmp );
3680+ __ testptr (obj, obj );
36613681 __ jcc (Assembler::notZero, update);
36623682 __ stop (" unexpected null obj" );
36633683#endif
@@ -3669,7 +3689,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36693689#ifdef ASSERT
36703690 if (exact_klass != nullptr ) {
36713691 Label ok;
3672- __ load_klass (tmp, tmp , tmp_load_klass);
3692+ __ load_klass (tmp, obj , tmp_load_klass);
36733693 __ push (tmp);
36743694 __ mov_metadata (tmp, exact_klass->constant_encoding ());
36753695 __ cmpptr (tmp, Address (rsp, 0 ));
@@ -3684,9 +3704,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36843704 if (exact_klass != nullptr ) {
36853705 __ mov_metadata (tmp, exact_klass->constant_encoding ());
36863706 } else {
3687- __ load_klass (tmp, tmp , tmp_load_klass);
3707+ __ load_klass (tmp, obj , tmp_load_klass);
36883708 }
3689-
3709+ #ifdef _LP64
3710+ __ mov (rscratch1, tmp); // save original value before XOR
3711+ #endif
36903712 __ xorptr (tmp, mdo_addr);
36913713 __ testptr (tmp, TypeEntries::type_klass_mask);
36923714 // 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) {
36973719 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
36983720
36993721 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
37043725 // There is a chance that the checks above (re-reading profiling
37053726 // data from memory) fail if another thread has just set the
37063727 // profiling to this obj's klass
3728+ __ mov (tmp, rscratch1); // get back original value before XOR
37073729 __ xorptr (tmp, mdo_addr);
37083730 __ testptr (tmp, TypeEntries::type_klass_mask);
37093731 __ jccb (Assembler::zero, next);
3732+ #endif
37103733 }
37113734 } else {
37123735 assert (ciTypeEntries::valid_ciklass (current_klass) != nullptr &&
37133736 ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " conflict only" );
37143737
3715- __ movptr (tmp, mdo_addr);
3716- __ testptr (tmp, TypeEntries::type_unknown);
3738+ __ testptr (mdo_addr, TypeEntries::type_unknown);
37173739 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
37183740 }
37193741
@@ -3726,6 +3748,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37263748 __ bind (none);
37273749 // first time here. Set profile type.
37283750 __ movptr (mdo_addr, tmp);
3751+ #ifdef ASSERT
3752+ __ andptr (tmp, TypeEntries::type_klass_mask);
3753+ __ verify_klass_ptr (tmp);
3754+ #endif
37293755 }
37303756 } else {
37313757 // There's a single possible klass at this profile point
@@ -3740,10 +3766,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37403766 {
37413767 Label ok;
37423768 __ 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);
37473771 // may have been set by another thread
37483772 __ mov_metadata (tmp, exact_klass->constant_encoding ());
37493773 __ xorptr (tmp, mdo_addr);
@@ -3759,20 +3783,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37593783#endif
37603784 // first time here. Set profile type.
37613785 __ movptr (mdo_addr, tmp);
3786+ #ifdef ASSERT
3787+ __ andptr (tmp, TypeEntries::type_klass_mask);
3788+ __ verify_klass_ptr (tmp);
3789+ #endif
37623790 } else {
37633791 assert (ciTypeEntries::valid_ciklass (current_klass) != nullptr &&
37643792 ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " inconsistent" );
37653793
3766- __ movptr (tmp, mdo_addr);
3767- __ testptr (tmp, TypeEntries::type_unknown);
3794+ __ testptr (mdo_addr, TypeEntries::type_unknown);
37683795 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
37693796
37703797 __ orptr (mdo_addr, TypeEntries::type_unknown);
37713798 }
37723799 }
3773-
3774- __ bind (next);
37753800 }
3801+ __ bind (next);
37763802}
37773803
37783804void LIR_Assembler::emit_delay (LIR_OpDelay*) {
0 commit comments