Mercurial > hg > truffle
comparison src/share/vm/runtime/simpleThresholdPolicy.cpp @ 2252:72d6c57d0658
7017434: Tiered needs to support reprofiling
Summary: Tiered needs to support proper method reprofiling after deopts.
Reviewed-by: kvn
author | iveresov |
---|---|
date | Wed, 09 Feb 2011 16:34:34 -0800 |
parents | f95d63e2154a |
children | 97b64f73103b |
comparison
equal
deleted
inserted
replaced
2251:336d17dff7cc | 2252:72d6c57d0658 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
26 #include "compiler/compileBroker.hpp" | 26 #include "compiler/compileBroker.hpp" |
27 #include "memory/resourceArea.hpp" | 27 #include "memory/resourceArea.hpp" |
28 #include "runtime/arguments.hpp" | 28 #include "runtime/arguments.hpp" |
29 #include "runtime/simpleThresholdPolicy.hpp" | 29 #include "runtime/simpleThresholdPolicy.hpp" |
30 #include "runtime/simpleThresholdPolicy.inline.hpp" | 30 #include "runtime/simpleThresholdPolicy.inline.hpp" |
31 #include "code/scopeDesc.hpp" | |
31 | 32 |
32 // Print an event. | 33 // Print an event. |
33 void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodHandle imh, | 34 void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodHandle imh, |
34 int bci, CompLevel level) { | 35 int bci, CompLevel level) { |
35 bool inlinee_event = mh() != imh(); | 36 bool inlinee_event = mh() != imh(); |
46 case LOOP: | 47 case LOOP: |
47 tty->print("loop"); | 48 tty->print("loop"); |
48 break; | 49 break; |
49 case COMPILE: | 50 case COMPILE: |
50 tty->print("compile"); | 51 tty->print("compile"); |
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"); | |
51 } | 64 } |
52 | 65 |
53 tty->print(" level: %d ", level); | 66 tty->print(" level: %d ", level); |
54 | 67 |
55 ResourceMark rm; | 68 ResourceMark rm; |
67 print_specific(type, mh, imh, bci, level); | 80 print_specific(type, mh, imh, bci, level); |
68 | 81 |
69 if (type != COMPILE) { | 82 if (type != COMPILE) { |
70 methodDataHandle mdh = mh->method_data(); | 83 methodDataHandle mdh = mh->method_data(); |
71 int mdo_invocations = 0, mdo_backedges = 0; | 84 int mdo_invocations = 0, mdo_backedges = 0; |
85 int mdo_invocations_start = 0, mdo_backedges_start = 0; | |
72 if (mdh() != NULL) { | 86 if (mdh() != NULL) { |
73 mdo_invocations = mdh->invocation_count(); | 87 mdo_invocations = mdh->invocation_count(); |
74 mdo_backedges = mdh->backedge_count(); | 88 mdo_backedges = mdh->backedge_count(); |
75 } | 89 mdo_invocations_start = mdh->invocation_count_start(); |
76 tty->print(" total: %d,%d mdo: %d,%d", | 90 mdo_backedges_start = mdh->backedge_count_start(); |
91 } | |
92 tty->print(" total: %d,%d mdo: %d(%d),%d(%d)", | |
77 invocation_count, backedge_count, | 93 invocation_count, backedge_count, |
78 mdo_invocations, mdo_backedges); | 94 mdo_invocations, mdo_invocations_start, |
95 mdo_backedges, mdo_backedges_start); | |
79 tty->print(" max levels: %d,%d", | 96 tty->print(" max levels: %d,%d", |
80 mh->highest_comp_level(), mh->highest_osr_comp_level()); | 97 mh->highest_comp_level(), mh->highest_osr_comp_level()); |
81 if (inlinee_event) { | 98 if (inlinee_event) { |
82 tty->print(" inlinee max levels: %d,%d", imh->highest_comp_level(), imh->highest_osr_comp_level()); | 99 tty->print(" inlinee max levels: %d,%d", imh->highest_comp_level(), imh->highest_osr_comp_level()); |
83 } | 100 } |
134 } | 151 } |
135 | 152 |
136 // Called with the queue locked and with at least one element | 153 // Called with the queue locked and with at least one element |
137 CompileTask* SimpleThresholdPolicy::select_task(CompileQueue* compile_queue) { | 154 CompileTask* SimpleThresholdPolicy::select_task(CompileQueue* compile_queue) { |
138 return compile_queue->first(); | 155 return compile_queue->first(); |
156 } | |
157 | |
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 } | |
139 } | 170 } |
140 | 171 |
141 nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee, | 172 nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee, |
142 int branch_bci, int bci, CompLevel comp_level, TRAPS) { | 173 int branch_bci, int bci, CompLevel comp_level, TRAPS) { |
143 if (comp_level == CompLevel_none && | 174 if (comp_level == CompLevel_none && |
252 return false; | 283 return false; |
253 } | 284 } |
254 | 285 |
255 // Common transition function. Given a predicate determines if a method should transition to another level. | 286 // Common transition function. Given a predicate determines if a method should transition to another level. |
256 CompLevel SimpleThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) { | 287 CompLevel SimpleThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) { |
288 if (is_trivial(method)) return CompLevel_simple; | |
289 | |
257 CompLevel next_level = cur_level; | 290 CompLevel next_level = cur_level; |
258 int i = method->invocation_count(); | 291 int i = method->invocation_count(); |
259 int b = method->backedge_count(); | 292 int b = method->backedge_count(); |
260 | 293 |
261 switch(cur_level) { | 294 switch(cur_level) { |
262 case CompLevel_none: | 295 case CompLevel_none: |
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; | |
301 } | |
302 break; | |
303 case CompLevel_limited_profile: | |
304 case CompLevel_full_profile: | |
263 { | 305 { |
264 methodDataOop mdo = method->method_data(); | 306 methodDataOop mdo = method->method_data(); |
265 if (mdo != NULL) { | 307 if (mdo != NULL) { |
266 int mdo_i = mdo->invocation_count(); | 308 if (mdo->would_profile()) { |
267 int mdo_b = mdo->backedge_count(); | 309 int mdo_i = mdo->invocation_count_delta(); |
268 // If we were at full profile level, would we switch to full opt? | 310 int mdo_b = mdo->backedge_count_delta(); |
269 if ((this->*p)(mdo_i, mdo_b, CompLevel_full_profile)) { | 311 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
312 next_level = CompLevel_full_optimization; | |
313 } | |
314 } else { | |
270 next_level = CompLevel_full_optimization; | 315 next_level = CompLevel_full_optimization; |
271 } | 316 } |
272 } | 317 } |
273 } | 318 } |
274 if (next_level == cur_level && (this->*p)(i, b, cur_level)) { | |
275 if (is_trivial(method)) { | |
276 next_level = CompLevel_simple; | |
277 } else { | |
278 next_level = CompLevel_full_profile; | |
279 } | |
280 } | |
281 break; | |
282 case CompLevel_limited_profile: | |
283 case CompLevel_full_profile: | |
284 if (is_trivial(method)) { | |
285 next_level = CompLevel_simple; | |
286 } else { | |
287 methodDataOop mdo = method->method_data(); | |
288 guarantee(mdo != NULL, "MDO should always exist"); | |
289 if (mdo->would_profile()) { | |
290 int mdo_i = mdo->invocation_count(); | |
291 int mdo_b = mdo->backedge_count(); | |
292 if ((this->*p)(mdo_i, mdo_b, cur_level)) { | |
293 next_level = CompLevel_full_optimization; | |
294 } | |
295 } else { | |
296 next_level = CompLevel_full_optimization; | |
297 } | |
298 } | |
299 break; | 319 break; |
300 } | 320 } |
301 return next_level; | 321 return next_level; |
302 } | 322 } |
303 | 323 |
304 // Determine if a method should be compiled with a normal entry point at a different level. | 324 // Determine if a method should be compiled with a normal entry point at a different level. |
305 CompLevel SimpleThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { | 325 CompLevel SimpleThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { |
306 CompLevel highest_level = (CompLevel)method->highest_comp_level(); | |
307 if (cur_level == CompLevel_none && highest_level > cur_level) { | |
308 // TODO: We may want to try to do more extensive reprofiling in this case. | |
309 return highest_level; | |
310 } | |
311 | |
312 CompLevel osr_level = (CompLevel) method->highest_osr_comp_level(); | 326 CompLevel osr_level = (CompLevel) method->highest_osr_comp_level(); |
313 CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level); | 327 CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level); |
314 | 328 |
315 // If OSR method level is greater than the regular method level, the levels should be | 329 // If OSR method level is greater than the regular method level, the levels should be |
316 // equalized by raising the regular method level in order to avoid OSRs during each | 330 // equalized by raising the regular method level in order to avoid OSRs during each |