319 * are possible. |
320 * are possible. |
320 * |
321 * |
321 */ |
322 */ |
322 |
323 |
323 // Common transition function. Given a predicate determines if a method should transition to another level. |
324 // Common transition function. Given a predicate determines if a method should transition to another level. |
324 CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) { |
325 CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level, bool disable_feedback) { |
325 if (is_trivial(method)) return CompLevel_simple; |
|
326 |
|
327 CompLevel next_level = cur_level; |
326 CompLevel next_level = cur_level; |
328 int i = method->invocation_count(); |
327 int i = method->invocation_count(); |
329 int b = method->backedge_count(); |
328 int b = method->backedge_count(); |
330 |
329 |
331 switch(cur_level) { |
330 if (is_trivial(method)) { |
332 case CompLevel_none: |
331 next_level = CompLevel_simple; |
333 // If we were at full profile level, would we switch to full opt? |
332 } else { |
334 if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) { |
333 switch(cur_level) { |
335 next_level = CompLevel_full_optimization; |
334 case CompLevel_none: |
336 } else if ((this->*p)(i, b, cur_level)) { |
335 // If we were at full profile level, would we switch to full opt? |
337 // C1-generated fully profiled code is about 30% slower than the limited profile |
336 if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) { |
338 // code that has only invocation and backedge counters. The observation is that |
337 next_level = CompLevel_full_optimization; |
339 // if C2 queue is large enough we can spend too much time in the fully profiled code |
338 } else if ((this->*p)(i, b, cur_level)) { |
340 // while waiting for C2 to pick the method from the queue. To alleviate this problem |
339 // C1-generated fully profiled code is about 30% slower than the limited profile |
341 // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long |
340 // code that has only invocation and backedge counters. The observation is that |
342 // we choose to compile a limited profiled version and then recompile with full profiling |
341 // if C2 queue is large enough we can spend too much time in the fully profiled code |
343 // when the load on C2 goes down. |
342 // while waiting for C2 to pick the method from the queue. To alleviate this problem |
344 if (CompileBroker::queue_size(CompLevel_full_optimization) > |
343 // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long |
345 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
344 // we choose to compile a limited profiled version and then recompile with full profiling |
346 next_level = CompLevel_limited_profile; |
345 // when the load on C2 goes down. |
|
346 if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) > |
|
347 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
|
348 next_level = CompLevel_limited_profile; |
|
349 } else { |
|
350 next_level = CompLevel_full_profile; |
|
351 } |
|
352 } |
|
353 break; |
|
354 case CompLevel_limited_profile: |
|
355 if (is_method_profiled(method)) { |
|
356 // Special case: we got here because this method was fully profiled in the interpreter. |
|
357 next_level = CompLevel_full_optimization; |
347 } else { |
358 } else { |
348 next_level = CompLevel_full_profile; |
359 methodDataOop mdo = method->method_data(); |
349 } |
360 if (mdo != NULL) { |
350 } |
361 if (mdo->would_profile()) { |
351 break; |
362 if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= |
352 case CompLevel_limited_profile: |
363 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && |
353 if (is_method_profiled(method)) { |
364 (this->*p)(i, b, cur_level))) { |
354 // Special case: we got here because this method was fully profiled in the interpreter. |
365 next_level = CompLevel_full_profile; |
355 next_level = CompLevel_full_optimization; |
366 } |
356 } else { |
367 } else { |
357 methodDataOop mdo = method->method_data(); |
|
358 if (mdo != NULL) { |
|
359 if (mdo->would_profile()) { |
|
360 if (CompileBroker::queue_size(CompLevel_full_optimization) <= |
|
361 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && |
|
362 (this->*p)(i, b, cur_level)) { |
|
363 next_level = CompLevel_full_profile; |
|
364 } |
|
365 } else { |
|
366 next_level = CompLevel_full_optimization; |
|
367 } |
|
368 } |
|
369 } |
|
370 break; |
|
371 case CompLevel_full_profile: |
|
372 { |
|
373 methodDataOop mdo = method->method_data(); |
|
374 if (mdo != NULL) { |
|
375 if (mdo->would_profile()) { |
|
376 int mdo_i = mdo->invocation_count_delta(); |
|
377 int mdo_b = mdo->backedge_count_delta(); |
|
378 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
|
379 next_level = CompLevel_full_optimization; |
368 next_level = CompLevel_full_optimization; |
380 } |
369 } |
381 } else { |
370 } |
382 next_level = CompLevel_full_optimization; |
371 } |
383 } |
372 break; |
384 } |
373 case CompLevel_full_profile: |
385 } |
374 { |
386 break; |
375 methodDataOop mdo = method->method_data(); |
387 } |
376 if (mdo != NULL) { |
388 return next_level; |
377 if (mdo->would_profile()) { |
|
378 int mdo_i = mdo->invocation_count_delta(); |
|
379 int mdo_b = mdo->backedge_count_delta(); |
|
380 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
|
381 next_level = CompLevel_full_optimization; |
|
382 } |
|
383 } else { |
|
384 next_level = CompLevel_full_optimization; |
|
385 } |
|
386 } |
|
387 } |
|
388 break; |
|
389 } |
|
390 } |
|
391 return MIN2(next_level, (CompLevel)TieredStopAtLevel); |
389 } |
392 } |
390 |
393 |
391 // Determine if a method should be compiled with a normal entry point at a different level. |
394 // Determine if a method should be compiled with a normal entry point at a different level. |
392 CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { |
395 CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { |
393 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), |
396 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), |
394 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level)); |
397 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); |
395 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); |
398 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); |
396 |
399 |
397 // If OSR method level is greater than the regular method level, the levels should be |
400 // If OSR method level is greater than the regular method level, the levels should be |
398 // equalized by raising the regular method level in order to avoid OSRs during each |
401 // equalized by raising the regular method level in order to avoid OSRs during each |
399 // invocation of the method. |
402 // invocation of the method. |
404 next_level = CompLevel_full_optimization; |
407 next_level = CompLevel_full_optimization; |
405 } |
408 } |
406 } else { |
409 } else { |
407 next_level = MAX2(osr_level, next_level); |
410 next_level = MAX2(osr_level, next_level); |
408 } |
411 } |
409 |
|
410 return next_level; |
412 return next_level; |
411 } |
413 } |
412 |
414 |
413 // Determine if we should do an OSR compilation of a given method. |
415 // Determine if we should do an OSR compilation of a given method. |
414 CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { |
416 CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { |
415 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level); |
417 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); |
416 if (cur_level == CompLevel_none) { |
418 if (cur_level == CompLevel_none) { |
417 // If there is a live OSR method that means that we deopted to the interpreter |
419 // If there is a live OSR method that means that we deopted to the interpreter |
418 // for the transition. |
420 // for the transition. |
419 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); |
421 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); |
420 if (osr_level > CompLevel_none) { |
422 if (osr_level > CompLevel_none) { |
458 } |
460 } |
459 |
461 |
460 if (is_compilation_enabled()) { |
462 if (is_compilation_enabled()) { |
461 CompLevel next_osr_level = loop_event(imh(), level); |
463 CompLevel next_osr_level = loop_event(imh(), level); |
462 CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level(); |
464 CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level(); |
463 if (next_osr_level == CompLevel_limited_profile) { |
|
464 next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods. |
|
465 } |
|
466 |
|
467 // At the very least compile the OSR version |
465 // At the very least compile the OSR version |
468 if (!CompileBroker::compilation_is_in_queue(imh, bci)) { |
466 if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_osr_level != level) { |
469 // Check if there's a method like that already |
467 compile(imh, bci, next_osr_level, THREAD); |
470 nmethod* osr_nm = NULL; |
|
471 if (max_osr_level >= next_osr_level) { |
|
472 // There is an osr method already with the same |
|
473 // or greater level, check if it has the bci we need |
|
474 osr_nm = imh->lookup_osr_nmethod_for(bci, next_osr_level, false); |
|
475 } |
|
476 if (osr_nm == NULL) { |
|
477 compile(imh, bci, next_osr_level, THREAD); |
|
478 } |
|
479 } |
468 } |
480 |
469 |
481 // Use loop event as an opportunity to also check if there's been |
470 // Use loop event as an opportunity to also check if there's been |
482 // enough calls. |
471 // enough calls. |
483 CompLevel cur_level, next_level; |
472 CompLevel cur_level, next_level; |