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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 436643002: Faster IC stubs by specializing them for Binary Smi operations (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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 39414)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -112,7 +112,7 @@
// Attempt to build ICData for call using propagated class-ids.
bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
ASSERT(call->HasICData());
- if (call->ic_data()->NumberOfChecks() > 0) {
+ if (call->ic_data()->NumberOfUsedChecks() > 0) {
// This occurs when an instance call has too many checks, will be converted
// to megamorphic call.
return false;
@@ -195,8 +195,7 @@
intptr_t cid) {
ASSERT(ic_data.NumArgsTested() == 1);
- if ((ic_data.NumberOfChecks() == 1) &&
- (ic_data.GetReceiverClassIdAt(0) == cid)) {
+ if ((ic_data.NumberOfUsedChecks() == 1) && ic_data.HasReceiverClassId(cid)) {
return ic_data; // Nothing to do
}
@@ -853,17 +852,21 @@
intptr_t argument_class_id) {
ASSERT(receiver_class_id != kIllegalCid);
ASSERT(argument_class_id != kIllegalCid);
- if (ic_data.NumArgsTested() != 2) return false;
+ if (ic_data.NumArgsTested() != 2) {
+ return false;
+ }
Function& target = Function::Handle();
const intptr_t len = ic_data.NumberOfChecks();
for (intptr_t i = 0; i < len; i++) {
GrowableArray<intptr_t> class_ids;
- ic_data.GetCheckAt(i, &class_ids, &target);
- ASSERT(class_ids.length() == 2);
- if ((class_ids[0] == receiver_class_id) &&
- (class_ids[1] == argument_class_id)) {
- return true;
+ if (ic_data.IsUsedAt(i)) {
+ ic_data.GetCheckAt(i, &class_ids, &target);
+ ASSERT(class_ids.length() == 2);
+ if ((class_ids[0] == receiver_class_id) &&
+ (class_ids[1] == argument_class_id)) {
+ return true;
+ }
}
}
return false;
@@ -887,16 +890,20 @@
const ICData& ic_data,
const GrowableArray<intptr_t>& receiver_class_ids,
const GrowableArray<intptr_t>& argument_class_ids) {
- if (ic_data.NumArgsTested() != 2) return false;
+ if (ic_data.NumArgsTested() != 2) {
+ return false;
+ }
Function& target = Function::Handle();
const intptr_t len = ic_data.NumberOfChecks();
for (intptr_t i = 0; i < len; i++) {
- GrowableArray<intptr_t> class_ids;
- ic_data.GetCheckAt(i, &class_ids, &target);
- ASSERT(class_ids.length() == 2);
- if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) ||
- !ClassIdIsOneOf(class_ids[1], argument_class_ids)) {
- return false;
+ if (ic_data.IsUsedAt(i)) {
+ GrowableArray<intptr_t> class_ids;
+ ic_data.GetCheckAt(i, &class_ids, &target);
+ ASSERT(class_ids.length() == 2);
+ if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) ||
+ !ClassIdIsOneOf(class_ids[1], argument_class_ids)) {
+ return false;
+ }
}
}
return true;
@@ -904,34 +911,47 @@
static bool HasOnlyOneSmi(const ICData& ic_data) {
- return (ic_data.NumberOfChecks() == 1)
+ return (ic_data.NumberOfUsedChecks() == 1)
&& ic_data.HasReceiverClassId(kSmiCid);
}
static bool HasOnlySmiOrMint(const ICData& ic_data) {
- if (ic_data.NumberOfChecks() == 1) {
+ if (ic_data.NumberOfUsedChecks() == 1) {
return ic_data.HasReceiverClassId(kSmiCid)
|| ic_data.HasReceiverClassId(kMintCid);
}
- return (ic_data.NumberOfChecks() == 2)
+ return (ic_data.NumberOfUsedChecks() == 2)
&& ic_data.HasReceiverClassId(kSmiCid)
&& ic_data.HasReceiverClassId(kMintCid);
}
static bool HasOnlyTwoOf(const ICData& ic_data, intptr_t cid) {
- return (ic_data.NumberOfChecks() == 1) &&
- ICDataHasReceiverArgumentClassIds(ic_data, cid, cid);
+ if (ic_data.NumberOfUsedChecks() != 1) {
+ return false;
+ }
+ GrowableArray<intptr_t> first;
+ GrowableArray<intptr_t> second;
+ ic_data.GetUsedCidsForTwoArgs(&first, &second);
+ return (first[0] == cid) && (second[0] == cid);
}
// Returns false if the ICData contains anything other than the 4 combinations
// of Mint and Smi for the receiver and argument classes.
static bool HasTwoMintOrSmi(const ICData& ic_data) {
- GrowableArray<intptr_t> class_ids(2);
- class_ids.Add(kSmiCid);
- class_ids.Add(kMintCid);
- return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids);
+ GrowableArray<intptr_t> first;
+ GrowableArray<intptr_t> second;
+ ic_data.GetUsedCidsForTwoArgs(&first, &second);
+ for (intptr_t i = 0; i < first.length(); i++) {
+ if ((first[i] != kSmiCid) && (first[i] != kMintCid)) {
+ return false;
+ }
+ if ((second[i] != kSmiCid) && (second[i] != kMintCid)) {
+ return false;
+ }
+ }
+ return true;
}
@@ -946,7 +966,7 @@
static bool HasOnlyOneDouble(const ICData& ic_data) {
- return (ic_data.NumberOfChecks() == 1)
+ return (ic_data.NumberOfUsedChecks() == 1)
&& ic_data.HasReceiverClassId(kDoubleCid);
}
@@ -1001,8 +1021,8 @@
const ICData& unary_checks,
intptr_t deopt_id,
intptr_t token_pos) {
- if ((unary_checks.NumberOfChecks() == 1) &&
- (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
+ if ((unary_checks.NumberOfUsedChecks() == 1) &&
+ unary_checks.HasReceiverClassId(kSmiCid)) {
return new(I) CheckSmiInstr(new(I) Value(to_check),
deopt_id,
token_pos);
@@ -1037,10 +1057,14 @@
const ICData& ic_data,
intptr_t arg_number) {
ASSERT(ic_data.NumArgsTested() > arg_number);
+ if (ic_data.NumberOfUsedChecks() == 0) {
+ return false;
+ }
const intptr_t num_checks = ic_data.NumberOfChecks();
- if (num_checks == 0) return false;
for (intptr_t i = 0; i < num_checks; i++) {
- if (ic_data.GetClassIdAt(i, arg_number) != cid) return false;
+ if (ic_data.IsUsedAt(i) && ic_data.GetClassIdAt(i, arg_number) != cid) {
+ return false;
+ }
}
return true;
}
@@ -1134,7 +1158,10 @@
if (!call->HasICData()) return false;
const ICData& ic_data =
ICData::Handle(I, call->ic_data()->AsUnaryClassChecks());
- if (ic_data.NumberOfChecks() != 1) return false;
+ if (ic_data.NumberOfChecks() != 1) {
+ return false;
+ }
+ ASSERT(ic_data.NumberOfUsedChecks() == 1);
ASSERT(ic_data.HasOneTarget());
const Function& target = Function::Handle(I, ic_data.GetTargetAt(0));
@@ -1693,7 +1720,10 @@
if (!call->HasICData()) return false;
const ICData& ic_data =
ICData::Handle(I, call->ic_data()->AsUnaryClassChecks());
- if (ic_data.NumberOfChecks() != 1) return false;
+ if (ic_data.NumberOfChecks() != 1) {
+ return false;
+ }
+ ASSERT(ic_data.NumberOfUsedChecks() == 1);
ASSERT(ic_data.HasOneTarget());
const Function& target = Function::Handle(I, ic_data.GetTargetAt(0));
@@ -2628,7 +2658,7 @@
bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
ASSERT(call->HasICData());
const ICData& ic_data = *call->ic_data();
- if (ic_data.NumberOfChecks() == 0) {
+ if (ic_data.NumberOfUsedChecks() == 0) {
// No type feedback collected.
return false;
}
@@ -2834,7 +2864,7 @@
bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
ASSERT(call->HasICData());
const ICData& ic_data = *call->ic_data();
- if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) {
+ if ((ic_data.NumberOfUsedChecks() == 0) || !ic_data.HasOneTarget()) {
// No type feedback collected or multiple targets found.
return false;
}
@@ -4129,7 +4159,7 @@
// 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)) {
+ if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) {
return;
}
@@ -4148,7 +4178,7 @@
const ICData& unary_checks =
ICData::ZoneHandle(I, instr->ic_data()->AsUnaryClassChecks());
- intptr_t max_checks = (op_kind == Token::kEQ)
+ const intptr_t max_checks = (op_kind == Token::kEQ)
? FLAG_max_equality_polymorphic_checks
: FLAG_max_polymorphic_checks;
if ((unary_checks.NumberOfChecks() > max_checks) &&

Powered by Google App Engine
This is Rietveld 408576698