annotate src/share/vm/opto/doCall.cpp @ 3992:d1bdeef3e3e2

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