hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
changeset 20702 bbe0fcde6e13
parent 20022 e6e3f5ff6d73
child 21088 4f0ada6dcace
equal deleted inserted replaced
20701:ef9996662fd5 20702:bbe0fcde6e13
  3630     // Static call
  3630     // Static call
  3631     __ addptr(counter_addr, DataLayout::counter_increment);
  3631     __ addptr(counter_addr, DataLayout::counter_increment);
  3632   }
  3632   }
  3633 }
  3633 }
  3634 
  3634 
       
  3635 void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
       
  3636   Register obj = op->obj()->as_register();
       
  3637   Register tmp = op->tmp()->as_pointer_register();
       
  3638   Address mdo_addr = as_Address(op->mdp()->as_address_ptr());
       
  3639   ciKlass* exact_klass = op->exact_klass();
       
  3640   intptr_t current_klass = op->current_klass();
       
  3641   bool not_null = op->not_null();
       
  3642   bool no_conflict = op->no_conflict();
       
  3643 
       
  3644   Label update, next, none;
       
  3645 
       
  3646   bool do_null = !not_null;
       
  3647   bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass;
       
  3648   bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set;
       
  3649 
       
  3650   assert(do_null || do_update, "why are we here?");
       
  3651   assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?");
       
  3652 
       
  3653   __ verify_oop(obj);
       
  3654 
       
  3655   if (tmp != obj) {
       
  3656     __ mov(tmp, obj);
       
  3657   }
       
  3658   if (do_null) {
       
  3659     __ testptr(tmp, tmp);
       
  3660     __ jccb(Assembler::notZero, update);
       
  3661     if (!TypeEntries::was_null_seen(current_klass)) {
       
  3662       __ orptr(mdo_addr, TypeEntries::null_seen);
       
  3663     }
       
  3664     if (do_update) {
       
  3665 #ifndef ASSERT
       
  3666       __ jmpb(next);
       
  3667     }
       
  3668 #else
       
  3669       __ jmp(next);
       
  3670     }
       
  3671   } else {
       
  3672     __ testptr(tmp, tmp);
       
  3673     __ jccb(Assembler::notZero, update);
       
  3674     __ stop("unexpect null obj");
       
  3675 #endif
       
  3676   }
       
  3677 
       
  3678   __ bind(update);
       
  3679 
       
  3680   if (do_update) {
       
  3681 #ifdef ASSERT
       
  3682     if (exact_klass != NULL) {
       
  3683       Label ok;
       
  3684       __ load_klass(tmp, tmp);
       
  3685       __ push(tmp);
       
  3686       __ mov_metadata(tmp, exact_klass->constant_encoding());
       
  3687       __ cmpptr(tmp, Address(rsp, 0));
       
  3688       __ jccb(Assembler::equal, ok);
       
  3689       __ stop("exact klass and actual klass differ");
       
  3690       __ bind(ok);
       
  3691       __ pop(tmp);
       
  3692     }
       
  3693 #endif
       
  3694     if (!no_conflict) {
       
  3695       if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
       
  3696         if (exact_klass != NULL) {
       
  3697           __ mov_metadata(tmp, exact_klass->constant_encoding());
       
  3698         } else {
       
  3699           __ load_klass(tmp, tmp);
       
  3700         }
       
  3701 
       
  3702         __ xorptr(tmp, mdo_addr);
       
  3703         __ testptr(tmp, TypeEntries::type_klass_mask);
       
  3704         // klass seen before, nothing to do. The unknown bit may have been
       
  3705         // set already but no need to check.
       
  3706         __ jccb(Assembler::zero, next);
       
  3707 
       
  3708         __ testptr(tmp, TypeEntries::type_unknown);
       
  3709         __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
       
  3710 
       
  3711         if (TypeEntries::is_type_none(current_klass)) {
       
  3712           __ cmpptr(mdo_addr, 0);
       
  3713           __ jccb(Assembler::equal, none);
       
  3714           __ cmpptr(mdo_addr, TypeEntries::null_seen);
       
  3715           __ jccb(Assembler::equal, none);
       
  3716           // There is a chance that the checks above (re-reading profiling
       
  3717           // data from memory) fail if another thread has just set the
       
  3718           // profiling to this obj's klass
       
  3719           __ xorptr(tmp, mdo_addr);
       
  3720           __ testptr(tmp, TypeEntries::type_klass_mask);
       
  3721           __ jccb(Assembler::zero, next);
       
  3722         }
       
  3723       } else {
       
  3724         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
       
  3725                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
       
  3726 
       
  3727         __ movptr(tmp, mdo_addr);
       
  3728         __ testptr(tmp, TypeEntries::type_unknown);
       
  3729         __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
       
  3730       }
       
  3731 
       
  3732       // different than before. Cannot keep accurate profile.
       
  3733       __ orptr(mdo_addr, TypeEntries::type_unknown);
       
  3734 
       
  3735       if (TypeEntries::is_type_none(current_klass)) {
       
  3736         __ jmpb(next);
       
  3737 
       
  3738         __ bind(none);
       
  3739         // first time here. Set profile type.
       
  3740         __ movptr(mdo_addr, tmp);
       
  3741       }
       
  3742     } else {
       
  3743       // There's a single possible klass at this profile point
       
  3744       assert(exact_klass != NULL, "should be");
       
  3745       if (TypeEntries::is_type_none(current_klass)) {
       
  3746         __ mov_metadata(tmp, exact_klass->constant_encoding());
       
  3747         __ xorptr(tmp, mdo_addr);
       
  3748         __ testptr(tmp, TypeEntries::type_klass_mask);
       
  3749 #ifdef ASSERT
       
  3750         __ jcc(Assembler::zero, next);
       
  3751 
       
  3752         {
       
  3753           Label ok;
       
  3754           __ push(tmp);
       
  3755           __ cmpptr(mdo_addr, 0);
       
  3756           __ jcc(Assembler::equal, ok);
       
  3757           __ cmpptr(mdo_addr, TypeEntries::null_seen);
       
  3758           __ jcc(Assembler::equal, ok);
       
  3759           // may have been set by another thread
       
  3760           __ mov_metadata(tmp, exact_klass->constant_encoding());
       
  3761           __ xorptr(tmp, mdo_addr);
       
  3762           __ testptr(tmp, TypeEntries::type_mask);
       
  3763           __ jcc(Assembler::zero, ok);
       
  3764 
       
  3765           __ stop("unexpected profiling mismatch");
       
  3766           __ bind(ok);
       
  3767           __ pop(tmp);
       
  3768         }
       
  3769 #else
       
  3770         __ jccb(Assembler::zero, next);
       
  3771 #endif
       
  3772         // first time here. Set profile type.
       
  3773         __ movptr(mdo_addr, tmp);
       
  3774       } else {
       
  3775         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
       
  3776                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
       
  3777 
       
  3778         __ movptr(tmp, mdo_addr);
       
  3779         __ testptr(tmp, TypeEntries::type_unknown);
       
  3780         __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
       
  3781 
       
  3782         __ orptr(mdo_addr, TypeEntries::type_unknown);
       
  3783       }
       
  3784     }
       
  3785 
       
  3786     __ bind(next);
       
  3787   }
       
  3788 }
       
  3789 
  3635 void LIR_Assembler::emit_delay(LIR_OpDelay*) {
  3790 void LIR_Assembler::emit_delay(LIR_OpDelay*) {
  3636   Unimplemented();
  3791   Unimplemented();
  3637 }
  3792 }
  3638 
  3793 
  3639 
  3794