3770
3771 assert(labels.is_nonempty(), "must be");
3772 assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt()));
3773
3774 // Since MachConstantNode::constant_offset() also contains
3775 // table_base_offset() we need to subtract the table_base_offset()
3776 // to get the plain offset into the constant table.
3777 int offset = n->constant_offset() - table_base_offset();
3778
3779 MacroAssembler _masm(&cb);
3780 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
3781
3782 for (uint i = 0; i < n->outcnt(); i++) {
3783 address* constant_addr = &jump_table_base[i];
3784 assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i)));
3785 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
3786 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
3787 }
3788 }
3789
3790 // The message about the current inlining is accumulated in
3791 // _print_inlining_stream and transfered into the _print_inlining_list
3792 // once we know whether inlining succeeds or not. For regular
3793 // inlining, messages are appended to the buffer pointed by
3794 // _print_inlining_idx in the _print_inlining_list. For late inlining,
3795 // a new buffer is added after _print_inlining_idx in the list. This
3796 // way we can update the inlining message for late inlining call site
3797 // when the inlining is attempted again.
3798 void Compile::print_inlining_init() {
3799 if (print_inlining() || print_intrinsics()) {
3800 _print_inlining_stream = new stringStream();
3801 _print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
3802 }
3803 }
3804
3805 void Compile::print_inlining_reinit() {
3806 if (print_inlining() || print_intrinsics()) {
3807 // Re allocate buffer when we change ResourceMark
3808 _print_inlining_stream = new stringStream();
3809 }
|
3770
3771 assert(labels.is_nonempty(), "must be");
3772 assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt()));
3773
3774 // Since MachConstantNode::constant_offset() also contains
3775 // table_base_offset() we need to subtract the table_base_offset()
3776 // to get the plain offset into the constant table.
3777 int offset = n->constant_offset() - table_base_offset();
3778
3779 MacroAssembler _masm(&cb);
3780 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
3781
3782 for (uint i = 0; i < n->outcnt(); i++) {
3783 address* constant_addr = &jump_table_base[i];
3784 assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i)));
3785 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
3786 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
3787 }
3788 }
3789
3790 //----------------------------static_subtype_check-----------------------------
3791 // Shortcut important common cases when superklass is exact:
3792 // (0) superklass is java.lang.Object (can occur in reflective code)
3793 // (1) subklass is already limited to a subtype of superklass => always ok
3794 // (2) subklass does not overlap with superklass => always fail
3795 // (3) superklass has NO subtypes and we can check with a simple compare.
3796 int Compile::static_subtype_check(ciKlass* superk, ciKlass* subk) {
3797 if (StressReflectiveCode) {
3798 return SSC_full_test; // Let caller generate the general case.
3799 }
3800
3801 if (superk == env()->Object_klass()) {
3802 return SSC_always_true; // (0) this test cannot fail
3803 }
3804
3805 ciType* superelem = superk;
3806 if (superelem->is_array_klass())
3807 superelem = superelem->as_array_klass()->base_element_type();
3808
3809 if (!subk->is_interface()) { // cannot trust static interface types yet
3810 if (subk->is_subtype_of(superk)) {
3811 return SSC_always_true; // (1) false path dead; no dynamic test needed
3812 }
3813 if (!(superelem->is_klass() && superelem->as_klass()->is_interface()) &&
3814 !superk->is_subtype_of(subk)) {
3815 return SSC_always_false;
3816 }
3817 }
3818
3819 // If casting to an instance klass, it must have no subtypes
3820 if (superk->is_interface()) {
3821 // Cannot trust interfaces yet.
3822 // %%% S.B. superk->nof_implementors() == 1
3823 } else if (superelem->is_instance_klass()) {
3824 ciInstanceKlass* ik = superelem->as_instance_klass();
3825 if (!ik->has_subklass() && !ik->is_interface()) {
3826 if (!ik->is_final()) {
3827 // Add a dependency if there is a chance of a later subclass.
3828 dependencies()->assert_leaf_type(ik);
3829 }
3830 return SSC_easy_test; // (3) caller can do a simple ptr comparison
3831 }
3832 } else {
3833 // A primitive array type has no subtypes.
3834 return SSC_easy_test; // (3) caller can do a simple ptr comparison
3835 }
3836
3837 return SSC_full_test;
3838 }
3839
3840 // The message about the current inlining is accumulated in
3841 // _print_inlining_stream and transfered into the _print_inlining_list
3842 // once we know whether inlining succeeds or not. For regular
3843 // inlining, messages are appended to the buffer pointed by
3844 // _print_inlining_idx in the _print_inlining_list. For late inlining,
3845 // a new buffer is added after _print_inlining_idx in the list. This
3846 // way we can update the inlining message for late inlining call site
3847 // when the inlining is attempted again.
3848 void Compile::print_inlining_init() {
3849 if (print_inlining() || print_intrinsics()) {
3850 _print_inlining_stream = new stringStream();
3851 _print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
3852 }
3853 }
3854
3855 void Compile::print_inlining_reinit() {
3856 if (print_inlining() || print_intrinsics()) {
3857 // Re allocate buffer when we change ResourceMark
3858 _print_inlining_stream = new stringStream();
3859 }
|