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 |