Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11367022: Any instance call with too many checks is left to be megamorphic. This helps with, e.g., LoadField … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 14376)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -1123,59 +1123,67 @@
// 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()->NumberOfChecks() > 0)) {
- const Token::Kind op_kind = instr->token_kind();
- if ((op_kind == Token::kASSIGN_INDEX) &&
- TryReplaceWithStoreIndexed(instr)) {
- return;
+ if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) {
+ // An instance call without ICData will trigger deoptimization.
+ return;
+ }
+
+ const ICData& unary_checks =
+ ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
+ if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) &&
+ InstanceCallNeedsClassCheck(instr)) {
+ // Too many checks, leave it megamorphic.
+ return;
+ }
+
+ const Token::Kind op_kind = instr->token_kind();
+ if ((op_kind == Token::kASSIGN_INDEX) &&
+ TryReplaceWithStoreIndexed(instr)) {
+ return;
+ }
+ if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
+ return;
+ }
+ if (Token::IsBinaryOperator(op_kind) &&
+ TryReplaceWithBinaryOp(instr, op_kind)) {
+ return;
+ }
+ if (Token::IsPrefixOperator(op_kind) &&
+ TryReplaceWithUnaryOp(instr, op_kind)) {
+ return;
+ }
+ if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) {
+ return;
+ }
+ if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) {
+ return;
+ }
+ if (TryInlineInstanceMethod(instr)) {
+ return;
+ }
+ if (!InstanceCallNeedsClassCheck(instr)) {
+ const bool call_with_checks = false;
+ PolymorphicInstanceCallInstr* call =
+ new PolymorphicInstanceCallInstr(instr, unary_checks,
+ call_with_checks);
+ instr->ReplaceWith(call, current_iterator());
+ return;
+ }
+ if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
+ bool call_with_checks;
+ if (unary_checks.HasOneTarget()) {
+ // Type propagation has not run yet, we cannot eliminate the check.
+ AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy());
+ // Call can still deoptimize, do not detach environment from instr.
+ call_with_checks = false;
+ } else {
+ call_with_checks = true;
}
- if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
- return;
- }
- if (Token::IsBinaryOperator(op_kind) &&
- TryReplaceWithBinaryOp(instr, op_kind)) {
- return;
- }
- if (Token::IsPrefixOperator(op_kind) &&
- TryReplaceWithUnaryOp(instr, op_kind)) {
- return;
- }
- if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) {
- return;
- }
- if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) {
- return;
- }
- if (TryInlineInstanceMethod(instr)) {
- return;
- }
- const ICData& unary_checks =
- ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
- if (!InstanceCallNeedsClassCheck(instr)) {
- const bool call_with_checks = false;
- PolymorphicInstanceCallInstr* call =
- new PolymorphicInstanceCallInstr(instr, unary_checks,
- call_with_checks);
- instr->ReplaceWith(call, current_iterator());
- return;
- }
- if (instr->ic_data()->NumberOfChecks() <= FLAG_max_polymorphic_checks) {
- bool call_with_checks;
- if (unary_checks.HasOneTarget()) {
- // Type propagation has not run yet, we cannot eliminate the check.
- AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy());
- // Call can still deoptimize, do not detach environment from instr.
- call_with_checks = false;
- } else {
- call_with_checks = true;
- }
- PolymorphicInstanceCallInstr* call =
- new PolymorphicInstanceCallInstr(instr, unary_checks,
- call_with_checks);
- instr->ReplaceWith(call, current_iterator());
- }
+ PolymorphicInstanceCallInstr* call =
+ new PolymorphicInstanceCallInstr(instr, unary_checks,
+ call_with_checks);
+ instr->ReplaceWith(call, current_iterator());
}
- // An instance call without ICData will trigger deoptimization.
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698