Mercurial > hg > truffle
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 |
rev | line source |
---|---|
0 | 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 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/ciCallSite.hpp" | |
27 #include "ci/ciMethodHandle.hpp" | |
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 | 30 #include "compiler/compileLog.hpp" |
31 #include "interpreter/linkResolver.hpp" | |
32 #include "opto/addnode.hpp" | |
33 #include "opto/callGenerator.hpp" | |
34 #include "opto/cfgnode.hpp" | |
35 #include "opto/mulnode.hpp" | |
36 #include "opto/parse.hpp" | |
37 #include "opto/rootnode.hpp" | |
38 #include "opto/runtime.hpp" | |
39 #include "opto/subnode.hpp" | |
40 #include "prims/nativeLookup.hpp" | |
41 #include "runtime/sharedRuntime.hpp" | |
0 | 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 | 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 | 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 | 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 | 61 } |
62 } | |
63 | |
7478 | 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 | 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 | 71 |
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 | 74 allow_inline = false; |
75 } | |
76 | |
77 // Note: When we get profiling during stage-1 compiles, we want to pull | |
78 // from more specific profile data which pertains to this inlining. | |
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 | 81 |
82 // See how many times this site has been invoked. | |
83 int site_count = profile.count(); | |
84 int receiver_count = -1; | |
7478 | 85 if (call_does_dispatch && UseTypeProfile && profile.has_receiver(0)) { |
0 | 86 // Receivers in the profile structure are ordered by call counts |
87 // so that the most called (major) receiver is profile.receiver(0). | |
88 receiver_count = profile.receiver_count(0); | |
89 } | |
90 | |
91 CompileLog* log = this->log(); | |
92 if (log != NULL) { | |
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 | 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 | 97 if (call_does_dispatch) log->print(" virtual='1'"); |
0 | 98 if (allow_inline) log->print(" inline='1'"); |
99 if (receiver_count >= 0) { | |
100 log->print(" receiver='%d' receiver_count='%d'", rid, receiver_count); | |
101 if (profile.has_receiver(1)) { | |
102 log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1)); | |
103 } | |
104 } | |
105 log->end_elem(); | |
106 } | |
107 | |
108 // Special case the handling of certain common, profitable library | |
109 // methods. If these methods are replaced with specialized code, | |
110 // then we return it as the inlined version of the call. | |
111 // We do this before the strict f.p. check below because the | |
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 | 114 CallGenerator* cg = find_intrinsic(callee, call_does_dispatch); |
6894 | 115 if (cg != NULL) { |
116 if (cg->is_predicted()) { | |
117 // Code without intrinsic but, hopefully, inlined. | |
118 CallGenerator* inline_cg = this->call_generator(callee, | |
7478 | 119 vtable_index, call_does_dispatch, jvms, allow_inline, prof_factor, false); |
6894 | 120 if (inline_cg != NULL) { |
121 cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg); | |
122 } | |
123 } | |
124 return cg; | |
125 } | |
0 | 126 } |
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 | 133 CallGenerator* cg = CallGenerator::for_method_handle_call(jvms, caller, callee, delayed_forbidden); |
7478 | 134 assert(cg == NULL || !delayed_forbidden || !cg->is_late_inline() || cg->is_mh_late_inline(), "unexpected CallGenerator"); |
7473 | 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 | 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 | 140 allow_inline = false; |
141 } | |
142 | |
143 // Attempt to inline... | |
144 if (allow_inline) { | |
145 // The profile data is only partly attributable to this caller, | |
146 // scale back the call site information. | |
147 float past_uses = jvms->method()->scale_count(site_count, prof_factor); | |
148 // This is the number of times we expect the call code to be used. | |
149 float expected_uses = past_uses; | |
150 | |
151 // Try inlining a bytecoded method: | |
7478 | 152 if (!call_does_dispatch) { |
0 | 153 InlineTree* ilt; |
154 if (UseOldInlining) { | |
155 ilt = InlineTree::find_subtree_from_root(this->ilt(), jvms->caller(), jvms->method()); | |
156 } else { | |
157 // Make a disembodied, stateless ILT. | |
158 // TO DO: When UseOldInlining is removed, copy the ILT code elsewhere. | |
159 float site_invoke_ratio = prof_factor; | |
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 | 162 } |
163 WarmCallInfo scratch_ci; | |
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 | 166 bool should_delay = false; |
167 WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci, should_delay); | |
0 | 168 assert(ci != &scratch_ci, "do not let this pointer escape"); |
169 bool allow_inline = (ci != NULL && !ci->is_cold()); | |
170 bool require_inline = (allow_inline && ci->is_hot()); | |
171 | |
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 | 174 |
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 | 179 if (should_delay_inlining(callee, jvms)) { |
180 assert(!delayed_forbidden, "strange"); | |
181 return CallGenerator::for_string_late_inline(callee, cg); | |
182 } else if ((should_delay || AlwaysIncrementalInline) && !delayed_forbidden) { | |
183 return CallGenerator::for_late_inline(callee, cg); | |
184 } | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
844
diff
changeset
|
185 } |
7473 | 186 if (cg == NULL || should_delay) { |
0 | 187 // Fall through. |
188 } else if (require_inline || !InlineWarmCalls) { | |
189 return cg; | |
190 } else { | |
7478 | 191 CallGenerator* cold_cg = call_generator(callee, vtable_index, call_does_dispatch, jvms, false, prof_factor); |
0 | 192 return CallGenerator::for_warm_call(ci, cold_cg, cg); |
193 } | |
194 } | |
195 } | |
196 | |
197 // Try using the type profile. | |
7478 | 198 if (call_does_dispatch && site_count > 0 && receiver_count > 0) { |
0 | 199 // The major receiver's count >= TypeProfileMajorReceiverPercent of site_count. |
200 bool have_major_receiver = (100.*profile.receiver_prob(0) >= (float)TypeProfileMajorReceiverPercent); | |
201 ciMethod* receiver_method = NULL; | |
202 if (have_major_receiver || profile.morphism() == 1 || | |
203 (profile.morphism() == 2 && UseBimorphicInlining)) { | |
204 // receiver_method = profile.method(); | |
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 | 207 profile.receiver(0)); |
208 } | |
209 if (receiver_method != NULL) { | |
210 // The single majority receiver sufficiently outweighs the minority. | |
211 CallGenerator* hit_cg = this->call_generator(receiver_method, | |
7478 | 212 vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor); |
0 | 213 if (hit_cg != NULL) { |
214 // Look up second receiver. | |
215 CallGenerator* next_hit_cg = NULL; | |
216 ciMethod* next_receiver_method = NULL; | |
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 | 219 profile.receiver(1)); |
220 if (next_receiver_method != NULL) { | |
221 next_hit_cg = this->call_generator(next_receiver_method, | |
7478 | 222 vtable_index, !call_does_dispatch, jvms, |
0 | 223 allow_inline, prof_factor); |
224 if (next_hit_cg != NULL && !next_hit_cg->is_inline() && | |
225 have_major_receiver && UseOnlyInlinedBimorphic) { | |
226 // Skip if we can't inline second receiver's method | |
227 next_hit_cg = NULL; | |
228 } | |
229 } | |
230 } | |
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 | 235 if (( profile.morphism() == 1 || |
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 | 238 ) { |
239 // Generate uncommon trap for class check failure path | |
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 | 242 Deoptimization::Action_maybe_recompile); |
243 } else { | |
244 // Generate virtual call for class check failure path | |
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 | 247 } |
248 if (miss_cg != NULL) { | |
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 | 251 // We don't need to record dependency on a receiver here and below. |
252 // Whenever we inline, the dependency is added by Parse::Parse(). | |
253 miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX); | |
254 } | |
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 | 258 if (cg != NULL) return cg; |
259 } | |
260 } | |
261 } | |
262 } | |
263 } | |
264 } | |
265 | |
266 // There was no special inlining tactic, or it bailed out. | |
267 // Use a more generic tactic, like a simple call. | |
7478 | 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 | 270 } else { |
271 // Class Hierarchy Analysis or Type Profile reveals a unique target, | |
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 | 274 } |
275 } | |
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 | 330 |
331 // uncommon-trap call-sites where callee is unloaded, uninitialized or will not link | |
332 bool Parse::can_not_compile_call_site(ciMethod *dest_method, ciInstanceKlass* klass) { | |
333 // Additional inputs to consider... | |
334 // bc = bc() | |
335 // caller = method() | |
336 // iter().get_method_holder_index() | |
337 assert( dest_method->is_loaded(), "ciTypeFlow should not let us get here" ); | |
338 // Interface classes can be loaded & linked and never get around to | |
339 // being initialized. Uncommon-trap for not-initialized static or | |
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 | 344 !holder_klass->is_interface()) { |
345 uncommon_trap(Deoptimization::Reason_uninitialized, | |
346 Deoptimization::Action_reinterpret, | |
347 holder_klass); | |
348 return true; | |
349 } | |
350 | |
6973 | 351 assert(dest_method->is_loaded(), "dest_method: typeflow responsibility"); |
0 | 352 return false; |
353 } | |
354 | |
355 | |
356 //------------------------------do_call---------------------------------------- | |
357 // Handle your basic call. Inline if we can & want to, else just setup call. | |
358 void Parse::do_call() { | |
359 // It's likely we are going to add debug info soon. | |
360 // Also, if we inline a guy who eventually needs debug info for this JVMS, | |
361 // our contribution to it is cleaned up right here. | |
362 kill_dead_locals(); | |
363 | |
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 | 368 |
369 // Find target being called | |
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 | 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 | 377 |
378 // uncommon-trap when callee is unloaded, uninitialized or will not link | |
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 | 381 #ifndef PRODUCT |
382 if (PrintOpto && (Verbose || WizardMode)) { | |
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 | 385 } |
386 #endif | |
387 return; | |
388 } | |
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 | 391 // Note: this takes into account invokeinterface of methods declared in java/lang/Object, |
392 // which should be invokevirtuals but according to the VM spec may be invokeinterfaces | |
393 assert(holder_klass->is_interface() || holder_klass->super() == NULL || (bc() != Bytecodes::_invokeinterface), "must match bc"); | |
394 // Note: In the absence of miranda methods, an abstract class K can perform | |
395 // an invokevirtual directly on an interface method I.m if K implements I. | |
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 | 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 | 410 // --------------------- |
411 // Does Class Hierarchy Analysis reveal only a single target of a v-call? | |
412 // Then we may inline or make a static call, but become dependent on there being only 1 target. | |
413 // Does the call-site type profile reveal only one receiver? | |
414 // Then we may introduce a run-time check and inline on the path where it succeeds. | |
415 // The other path may uncommon_trap, check for another receiver, or do a v-call. | |
416 | |
7478 | 417 // Try to get the most accurate receiver type |
418 ciMethod* callee = orig_callee; | |
419 int vtable_index = Method::invalid_vtable_index; | |
420 bool call_does_dispatch = false; | |
0 | 421 |
422 if (is_virtual_or_interface) { | |
423 Node* receiver_node = stack(sp() - nargs); | |
424 const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); | |
7478 | 425 // call_does_dispatch and vtable_index are out-parameters. They might be changed. |
426 callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type, | |
427 is_virtual, | |
428 call_does_dispatch, vtable_index); // out-parameters | |
0 | 429 } |
430 | |
431 // Note: It's OK to try to inline a virtual call. | |
432 // The call generator will not attempt to inline a polymorphic call | |
433 // unless it knows how to optimize the receiver dispatch. | |
434 bool try_inline = (C->do_inlining() || InlineAccessors); | |
435 | |
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 | 438 JVMState* jvms = sync_jvms(); |
439 | |
440 // --------------------- | |
441 // Decide call tactic. | |
442 // This call checks with CHA, the interpreter profile, intrinsics table, etc. | |
443 // It decides whether inlining is desirable or not. | |
7478 | 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 | 448 |
449 // --------------------- | |
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 | 452 |
453 #ifndef PRODUCT | |
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 | 456 |
457 // Record first part of parsing work for this call | |
458 parse_histogram()->record_change(); | |
459 #endif // not PRODUCT | |
460 | |
461 assert(jvms == this->jvms(), "still operating on the right JVMS"); | |
462 assert(jvms_in_sync(), "jvms must carry full info into CG"); | |
463 | |
464 // save across call, for a subsequent cast_not_null. | |
465 Node* receiver = has_receiver ? argument(0) : NULL; | |
466 | |
467 // Bump method data counters (We profile *before* the call is made | |
468 // because exceptions don't return to the call site.) | |
469 profile_call(receiver); | |
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 | 473 // When inlining attempt fails (e.g., too many arguments), |
474 // it may contaminate the current compile state, making it | |
475 // impossible to pull back and try again. Once we call | |
476 // cg->generate(), we are committed. If it fails, the whole | |
477 // compilation task is compromised. | |
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 | 480 // This can happen if a library intrinsic is available, but refuses |
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 | 484 cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false); |
0 | 485 if ((new_jvms = cg->generate(jvms)) == NULL) { |
486 guarantee(failing(), "call failed to generate: calls should work"); | |
487 return; | |
488 } | |
489 } | |
490 | |
491 if (cg->is_inline()) { | |
67 | 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 | 495 } |
496 | |
497 // Reset parser state from [new_]jvms, which now carries results of the call. | |
498 // Return value (if any) is already pushed on the stack by the cg. | |
499 add_exception_states_from(new_jvms); | |
500 if (new_jvms->map()->control() == top()) { | |
501 stop_and_kill_map(); | |
502 } else { | |
503 assert(new_jvms->same_calls_as(jvms), "method/bci left unchanged"); | |
504 set_jvms(new_jvms); | |
505 } | |
506 | |
507 if (!stopped()) { | |
508 // This was some sort of virtual call, which did a null check for us. | |
509 // Now we can assert receiver-not-null, on the normal return path. | |
510 if (receiver != NULL && cg->is_virtual()) { | |
511 Node* cast = cast_not_null(receiver); | |
512 // %%% assert(receiver == cast, "should already have cast the receiver"); | |
513 } | |
514 | |
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 | 519 ciType* ctype = declared_signature->return_type(); |
520 | |
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 | 532 // Nothing. These cases are handled in lambda form bytecode. |
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 | 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 | 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 | 548 pop_node(rt); |
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 | 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 | 564 |
565 // If the return type of the method is not loaded, assert that the | |
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 | 568 #ifndef PRODUCT |
569 if (PrintOpto && (Verbose || WizardMode)) { | |
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 | 572 } |
573 #endif | |
574 if (C->log() != NULL) { | |
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 | 577 } |
578 // If there is going to be a trap, put it at the next bytecode: | |
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 | 581 set_bci(iter().cur_bci()); // put it back |
582 } | |
583 } | |
584 | |
585 // Restart record of parsing work after possible inlining of call | |
586 #ifndef PRODUCT | |
587 parse_histogram()->set_initial_state(bc()); | |
588 #endif | |
589 } | |
590 | |
591 //---------------------------catch_call_exceptions----------------------------- | |
592 // Put a Catch and CatchProj nodes behind a just-created call. | |
593 // Send their caught exceptions to the proper handler. | |
594 // This may be used after a call to the rethrow VM stub, | |
595 // when it is needed to process unloaded exception classes. | |
596 void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) { | |
597 // Exceptions are delivered through this channel: | |
598 Node* i_o = this->i_o(); | |
599 | |
600 // Add a CatchNode. | |
601 GrowableArray<int>* bcis = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, -1); | |
602 GrowableArray<const Type*>* extypes = new (C->node_arena()) GrowableArray<const Type*>(C->node_arena(), 8, 0, NULL); | |
603 GrowableArray<int>* saw_unloaded = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, 0); | |
604 | |
605 for (; !handlers.is_done(); handlers.next()) { | |
606 ciExceptionHandler* h = handlers.handler(); | |
607 int h_bci = h->handler_bci(); | |
608 ciInstanceKlass* h_klass = h->is_catch_all() ? env()->Throwable_klass() : h->catch_klass(); | |
609 // Do not introduce unloaded exception types into the graph: | |
610 if (!h_klass->is_loaded()) { | |
611 if (saw_unloaded->contains(h_bci)) { | |
612 /* We've already seen an unloaded exception with h_bci, | |
613 so don't duplicate. Duplication will cause the CatchNode to be | |
614 unnecessarily large. See 4713716. */ | |
615 continue; | |
616 } else { | |
617 saw_unloaded->append(h_bci); | |
618 } | |
619 } | |
620 const Type* h_extype = TypeOopPtr::make_from_klass(h_klass); | |
621 // (We use make_from_klass because it respects UseUniqueSubclasses.) | |
622 h_extype = h_extype->join(TypeInstPtr::NOTNULL); | |
623 assert(!h_extype->empty(), "sanity"); | |
624 // Note: It's OK if the BCIs repeat themselves. | |
625 bcis->append(h_bci); | |
626 extypes->append(h_extype); | |
627 } | |
628 | |
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 | 631 Node *catch_ = _gvn.transform(cn); |
632 | |
633 // now branch with the exception state to each of the (potential) | |
634 // handlers | |
635 for(int i=0; i < len; i++) { | |
636 // Setup JVM state to enter the handler. | |
637 PreserveJVMState pjvms(this); | |
638 // Locals are just copied from before the call. | |
639 // Get control from the CatchNode. | |
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 | 642 // This handler cannot happen? |
643 if (ctrl == top()) continue; | |
644 set_control(ctrl); | |
645 | |
646 // Create exception oop | |
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 | 649 |
650 // Handle unloaded exception classes. | |
651 if (saw_unloaded->contains(handler_bci)) { | |
652 // An unloaded exception type is coming here. Do an uncommon trap. | |
653 #ifndef PRODUCT | |
654 // We do not expect the same handler bci to take both cold unloaded | |
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 | 658 method()->print_name(); tty->cr(); |
659 } else if (PrintOpto && (Verbose || WizardMode)) { | |
660 tty->print("Bailing out on unloaded exception type "); | |
661 extype->klass()->print_name(); | |
662 tty->print(" at bci:%d in ", bci()); | |
663 method()->print_name(); tty->cr(); | |
664 } | |
665 #endif | |
666 // Emit an uncommon trap instead of processing the block. | |
667 set_bci(handler_bci); | |
668 push_ex_oop(ex_oop); | |
669 uncommon_trap(Deoptimization::Reason_unloaded, | |
670 Deoptimization::Action_reinterpret, | |
671 extype->klass(), "!loaded exception"); | |
672 set_bci(iter().cur_bci()); // put it back | |
673 continue; | |
674 } | |
675 | |
676 // go to the exception handler | |
677 if (handler_bci < 0) { // merge with corresponding rethrow node | |
678 throw_to_exit(make_exception_state(ex_oop)); | |
679 } else { // Else jump to corresponding handle | |
680 push_ex_oop(ex_oop); // Clear stack and push just the oop. | |
681 merge_exception(handler_bci); | |
682 } | |
683 } | |
684 | |
685 // The first CatchProj is for the normal return. | |
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 | 688 } |
689 | |
690 | |
691 //----------------------------catch_inline_exceptions-------------------------- | |
692 // Handle all exceptions thrown by an inlined method or individual bytecode. | |
693 // Common case 1: we have no handler, so all exceptions merge right into | |
694 // the rethrow case. | |
695 // Case 2: we have some handlers, with loaded exception klasses that have | |
696 // no subklasses. We do a Deutsch-Shiffman style type-check on the incoming | |
697 // exception oop and branch to the handler directly. | |
698 // Case 3: We have some handlers with subklasses or are not loaded at | |
699 // compile-time. We have to call the runtime to resolve the exception. | |
700 // So we insert a RethrowCall and all the logic that goes with it. | |
701 void Parse::catch_inline_exceptions(SafePointNode* ex_map) { | |
702 // Caller is responsible for saving away the map for normal control flow! | |
703 assert(stopped(), "call set_map(NULL) first"); | |
704 assert(method()->has_exception_handlers(), "don't come here w/o work to do"); | |
705 | |
706 Node* ex_node = saved_ex_oop(ex_map); | |
707 if (ex_node == top()) { | |
708 // No action needed. | |
709 return; | |
710 } | |
711 const TypeInstPtr* ex_type = _gvn.type(ex_node)->isa_instptr(); | |
712 NOT_PRODUCT(if (ex_type==NULL) tty->print_cr("*** Exception not InstPtr")); | |
713 if (ex_type == NULL) | |
714 ex_type = TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr(); | |
715 | |
716 // determine potential exception handlers | |
717 ciExceptionHandlerStream handlers(method(), bci(), | |
718 ex_type->klass()->as_instance_klass(), | |
719 ex_type->klass_is_exact()); | |
720 | |
721 // Start executing from the given throw state. (Keep its stack, for now.) | |
722 // Get the exception oop as known at compile time. | |
723 ex_node = use_exception_state(ex_map); | |
724 | |
725 // Get the exception oop klass from its header | |
726 Node* ex_klass_node = NULL; | |
727 if (has_ex_handler() && !ex_type->klass_is_exact()) { | |
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 | 730 |
731 // Compute the exception klass a little more cleverly. | |
732 // Obvious solution is to simple do a LoadKlass from the 'ex_node'. | |
733 // However, if the ex_node is a PhiNode, I'm going to do a LoadKlass for | |
734 // each arm of the Phi. If I know something clever about the exceptions | |
735 // I'm loading the class from, I can replace the LoadKlass with the | |
736 // klass constant for the exception oop. | |
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 | 739 for( uint i = 1; i < ex_node->req(); i++ ) { |
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 | 742 ex_klass_node->init_req( i, k ); |
743 } | |
744 _gvn.set_type(ex_klass_node, TypeKlassPtr::OBJECT); | |
745 | |
746 } | |
747 } | |
748 | |
749 // Scan the exception table for applicable handlers. | |
750 // If none, we can call rethrow() and be done! | |
751 // If precise (loaded with no subklasses), insert a D.S. style | |
752 // pointer compare to the correct handler and loop back. | |
753 // If imprecise, switch to the Rethrow VM-call style handling. | |
754 | |
755 int remaining = handlers.count_remaining(); | |
756 | |
757 // iterate through all entries sequentially | |
758 for (;!handlers.is_done(); handlers.next()) { | |
759 ciExceptionHandler* handler = handlers.handler(); | |
760 | |
761 if (handler->is_rethrow()) { | |
762 // If we fell off the end of the table without finding an imprecise | |
763 // exception klass (and without finding a generic handler) then we | |
764 // know this exception is not handled in this method. We just rethrow | |
765 // the exception into the caller. | |
766 throw_to_exit(make_exception_state(ex_node)); | |
767 return; | |
768 } | |
769 | |
770 // exception handler bci range covers throw_bci => investigate further | |
771 int handler_bci = handler->handler_bci(); | |
772 | |
773 if (remaining == 1) { | |
774 push_ex_oop(ex_node); // Push exception oop for handler | |
775 #ifndef PRODUCT | |
776 if (PrintOpto && WizardMode) { | |
777 tty->print_cr(" Catching every inline exception bci:%d -> handler_bci:%d", bci(), handler_bci); | |
778 } | |
779 #endif | |
780 merge_exception(handler_bci); // jump to handler | |
781 return; // No more handling to be done here! | |
782 } | |
783 | |
1344 | 784 // Get the handler's klass |
0 | 785 ciInstanceKlass* klass = handler->catch_klass(); |
1344 | 786 |
787 if (!klass->is_loaded()) { // klass is not loaded? | |
788 // fall through into catch_call_exceptions which will emit a | |
789 // handler with an uncommon trap. | |
790 break; | |
0 | 791 } |
792 | |
793 if (klass->is_interface()) // should not happen, but... | |
794 break; // bail out | |
795 | |
1344 | 796 // Check the type of the exception against the catch type |
0 | 797 const TypeKlassPtr *tk = TypeKlassPtr::make(klass); |
798 Node* con = _gvn.makecon(tk); | |
1344 | 799 Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con); |
800 if (!stopped()) { | |
801 PreserveJVMState pjvms(this); | |
802 const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr(); | |
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 | 805 push_ex_oop(ex_oop); // Push exception oop for handler |
806 #ifndef PRODUCT | |
807 if (PrintOpto && WizardMode) { | |
808 tty->print(" Catching inline exception bci:%d -> handler_bci:%d -- ", bci(), handler_bci); | |
809 klass->print_name(); | |
810 tty->cr(); | |
811 } | |
812 #endif | |
813 merge_exception(handler_bci); | |
814 } | |
1344 | 815 set_control(not_subtype_ctrl); |
0 | 816 |
817 // Come here if exception does not match handler. | |
818 // Carry on with more handler checks. | |
819 --remaining; | |
820 } | |
821 | |
822 assert(!stopped(), "you should return if you finish the chain"); | |
823 | |
824 // Oops, need to call into the VM to resolve the klasses at runtime. | |
825 // Note: This call must not deoptimize, since it is not a real at this bci! | |
826 kill_dead_locals(); | |
827 | |
828 make_runtime_call(RC_NO_LEAF | RC_MUST_THROW, | |
829 OptoRuntime::rethrow_Type(), | |
830 OptoRuntime::rethrow_stub(), | |
831 NULL, NULL, | |
832 ex_node); | |
833 | |
834 // Rethrow is a pure call, no side effects, only a result. | |
835 // The result cannot be allocated, so we use I_O | |
836 | |
837 // Catch exceptions from the rethrow | |
838 catch_call_exceptions(handlers); | |
839 } | |
840 | |
841 | |
842 // (Note: Moved add_debug_info into GraphKit::add_safepoint_edges.) | |
843 | |
844 | |
845 #ifndef PRODUCT | |
846 void Parse::count_compiled_calls(bool at_method_entry, bool is_inline) { | |
847 if( CountCompiledCalls ) { | |
848 if( at_method_entry ) { | |
849 // bump invocation counter if top method (for statistics) | |
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 | 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 | 854 increment_counter(adr2); |
855 } | |
856 } else if (is_inline) { | |
857 switch (bc()) { | |
858 case Bytecodes::_invokevirtual: increment_counter(SharedRuntime::nof_inlined_calls_addr()); break; | |
859 case Bytecodes::_invokeinterface: increment_counter(SharedRuntime::nof_inlined_interface_calls_addr()); break; | |
860 case Bytecodes::_invokestatic: | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
367
diff
changeset
|
861 case Bytecodes::_invokedynamic: |
0 | 862 case Bytecodes::_invokespecial: increment_counter(SharedRuntime::nof_inlined_static_calls_addr()); break; |
863 default: fatal("unexpected call bytecode"); | |
864 } | |
865 } else { | |
866 switch (bc()) { | |
867 case Bytecodes::_invokevirtual: increment_counter(SharedRuntime::nof_normal_calls_addr()); break; | |
868 case Bytecodes::_invokeinterface: increment_counter(SharedRuntime::nof_interface_calls_addr()); break; | |
869 case Bytecodes::_invokestatic: | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
367
diff
changeset
|
870 case Bytecodes::_invokedynamic: |
0 | 871 case Bytecodes::_invokespecial: increment_counter(SharedRuntime::nof_static_calls_addr()); break; |
872 default: fatal("unexpected call bytecode"); | |
873 } | |
874 } | |
875 } | |
876 } | |
877 #endif //PRODUCT | |
878 | |
879 | |
7478 | 880 ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, |
881 ciMethod* callee, const TypeOopPtr* receiver_type, | |
882 bool is_virtual, | |
883 bool& call_does_dispatch, int& vtable_index) { | |
884 // Set default values for out-parameters. | |
885 call_does_dispatch = true; | |
886 vtable_index = Method::invalid_vtable_index; | |
887 | |
888 // Choose call strategy. | |
889 ciMethod* optimized_virtual_method = optimize_inlining(caller, bci, klass, callee, receiver_type); | |
890 | |
891 // Have the call been sufficiently improved such that it is no longer a virtual? | |
892 if (optimized_virtual_method != NULL) { | |
893 callee = optimized_virtual_method; | |
894 call_does_dispatch = false; | |
895 } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) { | |
896 // We can make a vtable call at this site | |
897 vtable_index = callee->resolve_vtable_index(caller->holder(), klass); | |
898 } | |
899 return callee; | |
900 } | |
901 | |
0 | 902 // Identify possible target method and inlining style |
7478 | 903 ciMethod* Compile::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, |
904 ciMethod* callee, const TypeOopPtr* receiver_type) { | |
0 | 905 // only use for virtual or interface calls |
906 | |
907 // If it is obviously final, do not bother to call find_monomorphic_target, | |
908 // because the class hierarchy checks are not needed, and may fail due to | |
909 // incompletely loaded classes. Since we do our own class loading checks | |
910 // in this module, we may confidently bind to any method. | |
7478 | 911 if (callee->can_be_statically_bound()) { |
912 return callee; | |
0 | 913 } |
914 | |
915 // Attempt to improve the receiver | |
916 bool actual_receiver_is_exact = false; | |
917 ciInstanceKlass* actual_receiver = klass; | |
918 if (receiver_type != NULL) { | |
919 // Array methods are all inherited from Object, and are monomorphic. | |
920 if (receiver_type->isa_aryptr() && | |
7478 | 921 callee->holder() == env()->Object_klass()) { |
922 return callee; | |
0 | 923 } |
924 | |
925 // All other interesting cases are instance klasses. | |
926 if (!receiver_type->isa_instptr()) { | |
927 return NULL; | |
928 } | |
929 | |
930 ciInstanceKlass *ikl = receiver_type->klass()->as_instance_klass(); | |
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 | 933 // ikl is a same or better type than the original actual_receiver, |
934 // e.g. static receiver from bytecodes. | |
935 actual_receiver = ikl; | |
936 // Is the actual_receiver exact? | |
937 actual_receiver_is_exact = receiver_type->klass_is_exact(); | |
938 } | |
939 } | |
940 | |
941 ciInstanceKlass* calling_klass = caller->holder(); | |
7478 | 942 ciMethod* cha_monomorphic_target = callee->find_monomorphic_target(calling_klass, klass, actual_receiver); |
0 | 943 if (cha_monomorphic_target != NULL) { |
944 assert(!cha_monomorphic_target->is_abstract(), ""); | |
945 // Look at the method-receiver type. Does it add "too much information"? | |
946 ciKlass* mr_klass = cha_monomorphic_target->holder(); | |
947 const Type* mr_type = TypeInstPtr::make(TypePtr::BotPTR, mr_klass); | |
948 if (receiver_type == NULL || !receiver_type->higher_equal(mr_type)) { | |
949 // Calling this method would include an implicit cast to its holder. | |
950 // %%% Not yet implemented. Would throw minor asserts at present. | |
951 // %%% The most common wins are already gained by +UseUniqueSubclasses. | |
952 // To fix, put the higher_equal check at the call of this routine, | |
953 // and add a CheckCastPP to the receiver. | |
954 if (TraceDependencies) { | |
955 tty->print_cr("found unique CHA method, but could not cast up"); | |
956 tty->print(" method = "); | |
957 cha_monomorphic_target->print(); | |
958 tty->cr(); | |
959 } | |
7478 | 960 if (log() != NULL) { |
961 log()->elem("missed_CHA_opportunity klass='%d' method='%d'", | |
962 log()->identify(klass), | |
963 log()->identify(cha_monomorphic_target)); | |
0 | 964 } |
965 cha_monomorphic_target = NULL; | |
966 } | |
967 } | |
968 if (cha_monomorphic_target != NULL) { | |
969 // Hardwiring a virtual. | |
970 // If we inlined because CHA revealed only a single target method, | |
971 // then we are dependent on that target method not getting overridden | |
972 // by dynamic class loading. Be sure to test the "static" receiver | |
973 // dest_method here, as opposed to the actual receiver, which may | |
974 // falsely lead us to believe that the receiver is final or private. | |
7478 | 975 dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target); |
0 | 976 return cha_monomorphic_target; |
977 } | |
978 | |
979 // If the type is exact, we can still bind the method w/o a vcall. | |
980 // (This case comes after CHA so we can see how much extra work it does.) | |
981 if (actual_receiver_is_exact) { | |
982 // In case of evolution, there is a dependence on every inlined method, since each | |
983 // such method can be changed when its class is redefined. | |
7478 | 984 ciMethod* exact_method = callee->resolve_invoke(calling_klass, actual_receiver); |
0 | 985 if (exact_method != NULL) { |
986 #ifndef PRODUCT | |
987 if (PrintOpto) { | |
988 tty->print(" Calling method via exact type @%d --- ", bci); | |
989 exact_method->print_name(); | |
990 tty->cr(); | |
991 } | |
992 #endif | |
993 return exact_method; | |
994 } | |
995 } | |
996 | |
997 return NULL; | |
998 } |