Mercurial > hg > truffle
annotate src/share/vm/opto/bytecodeInfo.cpp @ 1145:e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa
author | ysr |
---|---|
date | Wed, 23 Dec 2009 09:23:54 -0800 |
parents | 15bbd3f505c0 |
children | 97125851f396 |
rev | line source |
---|---|
0 | 1 /* |
844 | 2 * Copyright 1998-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_bytecodeInfo.cpp.incl" | |
27 | |
28 //============================================================================= | |
29 //------------------------------InlineTree------------------------------------- | |
30 InlineTree::InlineTree( Compile* c, const InlineTree *caller_tree, ciMethod* callee, JVMState* caller_jvms, int caller_bci, float site_invoke_ratio ) | |
31 : C(c), _caller_jvms(caller_jvms), | |
32 _caller_tree((InlineTree*)caller_tree), | |
33 _method(callee), _site_invoke_ratio(site_invoke_ratio), | |
34 _count_inline_bcs(method()->code_size()) { | |
35 NOT_PRODUCT(_count_inlines = 0;) | |
36 if (_caller_jvms != NULL) { | |
37 // Keep a private copy of the caller_jvms: | |
38 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms()); | |
39 _caller_jvms->set_bci(caller_jvms->bci()); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
726
diff
changeset
|
40 assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); |
0 | 41 } |
42 assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); | |
43 assert((caller_tree == NULL ? 0 : caller_tree->inline_depth() + 1) == inline_depth(), "correct (redundant) depth parameter"); | |
44 assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); | |
45 if (UseOldInlining) { | |
46 // Update hierarchical counts, count_inline_bcs() and count_inlines() | |
47 InlineTree *caller = (InlineTree *)caller_tree; | |
48 for( ; caller != NULL; caller = ((InlineTree *)(caller->caller_tree())) ) { | |
49 caller->_count_inline_bcs += count_inline_bcs(); | |
50 NOT_PRODUCT(caller->_count_inlines++;) | |
51 } | |
52 } | |
53 } | |
54 | |
55 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio) | |
56 : C(c), _caller_jvms(caller_jvms), _caller_tree(NULL), | |
57 _method(callee_method), _site_invoke_ratio(site_invoke_ratio), | |
58 _count_inline_bcs(method()->code_size()) { | |
59 NOT_PRODUCT(_count_inlines = 0;) | |
60 assert(!UseOldInlining, "do not use for old stuff"); | |
61 } | |
62 | |
63 | |
64 | |
65 static void print_indent(int depth) { | |
66 tty->print(" "); | |
67 for (int i = depth; i != 0; --i) tty->print(" "); | |
68 } | |
69 | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
70 static bool is_init_with_ea(ciMethod* callee_method, |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
71 ciMethod* caller_method, Compile* C) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
72 // True when EA is ON and a java constructor is called or |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
73 // a super constructor is called from an inlined java constructor. |
244 | 74 return C->do_escape_analysis() && EliminateAllocations && |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
75 ( callee_method->is_initializer() || |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
76 (caller_method->is_initializer() && |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
77 caller_method != C->method() && |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
78 caller_method->holder()->is_subclass_of(callee_method->holder())) |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
79 ); |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
80 } |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
81 |
0 | 82 // positive filter: should send be inlined? returns NULL, if yes, or rejection msg |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
83 const char* InlineTree::shouldInline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { |
0 | 84 // Allows targeted inlining |
85 if(callee_method->should_inline()) { | |
86 *wci_result = *(WarmCallInfo::always_hot()); | |
87 if (PrintInlining && Verbose) { | |
88 print_indent(inline_depth()); | |
89 tty->print_cr("Inlined method is hot: "); | |
90 } | |
91 return NULL; | |
92 } | |
93 | |
94 // positive filter: should send be inlined? returns NULL (--> yes) | |
95 // or rejection msg | |
96 int max_size = C->max_inline_size(); | |
97 int size = callee_method->code_size(); | |
98 | |
99 // Check for too many throws (and not too huge) | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
100 if(callee_method->interpreter_throwout_count() > InlineThrowCount && |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
101 size < InlineThrowMaxSize ) { |
0 | 102 wci_result->set_profit(wci_result->profit() * 100); |
103 if (PrintInlining && Verbose) { | |
104 print_indent(inline_depth()); | |
105 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); | |
106 } | |
107 return NULL; | |
108 } | |
109 | |
110 if (!UseOldInlining) { | |
111 return NULL; // size and frequency are represented in a new way | |
112 } | |
113 | |
114 int call_site_count = method()->scale_count(profile.count()); | |
115 int invoke_count = method()->interpreter_invocation_count(); | |
116 assert( invoke_count != 0, "Require invokation count greater than zero"); | |
117 int freq = call_site_count/invoke_count; | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
118 |
0 | 119 // bump the max size if the call is frequent |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
120 if ((freq >= InlineFrequencyRatio) || |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
121 (call_site_count >= InlineFrequencyCount) || |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
122 is_init_with_ea(callee_method, caller_method, C)) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
123 |
0 | 124 max_size = C->freq_inline_size(); |
125 if (size <= max_size && TraceFrequencyInlining) { | |
126 print_indent(inline_depth()); | |
127 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count); | |
128 print_indent(inline_depth()); | |
129 callee_method->print(); | |
130 tty->cr(); | |
131 } | |
132 } else { | |
133 // Not hot. Check for medium-sized pre-existing nmethod at cold sites. | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
134 if (callee_method->has_compiled_code() && |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
135 callee_method->instructions_size() > InlineSmallCode/4) |
0 | 136 return "already compiled into a medium method"; |
137 } | |
138 if (size > max_size) { | |
139 if (max_size > C->max_inline_size()) | |
140 return "hot method too big"; | |
141 return "too big"; | |
142 } | |
143 return NULL; | |
144 } | |
145 | |
146 | |
147 // negative filter: should send NOT be inlined? returns NULL, ok to inline, or rejection msg | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
148 const char* InlineTree::shouldNotInline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { |
0 | 149 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg |
150 if (!UseOldInlining) { | |
151 const char* fail = NULL; | |
152 if (callee_method->is_abstract()) fail = "abstract method"; | |
153 // note: we allow ik->is_abstract() | |
154 if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized"; | |
155 if (callee_method->is_native()) fail = "native method"; | |
156 | |
157 if (fail) { | |
158 *wci_result = *(WarmCallInfo::always_cold()); | |
159 return fail; | |
160 } | |
161 | |
162 if (callee_method->has_unloaded_classes_in_signature()) { | |
163 wci_result->set_profit(wci_result->profit() * 0.1); | |
164 } | |
165 | |
166 // don't inline exception code unless the top method belongs to an | |
167 // exception class | |
168 if (callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { | |
169 ciMethod* top_method = caller_jvms() ? caller_jvms()->of_depth(1)->method() : method(); | |
170 if (!top_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { | |
171 wci_result->set_profit(wci_result->profit() * 0.1); | |
172 } | |
173 } | |
174 | |
175 if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode) { | |
176 wci_result->set_profit(wci_result->profit() * 0.1); | |
177 // %%% adjust wci_result->size()? | |
178 } | |
179 | |
180 return NULL; | |
181 } | |
182 | |
183 // First check all inlining restrictions which are required for correctness | |
184 if (callee_method->is_abstract()) return "abstract method"; | |
185 // note: we allow ik->is_abstract() | |
186 if (!callee_method->holder()->is_initialized()) return "method holder not initialized"; | |
187 if (callee_method->is_native()) return "native method"; | |
188 if (callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes"; | |
189 | |
190 if (callee_method->should_inline()) { | |
191 // ignore heuristic controls on inlining | |
192 return NULL; | |
193 } | |
194 | |
195 // Now perform checks which are heuristic | |
196 | |
197 if( callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode ) | |
198 return "already compiled into a big method"; | |
199 | |
200 // don't inline exception code unless the top method belongs to an | |
201 // exception class | |
202 if (caller_tree() != NULL && | |
203 callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) { | |
204 const InlineTree *top = this; | |
205 while (top->caller_tree() != NULL) top = top->caller_tree(); | |
206 ciInstanceKlass* k = top->method()->holder(); | |
207 if (!k->is_subclass_of(C->env()->Throwable_klass())) | |
208 return "exception method"; | |
209 } | |
210 | |
211 // use frequency-based objections only for non-trivial methods | |
212 if (callee_method->code_size() <= MaxTrivialSize) return NULL; | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
213 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
214 // don't use counts with -Xcomp or CTW |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
215 if (UseInterpreter && !CompileTheWorld) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
216 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
217 if (!callee_method->has_compiled_code() && |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
218 !callee_method->was_executed_more_than(0)) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
219 return "never executed"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
220 } |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
221 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
222 if (is_init_with_ea(callee_method, caller_method, C)) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
223 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
224 // Escape Analysis: inline all executed constructors |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
225 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
226 } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
227 CompileThreshold >> 1))) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
228 return "executed < MinInliningThreshold times"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
229 } |
0 | 230 } |
231 | |
232 if (callee_method->should_not_inline()) { | |
233 return "disallowed by CompilerOracle"; | |
234 } | |
235 | |
675 | 236 if (UseStringCache) { |
237 // Do not inline StringCache::profile() method used only at the beginning. | |
238 if (callee_method->name() == ciSymbol::profile_name() && | |
239 callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) { | |
240 return "profiling method"; | |
241 } | |
242 } | |
243 | |
0 | 244 return NULL; |
245 } | |
246 | |
247 //-----------------------------try_to_inline----------------------------------- | |
248 // return NULL if ok, reason for not inlining otherwise | |
249 // Relocated from "InliningClosure::try_to_inline" | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
250 const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) { |
0 | 251 |
252 // Old algorithm had funny accumulating BC-size counters | |
253 if (UseOldInlining && ClipInlining | |
254 && (int)count_inline_bcs() >= DesiredMethodLimit) { | |
255 return "size > DesiredMethodLimit"; | |
256 } | |
257 | |
258 const char *msg = NULL; | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
259 if ((msg = shouldInline(callee_method, caller_method, caller_bci, |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
260 profile, wci_result)) != NULL) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
261 return msg; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
262 } |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
263 if ((msg = shouldNotInline(callee_method, caller_method, |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
264 wci_result)) != NULL) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
265 return msg; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
266 } |
0 | 267 |
268 bool is_accessor = InlineAccessors && callee_method->is_accessor(); | |
269 | |
270 // suppress a few checks for accessors and trivial methods | |
271 if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
272 |
0 | 273 // don't inline into giant methods |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
274 if (C->unique() > (uint)NodeCountInliningCutoff) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
275 return "NodeCountInliningCutoff"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
276 } |
0 | 277 |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
278 if ((!UseInterpreter || CompileTheWorld) && |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
279 is_init_with_ea(callee_method, caller_method, C)) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
280 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
281 // Escape Analysis stress testing when running Xcomp or CTW: |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
282 // inline constructors even if they are not reached. |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
283 |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
284 } else if (profile.count() == 0) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
285 // don't inline unreached call sites |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
286 return "call site not reached"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
287 } |
0 | 288 } |
289 | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
290 if (!C->do_inlining() && InlineAccessors && !is_accessor) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
291 return "not an accessor"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
292 } |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
293 if( inline_depth() > MaxInlineLevel ) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
294 return "inlining too deep"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
295 } |
0 | 296 if( method() == callee_method && |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
297 inline_depth() > MaxRecursiveInlineLevel ) { |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
298 return "recursively inlining too deep"; |
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
299 } |
0 | 300 |
301 int size = callee_method->code_size(); | |
302 | |
303 if (UseOldInlining && ClipInlining | |
304 && (int)count_inline_bcs() + size >= DesiredMethodLimit) { | |
305 return "size > DesiredMethodLimit"; | |
306 } | |
307 | |
308 // ok, inline this method | |
309 return NULL; | |
310 } | |
311 | |
312 //------------------------------pass_initial_checks---------------------------- | |
313 bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* callee_method) { | |
314 ciInstanceKlass *callee_holder = callee_method ? callee_method->holder() : NULL; | |
315 // Check if a callee_method was suggested | |
316 if( callee_method == NULL ) return false; | |
317 // Check if klass of callee_method is loaded | |
318 if( !callee_holder->is_loaded() ) return false; | |
319 if( !callee_holder->is_initialized() ) return false; | |
320 if( !UseInterpreter || CompileTheWorld /* running Xcomp or CTW */ ) { | |
321 // Checks that constant pool's call site has been visited | |
322 // stricter than callee_holder->is_initialized() | |
323 ciBytecodeStream iter(caller_method); | |
324 iter.force_bci(caller_bci); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
675
diff
changeset
|
325 int index = iter.get_index_int(); |
0 | 326 if( !caller_method->is_klass_loaded(index, true) ) { |
327 return false; | |
328 } | |
329 // Try to do constant pool resolution if running Xcomp | |
330 Bytecodes::Code call_bc = iter.cur_bc(); | |
331 if( !caller_method->check_call(index, call_bc == Bytecodes::_invokestatic) ) { | |
332 return false; | |
333 } | |
334 } | |
335 // We will attempt to see if a class/field/etc got properly loaded. If it | |
336 // did not, it may attempt to throw an exception during our probing. Catch | |
337 // and ignore such exceptions and do not attempt to compile the method. | |
338 if( callee_method->should_exclude() ) return false; | |
339 | |
340 return true; | |
341 } | |
342 | |
343 #ifndef PRODUCT | |
344 //------------------------------print_inlining--------------------------------- | |
345 // Really, the failure_msg can be a success message also. | |
346 void InlineTree::print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const { | |
347 print_indent(inline_depth()); | |
348 tty->print("@ %d ", caller_bci); | |
349 if( callee_method ) callee_method->print_short_name(); | |
350 else tty->print(" callee not monotonic or profiled"); | |
351 tty->print(" %s", (failure_msg ? failure_msg : "inline")); | |
352 if( Verbose && callee_method ) { | |
353 const InlineTree *top = this; | |
354 while( top->caller_tree() != NULL ) { top = top->caller_tree(); } | |
355 tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count()); | |
356 } | |
357 tty->cr(); | |
358 } | |
359 #endif | |
360 | |
361 //------------------------------ok_to_inline----------------------------------- | |
362 WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci) { | |
363 assert(callee_method != NULL, "caller checks for optimized virtual!"); | |
364 #ifdef ASSERT | |
365 // Make sure the incoming jvms has the same information content as me. | |
366 // This means that we can eventually make this whole class AllStatic. | |
367 if (jvms->caller() == NULL) { | |
368 assert(_caller_jvms == NULL, "redundant instance state"); | |
369 } else { | |
370 assert(_caller_jvms->same_calls_as(jvms->caller()), "redundant instance state"); | |
371 } | |
372 assert(_method == jvms->method(), "redundant instance state"); | |
373 #endif | |
374 const char *failure_msg = NULL; | |
375 int caller_bci = jvms->bci(); | |
376 ciMethod *caller_method = jvms->method(); | |
377 | |
378 if( !pass_initial_checks(caller_method, caller_bci, callee_method)) { | |
379 if( PrintInlining ) { | |
380 failure_msg = "failed_initial_checks"; | |
381 print_inlining( callee_method, caller_bci, failure_msg); | |
382 } | |
383 return NULL; | |
384 } | |
385 | |
386 // Check if inlining policy says no. | |
387 WarmCallInfo wci = *(initial_wci); | |
41
874b2c4f43d1
6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents:
0
diff
changeset
|
388 failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci); |
0 | 389 if (failure_msg != NULL && C->log() != NULL) { |
390 C->log()->begin_elem("inline_fail reason='"); | |
391 C->log()->text("%s", failure_msg); | |
392 C->log()->end_elem("'"); | |
393 } | |
394 | |
395 #ifndef PRODUCT | |
396 if (UseOldInlining && InlineWarmCalls | |
397 && (PrintOpto || PrintOptoInlining || PrintInlining)) { | |
398 bool cold = wci.is_cold(); | |
399 bool hot = !cold && wci.is_hot(); | |
400 bool old_cold = (failure_msg != NULL); | |
401 if (old_cold != cold || (Verbose || WizardMode)) { | |
402 tty->print(" OldInlining= %4s : %s\n WCI=", | |
403 old_cold ? "cold" : "hot", failure_msg ? failure_msg : "OK"); | |
404 wci.print(); | |
405 } | |
406 } | |
407 #endif | |
408 if (UseOldInlining) { | |
409 if (failure_msg == NULL) | |
410 wci = *(WarmCallInfo::always_hot()); | |
411 else | |
412 wci = *(WarmCallInfo::always_cold()); | |
413 } | |
414 if (!InlineWarmCalls) { | |
415 if (!wci.is_cold() && !wci.is_hot()) { | |
416 // Do not inline the warm calls. | |
417 wci = *(WarmCallInfo::always_cold()); | |
418 } | |
419 } | |
420 | |
421 if (!wci.is_cold()) { | |
422 // In -UseOldInlining, the failure_msg may also be a success message. | |
423 if (failure_msg == NULL) failure_msg = "inline (hot)"; | |
424 | |
425 // Inline! | |
426 if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg); | |
427 if (UseOldInlining) | |
428 build_inline_tree_for_callee(callee_method, jvms, caller_bci); | |
429 if (InlineWarmCalls && !wci.is_hot()) | |
430 return new (C) WarmCallInfo(wci); // copy to heap | |
431 return WarmCallInfo::always_hot(); | |
432 } | |
433 | |
434 // Do not inline | |
435 if (failure_msg == NULL) failure_msg = "too cold to inline"; | |
436 if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg); | |
437 return NULL; | |
438 } | |
439 | |
440 //------------------------------compute_callee_frequency----------------------- | |
441 float InlineTree::compute_callee_frequency( int caller_bci ) const { | |
442 int count = method()->interpreter_call_site_count(caller_bci); | |
443 int invcnt = method()->interpreter_invocation_count(); | |
444 float freq = (float)count/(float)invcnt; | |
445 // Call-site count / interpreter invocation count, scaled recursively. | |
446 // Always between 0.0 and 1.0. Represents the percentage of the method's | |
447 // total execution time used at this call site. | |
448 | |
449 return freq; | |
450 } | |
451 | |
452 //------------------------------build_inline_tree_for_callee------------------- | |
453 InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, JVMState* caller_jvms, int caller_bci) { | |
454 float recur_frequency = _site_invoke_ratio * compute_callee_frequency(caller_bci); | |
455 // Attempt inlining. | |
456 InlineTree* old_ilt = callee_at(caller_bci, callee_method); | |
457 if (old_ilt != NULL) { | |
458 return old_ilt; | |
459 } | |
460 InlineTree *ilt = new InlineTree( C, this, callee_method, caller_jvms, caller_bci, recur_frequency ); | |
461 _subtrees.append( ilt ); | |
462 | |
463 NOT_PRODUCT( _count_inlines += 1; ) | |
464 | |
465 return ilt; | |
466 } | |
467 | |
468 | |
469 //---------------------------------------callee_at----------------------------- | |
470 InlineTree *InlineTree::callee_at(int bci, ciMethod* callee) const { | |
471 for (int i = 0; i < _subtrees.length(); i++) { | |
472 InlineTree* sub = _subtrees.at(i); | |
473 if (sub->caller_bci() == bci && callee == sub->method()) { | |
474 return sub; | |
475 } | |
476 } | |
477 return NULL; | |
478 } | |
479 | |
480 | |
481 //------------------------------build_inline_tree_root------------------------- | |
482 InlineTree *InlineTree::build_inline_tree_root() { | |
483 Compile* C = Compile::current(); | |
484 | |
485 // Root of inline tree | |
486 InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F); | |
487 | |
488 return ilt; | |
489 } | |
490 | |
491 | |
492 //-------------------------find_subtree_from_root----------------------------- | |
493 // Given a jvms, which determines a call chain from the root method, | |
494 // find the corresponding inline tree. | |
495 // Note: This method will be removed or replaced as InlineTree goes away. | |
496 InlineTree* InlineTree::find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found) { | |
497 InlineTree* iltp = root; | |
498 uint depth = jvms && jvms->has_method() ? jvms->depth() : 0; | |
499 for (uint d = 1; d <= depth; d++) { | |
500 JVMState* jvmsp = jvms->of_depth(d); | |
501 // Select the corresponding subtree for this bci. | |
502 assert(jvmsp->method() == iltp->method(), "tree still in sync"); | |
503 ciMethod* d_callee = (d == depth) ? callee : jvms->of_depth(d+1)->method(); | |
504 InlineTree* sub = iltp->callee_at(jvmsp->bci(), d_callee); | |
505 if (!sub) { | |
506 if (create_if_not_found && d == depth) { | |
507 return iltp->build_inline_tree_for_callee(d_callee, jvmsp, jvmsp->bci()); | |
508 } | |
509 assert(sub != NULL, "should be a sub-ilt here"); | |
510 return NULL; | |
511 } | |
512 iltp = sub; | |
513 } | |
514 return iltp; | |
515 } |