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