| Index: runtime/vm/jit_optimizer.cc
|
| diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
|
| index 9e71b2728a12de19a082ce4d0ae07d76ab7f6825..bdfcddcf09c00fd4e391dfcdc6dc4debc786c0ba 100644
|
| --- a/runtime/vm/jit_optimizer.cc
|
| +++ b/runtime/vm/jit_optimizer.cc
|
| @@ -1549,17 +1549,6 @@ void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
|
| const ICData& unary_checks =
|
| ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
|
|
|
| - const bool is_dense = CheckClassInstr::IsDenseCidRange(unary_checks);
|
| - const intptr_t number_of_checks = unary_checks.NumberOfChecks();
|
| - if (op_kind == Token::kEQ &&
|
| - number_of_checks > FLAG_max_equality_polymorphic_checks && !is_dense &&
|
| - flow_graph()->InstanceCallNeedsClassCheck(
|
| - instr, RawFunction::kRegularFunction)) {
|
| - // Too many checks, it will be megamorphic which needs unary checks.
|
| - instr->set_ic_data(&unary_checks);
|
| - return;
|
| - }
|
| -
|
| if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) {
|
| return;
|
| }
|
| @@ -1628,8 +1617,20 @@ void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
|
| }
|
| }
|
|
|
| + // If there is only one target we can make this into a deopting class check,
|
| + // followed by a call instruction that does not check the class of the
|
| + // receiver. This enables a lot of optimizations because after the class
|
| + // check we can probably inline the call and not worry about side effects.
|
| + // However, this can fall down if new receiver classes arrive at this call
|
| + // site after we generated optimized code. This causes a deopt, and after a
|
| + // few deopts we won't optimize this function any more at all. Therefore for
|
| + // very polymorphic sites we don't make this optimization, keeping it as a
|
| + // regular checked PolymorphicInstanceCall, which falls back to the slow but
|
| + // non-deopting megamorphic call stub when it sees new receiver classes.
|
| bool call_with_checks;
|
| - if (has_one_target && FLAG_polymorphic_with_deopt) {
|
| + if (has_one_target && FLAG_polymorphic_with_deopt &&
|
| + (!instr->ic_data()->HasDeoptReason(ICData::kDeoptCheckClass) ||
|
| + unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) {
|
| // Type propagation has not run yet, we cannot eliminate the check.
|
| AddReceiverCheck(instr);
|
| // Call can still deoptimize, do not detach environment from instr.
|
|
|