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