Mercurial > hg > truffle
annotate src/share/vm/runtime/compilationPolicy.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | 3e8fbc61cee8 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
21 * questions. |
0 | 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 | |
1202 | 69 (UseCompiler && AlwaysCompileLoopMethods && m->has_loops() && CompileBroker::should_compile_new_jobs()); // eagerly compile loop methods |
0 | 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 | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
77 // Math intrinsics should never be compiled as this can lead to |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
78 // monotonicity problems because the interpreter will prefer the |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
79 // compiled code to the intrinsic version. This can't happen in |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
80 // production because the invocation counter can't be incremented |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
81 // but we shouldn't expose the system to this problem in testing |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
82 // modes. |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
83 if (!AbstractInterpreter::can_be_compiled(m)) { |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
84 return false; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
85 } |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
0
diff
changeset
|
86 |
0 | 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 | |
1202 | 140 if (!delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler && CompileBroker::should_compile_new_jobs()) { |
0 | 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 | |
1202 | 165 if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m) && CompileBroker::should_compile_new_jobs()) { |
0 | 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 | |
1202 | 207 if (m->code() == NULL && !delayCompilationDuringStartup() && canBeCompiled(m) && UseCompiler && CompileBroker::should_compile_new_jobs()) { |
0 | 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 | |
1202 | 251 if (!m->is_not_osr_compilable() && !delayCompilationDuringStartup() && canBeCompiled(m) && CompileBroker::should_compile_new_jobs()) { |
0 | 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 |