Mercurial > hg > graal-jvmci-8
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 |