Index: runtime/vm/flow_graph_optimizer.cc |
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc |
index 2db078f4b423afbaee61bad65e8a6e18f191df67..91e6a58dbb6370afc112530f318645444b1c48cc 100644 |
--- a/runtime/vm/flow_graph_optimizer.cc |
+++ b/runtime/vm/flow_graph_optimizer.cc |
@@ -4088,7 +4088,8 @@ void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { |
// reported, so do not replace the instance call. |
return; |
} |
- if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
+ if ((unary_checks.NumberOfChecks() > 0) && |
+ (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) { |
ZoneGrowableArray<intptr_t>* results = |
new(Z) ZoneGrowableArray<intptr_t>(unary_checks.NumberOfChecks() * 2); |
Bool& as_bool = |
@@ -4179,7 +4180,8 @@ void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
// reported, so do not replace the instance call. |
return; |
} |
- if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
+ if ((unary_checks.NumberOfChecks() > 0) && |
+ (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) { |
ZoneGrowableArray<intptr_t>* results = |
new(Z) ZoneGrowableArray<intptr_t>(unary_checks.NumberOfChecks() * 2); |
const Bool& as_bool = Bool::ZoneHandle(Z, |
@@ -4213,22 +4215,41 @@ void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
} |
+// Special optimizations when running in --noopt mode. |
+void FlowGraphOptimizer::InstanceCallNoopt(InstanceCallInstr* instr) { |
+ // TODO(srdjan): Investigate other attempts, as they are not allowed to |
+ // deoptimize. |
+ const Token::Kind op_kind = instr->token_kind(); |
+ if (instr->HasICData() && (instr->ic_data()->NumberOfUsedChecks() > 0)) { |
+ if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr, false)) { |
+ return; |
+ } |
+ } |
+ |
+ // Type test is special as it always gets converted into inlined code. |
+ if (Token::IsTypeTestOperator(op_kind)) { |
+ ReplaceWithInstanceOf(instr); |
+ return; |
+ } |
+ if (Token::IsTypeCastOperator(op_kind)) { |
+ ReplaceWithTypeCast(instr); |
+ return; |
+ } |
+} |
+ |
+ |
// Tries to optimize instance call by replacing it with a faster instruction |
// (e.g, binary op, field load, ..). |
void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
- if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) { |
+ if (Compiler::always_optimize()) { |
+ InstanceCallNoopt(instr); |
return; |
} |
- const Token::Kind op_kind = instr->token_kind(); |
- if (Compiler::always_optimize()) { |
- // TODO(srdjan): Investigate other attempts, as they are not allowed to |
- // deoptimize. |
- if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr, false)) { |
- return; |
- } |
+ if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) { |
return; |
} |
+ const Token::Kind op_kind = instr->token_kind(); |
// Type test is special as it always gets converted into inlined code. |
if (Token::IsTypeTestOperator(op_kind)) { |