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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11048032: Support for mixed null/smi equality: do not deoptimize, emit same optimized code as if that was smi… (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
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 13236)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -230,12 +230,13 @@
}
+// Returns true if ICData tests two arguments and all ICData cids are in the
+// required sets 'receiver_class_ids' or 'argument_class_ids', respectively.
static bool ICDataHasOnlyReceiverArgumentClassIds(
const ICData& ic_data,
const GrowableArray<intptr_t>& receiver_class_ids,
const GrowableArray<intptr_t>& argument_class_ids) {
if (ic_data.num_args_tested() != 2) return false;
-
Function& target = Function::Handle();
for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
GrowableArray<intptr_t> class_ids;
@@ -345,7 +346,8 @@
// Type propagation has not run yet, we cannot eliminate the check.
const ICData& unary_checks =
ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
- CheckClassInstr* check = new CheckClassInstr(value, call, unary_checks);
+ CheckClassInstr* check =
+ new CheckClassInstr(value, call->deopt_id(), unary_checks);
InsertBefore(call, check, call->env(), Definition::kEffect);
}
@@ -1084,9 +1086,11 @@
instr->ReplaceWith(strict_comp, iterator);
return;
}
- if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) return;
+ if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) {
+ return;
+ }
+ ASSERT(comp->ic_data()->num_args_tested() == 2);
if (comp->ic_data()->NumberOfChecks() == 1) {
- ASSERT(comp->ic_data()->num_args_tested() == 2);
GrowableArray<intptr_t> class_ids;
Function& target = Function::Handle();
comp->ic_data()->GetCheckAt(0, &class_ids, &target);
@@ -1118,6 +1122,60 @@
} else if (comp->ic_data()->AllReceiversAreNumbers()) {
comp->set_receiver_class_id(kNumberCid);
}
+
+ if (comp->receiver_class_id() != kIllegalCid) {
+ // Done.
+ return;
+ }
+
+ // Check if ICDData contains checks with Smi/Null combinations. In that case
+ // we can still emit the optimized Smi equality operation but need to add
+ // checks for null or Smi.
+ // TODO(srdjan): Add it for Double and Mint.
+ GrowableArray<intptr_t> smi_or_null(2);
+ smi_or_null.Add(kSmiCid);
+ smi_or_null.Add(kNullCid);
+ if (ICDataHasOnlyReceiverArgumentClassIds(
+ *comp->ic_data(), smi_or_null, smi_or_null)) {
+ ICData& unary_checks =
+ ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
+ const intptr_t deopt_id = comp->deopt_id();
+ if ((unary_checks.NumberOfChecks() == 1) &&
+ (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
+ // Smi only.
+ optimizer->InsertBefore(
+ instr,
+ new CheckSmiInstr(comp->left()->Copy(), deopt_id),
+ instr->env(),
+ Definition::kEffect);
+ } else {
+ // Smi or NULL.
+ optimizer->InsertBefore(
+ instr,
+ new CheckClassInstr(comp->left()->Copy(), deopt_id, unary_checks),
+ instr->env(),
+ Definition::kEffect);
+ }
+
+ unary_checks = comp->ic_data()->AsUnaryClassChecksForArgNr(1);
+ if ((unary_checks.NumberOfChecks() == 1) &&
+ (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
+ // Smi only.
+ optimizer->InsertBefore(
+ instr,
+ new CheckSmiInstr(comp->right()->Copy(), deopt_id),
+ instr->env(),
+ Definition::kEffect);
+ } else {
+ // Smi or NULL.
+ optimizer->InsertBefore(
+ instr,
+ new CheckClassInstr(comp->right()->Copy(), deopt_id, unary_checks),
+ instr->env(),
+ Definition::kEffect);
+ }
+ comp->set_receiver_class_id(kSmiCid);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698