annotate src/share/vm/opto/doCall.cpp @ 4710:41406797186b

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