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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10594002: More ICData cleanups: try to use ICData instead of converting it to another intermediate representa… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.cc » ('j') | 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 8871)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -35,12 +35,10 @@
}
-static bool ICDataHasReceiverClass(const ICData& ic_data, intptr_t class_id) {
+static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) {
ASSERT(ic_data.num_args_tested() > 0);
- Function& target = Function::Handle();
for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
- intptr_t test_class_id;
- ic_data.GetOneClassCheckAt(i, &test_class_id, &target);
+ const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i);
if (test_class_id == class_id) {
return true;
}
@@ -52,18 +50,18 @@
static bool ICDataHasReceiverArgumentClasses(const ICData& ic_data,
intptr_t receiver_class_id,
intptr_t argument_class_id) {
- if (ic_data.num_args_tested() != 2) {
- return false;
- }
+ ASSERT(receiver_class_id != kIllegalObjectKind);
+ ASSERT(argument_class_id != kIllegalObjectKind);
+ 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;
ic_data.GetCheckAt(i, &class_ids, &target);
ASSERT(class_ids.length() == 2);
- if (class_ids[0] == receiver_class_id) {
- if (class_ids[1] == argument_class_id) {
- return true;
- }
+ if ((class_ids[0] == receiver_class_id) &&
+ (class_ids[1] == argument_class_id)) {
+ return true;
}
}
return false;
@@ -71,7 +69,7 @@
static bool HasOneSmi(const ICData& ic_data) {
- return ICDataHasReceiverClass(ic_data, kSmi);
+ return ICDataHasReceiverClassId(ic_data, kSmi);
}
@@ -86,7 +84,7 @@
static bool HasOneDouble(const ICData& ic_data) {
- return ICDataHasReceiverClass(ic_data, kDouble);
+ return ICDataHasReceiverClassId(ic_data, kDouble);
}
@@ -181,18 +179,13 @@
// TODO(srdjan): if targets are native use their C_function to compare.
static bool HasOneTarget(const ICData& ic_data) {
ASSERT(ic_data.NumberOfChecks() > 0);
- Function& prev_target = Function::Handle();
- GrowableArray<intptr_t> class_ids;
- ic_data.GetCheckAt(0, &class_ids, &prev_target);
- ASSERT(!prev_target.IsNull());
- Function& target = Function::Handle();
+ const Function& first_target = Function::Handle(ic_data.GetTargetAt(0));
+ Function& test_target = Function::Handle();
for (intptr_t i = 1; i < ic_data.NumberOfChecks(); i++) {
- ic_data.GetCheckAt(i, &class_ids, &target);
- ASSERT(!target.IsNull());
- if (prev_target.raw() != target.raw()) {
+ test_target = ic_data.GetTargetAt(i);
+ if (first_target.raw() != test_target.raw()) {
return false;
}
- prev_target = target.raw();
}
return true;
}
@@ -213,73 +206,39 @@
}
-// Returns all receiver class-ids and corresponding tagets for the given
-// 'ic_data', sorted so that a smi class id is at index[0] if it exists.
-// 'targets' can be NULL in which case it is not collected,
-static void ExtractClassIdsAndTargets(const ICData& ic_data,
- ZoneGrowableArray<intptr_t>* class_ids,
- ZoneGrowableArray<Function*>* targets) {
- ASSERT(class_ids != NULL);
- class_ids->Clear();
- if (targets != NULL) {
- targets->Clear();
- }
- intptr_t smi_index = -1;
- Function& target = Function::Handle();
- GrowableArray<intptr_t> unsorted_class_ids;
+// Returns ICData with num_args_checked == 1. If necessary creates a new ICData
+// object that contains unique receiver class-ids
+static RawICData* ToUnaryClassChecks(const ICData& ic_data) {
+ ASSERT(!ic_data.IsNull());
+ ASSERT(ic_data.num_args_tested() != 0);
+ if (ic_data.num_args_tested() == 1) return ic_data.raw();
+ const intptr_t kNumArgsTested = 1;
+ ICData& result = ICData::Handle(ICData::New(
+ Function::Handle(ic_data.function()),
+ String::Handle(ic_data.target_name()),
+ ic_data.id(),
+ kNumArgsTested));
for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
- ic_data.GetCheckAt(i, &unsorted_class_ids, &target);
- // Collect receiver class only.
- const intptr_t class_id = unsorted_class_ids[0];
- if (ic_data.num_args_tested() > 1) {
- // Check if we have not already entered the class-id.
- intptr_t duplicate_class_id = -1;
- for (intptr_t k = 0; k < class_ids->length(); k++) {
- if ((*class_ids)[k] == class_id) {
- duplicate_class_id = k;
- break;
- }
+ const intptr_t class_id = ic_data.GetReceiverClassIdAt(i);
+ intptr_t duplicate_class_id = -1;
+ for (intptr_t k = 0; k < result.NumberOfChecks(); k++) {
+ if (class_id == result.GetReceiverClassIdAt(k)) {
+ duplicate_class_id = k;
+ break;
}
- if (duplicate_class_id >= 0) {
- ASSERT((targets == NULL) ||
- ((*targets)[duplicate_class_id]->raw() == target.raw()));
- continue;
- }
}
- if (class_id == kSmi) {
- ASSERT(smi_index < 0); // Classes entered only once in ic_data.
- smi_index = class_ids->length();
+ if (duplicate_class_id >= 0) {
+ ASSERT(result.GetTargetAt(duplicate_class_id) == ic_data.GetTargetAt(i));
+ } else {
+ // This will make sure that Smi is first if it exists.
+ result.AddReceiverCheck(class_id,
+ Function::Handle(ic_data.GetTargetAt(i)));
}
- class_ids->Add(class_id);
- if (targets != NULL) {
- targets->Add(&Function::ZoneHandle(target.raw()));
- }
}
- if (smi_index >= 0) {
- // Smi class id must be at index 0.
- intptr_t temp_id = (*class_ids)[0];
- (*class_ids)[0] = (*class_ids)[smi_index];
- (*class_ids)[smi_index] = temp_id;
- if (targets != NULL) {
- Function* temp_func = (*targets)[0];
- (*targets)[0] = (*targets)[smi_index];
- (*targets)[smi_index] = temp_func;
- }
- }
+ return result.raw();
}
-// Returns array of all class ids that are in ic_data. The result is
-// normalized so that a smi class is at index 0 if it exists in the ic_data.
-static ZoneGrowableArray<intptr_t>* ExtractClassIds(const ICData& ic_data) {
- if (ic_data.NumberOfChecks() == 0) return NULL;
- ZoneGrowableArray<intptr_t>* result =
- new ZoneGrowableArray<intptr_t>(ic_data.NumberOfChecks());
- ExtractClassIdsAndTargets(ic_data, result, NULL);
- return result;
-}
-
-
// Only unique implicit instance getters can be currently handled.
bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallComp* comp) {
ASSERT(comp->HasICData());
@@ -304,7 +263,8 @@
const Field& field = Field::Handle(GetField(class_ids[0], field_name));
ASSERT(!field.IsNull());
LoadInstanceFieldComp* load = new LoadInstanceFieldComp(
- field, comp->InputAt(0), comp, ExtractClassIds(ic_data));
+ field, comp->InputAt(0), comp);
+ load->set_ic_data(comp->ic_data());
comp->ReplaceWith(load);
return true;
}
@@ -336,9 +296,9 @@
LoadVMFieldComp* load = new LoadVMFieldComp(
comp->InputAt(0),
length_offset,
- Type::ZoneHandle(Type::IntInterface()),
- comp,
- ExtractClassIds(ic_data));
+ Type::ZoneHandle(Type::IntInterface()));
+ load->set_original(comp);
+ load->set_ic_data(comp->ic_data());
comp->ReplaceWith(load);
return true;
}
@@ -348,9 +308,9 @@
LoadVMFieldComp* load = new LoadVMFieldComp(
comp->InputAt(0),
String::length_offset(),
- Type::ZoneHandle(Type::IntInterface()),
- comp,
- ExtractClassIds(ic_data));
+ Type::ZoneHandle(Type::IntInterface()));
+ load->set_original(comp);
+ load->set_ic_data(comp->ic_data());
comp->ReplaceWith(load);
return true;
}
@@ -412,13 +372,10 @@
}
const intptr_t kMaxChecks = 4;
if (comp->ic_data()->num_args_tested() <= kMaxChecks) {
- ZoneGrowableArray<intptr_t>* class_ids =
- new ZoneGrowableArray<intptr_t>();
- ZoneGrowableArray<Function*>* targets =
- new ZoneGrowableArray<Function*>();
- ExtractClassIdsAndTargets(*comp->ic_data(), class_ids, targets);
- PolymorphicInstanceCallComp* call =
- new PolymorphicInstanceCallComp(comp, *class_ids, *targets);
+ PolymorphicInstanceCallComp* call = new PolymorphicInstanceCallComp(comp);
+ ICData& unary_checks =
+ ICData::Handle(ToUnaryClassChecks(*comp->ic_data()));
+ call->set_ic_data(&unary_checks);
comp->ReplaceWith(call);
}
}
@@ -460,8 +417,8 @@
field,
comp->InputAt(0),
comp->InputAt(1),
- comp,
- ExtractClassIds(ic_data));
+ comp);
+ store->set_ic_data(comp->ic_data());
comp->ReplaceWith(store);
return true;
}
@@ -571,13 +528,11 @@
void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp) {
const intptr_t kMaxChecks = 4;
- if (comp->ic_data()->num_args_tested() <= kMaxChecks) {
- ZoneGrowableArray<intptr_t>* class_ids =
- new ZoneGrowableArray<intptr_t>();
- ZoneGrowableArray<Function*>* targets =
- new ZoneGrowableArray<Function*>();
- ExtractClassIdsAndTargets(*comp->ic_data(), class_ids, targets);
- comp->SetPolymorphicTargets(class_ids, targets);
+ if (comp->HasICData() && (comp->ic_data()->num_args_tested() <= kMaxChecks)) {
+ // Replace binary checks with unary ones.
+ ICData& unary_checks =
+ ICData::Handle(ToUnaryClassChecks(*comp->ic_data()));
+ comp->set_ic_data(&unary_checks);
}
// TODO(vegorov): recognize the pattern with BooleanNegate between comparsion
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698