Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/simpleThresholdPolicy.cpp @ 2607:008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
This is necessary to ensure correct continuation in the interpreter when the stateBefore is used as a deoptimization point.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Fri, 06 May 2011 17:47:17 +0200 |
parents | 72d6c57d0658 |
children | 97b64f73103b |
rev | line source |
---|---|
1783 | 1 /* |
2252 | 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
1783 | 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compileBroker.hpp" | |
27 #include "memory/resourceArea.hpp" | |
28 #include "runtime/arguments.hpp" | |
29 #include "runtime/simpleThresholdPolicy.hpp" | |
30 #include "runtime/simpleThresholdPolicy.inline.hpp" | |
2252 | 31 #include "code/scopeDesc.hpp" |
1783 | 32 |
33 // Print an event. | |
34 void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodHandle imh, | |
35 int bci, CompLevel level) { | |
36 bool inlinee_event = mh() != imh(); | |
37 | |
38 ttyLocker tty_lock; | |
39 tty->print("%lf: [", os::elapsedTime()); | |
40 | |
41 int invocation_count = mh->invocation_count(); | |
42 int backedge_count = mh->backedge_count(); | |
43 switch(type) { | |
44 case CALL: | |
45 tty->print("call"); | |
46 break; | |
47 case LOOP: | |
48 tty->print("loop"); | |
49 break; | |
50 case COMPILE: | |
51 tty->print("compile"); | |
2252 | 52 break; |
53 case KILL: | |
54 tty->print("kill"); | |
55 break; | |
56 case UPDATE: | |
57 tty->print("update"); | |
58 break; | |
59 case REPROFILE: | |
60 tty->print("reprofile"); | |
61 break; | |
62 default: | |
63 tty->print("unknown"); | |
1783 | 64 } |
65 | |
66 tty->print(" level: %d ", level); | |
67 | |
68 ResourceMark rm; | |
69 char *method_name = mh->name_and_sig_as_C_string(); | |
70 tty->print("[%s", method_name); | |
71 // We can have an inlinee, although currently we don't generate any notifications for the inlined methods. | |
72 if (inlinee_event) { | |
73 char *inlinee_name = imh->name_and_sig_as_C_string(); | |
74 tty->print(" [%s]] ", inlinee_name); | |
75 } | |
76 else tty->print("] "); | |
77 tty->print("@%d queues: %d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile), | |
78 CompileBroker::queue_size(CompLevel_full_optimization)); | |
79 | |
80 print_specific(type, mh, imh, bci, level); | |
81 | |
82 if (type != COMPILE) { | |
83 methodDataHandle mdh = mh->method_data(); | |
84 int mdo_invocations = 0, mdo_backedges = 0; | |
2252 | 85 int mdo_invocations_start = 0, mdo_backedges_start = 0; |
1783 | 86 if (mdh() != NULL) { |
87 mdo_invocations = mdh->invocation_count(); | |
88 mdo_backedges = mdh->backedge_count(); | |
2252 | 89 mdo_invocations_start = mdh->invocation_count_start(); |
90 mdo_backedges_start = mdh->backedge_count_start(); | |
1783 | 91 } |
2252 | 92 tty->print(" total: %d,%d mdo: %d(%d),%d(%d)", |
1783 | 93 invocation_count, backedge_count, |
2252 | 94 mdo_invocations, mdo_invocations_start, |
95 mdo_backedges, mdo_backedges_start); | |
1783 | 96 tty->print(" max levels: %d,%d", |
97 mh->highest_comp_level(), mh->highest_osr_comp_level()); | |
98 if (inlinee_event) { | |
99 tty->print(" inlinee max levels: %d,%d", imh->highest_comp_level(), imh->highest_osr_comp_level()); | |
100 } | |
101 tty->print(" compilable: "); | |
102 bool need_comma = false; | |
103 if (!mh->is_not_compilable(CompLevel_full_profile)) { | |
104 tty->print("c1"); | |
105 need_comma = true; | |
106 } | |
107 if (!mh->is_not_compilable(CompLevel_full_optimization)) { | |
108 if (need_comma) tty->print(", "); | |
109 tty->print("c2"); | |
110 need_comma = true; | |
111 } | |
112 if (!mh->is_not_osr_compilable()) { | |
113 if (need_comma) tty->print(", "); | |
114 tty->print("osr"); | |
115 } | |
116 tty->print(" status:"); | |
117 if (mh->queued_for_compilation()) { | |
118 tty->print(" in queue"); | |
119 } else tty->print(" idle"); | |
120 } | |
121 tty->print_cr("]"); | |
122 } | |
123 | |
124 void SimpleThresholdPolicy::initialize() { | |
125 if (FLAG_IS_DEFAULT(CICompilerCount)) { | |
126 FLAG_SET_DEFAULT(CICompilerCount, 3); | |
127 } | |
128 int count = CICompilerCount; | |
129 if (CICompilerCountPerCPU) { | |
130 count = MAX2(log2_intptr(os::active_processor_count()), 1) * 3 / 2; | |
131 } | |
132 set_c1_count(MAX2(count / 3, 1)); | |
133 set_c2_count(MAX2(count - count / 3, 1)); | |
134 } | |
135 | |
136 void SimpleThresholdPolicy::set_carry_if_necessary(InvocationCounter *counter) { | |
137 if (!counter->carry() && counter->count() > InvocationCounter::count_limit / 2) { | |
138 counter->set_carry_flag(); | |
139 } | |
140 } | |
141 | |
142 // Set carry flags on the counters if necessary | |
143 void SimpleThresholdPolicy::handle_counter_overflow(methodOop method) { | |
144 set_carry_if_necessary(method->invocation_counter()); | |
145 set_carry_if_necessary(method->backedge_counter()); | |
146 methodDataOop mdo = method->method_data(); | |
147 if (mdo != NULL) { | |
148 set_carry_if_necessary(mdo->invocation_counter()); | |
149 set_carry_if_necessary(mdo->backedge_counter()); | |
150 } | |
151 } | |
152 | |
153 // Called with the queue locked and with at least one element | |
154 CompileTask* SimpleThresholdPolicy::select_task(CompileQueue* compile_queue) { | |
155 return compile_queue->first(); | |
156 } | |
157 | |
2252 | 158 void SimpleThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) { |
159 for (ScopeDesc* sd = trap_scope;; sd = sd->sender()) { | |
160 if (PrintTieredEvents) { | |
161 methodHandle mh(sd->method()); | |
162 print_event(REPROFILE, mh, mh, InvocationEntryBci, CompLevel_none); | |
163 } | |
164 methodDataOop mdo = sd->method()->method_data(); | |
165 if (mdo != NULL) { | |
166 mdo->reset_start_counters(); | |
167 } | |
168 if (sd->is_top()) break; | |
169 } | |
170 } | |
171 | |
1783 | 172 nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee, |
173 int branch_bci, int bci, CompLevel comp_level, TRAPS) { | |
174 if (comp_level == CompLevel_none && | |
175 JvmtiExport::can_post_interpreter_events()) { | |
176 assert(THREAD->is_Java_thread(), "Should be java thread"); | |
177 if (((JavaThread*)THREAD)->is_interp_only_mode()) { | |
178 return NULL; | |
179 } | |
180 } | |
181 nmethod *osr_nm = NULL; | |
182 | |
183 handle_counter_overflow(method()); | |
184 if (method() != inlinee()) { | |
185 handle_counter_overflow(inlinee()); | |
186 } | |
187 | |
188 if (PrintTieredEvents) { | |
189 print_event(bci == InvocationEntryBci ? CALL : LOOP, method, inlinee, bci, comp_level); | |
190 } | |
191 | |
192 if (bci == InvocationEntryBci) { | |
193 method_invocation_event(method, inlinee, comp_level, THREAD); | |
194 } else { | |
195 method_back_branch_event(method, inlinee, bci, comp_level, THREAD); | |
196 int highest_level = method->highest_osr_comp_level(); | |
197 if (highest_level > comp_level) { | |
198 osr_nm = method->lookup_osr_nmethod_for(bci, highest_level, false); | |
199 } | |
200 } | |
201 return osr_nm; | |
202 } | |
203 | |
204 // Check if the method can be compiled, change level if necessary | |
205 void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, TRAPS) { | |
206 // Take the given ceiling into the account. | |
207 // NOTE: You can set it to 1 to get a pure C1 version. | |
208 if ((CompLevel)TieredStopAtLevel < level) { | |
209 level = (CompLevel)TieredStopAtLevel; | |
210 } | |
211 if (level == CompLevel_none) { | |
212 return; | |
213 } | |
1964
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
214 // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
215 // in the interpreter and then compile with C2 (the transition function will request that, |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
216 // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with |
22ef3370343b
7000349: Tiered reacts incorrectly to C1 compilation failures
iveresov
parents:
1783
diff
changeset
|
217 // pure C1. |
1783 | 218 if (!can_be_compiled(mh, level)) { |
219 if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) { | |
220 compile(mh, bci, CompLevel_simple, THREAD); | |
221 } | |
222 return; | |
223 } | |
224 if (bci != InvocationEntryBci && mh->is_not_osr_compilable()) { | |
225 return; | |
226 } | |
227 if (PrintTieredEvents) { | |
228 print_event(COMPILE, mh, mh, bci, level); | |
229 } | |
230 if (!CompileBroker::compilation_is_in_queue(mh, bci)) { | |
231 submit_compile(mh, bci, level, THREAD); | |
232 } | |
233 } | |
234 | |
235 // Tell the broker to compile the method | |
236 void SimpleThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) { | |
237 int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); | |
238 CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD); | |
239 } | |
240 | |
241 // Call and loop predicates determine whether a transition to a higher | |
242 // compilation level should be performed (pointers to predicate functions | |
243 // are passed to common() transition function). | |
244 bool SimpleThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) { | |
245 switch(cur_level) { | |
246 case CompLevel_none: | |
247 case CompLevel_limited_profile: { | |
248 return loop_predicate_helper<CompLevel_none>(i, b, 1.0); | |
249 } | |
250 case CompLevel_full_profile: { | |
251 return loop_predicate_helper<CompLevel_full_profile>(i, b, 1.0); | |
252 } | |
253 default: | |
254 return true; | |
255 } | |
256 } | |
257 | |
258 bool SimpleThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) { | |
259 switch(cur_level) { | |
260 case CompLevel_none: | |
261 case CompLevel_limited_profile: { | |
262 return call_predicate_helper<CompLevel_none>(i, b, 1.0); | |
263 } | |
264 case CompLevel_full_profile: { | |
265 return call_predicate_helper<CompLevel_full_profile>(i, b, 1.0); | |
266 } | |
267 default: | |
268 return true; | |
269 } | |
270 } | |
271 | |
272 // Determine is a method is mature. | |
273 bool SimpleThresholdPolicy::is_mature(methodOop method) { | |
274 if (is_trivial(method)) return true; | |
275 methodDataOop mdo = method->method_data(); | |
276 if (mdo != NULL) { | |
277 int i = mdo->invocation_count(); | |
278 int b = mdo->backedge_count(); | |
279 double k = ProfileMaturityPercentage / 100.0; | |
280 return call_predicate_helper<CompLevel_full_profile>(i, b, k) || | |
281 loop_predicate_helper<CompLevel_full_profile>(i, b, k); | |
282 } | |
283 return false; | |
284 } | |
285 | |
286 // Common transition function. Given a predicate determines if a method should transition to another level. | |
287 CompLevel SimpleThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) { | |
2252 | 288 if (is_trivial(method)) return CompLevel_simple; |
289 | |
1783 | 290 CompLevel next_level = cur_level; |
291 int i = method->invocation_count(); | |
292 int b = method->backedge_count(); | |
293 | |
294 switch(cur_level) { | |
295 case CompLevel_none: | |
2252 | 296 // If we were at full profile level, would we switch to full opt? |
297 if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) { | |
298 next_level = CompLevel_full_optimization; | |
299 } else if ((this->*p)(i, b, cur_level)) { | |
300 next_level = CompLevel_full_profile; | |
1783 | 301 } |
302 break; | |
303 case CompLevel_limited_profile: | |
304 case CompLevel_full_profile: | |
2252 | 305 { |
1783 | 306 methodDataOop mdo = method->method_data(); |
2252 | 307 if (mdo != NULL) { |
308 if (mdo->would_profile()) { | |
309 int mdo_i = mdo->invocation_count_delta(); | |
310 int mdo_b = mdo->backedge_count_delta(); | |
311 if ((this->*p)(mdo_i, mdo_b, cur_level)) { | |
312 next_level = CompLevel_full_optimization; | |
313 } | |
314 } else { | |
1783 | 315 next_level = CompLevel_full_optimization; |
316 } | |
317 } | |
318 } | |
319 break; | |
320 } | |
321 return next_level; | |
322 } | |
323 | |
324 // Determine if a method should be compiled with a normal entry point at a different level. | |
325 CompLevel SimpleThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { | |
326 CompLevel osr_level = (CompLevel) method->highest_osr_comp_level(); | |
327 CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level); | |
328 | |
329 // If OSR method level is greater than the regular method level, the levels should be | |
330 // equalized by raising the regular method level in order to avoid OSRs during each | |
331 // invocation of the method. | |
332 if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { | |
333 methodDataOop mdo = method->method_data(); | |
334 guarantee(mdo != NULL, "MDO should not be NULL"); | |
335 if (mdo->invocation_count() >= 1) { | |
336 next_level = CompLevel_full_optimization; | |
337 } | |
338 } else { | |
339 next_level = MAX2(osr_level, next_level); | |
340 } | |
341 | |
342 return next_level; | |
343 } | |
344 | |
345 // Determine if we should do an OSR compilation of a given method. | |
346 CompLevel SimpleThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { | |
347 if (cur_level == CompLevel_none) { | |
348 // If there is a live OSR method that means that we deopted to the interpreter | |
349 // for the transition. | |
350 CompLevel osr_level = (CompLevel)method->highest_osr_comp_level(); | |
351 if (osr_level > CompLevel_none) { | |
352 return osr_level; | |
353 } | |
354 } | |
355 return common(&SimpleThresholdPolicy::loop_predicate, method, cur_level); | |
356 } | |
357 | |
358 | |
359 // Handle the invocation event. | |
360 void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, | |
361 CompLevel level, TRAPS) { | |
362 if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { | |
363 CompLevel next_level = call_event(mh(), level); | |
364 if (next_level != level) { | |
365 compile(mh, InvocationEntryBci, next_level, THREAD); | |
366 } | |
367 } | |
368 } | |
369 | |
370 // Handle the back branch event. Notice that we can compile the method | |
371 // with a regular entry from here. | |
372 void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, | |
373 int bci, CompLevel level, TRAPS) { | |
374 // If the method is already compiling, quickly bail out. | |
375 if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) { | |
376 // Use loop event as an opportinity to also check there's been | |
377 // enough calls. | |
378 CompLevel cur_level = comp_level(mh()); | |
379 CompLevel next_level = call_event(mh(), cur_level); | |
380 CompLevel next_osr_level = loop_event(mh(), level); | |
381 | |
382 next_level = MAX2(next_level, | |
383 next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level); | |
384 bool is_compiling = false; | |
385 if (next_level != cur_level) { | |
386 compile(mh, InvocationEntryBci, next_level, THREAD); | |
387 is_compiling = true; | |
388 } | |
389 | |
390 // Do the OSR version | |
391 if (!is_compiling && next_osr_level != level) { | |
392 compile(mh, bci, next_osr_level, THREAD); | |
393 } | |
394 } | |
395 } |