annotate src/share/vm/opto/doCall.cpp @ 1994:6cd6d394f280

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