annotate src/share/vm/opto/doCall.cpp @ 9126:bc26f978b0ce

HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly don't use the (wrong) cached value, but ask the runtime on each request. Fixes regression on xml.* benchmarks @ specjvm2008. The problem was: After the constructor of Object was deoptimized due to an assumption violation, it was recompiled again after some time. However, on recompilation, the value of hasFinalizeSubclass for the class was not updated and it was compiled again with a, now wrong, assumption, which then triggers deoptimization again. This was repeated until it hit the recompilation limit (defined by PerMethodRecompilationCutoff), and therefore only executed by the interpreter from now on, causing the performance regression.
author Bernhard Urban <bernhard.urban@jku.at>
date Mon, 15 Apr 2013 19:54:58 +0200
parents f1de9dbc914e
children 6f3fd5150b67
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1344
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1344
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1344
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
26 #include "ci/ciCallSite.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
27 #include "ci/ciMethodHandle.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
28 #include "classfile/vmSymbols.hpp"
2405
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 1972
diff changeset
29 #include "compiler/compileBroker.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
30 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
31 #include "interpreter/linkResolver.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
32 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
33 #include "opto/callGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
34 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
35 #include "opto/mulnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
36 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
37 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
38 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
39 #include "opto/subnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
40 #include "prims/nativeLookup.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1823
diff changeset
41 #include "runtime/sharedRuntime.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
43 void trace_type_profile(Compile* C, ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
6793
9d89c76b0505 7198499: TraceTypeProfile as diagnostic option
twisti
parents: 6725
diff changeset
44 if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
45 outputStream* out = tty;
2405
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 1972
diff changeset
46 if (!PrintInlining) {
6793
9d89c76b0505 7198499: TraceTypeProfile as diagnostic option
twisti
parents: 6725
diff changeset
47 if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
2405
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 1972
diff changeset
48 method->print_short_name();
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 1972
diff changeset
49 tty->cr();
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 1972
diff changeset
50 }
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 1972
diff changeset
51 CompileTask::print_inlining(prof_method, depth, bci);
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
52 } else {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
53 out = C->print_inlining_stream();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
54 }
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
55 CompileTask::print_inline_indent(depth, out);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
56 out->print(" \\-> TypeProfile (%d/%d counts) = ", receiver_count, site_count);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
57 stringStream ss;
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
58 prof_klass->name()->print_symbol_on(&ss);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
59 out->print(ss.as_string());
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
60 out->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
64 CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_does_dispatch,
1157
c3b315a0d58a 6912063: inlining parameters need to be adjusted for some uses of the JVM
jrose
parents: 1138
diff changeset
65 JVMState* jvms, bool allow_inline,
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
66 float prof_factor, bool allow_intrinsics, bool delayed_forbidden) {
3371
fabcf26ee72f 6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents: 3366
diff changeset
67 ciMethod* caller = jvms->method();
fabcf26ee72f 6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents: 3366
diff changeset
68 int bci = jvms->bci();
fabcf26ee72f 6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents: 3366
diff changeset
69 Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
70 guarantee(callee != NULL, "failed method resolution");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Dtrace currently doesn't work unless all calls are vanilla
780
c96bf21b756f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 726
diff changeset
73 if (env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
74 allow_inline = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // Note: When we get profiling during stage-1 compiles, we want to pull
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // from more specific profile data which pertains to this inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Right now, ignore the information in jvms->caller(), and do method[bci].
3371
fabcf26ee72f 6998541: JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
twisti
parents: 3366
diff changeset
80 ciCallProfile profile = caller->call_profile_at_bci(bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // See how many times this site has been invoked.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 int site_count = profile.count();
a61af66fc99e Initial load
duke
parents:
diff changeset
84 int receiver_count = -1;
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
85 if (call_does_dispatch && UseTypeProfile && profile.has_receiver(0)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // Receivers in the profile structure are ordered by call counts
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // so that the most called (major) receiver is profile.receiver(0).
a61af66fc99e Initial load
duke
parents:
diff changeset
88 receiver_count = profile.receiver_count(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 CompileLog* log = this->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
93 int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1206
diff changeset
94 int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
95 log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
96 log->identify(callee), site_count, prof_factor);
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
97 if (call_does_dispatch) log->print(" virtual='1'");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (allow_inline) log->print(" inline='1'");
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (receiver_count >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 if (profile.has_receiver(1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 log->end_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Special case the handling of certain common, profitable library
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // methods. If these methods are replaced with specialized code,
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // then we return it as the inlined version of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // We do this before the strict f.p. check below because the
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // intrinsics handle strict f.p. correctly.
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4117
diff changeset
113 if (allow_inline && allow_intrinsics) {
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
114 CallGenerator* cg = find_intrinsic(callee, call_does_dispatch);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
115 if (cg != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
116 if (cg->is_predicted()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
117 // Code without intrinsic but, hopefully, inlined.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
118 CallGenerator* inline_cg = this->call_generator(callee,
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
119 vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, false);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
120 if (inline_cg != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
121 cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
122 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
123 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
124 return cg;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
125 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3784
diff changeset
128 // Do method handle calls.
1823
8aa5fd5d2046 6987634: JSR 292 assert(start_bci() >= 0 && start_bci() < code_size()) failed: correct osr_bci argument
twisti
parents: 1645
diff changeset
129 // NOTE: This must happen before normal inlining logic below since
8aa5fd5d2046 6987634: JSR 292 assert(start_bci() >= 0 && start_bci() < code_size()) failed: correct osr_bci argument
twisti
parents: 1645
diff changeset
130 // MethodHandle.invoke* are native methods which obviously don't
8aa5fd5d2046 6987634: JSR 292 assert(start_bci() >= 0 && start_bci() < code_size()) failed: correct osr_bci argument
twisti
parents: 1645
diff changeset
131 // have bytecodes and so normal inlining fails.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
132 if (callee->is_method_handle_intrinsic()) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
133 CallGenerator* cg = CallGenerator::for_method_handle_call(jvms, caller, callee, delayed_forbidden);
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
134 assert(cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator");
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
135 return cg;
1823
8aa5fd5d2046 6987634: JSR 292 assert(start_bci() >= 0 && start_bci() < code_size()) failed: correct osr_bci argument
twisti
parents: 1645
diff changeset
136 }
8aa5fd5d2046 6987634: JSR 292 assert(start_bci() >= 0 && start_bci() < code_size()) failed: correct osr_bci argument
twisti
parents: 1645
diff changeset
137
0
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // Do not inline strict fp into non-strict code, or the reverse
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
139 if (caller->is_strict() ^ callee->is_strict()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
140 allow_inline = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Attempt to inline...
a61af66fc99e Initial load
duke
parents:
diff changeset
144 if (allow_inline) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // The profile data is only partly attributable to this caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // scale back the call site information.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 float past_uses = jvms->method()->scale_count(site_count, prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // This is the number of times we expect the call code to be used.
a61af66fc99e Initial load
duke
parents:
diff changeset
149 float expected_uses = past_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Try inlining a bytecoded method:
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
152 if (!call_does_dispatch) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
153 InlineTree* ilt;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 if (UseOldInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
156 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Make a disembodied, stateless ILT.
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // TO DO: When UseOldInlining is removed, copy the ILT code elsewhere.
a61af66fc99e Initial load
duke
parents:
diff changeset
159 float site_invoke_ratio = prof_factor;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // Note: ilt is for the root of this parse, not the present call site.
3784
aabf25fa3f05 7057587: JSR 292 - crash with jruby in test/test_respond_to.rb
never
parents: 3752
diff changeset
161 ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio, MaxInlineLevel);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163 WarmCallInfo scratch_ci;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if (!UseOldInlining)
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
165 scratch_ci.init(jvms, callee, profile, prof_factor);
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
166 bool should_delay = false;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
167 WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci, should_delay);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
168 assert(ci != &scratch_ci, "do not let this pointer escape");
a61af66fc99e Initial load
duke
parents:
diff changeset
169 bool allow_inline = (ci != NULL && !ci->is_cold());
a61af66fc99e Initial load
duke
parents:
diff changeset
170 bool require_inline = (allow_inline && ci->is_hot());
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if (allow_inline) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
173 CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses);
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
174
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
175 if (require_inline && cg != NULL) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
176 // Delay the inlining of this method to give us the
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
177 // opportunity to perform some high level optimizations
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
178 // first.
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
179 if (should_delay_inlining(callee, jvms)) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
180 assert(!delayed_forbidden, "strange");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
181 return CallGenerator::for_string_late_inline(callee, cg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
182 } else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
183 return CallGenerator::for_late_inline(callee, cg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
184 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
185 }
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
186 if (cg == NULL || should_delay) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // Fall through.
a61af66fc99e Initial load
duke
parents:
diff changeset
188 } else if (require_inline || !InlineWarmCalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 return cg;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 } else {
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
191 CallGenerator* cold_cg = call_generator(callee, vtable_index, call_does_dispatch, jvms, false, prof_factor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
192 return CallGenerator::for_warm_call(ci, cold_cg, cg);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // Try using the type profile.
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
198 if (call_does_dispatch && site_count > 0 && receiver_count > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 ciMethod* receiver_method = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if (have_major_receiver || profile.morphism() == 1 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
203 (profile.morphism() == 2 && UseBimorphicInlining)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // receiver_method = profile.method();
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Profiles do not suggest methods now. Look it up in the major receiver.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
206 receiver_method = callee->resolve_invoke(jvms->method()->holder(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
207 profile.receiver(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (receiver_method != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // The single majority receiver sufficiently outweighs the minority.
a61af66fc99e Initial load
duke
parents:
diff changeset
211 CallGenerator* hit_cg = this->call_generator(receiver_method,
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
212 vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213 if (hit_cg != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Look up second receiver.
a61af66fc99e Initial load
duke
parents:
diff changeset
215 CallGenerator* next_hit_cg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 ciMethod* next_receiver_method = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (profile.morphism() == 2 && UseBimorphicInlining) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
218 next_receiver_method = callee->resolve_invoke(jvms->method()->holder(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
219 profile.receiver(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
220 if (next_receiver_method != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 next_hit_cg = this->call_generator(next_receiver_method,
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
222 vtable_index, !call_does_dispatch, jvms,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
223 allow_inline, prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if (next_hit_cg != NULL && !next_hit_cg->is_inline() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
225 have_major_receiver && UseOnlyInlinedBimorphic) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Skip if we can't inline second receiver's method
a61af66fc99e Initial load
duke
parents:
diff changeset
227 next_hit_cg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 CallGenerator* miss_cg;
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1157
diff changeset
232 Deoptimization::DeoptReason reason = (profile.morphism() == 2) ?
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1157
diff changeset
233 Deoptimization::Reason_bimorphic :
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1157
diff changeset
234 Deoptimization::Reason_class_check;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235 if (( profile.morphism() == 1 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
236 (profile.morphism() == 2 && next_hit_cg != NULL) ) &&
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1157
diff changeset
237 !too_many_traps(jvms->method(), jvms->bci(), reason)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
238 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // Generate uncommon trap for class check failure path
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // in case of monomorphic or bimorphic virtual call site.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
241 miss_cg = CallGenerator::for_uncommon_trap(callee, reason,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
242 Deoptimization::Action_maybe_recompile);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // Generate virtual call for class check failure path
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // in case of polymorphic virtual call site.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
246 miss_cg = CallGenerator::for_virtual_call(callee, vtable_index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (miss_cg != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 if (next_hit_cg != NULL) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
250 trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // We don't need to record dependency on a receiver here and below.
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Whenever we inline, the dependency is added by Parse::Parse().
a61af66fc99e Initial load
duke
parents:
diff changeset
253 miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if (miss_cg != NULL) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
256 trace_type_profile(C, jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count);
4117
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 3901
diff changeset
257 CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
258 if (cg != NULL) return cg;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // There was no special inlining tactic, or it bailed out.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Use a more generic tactic, like a simple call.
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
268 if (call_does_dispatch) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
269 return CallGenerator::for_virtual_call(callee, vtable_index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // Class Hierarchy Analysis or Type Profile reveals a unique target,
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // or it is a static or special call.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
273 return CallGenerator::for_direct_call(callee, should_delay_inlining(callee, jvms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
277 // Return true for methods that shouldn't be inlined early so that
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
278 // they are easier to analyze and optimize as intrinsics.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
279 bool Compile::should_delay_inlining(ciMethod* call_method, JVMState* jvms) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
280 if (has_stringbuilder()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
281
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
282 if ((call_method->holder() == C->env()->StringBuilder_klass() ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
283 call_method->holder() == C->env()->StringBuffer_klass()) &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
284 (jvms->method()->holder() == C->env()->StringBuilder_klass() ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
285 jvms->method()->holder() == C->env()->StringBuffer_klass())) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
286 // Delay SB calls only when called from non-SB code
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
287 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
288 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
289
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
290 switch (call_method->intrinsic_id()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
291 case vmIntrinsics::_StringBuilder_void:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
292 case vmIntrinsics::_StringBuilder_int:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
293 case vmIntrinsics::_StringBuilder_String:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
294 case vmIntrinsics::_StringBuilder_append_char:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
295 case vmIntrinsics::_StringBuilder_append_int:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
296 case vmIntrinsics::_StringBuilder_append_String:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
297 case vmIntrinsics::_StringBuilder_toString:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
298 case vmIntrinsics::_StringBuffer_void:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
299 case vmIntrinsics::_StringBuffer_int:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
300 case vmIntrinsics::_StringBuffer_String:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
301 case vmIntrinsics::_StringBuffer_append_char:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
302 case vmIntrinsics::_StringBuffer_append_int:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
303 case vmIntrinsics::_StringBuffer_append_String:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
304 case vmIntrinsics::_StringBuffer_toString:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
305 case vmIntrinsics::_Integer_toString:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
306 return true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
307
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
308 case vmIntrinsics::_String_String:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
309 {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
310 Node* receiver = jvms->map()->in(jvms->argoff() + 1);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
311 if (receiver->is_Proj() && receiver->in(0)->is_CallStaticJava()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
312 CallStaticJavaNode* csj = receiver->in(0)->as_CallStaticJava();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
313 ciMethod* m = csj->method();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
314 if (m != NULL &&
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
315 (m->intrinsic_id() == vmIntrinsics::_StringBuffer_toString ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
316 m->intrinsic_id() == vmIntrinsics::_StringBuilder_toString))
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
317 // Delay String.<init>(new SB())
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
318 return true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
319 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
320 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
321 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
322
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
323 default:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
324 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
325 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
326 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
327 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
328 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 844
diff changeset
329
0
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // uncommon-trap call-sites where callee is unloaded, uninitialized or will not link
a61af66fc99e Initial load
duke
parents:
diff changeset
332 bool Parse::can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass* klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Additional inputs to consider...
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // bc = bc()
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // caller = method()
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // iter().get_method_holder_index()
a61af66fc99e Initial load
duke
parents:
diff changeset
337 assert( dest_method->is_loaded(), "ciTypeFlow should not let us get here" );
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Interface classes can be loaded & linked and never get around to
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // being initialized. Uncommon-trap for not-initialized static or
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // v-calls. Let interface calls happen.
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1135
diff changeset
341 ciInstanceKlass* holder_klass = dest_method->holder();
1645
3941674cc7fa 6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents: 1552
diff changeset
342 if (!holder_klass->is_being_initialized() &&
3941674cc7fa 6958668: repeated uncommon trapping for new of klass which is being initialized
never
parents: 1552
diff changeset
343 !holder_klass->is_initialized() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
344 !holder_klass->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 uncommon_trap(Deoptimization::Reason_uninitialized,
a61af66fc99e Initial load
duke
parents:
diff changeset
346 Deoptimization::Action_reinterpret,
a61af66fc99e Initial load
duke
parents:
diff changeset
347 holder_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350
6973
bb33c6fdcf0d 8001077: remove ciMethod::will_link
bharadwaj
parents: 6894
diff changeset
351 assert(dest_method->is_loaded(), "dest_method: typeflow responsibility");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
352 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 //------------------------------do_call----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // Handle your basic call. Inline if we can & want to, else just setup call.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 void Parse::do_call() {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // It's likely we are going to add debug info soon.
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // Also, if we inline a guy who eventually needs debug info for this JVMS,
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // our contribution to it is cleaned up right here.
a61af66fc99e Initial load
duke
parents:
diff changeset
362 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // Set frequently used booleans
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
365 const bool is_virtual = bc() == Bytecodes::_invokevirtual;
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
366 const bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6973
diff changeset
367 const bool has_receiver = Bytecodes::has_receiver(bc());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // Find target being called
a61af66fc99e Initial load
duke
parents:
diff changeset
370 bool will_link;
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
371 ciSignature* declared_signature = NULL;
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
372 ciMethod* orig_callee = iter().get_method(will_link, &declared_signature); // callee in the bytecode
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
373 ciInstanceKlass* holder_klass = orig_callee->holder();
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
374 ciKlass* holder = iter().get_declared_method_holder();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375 ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
376 assert(declared_signature != NULL, "cannot be null");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // uncommon-trap when callee is unloaded, uninitialized or will not link
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // bailout when too many arguments for register representation
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
380 if (!will_link || can_not_compile_call_site(orig_callee, klass)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
381 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
382 if (PrintOpto && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 method()->print_name(); tty->print_cr(" can not compile call at bci %d to:", bci());
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
384 orig_callee->print_name(); tty->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
387 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 assert(holder_klass->is_loaded(), "");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
390 //assert((bc_callee->is_static() || is_invokedynamic) == !has_receiver , "must match bc"); // XXX invokehandle (cur_bc_raw)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // Note: this takes into account invokeinterface of methods declared in java/lang/Object,
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // which should be invokevirtuals but according to the VM spec may be invokeinterfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
393 assert(holder_klass->is_interface() || holder_klass->super() == NULL || (bc() != Bytecodes::_invokeinterface), "must match bc");
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // Note: In the absence of miranda methods, an abstract class K can perform
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // an invokevirtual directly on an interface method I.m if K implements I.
a61af66fc99e Initial load
duke
parents:
diff changeset
396
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6973
diff changeset
397 // orig_callee is the resolved callee which's signature includes the
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6973
diff changeset
398 // appendix argument.
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
399 const int nargs = orig_callee->arg_size();
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
400 const bool is_signature_polymorphic = MethodHandles::is_signature_polymorphic(orig_callee->intrinsic_id());
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
401
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
402 // Push appendix argument (MethodType, CallSite, etc.), if one.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
403 if (iter().has_appendix()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
404 ciObject* appendix_arg = iter().get_appendix();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
405 const TypeOopPtr* appendix_arg_type = TypeOopPtr::make_from_constant(appendix_arg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
406 Node* appendix_arg_node = _gvn.makecon(appendix_arg_type);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
407 push(appendix_arg_node);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
408 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
409
0
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // ---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // Does Class Hierarchy Analysis reveal only a single target of a v-call?
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // Then we may inline or make a static call, but become dependent on there being only 1 target.
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // Does the call-site type profile reveal only one receiver?
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Then we may introduce a run-time check and inline on the path where it succeeds.
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // The other path may uncommon_trap, check for another receiver, or do a v-call.
a61af66fc99e Initial load
duke
parents:
diff changeset
416
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
417 // Try to get the most accurate receiver type
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
418 ciMethod* callee = orig_callee;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
419 int vtable_index = Method::invalid_vtable_index;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
420 bool call_does_dispatch = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 if (is_virtual_or_interface) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 Node* receiver_node = stack(sp() - nargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
425 // call_does_dispatch and vtable_index are out-parameters. They might be changed.
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
426 callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
427 is_virtual,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
428 call_does_dispatch, vtable_index); // out-parameters
0
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Note: It's OK to try to inline a virtual call.
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // The call generator will not attempt to inline a polymorphic call
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // unless it knows how to optimize the receiver dispatch.
a61af66fc99e Initial load
duke
parents:
diff changeset
434 bool try_inline = (C->do_inlining() || InlineAccessors);
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // ---------------------
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
437 dec_sp(nargs); // Temporarily pop args for JVM state of call
0
a61af66fc99e Initial load
duke
parents:
diff changeset
438 JVMState* jvms = sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // ---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Decide call tactic.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // This call checks with CHA, the interpreter profile, intrinsics table, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // It decides whether inlining is desirable or not.
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
444 CallGenerator* cg = C->call_generator(callee, vtable_index, call_does_dispatch, jvms, try_inline, prof_factor());
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
445
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
446 // NOTE: Don't use orig_callee and callee after this point! Use cg->method() instead.
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
447 orig_callee = callee = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // ---------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Round double arguments before call
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
451 round_double_arguments(cg->method());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
452
a61af66fc99e Initial load
duke
parents:
diff changeset
453 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // bump global counters for calls
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
455 count_compiled_calls(/*at_method_entry*/ false, cg->is_inline());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // Record first part of parsing work for this call
a61af66fc99e Initial load
duke
parents:
diff changeset
458 parse_histogram()->record_change();
a61af66fc99e Initial load
duke
parents:
diff changeset
459 #endif // not PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 assert(jvms == this->jvms(), "still operating on the right JVMS");
a61af66fc99e Initial load
duke
parents:
diff changeset
462 assert(jvms_in_sync(), "jvms must carry full info into CG");
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // save across call, for a subsequent cast_not_null.
a61af66fc99e Initial load
duke
parents:
diff changeset
465 Node* receiver = has_receiver ? argument(0) : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
466
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // Bump method data counters (We profile *before* the call is made
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // because exceptions don't return to the call site.)
a61af66fc99e Initial load
duke
parents:
diff changeset
469 profile_call(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
470
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
471 JVMState* new_jvms = cg->generate(jvms);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
472 if (new_jvms == NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // When inlining attempt fails (e.g., too many arguments),
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // it may contaminate the current compile state, making it
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // impossible to pull back and try again. Once we call
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // cg->generate(), we are committed. If it fails, the whole
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // compilation task is compromised.
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (failing()) return;
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4117
diff changeset
479
0
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // This can happen if a library intrinsic is available, but refuses
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // the call site, perhaps because it did not match a pattern the
5927
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4117
diff changeset
482 // intrinsic was expecting to optimize. Should always be possible to
b40ac3579043 6658428: C2 doesn't inline java method if corresponding intrinsic failed to inline.
never
parents: 4117
diff changeset
483 // get a normal java call that may inline in that case
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
484 cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
485 if ((new_jvms = cg->generate(jvms)) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 guarantee(failing(), "call failed to generate: calls should work");
a61af66fc99e Initial load
duke
parents:
diff changeset
487 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 if (cg->is_inline()) {
67
16e1cb7cde24 6666343: Compile::has_loops not always set correctly
never
parents: 0
diff changeset
492 // Accumulate has_loops estimate
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
493 C->set_has_loops(C->has_loops() || cg->method()->has_loops());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
494 C->env()->notice_inlined_method(cg->method());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // Reset parser state from [new_]jvms, which now carries results of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // Return value (if any) is already pushed on the stack by the cg.
a61af66fc99e Initial load
duke
parents:
diff changeset
499 add_exception_states_from(new_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 if (new_jvms->map()->control() == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 stop_and_kill_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
502 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 assert(new_jvms->same_calls_as(jvms), "method/bci left unchanged");
a61af66fc99e Initial load
duke
parents:
diff changeset
504 set_jvms(new_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 if (!stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // This was some sort of virtual call, which did a null check for us.
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // Now we can assert receiver-not-null, on the normal return path.
a61af66fc99e Initial load
duke
parents:
diff changeset
510 if (receiver != NULL && cg->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
511 Node* cast = cast_not_null(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // %%% assert(receiver == cast, "should already have cast the receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Round double result after a call from strict to non-strict code
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
516 round_double_result(cg->method());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
517
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
518 ciType* rtype = cg->method()->return_type();
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
519 ciType* ctype = declared_signature->return_type();
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
520
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
521 if (Bytecodes::has_optional_appendix(iter().cur_bc_raw()) || is_signature_polymorphic) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
522 // Be careful here with return types.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
523 if (ctype != rtype) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
524 BasicType rt = rtype->basic_type();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
525 BasicType ct = ctype->basic_type();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
526 if (ct == T_VOID) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
527 // It's OK for a method to return a value that is discarded.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
528 // The discarding does not require any special action from the caller.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
529 // The Java code knows this, at VerifyType.isNullConversion.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
530 pop_node(rt); // whatever it was, pop it
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
531 } else if (rt == T_INT || is_subword_type(rt)) {
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
532 // Nothing. These cases are handled in lambda form bytecode.
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
533 assert(ct == T_INT || is_subword_type(ct), err_msg_res("must match: rt=%s, ct=%s", type2name(rt), type2name(ct)));
6270
b72784e722ff 7188276: JSR 292: assert(ct == T_OBJECT) failed: rt=T_OBJECT, ct=13
twisti
parents: 6268
diff changeset
534 } else if (rt == T_OBJECT || rt == T_ARRAY) {
b72784e722ff 7188276: JSR 292: assert(ct == T_OBJECT) failed: rt=T_OBJECT, ct=13
twisti
parents: 6268
diff changeset
535 assert(ct == T_OBJECT || ct == T_ARRAY, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct)));
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
536 if (ctype->is_loaded()) {
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
537 const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
538 const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
539 if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
540 Node* retnode = pop();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
541 Node* cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), retnode, sig_type));
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6270
diff changeset
542 push(cast_obj);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
543 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
544 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
545 } else {
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
546 assert(rt == ct, err_msg_res("unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct)));
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
547 // push a zero; it's better than getting an oop/int mismatch
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
548 pop_node(rt);
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
549 Node* retnode = zerocon(ct);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
550 push_node(ct, retnode);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
551 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
552 // Now that the value is well-behaved, continue with the call-site type.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
553 rtype = ctype;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
554 }
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
555 } else {
7604
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
556 // Symbolic resolution enforces the types to be the same.
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
557 // NOTE: We must relax the assert for unloaded types because two
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
558 // different ciType instances of the same unloaded class type
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
559 // can appear to be "loaded" by different loaders (depending on
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
560 // the accessing class).
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
561 assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype,
f1de9dbc914e 8006109: test/java/util/AbstractSequentialList/AddAll.java fails: assert(rtype == ctype) failed: mismatched return types
twisti
parents: 7478
diff changeset
562 err_msg_res("mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name()));
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
563 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // If the return type of the method is not loaded, assert that the
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // value we got is a null. Otherwise, we need to recompile.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
567 if (!rtype->is_loaded()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
568 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
569 if (PrintOpto && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 method()->print_name(); tty->print_cr(" asserting nullness of result at bci: %d", bci());
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
571 cg->method()->print_name(); tty->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
573 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 C->log()->elem("assert_null reason='return' klass='%d'",
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6086
diff changeset
576 C->log()->identify(rtype));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // If there is going to be a trap, put it at the next bytecode:
a61af66fc99e Initial load
duke
parents:
diff changeset
579 set_bci(iter().next_bci());
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6973
diff changeset
580 null_assert(peek());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
581 set_bci(iter().cur_bci()); // put it back
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Restart record of parsing work after possible inlining of call
a61af66fc99e Initial load
duke
parents:
diff changeset
586 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
587 parse_histogram()->set_initial_state(bc());
a61af66fc99e Initial load
duke
parents:
diff changeset
588 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 //---------------------------catch_call_exceptions-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Put a Catch and CatchProj nodes behind a just-created call.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // Send their caught exceptions to the proper handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // This may be used after a call to the rethrow VM stub,
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // when it is needed to process unloaded exception classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
596 void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Exceptions are delivered through this channel:
a61af66fc99e Initial load
duke
parents:
diff changeset
598 Node* i_o = this->i_o();
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Add a CatchNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
601 GrowableArray<int>* bcis = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 GrowableArray<const Type*>* extypes = new (C->node_arena()) GrowableArray<const Type*>(C->node_arena(), 8, 0, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
603 GrowableArray<int>* saw_unloaded = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 for (; !handlers.is_done(); handlers.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 ciExceptionHandler* h = handlers.handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
607 int h_bci = h->handler_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
608 ciInstanceKlass* h_klass = h->is_catch_all() ? env()->Throwable_klass() : h->catch_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // Do not introduce unloaded exception types into the graph:
a61af66fc99e Initial load
duke
parents:
diff changeset
610 if (!h_klass->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 if (saw_unloaded->contains(h_bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
612 /* We've already seen an unloaded exception with h_bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
613 so don't duplicate. Duplication will cause the CatchNode to be
a61af66fc99e Initial load
duke
parents:
diff changeset
614 unnecessarily large. See 4713716. */
a61af66fc99e Initial load
duke
parents:
diff changeset
615 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
617 saw_unloaded->append(h_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 const Type* h_extype = TypeOopPtr::make_from_klass(h_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // (We use make_from_klass because it respects UseUniqueSubclasses.)
a61af66fc99e Initial load
duke
parents:
diff changeset
622 h_extype = h_extype->join(TypeInstPtr::NOTNULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 assert(!h_extype->empty(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Note: It's OK if the BCIs repeat themselves.
a61af66fc99e Initial load
duke
parents:
diff changeset
625 bcis->append(h_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 extypes->append(h_extype);
a61af66fc99e Initial load
duke
parents:
diff changeset
627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 int len = bcis->length();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
630 CatchNode *cn = new (C) CatchNode(control(), i_o, len+1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
631 Node *catch_ = _gvn.transform(cn);
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // now branch with the exception state to each of the (potential)
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
635 for(int i=0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // Setup JVM state to enter the handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
637 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // Locals are just copied from before the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // Get control from the CatchNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 int handler_bci = bcis->at(i);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
641 Node* ctrl = _gvn.transform( new (C) CatchProjNode(catch_, i+1,handler_bci));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // This handler cannot happen?
a61af66fc99e Initial load
duke
parents:
diff changeset
643 if (ctrl == top()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
644 set_control(ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // Create exception oop
a61af66fc99e Initial load
duke
parents:
diff changeset
647 const TypeInstPtr* extype = extypes->at(i)->is_instptr();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
648 Node *ex_oop = _gvn.transform(new (C) CreateExNode(extypes->at(i), ctrl, i_o));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Handle unloaded exception classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if (saw_unloaded->contains(handler_bci)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // An unloaded exception type is coming here. Do an uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
653 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // We do not expect the same handler bci to take both cold unloaded
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // and hot loaded exceptions. But, watch for it.
6267
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
656 if ((Verbose || WizardMode) && extype->is_loaded()) {
977007096840 7187290: nightly failures after JSR 292 lazy method handle update
twisti
parents: 6266
diff changeset
657 tty->print("Warning: Handler @%d takes mixed loaded/unloaded exceptions in ", bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
658 method()->print_name(); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
659 } else if (PrintOpto && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
660 tty->print("Bailing out on unloaded exception type ");
a61af66fc99e Initial load
duke
parents:
diff changeset
661 extype->klass()->print_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
662 tty->print(" at bci:%d in ", bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
663 method()->print_name(); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // Emit an uncommon trap instead of processing the block.
a61af66fc99e Initial load
duke
parents:
diff changeset
667 set_bci(handler_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
668 push_ex_oop(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
669 uncommon_trap(Deoptimization::Reason_unloaded,
a61af66fc99e Initial load
duke
parents:
diff changeset
670 Deoptimization::Action_reinterpret,
a61af66fc99e Initial load
duke
parents:
diff changeset
671 extype->klass(), "!loaded exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
672 set_bci(iter().cur_bci()); // put it back
a61af66fc99e Initial load
duke
parents:
diff changeset
673 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // go to the exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
677 if (handler_bci < 0) { // merge with corresponding rethrow node
a61af66fc99e Initial load
duke
parents:
diff changeset
678 throw_to_exit(make_exception_state(ex_oop));
a61af66fc99e Initial load
duke
parents:
diff changeset
679 } else { // Else jump to corresponding handle
a61af66fc99e Initial load
duke
parents:
diff changeset
680 push_ex_oop(ex_oop); // Clear stack and push just the oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
681 merge_exception(handler_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // The first CatchProj is for the normal return.
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // (Note: If this is a call to rethrow_Java, this node goes dead.)
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
687 set_control(_gvn.transform( new (C) CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 //----------------------------catch_inline_exceptions--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // Handle all exceptions thrown by an inlined method or individual bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // Common case 1: we have no handler, so all exceptions merge right into
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // the rethrow case.
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // Case 2: we have some handlers, with loaded exception klasses that have
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // no subklasses. We do a Deutsch-Shiffman style type-check on the incoming
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // exception oop and branch to the handler directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // Case 3: We have some handlers with subklasses or are not loaded at
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // compile-time. We have to call the runtime to resolve the exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // So we insert a RethrowCall and all the logic that goes with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
701 void Parse::catch_inline_exceptions(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // Caller is responsible for saving away the map for normal control flow!
a61af66fc99e Initial load
duke
parents:
diff changeset
703 assert(stopped(), "call set_map(NULL) first");
a61af66fc99e Initial load
duke
parents:
diff changeset
704 assert(method()->has_exception_handlers(), "don't come here w/o work to do");
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 Node* ex_node = saved_ex_oop(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
707 if (ex_node == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // No action needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
709 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711 const TypeInstPtr* ex_type = _gvn.type(ex_node)->isa_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
712 NOT_PRODUCT(if (ex_type==NULL) tty->print_cr("*** Exception not InstPtr"));
a61af66fc99e Initial load
duke
parents:
diff changeset
713 if (ex_type == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
714 ex_type = TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // determine potential exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
717 ciExceptionHandlerStream handlers(method(), bci(),
a61af66fc99e Initial load
duke
parents:
diff changeset
718 ex_type->klass()->as_instance_klass(),
a61af66fc99e Initial load
duke
parents:
diff changeset
719 ex_type->klass_is_exact());
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // Start executing from the given throw state. (Keep its stack, for now.)
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // Get the exception oop as known at compile time.
a61af66fc99e Initial load
duke
parents:
diff changeset
723 ex_node = use_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
724
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // Get the exception oop klass from its header
a61af66fc99e Initial load
duke
parents:
diff changeset
726 Node* ex_klass_node = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 if (has_ex_handler() && !ex_type->klass_is_exact()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 Node* p = basic_plus_adr( ex_node, ex_node, oopDesc::klass_offset_in_bytes());
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 67
diff changeset
729 ex_klass_node = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // Compute the exception klass a little more cleverly.
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // Obvious solution is to simple do a LoadKlass from the 'ex_node'.
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // However, if the ex_node is a PhiNode, I'm going to do a LoadKlass for
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // each arm of the Phi. If I know something clever about the exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // I'm loading the class from, I can replace the LoadKlass with the
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // klass constant for the exception oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
737 if( ex_node->is_Phi() ) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
738 ex_klass_node = new (C) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
739 for( uint i = 1; i < ex_node->req(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 67
diff changeset
741 Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
742 ex_klass_node->init_req( i, k );
a61af66fc99e Initial load
duke
parents:
diff changeset
743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
744 _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // Scan the exception table for applicable handlers.
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // If none, we can call rethrow() and be done!
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // If precise (loaded with no subklasses), insert a D.S. style
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // pointer compare to the correct handler and loop back.
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // If imprecise, switch to the Rethrow VM-call style handling.
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 int remaining = handlers.count_remaining();
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // iterate through all entries sequentially
a61af66fc99e Initial load
duke
parents:
diff changeset
758 for (;!handlers.is_done(); handlers.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 ciExceptionHandler* handler = handlers.handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 if (handler->is_rethrow()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // If we fell off the end of the table without finding an imprecise
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // exception klass (and without finding a generic handler) then we
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // know this exception is not handled in this method. We just rethrow
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // the exception into the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
766 throw_to_exit(make_exception_state(ex_node));
a61af66fc99e Initial load
duke
parents:
diff changeset
767 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // exception handler bci range covers throw_bci => investigate further
a61af66fc99e Initial load
duke
parents:
diff changeset
771 int handler_bci = handler->handler_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 if (remaining == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 push_ex_oop(ex_node); // Push exception oop for handler
a61af66fc99e Initial load
duke
parents:
diff changeset
775 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
776 if (PrintOpto && WizardMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
777 tty->print_cr(" Catching every inline exception bci:%d -> handler_bci:%d", bci(), handler_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
780 merge_exception(handler_bci); // jump to handler
a61af66fc99e Initial load
duke
parents:
diff changeset
781 return; // No more handling to be done here!
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
783
1344
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
784 // Get the handler's klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
785 ciInstanceKlass* klass = handler->catch_klass();
1344
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
786
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
787 if (!klass->is_loaded()) { // klass is not loaded?
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
788 // fall through into catch_call_exceptions which will emit a
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
789 // handler with an uncommon trap.
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
790 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 if (klass->is_interface()) // should not happen, but...
a61af66fc99e Initial load
duke
parents:
diff changeset
794 break; // bail out
a61af66fc99e Initial load
duke
parents:
diff changeset
795
1344
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
796 // Check the type of the exception against the catch type
0
a61af66fc99e Initial load
duke
parents:
diff changeset
797 const TypeKlassPtr *tk = TypeKlassPtr::make(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 Node* con = _gvn.makecon(tk);
1344
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
799 Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con);
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
800 if (!stopped()) {
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
801 PreserveJVMState pjvms(this);
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
802 const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr();
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
803 assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness");
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6793
diff changeset
804 Node* ex_oop = _gvn.transform(new (C) CheckCastPPNode(control(), ex_node, tinst));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
805 push_ex_oop(ex_oop); // Push exception oop for handler
a61af66fc99e Initial load
duke
parents:
diff changeset
806 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
807 if (PrintOpto && WizardMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 tty->print(" Catching inline exception bci:%d -> handler_bci:%d -- ", bci(), handler_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
809 klass->print_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
810 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
812 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
813 merge_exception(handler_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }
1344
fdd57634910e 6926979: should simplify catch_inline_exception
never
parents: 1251
diff changeset
815 set_control(not_subtype_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // Come here if exception does not match handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // Carry on with more handler checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
819 --remaining;
a61af66fc99e Initial load
duke
parents:
diff changeset
820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
821
a61af66fc99e Initial load
duke
parents:
diff changeset
822 assert(!stopped(), "you should return if you finish the chain");
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Oops, need to call into the VM to resolve the klasses at runtime.
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // Note: This call must not deoptimize, since it is not a real at this bci!
a61af66fc99e Initial load
duke
parents:
diff changeset
826 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828 make_runtime_call(RC_NO_LEAF | RC_MUST_THROW,
a61af66fc99e Initial load
duke
parents:
diff changeset
829 OptoRuntime::rethrow_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
830 OptoRuntime::rethrow_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
831 NULL, NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
832 ex_node);
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // Rethrow is a pure call, no side effects, only a result.
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // The result cannot be allocated, so we use I_O
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // Catch exceptions from the rethrow
a61af66fc99e Initial load
duke
parents:
diff changeset
838 catch_call_exceptions(handlers);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // (Note: Moved add_debug_info into GraphKit::add_safepoint_edges.)
a61af66fc99e Initial load
duke
parents:
diff changeset
843
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
846 void Parse::count_compiled_calls(bool at_method_entry, bool is_inline) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 if( CountCompiledCalls ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 if( at_method_entry ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
849 // bump invocation counter if top method (for statistics)
a61af66fc99e Initial load
duke
parents:
diff changeset
850 if (CountCompiledCalls && depth() == 1) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
851 const TypePtr* addr_type = TypeMetadataPtr::make(method());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
852 Node* adr1 = makecon(addr_type);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6634
diff changeset
853 Node* adr2 = basic_plus_adr(adr1, adr1, in_bytes(Method::compiled_invocation_counter_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
854 increment_counter(adr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856 } else if (is_inline) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 switch (bc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 case Bytecodes::_invokevirtual: increment_counter(SharedRuntime::nof_inlined_calls_addr()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 case Bytecodes::_invokeinterface: increment_counter(SharedRuntime::nof_inlined_interface_calls_addr()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 case Bytecodes::_invokestatic:
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 367
diff changeset
861 case Bytecodes::_invokedynamic:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
862 case Bytecodes::_invokespecial: increment_counter(SharedRuntime::nof_inlined_static_calls_addr()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
863 default: fatal("unexpected call bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
866 switch (bc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
867 case Bytecodes::_invokevirtual: increment_counter(SharedRuntime::nof_normal_calls_addr()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 case Bytecodes::_invokeinterface: increment_counter(SharedRuntime::nof_interface_calls_addr()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
869 case Bytecodes::_invokestatic:
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 367
diff changeset
870 case Bytecodes::_invokedynamic:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
871 case Bytecodes::_invokespecial: increment_counter(SharedRuntime::nof_static_calls_addr()); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
872 default: fatal("unexpected call bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
877 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
880 ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
881 ciMethod* callee, const TypeOopPtr* receiver_type,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
882 bool is_virtual,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
883 bool& call_does_dispatch, int& vtable_index) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
884 // Set default values for out-parameters.
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
885 call_does_dispatch = true;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
886 vtable_index = Method::invalid_vtable_index;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
887
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
888 // Choose call strategy.
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
889 ciMethod* optimized_virtual_method = optimize_inlining(caller, bci, klass, callee, receiver_type);
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
890
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
891 // Have the call been sufficiently improved such that it is no longer a virtual?
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
892 if (optimized_virtual_method != NULL) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
893 callee = optimized_virtual_method;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
894 call_does_dispatch = false;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
895 } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
896 // We can make a vtable call at this site
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
897 vtable_index = callee->resolve_vtable_index(caller->holder(), klass);
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
898 }
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
899 return callee;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
900 }
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
901
0
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // Identify possible target method and inlining style
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
903 ciMethod* Compile::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
904 ciMethod* callee, const TypeOopPtr* receiver_type) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // only use for virtual or interface calls
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // If it is obviously final, do not bother to call find_monomorphic_target,
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // because the class hierarchy checks are not needed, and may fail due to
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // incompletely loaded classes. Since we do our own class loading checks
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // in this module, we may confidently bind to any method.
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
911 if (callee->can_be_statically_bound()) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
912 return callee;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
914
a61af66fc99e Initial load
duke
parents:
diff changeset
915 // Attempt to improve the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
916 bool actual_receiver_is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
917 ciInstanceKlass* actual_receiver = klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (receiver_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // Array methods are all inherited from Object, and are monomorphic.
a61af66fc99e Initial load
duke
parents:
diff changeset
920 if (receiver_type->isa_aryptr() &&
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
921 callee->holder() == env()->Object_klass()) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
922 return callee;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // All other interesting cases are instance klasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
926 if (!receiver_type->isa_instptr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
927 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
929
a61af66fc99e Initial load
duke
parents:
diff changeset
930 ciInstanceKlass *ikl = receiver_type->klass()->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 if (ikl->is_loaded() && ikl->is_initialized() && !ikl->is_interface() &&
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 196
diff changeset
932 (ikl == actual_receiver || ikl->is_subtype_of(actual_receiver))) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // ikl is a same or better type than the original actual_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // e.g. static receiver from bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
935 actual_receiver = ikl;
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // Is the actual_receiver exact?
a61af66fc99e Initial load
duke
parents:
diff changeset
937 actual_receiver_is_exact = receiver_type->klass_is_exact();
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 ciInstanceKlass* calling_klass = caller->holder();
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
942 ciMethod* cha_monomorphic_target = callee->find_monomorphic_target(calling_klass, klass, actual_receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
943 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 assert(!cha_monomorphic_target->is_abstract(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // Look at the method-receiver type. Does it add "too much information"?
a61af66fc99e Initial load
duke
parents:
diff changeset
946 ciKlass* mr_klass = cha_monomorphic_target->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
947 const Type* mr_type = TypeInstPtr::make(TypePtr::BotPTR, mr_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
948 if (receiver_type == NULL || !receiver_type->higher_equal(mr_type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // Calling this method would include an implicit cast to its holder.
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // %%% Not yet implemented. Would throw minor asserts at present.
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // %%% The most common wins are already gained by +UseUniqueSubclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
952 // To fix, put the higher_equal check at the call of this routine,
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // and add a CheckCastPP to the receiver.
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if (TraceDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
955 tty->print_cr("found unique CHA method, but could not cast up");
a61af66fc99e Initial load
duke
parents:
diff changeset
956 tty->print(" method = ");
a61af66fc99e Initial load
duke
parents:
diff changeset
957 cha_monomorphic_target->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
958 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
960 if (log() != NULL) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
961 log()->elem("missed_CHA_opportunity klass='%d' method='%d'",
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
962 log()->identify(klass),
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
963 log()->identify(cha_monomorphic_target));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965 cha_monomorphic_target = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
968 if (cha_monomorphic_target != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Hardwiring a virtual.
a61af66fc99e Initial load
duke
parents:
diff changeset
970 // If we inlined because CHA revealed only a single target method,
a61af66fc99e Initial load
duke
parents:
diff changeset
971 // then we are dependent on that target method not getting overridden
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // by dynamic class loading. Be sure to test the "static" receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // dest_method here, as opposed to the actual receiver, which may
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // falsely lead us to believe that the receiver is final or private.
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
975 dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
976 return cha_monomorphic_target;
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // If the type is exact, we can still bind the method w/o a vcall.
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // (This case comes after CHA so we can see how much extra work it does.)
a61af66fc99e Initial load
duke
parents:
diff changeset
981 if (actual_receiver_is_exact) {
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // In case of evolution, there is a dependence on every inlined method, since each
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // such method can be changed when its class is redefined.
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
984 ciMethod* exact_method = callee->resolve_invoke(calling_klass, actual_receiver);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
985 if (exact_method != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
986 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
987 if (PrintOpto) {
a61af66fc99e Initial load
duke
parents:
diff changeset
988 tty->print(" Calling method via exact type @%d --- ", bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
989 exact_method->print_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
990 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
993 return exact_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 }