@@ -3629,13 +3629,33 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36293629
36303630 __ verify_oop (obj);
36313631
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
36343645 }
3646+ #endif
36353647 if (do_null) {
3636- __ testptr (tmp, tmp );
3648+ __ testptr (obj, obj );
36373649 __ jccb (Assembler::notZero, update);
36383650 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 ();
36393659 __ orptr (mdo_addr, TypeEntries::null_seen);
36403660 }
36413661 if (do_update) {
@@ -3646,7 +3666,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36463666 __ jmp (next);
36473667 }
36483668 } else {
3649- __ testptr (tmp, tmp );
3669+ __ testptr (obj, obj );
36503670 __ jcc (Assembler::notZero, update);
36513671 __ stop (" unexpected null obj" );
36523672#endif
@@ -3658,7 +3678,7 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36583678#ifdef ASSERT
36593679 if (exact_klass != nullptr ) {
36603680 Label ok;
3661- __ load_klass (tmp, tmp , tmp_load_klass);
3681+ __ load_klass (tmp, obj , tmp_load_klass);
36623682 __ push (tmp);
36633683 __ mov_metadata (tmp, exact_klass->constant_encoding ());
36643684 __ cmpptr (tmp, Address (rsp, 0 ));
@@ -3673,9 +3693,11 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
36733693 if (exact_klass != nullptr ) {
36743694 __ mov_metadata (tmp, exact_klass->constant_encoding ());
36753695 } else {
3676- __ load_klass (tmp, tmp , tmp_load_klass);
3696+ __ load_klass (tmp, obj , tmp_load_klass);
36773697 }
3678-
3698+ #ifdef _LP64
3699+ __ mov (rscratch1, tmp); // save original value before XOR
3700+ #endif
36793701 __ xorptr (tmp, mdo_addr);
36803702 __ testptr (tmp, TypeEntries::type_klass_mask);
36813703 // 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) {
36863708 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
36873709
36883710 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
36933714 // There is a chance that the checks above (re-reading profiling
36943715 // data from memory) fail if another thread has just set the
36953716 // profiling to this obj's klass
3717+ __ mov (tmp, rscratch1); // get back original value before XOR
36963718 __ xorptr (tmp, mdo_addr);
36973719 __ testptr (tmp, TypeEntries::type_klass_mask);
36983720 __ jccb (Assembler::zero, next);
3721+ #endif
36993722 }
37003723 } else {
37013724 assert (ciTypeEntries::valid_ciklass (current_klass) != nullptr &&
37023725 ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " conflict only" );
37033726
3704- __ movptr (tmp, mdo_addr);
3705- __ testptr (tmp, TypeEntries::type_unknown);
3727+ __ testptr (mdo_addr, TypeEntries::type_unknown);
37063728 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
37073729 }
37083730
@@ -3715,6 +3737,10 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37153737 __ bind (none);
37163738 // first time here. Set profile type.
37173739 __ movptr (mdo_addr, tmp);
3740+ #ifdef ASSERT
3741+ __ andptr (tmp, TypeEntries::type_klass_mask);
3742+ __ verify_klass_ptr (tmp);
3743+ #endif
37183744 }
37193745 } else {
37203746 // There's a single possible klass at this profile point
@@ -3729,10 +3755,8 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37293755 {
37303756 Label ok;
37313757 __ 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);
37363760 // may have been set by another thread
37373761 __ mov_metadata (tmp, exact_klass->constant_encoding ());
37383762 __ xorptr (tmp, mdo_addr);
@@ -3748,20 +3772,22 @@ void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
37483772#endif
37493773 // first time here. Set profile type.
37503774 __ movptr (mdo_addr, tmp);
3775+ #ifdef ASSERT
3776+ __ andptr (tmp, TypeEntries::type_klass_mask);
3777+ __ verify_klass_ptr (tmp);
3778+ #endif
37513779 } else {
37523780 assert (ciTypeEntries::valid_ciklass (current_klass) != nullptr &&
37533781 ciTypeEntries::valid_ciklass (current_klass) != exact_klass, " inconsistent" );
37543782
3755- __ movptr (tmp, mdo_addr);
3756- __ testptr (tmp, TypeEntries::type_unknown);
3783+ __ testptr (mdo_addr, TypeEntries::type_unknown);
37573784 __ jccb (Assembler::notZero, next); // already unknown. Nothing to do anymore.
37583785
37593786 __ orptr (mdo_addr, TypeEntries::type_unknown);
37603787 }
37613788 }
3762-
3763- __ bind (next);
37643789 }
3790+ __ bind (next);
37653791}
37663792
37673793void LIR_Assembler::emit_delay (LIR_OpDelay*) {
0 commit comments