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(); |
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 |