Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/advancedThresholdPolicy.cpp @ 3791:2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
Summary: Recompile the enclosing methods without inlining of the method that has OSRed to level 4 or recompile the enclosing method at level 4.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Fri, 01 Jul 2011 10:37:37 -0700 |
parents | 6f6e91603a45 |
children | 43f9d800f276 |
comparison
equal
deleted
inserted
replaced
3790:6f6e91603a45 | 3791:2c359f27615c |
---|---|
169 max_method = method; | 169 max_method = method; |
170 } else { | 170 } else { |
171 // 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. |
172 if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { | 172 if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { |
173 if (PrintTieredEvents) { | 173 if (PrintTieredEvents) { |
174 print_event(KILL, method, method, task->osr_bci(), (CompLevel)task->comp_level()); | 174 print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); |
175 } | 175 } |
176 CompileTaskWrapper ctw(task); // Frees the task | 176 CompileTaskWrapper ctw(task); // Frees the task |
177 compile_queue->remove(task); | 177 compile_queue->remove(task); |
178 method->clear_queued_for_compilation(); | 178 method->clear_queued_for_compilation(); |
179 task = next_task; | 179 task = next_task; |
190 } | 190 } |
191 | 191 |
192 if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) { | 192 if (max_task->comp_level() == CompLevel_full_profile && is_method_profiled(max_method)) { |
193 max_task->set_comp_level(CompLevel_limited_profile); | 193 max_task->set_comp_level(CompLevel_limited_profile); |
194 if (PrintTieredEvents) { | 194 if (PrintTieredEvents) { |
195 print_event(UPDATE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); | 195 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); |
196 } | 196 } |
197 } | 197 } |
198 | 198 |
199 return max_task; | 199 return max_task; |
200 } | 200 } |
253 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { | 253 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
254 int i = method->invocation_count(); | 254 int i = method->invocation_count(); |
255 int b = method->backedge_count(); | 255 int b = method->backedge_count(); |
256 double k = Tier0ProfilingStartPercentage / 100.0; | 256 double k = Tier0ProfilingStartPercentage / 100.0; |
257 return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper<CompLevel_none>(i, b, k); | 257 return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper<CompLevel_none>(i, b, k); |
258 } | |
259 return false; | |
260 } | |
261 | |
262 // Inlining control: if we're compiling a profiled method with C1 and the callee | |
263 // is known to have OSRed in a C2 version, don't inline it. | |
264 bool AdvancedThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) { | |
265 CompLevel comp_level = (CompLevel)env->comp_level(); | |
266 if (comp_level == CompLevel_full_profile || | |
267 comp_level == CompLevel_limited_profile) { | |
268 return callee->highest_osr_comp_level() == CompLevel_full_optimization; | |
258 } | 269 } |
259 return false; | 270 return false; |
260 } | 271 } |
261 | 272 |
262 // Create MDO if necessary. | 273 // Create MDO if necessary. |
418 int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); | 429 int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); |
419 update_rate(os::javaTimeMillis(), mh()); | 430 update_rate(os::javaTimeMillis(), mh()); |
420 CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD); | 431 CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD); |
421 } | 432 } |
422 | 433 |
423 | |
424 // Handle the invocation event. | 434 // Handle the invocation event. |
425 void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, | 435 void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, |
426 CompLevel level, TRAPS) { | 436 CompLevel level, nmethod* nm, TRAPS) { |
427 if (should_create_mdo(mh(), level)) { | 437 if (should_create_mdo(mh(), level)) { |
428 create_mdo(mh, THREAD); | 438 create_mdo(mh, THREAD); |
429 } | 439 } |
430 if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { | 440 if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { |
431 CompLevel next_level = call_event(mh(), level); | 441 CompLevel next_level = call_event(mh(), level); |
436 } | 446 } |
437 | 447 |
438 // Handle the back branch event. Notice that we can compile the method | 448 // Handle the back branch event. Notice that we can compile the method |
439 // with a regular entry from here. | 449 // with a regular entry from here. |
440 void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, | 450 void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, |
441 int bci, CompLevel level, TRAPS) { | 451 int bci, CompLevel level, nmethod* nm, TRAPS) { |
442 if (should_create_mdo(mh(), level)) { | 452 if (should_create_mdo(mh(), level)) { |
443 create_mdo(mh, THREAD); | 453 create_mdo(mh, THREAD); |
444 } | 454 } |
445 | 455 // Check if MDO should be created for the inlined method |
446 // If the method is already compiling, quickly bail out. | 456 if (should_create_mdo(imh(), level)) { |
447 if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, bci)) { | 457 create_mdo(imh, THREAD); |
448 // Use loop event as an opportinity to also check there's been | 458 } |
449 // enough calls. | 459 |
450 CompLevel cur_level = comp_level(mh()); | 460 if (is_compilation_enabled()) { |
451 CompLevel next_level = call_event(mh(), cur_level); | 461 CompLevel next_osr_level = loop_event(imh(), level); |
452 CompLevel next_osr_level = loop_event(mh(), level); | 462 CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level(); |
453 if (next_osr_level == CompLevel_limited_profile) { | 463 if (next_osr_level == CompLevel_limited_profile) { |
454 next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods. | 464 next_osr_level = CompLevel_full_profile; // OSRs are supposed to be for very hot methods. |
455 } | 465 } |
456 next_level = MAX2(next_level, | 466 |
457 next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level); | 467 // At the very least compile the OSR version |
458 bool is_compiling = false; | 468 if (!CompileBroker::compilation_is_in_queue(imh, bci)) { |
459 if (next_level != cur_level) { | 469 // Check if there's a method like that already |
460 compile(mh, InvocationEntryBci, next_level, THREAD); | 470 nmethod* osr_nm = NULL; |
461 is_compiling = true; | 471 if (max_osr_level >= next_osr_level) { |
462 } | 472 // There is an osr method already with the same |
463 | 473 // or greater level, check if it has the bci we need |
464 // Do the OSR version | 474 osr_nm = imh->lookup_osr_nmethod_for(bci, next_osr_level, false); |
465 if (!is_compiling && next_osr_level != level) { | 475 } |
466 compile(mh, bci, next_osr_level, THREAD); | 476 if (osr_nm == NULL) { |
477 compile(imh, bci, next_osr_level, THREAD); | |
478 } | |
479 } | |
480 | |
481 // Use loop event as an opportunity to also check if there's been | |
482 // enough calls. | |
483 CompLevel cur_level, next_level; | |
484 if (mh() != imh()) { // If there is an enclosing method | |
485 guarantee(nm != NULL, "Should have nmethod here"); | |
486 cur_level = comp_level(mh()); | |
487 next_level = call_event(mh(), cur_level); | |
488 | |
489 if (max_osr_level == CompLevel_full_optimization) { | |
490 // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts | |
491 bool make_not_entrant = false; | |
492 if (nm->is_osr_method()) { | |
493 // This is an osr method, just make it not entrant and recompile later if needed | |
494 make_not_entrant = true; | |
495 } else { | |
496 if (next_level != CompLevel_full_optimization) { | |
497 // next_level is not full opt, so we need to recompile the | |
498 // enclosing method without the inlinee | |
499 cur_level = CompLevel_none; | |
500 make_not_entrant = true; | |
501 } | |
502 } | |
503 if (make_not_entrant) { | |
504 if (PrintTieredEvents) { | |
505 int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci; | |
506 print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level); | |
507 } | |
508 nm->make_not_entrant(); | |
509 } | |
510 } | |
511 if (!CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { | |
512 // Fix up next_level if necessary to avoid deopts | |
513 if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) { | |
514 next_level = CompLevel_full_profile; | |
515 } | |
516 if (cur_level != next_level) { | |
517 compile(mh, InvocationEntryBci, next_level, THREAD); | |
518 } | |
519 } | |
520 } else { | |
521 cur_level = comp_level(imh()); | |
522 next_level = call_event(imh(), cur_level); | |
523 if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) { | |
524 compile(imh, InvocationEntryBci, next_level, THREAD); | |
525 } | |
467 } | 526 } |
468 } | 527 } |
469 } | 528 } |
470 | 529 |
471 #endif // TIERED | 530 #endif // TIERED |