Chromium Code Reviews| Index: runtime/vm/jit_optimizer.cc |
| diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc |
| index d73600b2469d984194024c0e2c0a914a11d622fe..271a832f038fd10191322c1d668857fc61f79875 100644 |
| --- a/runtime/vm/jit_optimizer.cc |
| +++ b/runtime/vm/jit_optimizer.cc |
| @@ -2668,6 +2668,19 @@ void JitOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| } |
| +static bool IsDenseCidRange(const ICData& unary_checks) { |
|
Vyacheslav Egorov (Google)
2016/04/01 10:53:59
I am a bit concerned that we have two functions th
Florian Schneider
2016/04/01 15:58:43
Changed to use a single function CheckClassInstr::
|
| + if (unary_checks.GetReceiverClassIdAt(0) == kSmiCid) return false; |
| + intptr_t max = 0; |
| + intptr_t min = kIntptrMax; |
| + for (intptr_t i = 0; i < unary_checks.NumberOfChecks(); ++i) { |
| + intptr_t cid = unary_checks.GetCidAt(i); |
| + if (cid < min) min = cid; |
| + if (cid > max) max = cid; |
| + } |
| + return (max - min) < kBitsPerWord; |
| +} |
| + |
| + |
| // Tries to optimize instance call by replacing it with a faster instruction |
| // (e.g, binary op, field load, ..). |
| void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| @@ -2690,10 +2703,12 @@ void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| const ICData& unary_checks = |
| ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks()); |
| + const bool is_dense = IsDenseCidRange(unary_checks); |
| const intptr_t max_checks = (op_kind == Token::kEQ) |
| ? FLAG_max_equality_polymorphic_checks |
| : FLAG_max_polymorphic_checks; |
| if ((unary_checks.NumberOfChecks() > max_checks) && |
| + !is_dense && |
| flow_graph()->InstanceCallNeedsClassCheck( |
| instr, RawFunction::kRegularFunction)) { |
| // Too many checks, it will be megamorphic which needs unary checks. |
| @@ -2759,7 +2774,8 @@ void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| } |
| } |
| - if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
| + if ((unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) || |
| + (has_one_target && is_dense)) { |
| bool call_with_checks; |
| if (has_one_target && FLAG_polymorphic_with_deopt) { |
| // Type propagation has not run yet, we cannot eliminate the check. |