comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 12875:d13d7aba8c12

8023657: New type profiling points: arguments to call Summary: x86 interpreter and c1 type profiling for arguments at calls Reviewed-by: kvn, twisti
author roland
date Wed, 09 Oct 2013 16:32:21 +0200
parents da051ce490eb
children 252d541466ea
comparison
equal deleted inserted replaced
12874:46ef27bcacb3 12875:d13d7aba8c12
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