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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
844
bd02caa94611 6862919: Update copyright year
xdono
parents: 726
diff changeset
2 * Copyright 1998-2009 Sun Microsystems, Inc. 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 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_bytecodeInfo.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
29 //------------------------------InlineTree-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
30 InlineTree::InlineTree( Compile* c, const InlineTree *caller_tree, ciMethod* callee, JVMState* caller_jvms, int caller_bci, float site_invoke_ratio )
a61af66fc99e Initial load
duke
parents:
diff changeset
31 : C(c), _caller_jvms(caller_jvms),
a61af66fc99e Initial load
duke
parents:
diff changeset
32 _caller_tree((InlineTree*)caller_tree),
a61af66fc99e Initial load
duke
parents:
diff changeset
33 _method(callee), _site_invoke_ratio(site_invoke_ratio),
a61af66fc99e Initial load
duke
parents:
diff changeset
34 _count_inline_bcs(method()->code_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 NOT_PRODUCT(_count_inlines = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
36 if (_caller_jvms != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // Keep a private copy of the caller_jvms:
a61af66fc99e Initial load
duke
parents:
diff changeset
38 _caller_jvms = new (C) JVMState(caller_jvms->method(), caller_tree->caller_jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
41 }
a61af66fc99e Initial load
duke
parents:
diff changeset
42 assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS");
a61af66fc99e Initial load
duke
parents:
diff changeset
43 assert((caller_tree == NULL ? 0 : caller_tree->inline_depth() + 1) == inline_depth(), "correct (redundant) depth parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
44 assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if (UseOldInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // Update hierarchical counts, count_inline_bcs() and count_inlines()
a61af66fc99e Initial load
duke
parents:
diff changeset
47 InlineTree *caller = (InlineTree *)caller_tree;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 for( ; caller != NULL; caller = ((InlineTree *)(caller->caller_tree())) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 caller->_count_inline_bcs += count_inline_bcs();
a61af66fc99e Initial load
duke
parents:
diff changeset
50 NOT_PRODUCT(caller->_count_inlines++;)
a61af66fc99e Initial load
duke
parents:
diff changeset
51 }
a61af66fc99e Initial load
duke
parents:
diff changeset
52 }
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio)
a61af66fc99e Initial load
duke
parents:
diff changeset
56 : C(c), _caller_jvms(caller_jvms), _caller_tree(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _method(callee_method), _site_invoke_ratio(site_invoke_ratio),
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _count_inline_bcs(method()->code_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 NOT_PRODUCT(_count_inlines = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
60 assert(!UseOldInlining, "do not use for old stuff");
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static void print_indent(int depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
67 for (int i = depth; i != 0; --i) tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
524eca34ea76 6684714: Optimize EA Connection Graph build performance
kvn
parents: 41
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Allows targeted inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
85 if(callee_method->should_inline()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 *wci_result = *(WarmCallInfo::always_hot());
a61af66fc99e Initial load
duke
parents:
diff changeset
87 if (PrintInlining && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 print_indent(inline_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
89 tty->print_cr("Inlined method is hot: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // positive filter: should send be inlined? returns NULL (--> yes)
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // or rejection msg
a61af66fc99e Initial load
duke
parents:
diff changeset
96 int max_size = C->max_inline_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 int size = callee_method->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
102 wci_result->set_profit(wci_result->profit() * 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (PrintInlining && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 print_indent(inline_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
105 tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (!UseOldInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 return NULL; // size and frequency are represented in a new way
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 int call_site_count = method()->scale_count(profile.count());
a61af66fc99e Initial load
duke
parents:
diff changeset
115 int invoke_count = method()->interpreter_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
116 assert( invoke_count != 0, "Require invokation count greater than zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
124 max_size = C->freq_inline_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
125 if (size <= max_size && TraceFrequencyInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 print_indent(inline_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
127 tty->print_cr("Inlined frequent method (freq=%d count=%d):", freq, call_site_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 print_indent(inline_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
129 callee_method->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
130 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return "already compiled into a medium method";
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (size > max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if (max_size > C->max_inline_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
140 return "hot method too big";
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return "too big";
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (!UseOldInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 const char* fail = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if (callee_method->is_abstract()) fail = "abstract method";
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // note: we allow ik->is_abstract()
a61af66fc99e Initial load
duke
parents:
diff changeset
154 if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized";
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (callee_method->is_native()) fail = "native method";
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 if (fail) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 *wci_result = *(WarmCallInfo::always_cold());
a61af66fc99e Initial load
duke
parents:
diff changeset
159 return fail;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 if (callee_method->has_unloaded_classes_in_signature()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 wci_result->set_profit(wci_result->profit() * 0.1);
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // don't inline exception code unless the top method belongs to an
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // exception class
a61af66fc99e Initial load
duke
parents:
diff changeset
168 if (callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 ciMethod* top_method = caller_jvms() ? caller_jvms()->of_depth(1)->method() : method();
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (!top_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 wci_result->set_profit(wci_result->profit() * 0.1);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 wci_result->set_profit(wci_result->profit() * 0.1);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // %%% adjust wci_result->size()?
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // First check all inlining restrictions which are required for correctness
a61af66fc99e Initial load
duke
parents:
diff changeset
184 if (callee_method->is_abstract()) return "abstract method";
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // note: we allow ik->is_abstract()
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (!callee_method->holder()->is_initialized()) return "method holder not initialized";
a61af66fc99e Initial load
duke
parents:
diff changeset
187 if (callee_method->is_native()) return "native method";
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if (callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes";
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (callee_method->should_inline()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // ignore heuristic controls on inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
192 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Now perform checks which are heuristic
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if( callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode )
a61af66fc99e Initial load
duke
parents:
diff changeset
198 return "already compiled into a big method";
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // don't inline exception code unless the top method belongs to an
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // exception class
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if (caller_tree() != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
203 callee_method->holder()->is_subclass_of(C->env()->Throwable_klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 const InlineTree *top = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 while (top->caller_tree() != NULL) top = top->caller_tree();
a61af66fc99e Initial load
duke
parents:
diff changeset
206 ciInstanceKlass* k = top->method()->holder();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (!k->is_subclass_of(C->env()->Throwable_klass()))
a61af66fc99e Initial load
duke
parents:
diff changeset
208 return "exception method";
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // use frequency-based objections only for non-trivial methods
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if (callee_method->should_not_inline()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return "disallowed by CompilerOracle";
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
675
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
236 if (UseStringCache) {
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
237 // Do not inline StringCache::profile() method used only at the beginning.
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
238 if (callee_method->name() == ciSymbol::profile_name() &&
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
239 callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
240 return "profiling method";
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
241 }
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
242 }
f6da6f0174ac 6821700: tune VM flags for peak performance
kvn
parents: 367
diff changeset
243
0
a61af66fc99e Initial load
duke
parents:
diff changeset
244 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 //-----------------------------try_to_inline-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // return NULL if ok, reason for not inlining otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Old algorithm had funny accumulating BC-size counters
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (UseOldInlining && ClipInlining
a61af66fc99e Initial load
duke
parents:
diff changeset
254 && (int)count_inline_bcs() >= DesiredMethodLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 return "size > DesiredMethodLimit";
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 bool is_accessor = InlineAccessors && callee_method->is_accessor();
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // suppress a few checks for accessors and trivial methods
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 int size = callee_method->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if (UseOldInlining && ClipInlining
a61af66fc99e Initial load
duke
parents:
diff changeset
304 && (int)count_inline_bcs() + size >= DesiredMethodLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 return "size > DesiredMethodLimit";
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // ok, inline this method
a61af66fc99e Initial load
duke
parents:
diff changeset
309 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 //------------------------------pass_initial_checks----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
313 bool pass_initial_checks(ciMethod* caller_method, int caller_bci, ciMethod* callee_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 ciInstanceKlass *callee_holder = callee_method ? callee_method->holder() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Check if a callee_method was suggested
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if( callee_method == NULL ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // Check if klass of callee_method is loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if( !callee_holder->is_loaded() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if( !callee_holder->is_initialized() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 if( !UseInterpreter || CompileTheWorld /* running Xcomp or CTW */ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Checks that constant pool's call site has been visited
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // stricter than callee_holder->is_initialized()
a61af66fc99e Initial load
duke
parents:
diff changeset
323 ciBytecodeStream iter(caller_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
326 if( !caller_method->is_klass_loaded(index, true) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // Try to do constant pool resolution if running Xcomp
a61af66fc99e Initial load
duke
parents:
diff changeset
330 Bytecodes::Code call_bc = iter.cur_bc();
a61af66fc99e Initial load
duke
parents:
diff changeset
331 if( !caller_method->check_call(index, call_bc == Bytecodes::_invokestatic) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // We will attempt to see if a class/field/etc got properly loaded. If it
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // did not, it may attempt to throw an exception during our probing. Catch
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // and ignore such exceptions and do not attempt to compile the method.
a61af66fc99e Initial load
duke
parents:
diff changeset
338 if( callee_method->should_exclude() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
344 //------------------------------print_inlining---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // Really, the failure_msg can be a success message also.
a61af66fc99e Initial load
duke
parents:
diff changeset
346 void InlineTree::print_inlining(ciMethod *callee_method, int caller_bci, const char *failure_msg) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 print_indent(inline_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
348 tty->print("@ %d ", caller_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 if( callee_method ) callee_method->print_short_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
350 else tty->print(" callee not monotonic or profiled");
a61af66fc99e Initial load
duke
parents:
diff changeset
351 tty->print(" %s", (failure_msg ? failure_msg : "inline"));
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if( Verbose && callee_method ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 const InlineTree *top = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
354 while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
355 tty->print(" bcs: %d+%d invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 //------------------------------ok_to_inline-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
362 WarmCallInfo* InlineTree::ok_to_inline(ciMethod* callee_method, JVMState* jvms, ciCallProfile& profile, WarmCallInfo* initial_wci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 assert(callee_method != NULL, "caller checks for optimized virtual!");
a61af66fc99e Initial load
duke
parents:
diff changeset
364 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // Make sure the incoming jvms has the same information content as me.
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // This means that we can eventually make this whole class AllStatic.
a61af66fc99e Initial load
duke
parents:
diff changeset
367 if (jvms->caller() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
368 assert(_caller_jvms == NULL, "redundant instance state");
a61af66fc99e Initial load
duke
parents:
diff changeset
369 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 assert(_caller_jvms->same_calls_as(jvms->caller()), "redundant instance state");
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 assert(_method == jvms->method(), "redundant instance state");
a61af66fc99e Initial load
duke
parents:
diff changeset
373 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
374 const char *failure_msg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 int caller_bci = jvms->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
376 ciMethod *caller_method = jvms->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 if( !pass_initial_checks(caller_method, caller_bci, callee_method)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 if( PrintInlining ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 failure_msg = "failed_initial_checks";
a61af66fc99e Initial load
duke
parents:
diff changeset
381 print_inlining( callee_method, caller_bci, failure_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Check if inlining policy says no.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
389 if (failure_msg != NULL && C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 C->log()->begin_elem("inline_fail reason='");
a61af66fc99e Initial load
duke
parents:
diff changeset
391 C->log()->text("%s", failure_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 C->log()->end_elem("'");
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394
a61af66fc99e Initial load
duke
parents:
diff changeset
395 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
396 if (UseOldInlining && InlineWarmCalls
a61af66fc99e Initial load
duke
parents:
diff changeset
397 && (PrintOpto || PrintOptoInlining || PrintInlining)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 bool cold = wci.is_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
399 bool hot = !cold && wci.is_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
400 bool old_cold = (failure_msg != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 if (old_cold != cold || (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 tty->print(" OldInlining= %4s : %s\n WCI=",
a61af66fc99e Initial load
duke
parents:
diff changeset
403 old_cold ? "cold" : "hot", failure_msg ? failure_msg : "OK");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 wci.print();
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
408 if (UseOldInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 if (failure_msg == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
410 wci = *(WarmCallInfo::always_hot());
a61af66fc99e Initial load
duke
parents:
diff changeset
411 else
a61af66fc99e Initial load
duke
parents:
diff changeset
412 wci = *(WarmCallInfo::always_cold());
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (!InlineWarmCalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 if (!wci.is_cold() && !wci.is_hot()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // Do not inline the warm calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 wci = *(WarmCallInfo::always_cold());
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (!wci.is_cold()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // In -UseOldInlining, the failure_msg may also be a success message.
a61af66fc99e Initial load
duke
parents:
diff changeset
423 if (failure_msg == NULL) failure_msg = "inline (hot)";
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // Inline!
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (UseOldInlining)
a61af66fc99e Initial load
duke
parents:
diff changeset
428 build_inline_tree_for_callee(callee_method, jvms, caller_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 if (InlineWarmCalls && !wci.is_hot())
a61af66fc99e Initial load
duke
parents:
diff changeset
430 return new (C) WarmCallInfo(wci); // copy to heap
a61af66fc99e Initial load
duke
parents:
diff changeset
431 return WarmCallInfo::always_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // Do not inline
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if (failure_msg == NULL) failure_msg = "too cold to inline";
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 //------------------------------compute_callee_frequency-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
441 float InlineTree::compute_callee_frequency( int caller_bci ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
442 int count = method()->interpreter_call_site_count(caller_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
443 int invcnt = method()->interpreter_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
444 float freq = (float)count/(float)invcnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // Call-site count / interpreter invocation count, scaled recursively.
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // Always between 0.0 and 1.0. Represents the percentage of the method's
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // total execution time used at this call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 return freq;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 //------------------------------build_inline_tree_for_callee-------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
453 InlineTree *InlineTree::build_inline_tree_for_callee( ciMethod* callee_method, JVMState* caller_jvms, int caller_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 float recur_frequency = _site_invoke_ratio * compute_callee_frequency(caller_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Attempt inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
456 InlineTree* old_ilt = callee_at(caller_bci, callee_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (old_ilt != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 return old_ilt;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 InlineTree *ilt = new InlineTree( C, this, callee_method, caller_jvms, caller_bci, recur_frequency );
a61af66fc99e Initial load
duke
parents:
diff changeset
461 _subtrees.append( ilt );
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 NOT_PRODUCT( _count_inlines += 1; )
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 return ilt;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 //---------------------------------------callee_at-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
470 InlineTree *InlineTree::callee_at(int bci, ciMethod* callee) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 for (int i = 0; i < _subtrees.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 InlineTree* sub = _subtrees.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if (sub->caller_bci() == bci && callee == sub->method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 return sub;
a61af66fc99e Initial load
duke
parents:
diff changeset
475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 //------------------------------build_inline_tree_root-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
482 InlineTree *InlineTree::build_inline_tree_root() {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Root of inline tree
a61af66fc99e Initial load
duke
parents:
diff changeset
486 InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F);
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 return ilt;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 //-------------------------find_subtree_from_root-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // Given a jvms, which determines a call chain from the root method,
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // find the corresponding inline tree.
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // Note: This method will be removed or replaced as InlineTree goes away.
a61af66fc99e Initial load
duke
parents:
diff changeset
496 InlineTree* InlineTree::find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 InlineTree* iltp = root;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 uint depth = jvms && jvms->has_method() ? jvms->depth() : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
499 for (uint d = 1; d <= depth; d++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 JVMState* jvmsp = jvms->of_depth(d);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // Select the corresponding subtree for this bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
502 assert(jvmsp->method() == iltp->method(), "tree still in sync");
a61af66fc99e Initial load
duke
parents:
diff changeset
503 ciMethod* d_callee = (d == depth) ? callee : jvms->of_depth(d+1)->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
504 InlineTree* sub = iltp->callee_at(jvmsp->bci(), d_callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (!sub) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 if (create_if_not_found && d == depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
507 return iltp->build_inline_tree_for_callee(d_callee, jvmsp, jvmsp->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
509 assert(sub != NULL, "should be a sub-ilt here");
a61af66fc99e Initial load
duke
parents:
diff changeset
510 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512 iltp = sub;
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 return iltp;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }