annotate src/share/vm/runtime/compilationPolicy.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 a61af66fc99e
children ddb7834449d0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
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/_compilationPolicy.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 CompilationPolicy* CompilationPolicy::_policy;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 elapsedTimer CompilationPolicy::_accumulated_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 bool CompilationPolicy::_in_vm_startup;
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Determine compilation policy based on command line argument
a61af66fc99e Initial load
duke
parents:
diff changeset
33 void compilationPolicy_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
34 CompilationPolicy::set_in_vm_startup(DelayCompilationDuringStartup);
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 switch(CompilationPolicyChoice) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 case 0:
a61af66fc99e Initial load
duke
parents:
diff changeset
38 CompilationPolicy::set_policy(new SimpleCompPolicy());
a61af66fc99e Initial load
duke
parents:
diff changeset
39 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 case 1:
a61af66fc99e Initial load
duke
parents:
diff changeset
42 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
43 CompilationPolicy::set_policy(new StackWalkCompPolicy());
a61af66fc99e Initial load
duke
parents:
diff changeset
44 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
45 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
46 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
47 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
50 fatal("CompilationPolicyChoice must be in the range: [0-1]");
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 void CompilationPolicy::completed_vm_startup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 if (TraceCompilationPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 tty->print("CompilationPolicy: completed vm startup.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _in_vm_startup = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // Returns true if m must be compiled before executing it
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // This is intended to force compiles for methods (usually for
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // debugging) that would otherwise be interpreted for some reason.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 bool CompilationPolicy::mustBeCompiled(methodHandle m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 if (m->has_compiled_code()) return false; // already compiled
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if (!canBeCompiled(m)) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 return !UseInterpreter || // must compile all methods
a61af66fc99e Initial load
duke
parents:
diff changeset
69 (UseCompiler && AlwaysCompileLoopMethods && m->has_loops()); // eagerly compile loop methods
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Returns true if m is allowed to be compiled
a61af66fc99e Initial load
duke
parents:
diff changeset
73 bool CompilationPolicy::canBeCompiled(methodHandle m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 if (m->is_abstract()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 if (DontCompileHugeMethods && m->code_size() > HugeMethodLimit) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 return !m->is_not_compilable();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
81 void CompilationPolicy::print_time() {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 tty->print_cr ("Accumulated compilationPolicy times:");
a61af66fc99e Initial load
duke
parents:
diff changeset
83 tty->print_cr ("---------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
84 tty->print_cr (" Total: %3.3f sec.", _accumulated_time.seconds());
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 static void trace_osr_completion(nmethod* osr_nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (TraceOnStackReplacement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 if (osr_nm == NULL) tty->print_cr("compilation failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 else tty->print_cr("nmethod " INTPTR_FORMAT, osr_nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 }
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 void CompilationPolicy::reset_counter_for_invocation_event(methodHandle m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Make sure invocation and backedge counter doesn't overflow again right away
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // as would be the case for native methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // BUT also make sure the method doesn't look like it was never executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // Set carry bit and reduce counter's value to min(count, CompileThreshold/2).
a61af66fc99e Initial load
duke
parents:
diff changeset
101 m->invocation_counter()->set_carry();
a61af66fc99e Initial load
duke
parents:
diff changeset
102 m->backedge_counter()->set_carry();
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 void CompilationPolicy::reset_counter_for_back_branch_event(methodHandle m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Delay next back-branch event but pump up invocation counter to triger
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // whole method compilation.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 InvocationCounter* i = m->invocation_counter();
a61af66fc99e Initial load
duke
parents:
diff changeset
111 InvocationCounter* b = m->backedge_counter();
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // Don't set invocation_counter's value too low otherwise the method will
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // look like immature (ic < ~5300) which prevents the inlining based on
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // the type profiling.
a61af66fc99e Initial load
duke
parents:
diff changeset
116 i->set(i->state(), CompileThreshold);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Don't reset counter too low - it is used to check if OSR method is ready.
a61af66fc99e Initial load
duke
parents:
diff changeset
118 b->set(b->state(), CompileThreshold / 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // SimpleCompPolicy - compile current method
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 void SimpleCompPolicy::method_invocation_event( methodHandle m, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 int hot_count = m->invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
127 reset_counter_for_invocation_event(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 const char* comment = "count";
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (!delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 nmethod* nm = m->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (nm == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 const char* comment = "count";
a61af66fc99e Initial load
duke
parents:
diff changeset
134 CompileBroker::compile_method(m, InvocationEntryBci,
a61af66fc99e Initial load
duke
parents:
diff changeset
135 m, hot_count, comment, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 #ifdef TIERED
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if (nm->is_compiled_by_c1()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 const char* comment = "tier1 overflow";
a61af66fc99e Initial load
duke
parents:
diff changeset
141 CompileBroker::compile_method(m, InvocationEntryBci,
a61af66fc99e Initial load
duke
parents:
diff changeset
142 m, hot_count, comment, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144 #endif // TIERED
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 void SimpleCompPolicy::method_back_branch_event(methodHandle m, int branch_bci, int loop_top_bci, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 int hot_count = m->backedge_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
153 const char* comment = "backedge_count";
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 CompileBroker::compile_method(m, loop_top_bci, m, hot_count, comment, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(loop_top_bci));)
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 int SimpleCompPolicy::compilation_level(methodHandle m, int branch_bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
163 {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 #ifdef TIERED
a61af66fc99e Initial load
duke
parents:
diff changeset
165 if (!TieredCompilation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 return CompLevel_highest_tier;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 if (/* m()->tier1_compile_done() && */
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // QQQ HACK FIX ME set tier1_compile_done!!
a61af66fc99e Initial load
duke
parents:
diff changeset
170 !m()->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Grab the nmethod so it doesn't go away while it's being queried
a61af66fc99e Initial load
duke
parents:
diff changeset
172 nmethod* code = m()->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
173 if (code != NULL && code->is_compiled_by_c1()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 return CompLevel_highest_tier;
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return CompLevel_fast_compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
179 return CompLevel_highest_tier;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 #endif // TIERED
a61af66fc99e Initial load
duke
parents:
diff changeset
181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // StackWalkCompPolicy - walk up stack to find a suitable method to compile
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
186 const char* StackWalkCompPolicy::_msg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Consider m for compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void StackWalkCompPolicy::method_invocation_event(methodHandle m, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 int hot_count = m->invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 reset_counter_for_invocation_event(m);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 const char* comment = "count";
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if (m->code() == NULL && !delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 JavaThread *thread = (JavaThread*)THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 frame fr = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
201 assert(fr.is_interpreted_frame(), "must be interpreted");
a61af66fc99e Initial load
duke
parents:
diff changeset
202 assert(fr.interpreter_frame_method() == m(), "bad method");
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (TraceCompilationPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 tty->print("method invocation trigger: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 m->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)m(), m->code_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 javaVFrame* triggerVF = thread->last_java_vframe(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // triggerVF is the frame that triggered its counter
a61af66fc99e Initial load
duke
parents:
diff changeset
212 RFrame* first = new InterpretedRFrame(triggerVF->fr(), thread, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (first->top_method()->code() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // called obsolete method/nmethod -- no need to recompile
a61af66fc99e Initial load
duke
parents:
diff changeset
216 if (TraceCompilationPolicy) tty->print_cr(" --> " INTPTR_FORMAT, first->top_method()->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
217 } else if (compilation_level(m, InvocationEntryBci) == CompLevel_fast_compile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Tier1 compilation policy avaoids stack walking.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 CompileBroker::compile_method(m, InvocationEntryBci,
a61af66fc99e Initial load
duke
parents:
diff changeset
220 m, hot_count, comment, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 if (TimeCompilationPolicy) accumulated_time()->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
223 GrowableArray<RFrame*>* stack = new GrowableArray<RFrame*>(50);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 stack->push(first);
a61af66fc99e Initial load
duke
parents:
diff changeset
225 RFrame* top = findTopInlinableFrame(stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 if (TimeCompilationPolicy) accumulated_time()->stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
227 assert(top != NULL, "findTopInlinableFrame returned null");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 if (TraceCompilationPolicy) top->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
229 CompileBroker::compile_method(top->top_method(), InvocationEntryBci,
a61af66fc99e Initial load
duke
parents:
diff changeset
230 m, hot_count, comment, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int branch_bci, int loop_top_bci, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 assert(UseCompiler || CompileTheWorld, "UseCompiler should be set by now.");
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 int hot_count = m->backedge_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
239 const char* comment = "backedge_count";
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 CompileBroker::compile_method(m, loop_top_bci, m, hot_count, comment, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(loop_top_bci));)
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 int StackWalkCompPolicy::compilation_level(methodHandle m, int osr_bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
249 {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 int comp_level = CompLevel_full_optimization;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 if (TieredCompilation && osr_bci == InvocationEntryBci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (CompileTheWorld) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Under CTW, the first compile is tier1, the second tier2
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if (m->highest_tier_compile() == CompLevel_none) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 comp_level = CompLevel_fast_compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 } else if (!m->has_osr_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Before tier1 is done, use invocation_count + backedge_count to
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // compare against the threshold. After that, the counters may/will
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // be reset, so rely on the straight interpreter_invocation_count.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 if (m->highest_tier_compile() == CompLevel_initial_compile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if (m->interpreter_invocation_count() < Tier2CompileThreshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 comp_level = CompLevel_fast_compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265 } else if (m->invocation_count() + m->backedge_count() <
a61af66fc99e Initial load
duke
parents:
diff changeset
266 Tier2CompileThreshold) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 comp_level = CompLevel_fast_compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 return comp_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 RFrame* StackWalkCompPolicy::findTopInlinableFrame(GrowableArray<RFrame*>* stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // go up the stack until finding a frame that (probably) won't be inlined
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // into its caller
a61af66fc99e Initial load
duke
parents:
diff changeset
279 RFrame* current = stack->at(0); // current choice for stopping
a61af66fc99e Initial load
duke
parents:
diff changeset
280 assert( current && !current->is_compiled(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
281 const char* msg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 while (1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // before going up the stack further, check if doing so would get us into
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
287 RFrame* next = senderOf(current, stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if( !next ) // No next frame up the stack?
a61af66fc99e Initial load
duke
parents:
diff changeset
289 break; // Then compile with current frame
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 methodHandle m = current->top_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
292 methodHandle next_m = next->top_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 if (TraceCompilationPolicy && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 tty->print("[caller: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
296 next_m->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
297 tty->print("] ");
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if( !Inline ) { // Inlining turned off
a61af66fc99e Initial load
duke
parents:
diff changeset
301 msg = "Inlining turned off";
a61af66fc99e Initial load
duke
parents:
diff changeset
302 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (next_m->is_not_compilable()) { // Did fail to compile this before/
a61af66fc99e Initial load
duke
parents:
diff changeset
305 msg = "caller not compilable";
a61af66fc99e Initial load
duke
parents:
diff changeset
306 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (next->num() > MaxRecompilationSearchLength) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // don't go up too high when searching for recompilees
a61af66fc99e Initial load
duke
parents:
diff changeset
310 msg = "don't go up any further: > MaxRecompilationSearchLength";
a61af66fc99e Initial load
duke
parents:
diff changeset
311 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (next->distance() > MaxInterpretedSearchLength) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // don't go up too high when searching for recompilees
a61af66fc99e Initial load
duke
parents:
diff changeset
315 msg = "don't go up any further: next > MaxInterpretedSearchLength";
a61af66fc99e Initial load
duke
parents:
diff changeset
316 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // Compiled frame above already decided not to inline;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // do not recompile him.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 if (next->is_compiled()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 msg = "not going up into optimized code";
a61af66fc99e Initial load
duke
parents:
diff changeset
322 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // Interpreted frame above us was already compiled. Do not force
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // a recompile, although if the frame above us runs long enough an
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // OSR might still happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if( current->is_interpreted() && next_m->has_compiled_code() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 msg = "not going up -- already compiled caller";
a61af66fc99e Initial load
duke
parents:
diff changeset
330 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Compute how frequent this call site is. We have current method 'm'.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // We know next method 'next_m' is interpreted. Find the call site and
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // check the various invocation counts.
a61af66fc99e Initial load
duke
parents:
diff changeset
336 int invcnt = 0; // Caller counts
a61af66fc99e Initial load
duke
parents:
diff changeset
337 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 invcnt = next_m->interpreter_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340 int cnt = 0; // Call site counts
a61af66fc99e Initial load
duke
parents:
diff changeset
341 if (ProfileInterpreter && next_m->method_data() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 int bci = next->top_vframe()->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
344 ProfileData* data = next_m->method_data()->bci_to_data(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 if (data != NULL && data->is_CounterData())
a61af66fc99e Initial load
duke
parents:
diff changeset
346 cnt = data->as_CounterData()->count();
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Caller counts / call-site counts; i.e. is this call site
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // a hot call site for method next_m?
a61af66fc99e Initial load
duke
parents:
diff changeset
351 int freq = (invcnt) ? cnt/invcnt : cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Check size and frequency limits
a61af66fc99e Initial load
duke
parents:
diff changeset
354 if ((msg = shouldInline(m, freq, cnt)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // Check inlining negative tests
a61af66fc99e Initial load
duke
parents:
diff changeset
358 if ((msg = shouldNotInline(m)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // If the caller method is too big or something then we do not want to
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // compile it just to inline a method
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if (!canBeCompiled(next_m)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 msg = "caller cannot be compiled";
a61af66fc99e Initial load
duke
parents:
diff changeset
367 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 if( next_m->name() == vmSymbols::class_initializer_name() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 msg = "do not compile class initializer (OSR ok)";
a61af66fc99e Initial load
duke
parents:
diff changeset
372 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 if (TraceCompilationPolicy && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 tty->print("\n\t check caller: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
377 next_m->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 tty->print(" ( interpreted " INTPTR_FORMAT ", size=%d ) ", (address)next_m(), next_m->code_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 current = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 assert( !current || !current->is_compiled(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 if (TraceCompilationPolicy && msg) tty->print("(%s)\n", msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388 return current;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 RFrame* StackWalkCompPolicy::senderOf(RFrame* rf, GrowableArray<RFrame*>* stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 RFrame* sender = rf->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (sender && sender->num() == stack->length()) stack->push(sender);
a61af66fc99e Initial load
duke
parents:
diff changeset
394 return sender;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 const char* StackWalkCompPolicy::shouldInline(methodHandle m, float freq, int cnt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // Allows targeted inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // positive filter: should send be inlined? returns NULL (--> yes)
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // or rejection msg
a61af66fc99e Initial load
duke
parents:
diff changeset
402 int max_size = MaxInlineSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 int cost = m->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Check for too many throws (and not too huge)
a61af66fc99e Initial load
duke
parents:
diff changeset
406 if (m->interpreter_throwout_count() > InlineThrowCount && cost < InlineThrowMaxSize ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 // bump the max size if the call is frequent
a61af66fc99e Initial load
duke
parents:
diff changeset
411 if ((freq >= InlineFrequencyRatio) || (cnt >= InlineFrequencyCount)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 if (TraceFrequencyInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 tty->print("(Inlined frequent method)\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
414 m->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 max_size = FreqInlineSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 if (cost > max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 return (_msg = "too big");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 const char* StackWalkCompPolicy::shouldNotInline(methodHandle m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (m->is_abstract()) return (_msg = "abstract method");
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // note: we allow ik->is_abstract()
a61af66fc99e Initial load
duke
parents:
diff changeset
429 if (!instanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
430 if (m->is_native()) return (_msg = "native method");
a61af66fc99e Initial load
duke
parents:
diff changeset
431 nmethod* m_code = m->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
432 if( m_code != NULL && m_code->instructions_size() > InlineSmallCode )
a61af66fc99e Initial load
duke
parents:
diff changeset
433 return (_msg = "already compiled into a big method");
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // use frequency-based objections only for non-trivial methods
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (m->code_size() <= MaxTrivialSize) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
437 if (UseInterpreter) { // don't use counts with -Xcomp
a61af66fc99e Initial load
duke
parents:
diff changeset
438 if ((m->code() == NULL) && m->was_never_executed()) return (_msg = "never executed");
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if (!m->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) return (_msg = "executed < MinInliningThreshold times");
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441 if (methodOopDesc::has_unloaded_classes_in_signature(m, JavaThread::current())) return (_msg = "unloaded signature classes");
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 #endif // COMPILER2