1 /* |
1 /* |
2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2010, 2012, 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. |
71 |
71 |
72 set_start_time(os::javaTimeMillis()); |
72 set_start_time(os::javaTimeMillis()); |
73 } |
73 } |
74 |
74 |
75 // update_rate() is called from select_task() while holding a compile queue lock. |
75 // update_rate() is called from select_task() while holding a compile queue lock. |
76 void AdvancedThresholdPolicy::update_rate(jlong t, methodOop m) { |
76 void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) { |
77 if (is_old(m)) { |
77 if (is_old(m)) { |
78 // We don't remove old methods from the queue, |
78 // We don't remove old methods from the queue, |
79 // so we can just zero the rate. |
79 // so we can just zero the rate. |
80 m->set_rate(0); |
80 m->set_rate(0); |
81 return; |
81 return; |
104 } |
104 } |
105 } |
105 } |
106 |
106 |
107 // Check if this method has been stale from a given number of milliseconds. |
107 // Check if this method has been stale from a given number of milliseconds. |
108 // See select_task(). |
108 // See select_task(). |
109 bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, methodOop m) { |
109 bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) { |
110 jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); |
110 jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); |
111 jlong delta_t = t - m->prev_time(); |
111 jlong delta_t = t - m->prev_time(); |
112 if (delta_t > timeout && delta_s > timeout) { |
112 if (delta_t > timeout && delta_s > timeout) { |
113 int event_count = m->invocation_count() + m->backedge_count(); |
113 int event_count = m->invocation_count() + m->backedge_count(); |
114 int delta_e = event_count - m->prev_event_count(); |
114 int delta_e = event_count - m->prev_event_count(); |
118 return false; |
118 return false; |
119 } |
119 } |
120 |
120 |
121 // We don't remove old methods from the compile queue even if they have |
121 // We don't remove old methods from the compile queue even if they have |
122 // very low activity. See select_task(). |
122 // very low activity. See select_task(). |
123 bool AdvancedThresholdPolicy::is_old(methodOop method) { |
123 bool AdvancedThresholdPolicy::is_old(Method* method) { |
124 return method->invocation_count() > 50000 || method->backedge_count() > 500000; |
124 return method->invocation_count() > 50000 || method->backedge_count() > 500000; |
125 } |
125 } |
126 |
126 |
127 double AdvancedThresholdPolicy::weight(methodOop method) { |
127 double AdvancedThresholdPolicy::weight(Method* method) { |
128 return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); |
128 return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); |
129 } |
129 } |
130 |
130 |
131 // Apply heuristics and return true if x should be compiled before y |
131 // Apply heuristics and return true if x should be compiled before y |
132 bool AdvancedThresholdPolicy::compare_methods(methodOop x, methodOop y) { |
132 bool AdvancedThresholdPolicy::compare_methods(Method* x, Method* y) { |
133 if (x->highest_comp_level() > y->highest_comp_level()) { |
133 if (x->highest_comp_level() > y->highest_comp_level()) { |
134 // recompilation after deopt |
134 // recompilation after deopt |
135 return true; |
135 return true; |
136 } else |
136 } else |
137 if (x->highest_comp_level() == y->highest_comp_level()) { |
137 if (x->highest_comp_level() == y->highest_comp_level()) { |
141 } |
141 } |
142 return false; |
142 return false; |
143 } |
143 } |
144 |
144 |
145 // Is method profiled enough? |
145 // Is method profiled enough? |
146 bool AdvancedThresholdPolicy::is_method_profiled(methodOop method) { |
146 bool AdvancedThresholdPolicy::is_method_profiled(Method* method) { |
147 methodDataOop mdo = method->method_data(); |
147 MethodData* mdo = method->method_data(); |
148 if (mdo != NULL) { |
148 if (mdo != NULL) { |
149 int i = mdo->invocation_count_delta(); |
149 int i = mdo->invocation_count_delta(); |
150 int b = mdo->backedge_count_delta(); |
150 int b = mdo->backedge_count_delta(); |
151 return call_predicate_helper<CompLevel_full_profile>(i, b, 1); |
151 return call_predicate_helper<CompLevel_full_profile>(i, b, 1); |
152 } |
152 } |
154 } |
154 } |
155 |
155 |
156 // Called with the queue locked and with at least one element |
156 // Called with the queue locked and with at least one element |
157 CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { |
157 CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { |
158 CompileTask *max_task = NULL; |
158 CompileTask *max_task = NULL; |
159 methodHandle max_method; |
159 Method* max_method; |
160 jlong t = os::javaTimeMillis(); |
160 jlong t = os::javaTimeMillis(); |
161 // Iterate through the queue and find a method with a maximum rate. |
161 // Iterate through the queue and find a method with a maximum rate. |
162 for (CompileTask* task = compile_queue->first(); task != NULL;) { |
162 for (CompileTask* task = compile_queue->first(); task != NULL;) { |
163 CompileTask* next_task = task->next(); |
163 CompileTask* next_task = task->next(); |
164 methodHandle method = (methodOop)JNIHandles::resolve(task->method_handle()); |
164 Method* method = task->method(); |
165 update_rate(t, method()); |
165 MethodData* mdo = method->method_data(); |
|
166 update_rate(t, method); |
166 if (max_task == NULL) { |
167 if (max_task == NULL) { |
167 max_task = task; |
168 max_task = task; |
168 max_method = method; |
169 max_method = method; |
169 } else { |
170 } else { |
170 // If a method has been stale for some time, remove it from the queue. |
171 // If a method has been stale for some time, remove it from the queue. |
171 if (is_stale(t, TieredCompileTaskTimeout, method()) && !is_old(method())) { |
172 if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { |
172 if (PrintTieredEvents) { |
173 if (PrintTieredEvents) { |
173 print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); |
174 print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); |
174 } |
175 } |
175 CompileTaskWrapper ctw(task); // Frees the task |
176 CompileTaskWrapper ctw(task); // Frees the task |
176 compile_queue->remove(task); |
177 compile_queue->remove(task); |
178 task = next_task; |
179 task = next_task; |
179 continue; |
180 continue; |
180 } |
181 } |
181 |
182 |
182 // Select a method with a higher rate |
183 // Select a method with a higher rate |
183 if (compare_methods(method(), max_method())) { |
184 if (compare_methods(method, max_method)) { |
184 max_task = task; |
185 max_task = task; |
185 max_method = method; |
186 max_method = method; |
186 } |
187 } |
187 } |
188 } |
188 task = next_task; |
189 task = next_task; |
189 } |
190 } |
190 |
191 |
191 if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile |
192 if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile |
192 && is_method_profiled(max_method())) { |
193 && is_method_profiled(max_method)) { |
193 max_task->set_comp_level(CompLevel_limited_profile); |
194 max_task->set_comp_level(CompLevel_limited_profile); |
194 if (PrintTieredEvents) { |
195 if (PrintTieredEvents) { |
195 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); |
196 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); |
196 } |
197 } |
197 } |
198 } |
245 } |
246 } |
246 |
247 |
247 // If a method is old enough and is still in the interpreter we would want to |
248 // If a method is old enough and is still in the interpreter we would want to |
248 // start profiling without waiting for the compiled method to arrive. |
249 // start profiling without waiting for the compiled method to arrive. |
249 // We also take the load on compilers into the account. |
250 // We also take the load on compilers into the account. |
250 bool AdvancedThresholdPolicy::should_create_mdo(methodOop method, CompLevel cur_level) { |
251 bool AdvancedThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) { |
251 if (cur_level == CompLevel_none && |
252 if (cur_level == CompLevel_none && |
252 CompileBroker::queue_size(CompLevel_full_optimization) <= |
253 CompileBroker::queue_size(CompLevel_full_optimization) <= |
253 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
254 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
254 int i = method->invocation_count(); |
255 int i = method->invocation_count(); |
255 int b = method->backedge_count(); |
256 int b = method->backedge_count(); |
272 |
273 |
273 // Create MDO if necessary. |
274 // Create MDO if necessary. |
274 void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) { |
275 void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) { |
275 if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; |
276 if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; |
276 if (mh->method_data() == NULL) { |
277 if (mh->method_data() == NULL) { |
277 methodOopDesc::build_interpreter_method_data(mh, CHECK_AND_CLEAR); |
278 Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR); |
278 } |
279 } |
279 } |
280 } |
280 |
281 |
281 |
282 |
282 /* |
283 /* |
316 * are possible. |
317 * are possible. |
317 * |
318 * |
318 */ |
319 */ |
319 |
320 |
320 // Common transition function. Given a predicate determines if a method should transition to another level. |
321 // Common transition function. Given a predicate determines if a method should transition to another level. |
321 CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level, bool disable_feedback) { |
322 CompLevel AdvancedThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback) { |
322 CompLevel next_level = cur_level; |
323 CompLevel next_level = cur_level; |
323 int i = method->invocation_count(); |
324 int i = method->invocation_count(); |
324 int b = method->backedge_count(); |
325 int b = method->backedge_count(); |
325 |
326 |
326 if (is_trivial(method)) { |
327 if (is_trivial(method)) { |
350 case CompLevel_limited_profile: |
351 case CompLevel_limited_profile: |
351 if (is_method_profiled(method)) { |
352 if (is_method_profiled(method)) { |
352 // Special case: we got here because this method was fully profiled in the interpreter. |
353 // Special case: we got here because this method was fully profiled in the interpreter. |
353 next_level = CompLevel_full_optimization; |
354 next_level = CompLevel_full_optimization; |
354 } else { |
355 } else { |
355 methodDataOop mdo = method->method_data(); |
356 MethodData* mdo = method->method_data(); |
356 if (mdo != NULL) { |
357 if (mdo != NULL) { |
357 if (mdo->would_profile()) { |
358 if (mdo->would_profile()) { |
358 if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= |
359 if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= |
359 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && |
360 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && |
360 (this->*p)(i, b, cur_level))) { |
361 (this->*p)(i, b, cur_level))) { |
366 } |
367 } |
367 } |
368 } |
368 break; |
369 break; |
369 case CompLevel_full_profile: |
370 case CompLevel_full_profile: |
370 { |
371 { |
371 methodDataOop mdo = method->method_data(); |
372 MethodData* mdo = method->method_data(); |
372 if (mdo != NULL) { |
373 if (mdo != NULL) { |
373 if (mdo->would_profile()) { |
374 if (mdo->would_profile()) { |
374 int mdo_i = mdo->invocation_count_delta(); |
375 int mdo_i = mdo->invocation_count_delta(); |
375 int mdo_b = mdo->backedge_count_delta(); |
376 int mdo_b = mdo->backedge_count_delta(); |
376 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
377 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
386 } |
387 } |
387 return MIN2(next_level, (CompLevel)TieredStopAtLevel); |
388 return MIN2(next_level, (CompLevel)TieredStopAtLevel); |
388 } |
389 } |
389 |
390 |
390 // Determine if a method should be compiled with a normal entry point at a different level. |
391 // Determine if a method should be compiled with a normal entry point at a different level. |
391 CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { |
392 CompLevel AdvancedThresholdPolicy::call_event(Method* method, CompLevel cur_level) { |
392 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), |
393 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), |
393 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); |
394 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); |
394 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); |
395 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); |
395 |
396 |
396 // If OSR method level is greater than the regular method level, the levels should be |
397 // If OSR method level is greater than the regular method level, the levels should be |
397 // equalized by raising the regular method level in order to avoid OSRs during each |
398 // equalized by raising the regular method level in order to avoid OSRs during each |
398 // invocation of the method. |
399 // invocation of the method. |
399 if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { |
400 if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { |
400 methodDataOop mdo = method->method_data(); |
401 MethodData* mdo = method->method_data(); |
401 guarantee(mdo != NULL, "MDO should not be NULL"); |
402 guarantee(mdo != NULL, "MDO should not be NULL"); |
402 if (mdo->invocation_count() >= 1) { |
403 if (mdo->invocation_count() >= 1) { |
403 next_level = CompLevel_full_optimization; |
404 next_level = CompLevel_full_optimization; |
404 } |
405 } |
405 } else { |
406 } else { |
407 } |
408 } |
408 return next_level; |
409 return next_level; |
409 } |
410 } |
410 |
411 |
411 // Determine if we should do an OSR compilation of a given method. |
412 // Determine if we should do an OSR compilation of a given method. |
412 CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { |
413 CompLevel AdvancedThresholdPolicy::loop_event(Method* method, CompLevel cur_level) { |
413 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); |
414 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); |
414 if (cur_level == CompLevel_none) { |
415 if (cur_level == CompLevel_none) { |
415 // If there is a live OSR method that means that we deopted to the interpreter |
416 // If there is a live OSR method that means that we deopted to the interpreter |
416 // for the transition. |
417 // for the transition. |
417 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); |
418 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); |