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