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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 1207093002: Carefully restructure TryCreatICData and add guessing for getters and setters; helps --noopt a lot (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: x Created 5 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 | « 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
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index c8378b7923536f01bb51c5d50f74ca18c6966911..9d70bcd1fdc0d28f79f1c3fef4f7bdf13686d5c4 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -167,10 +167,6 @@ static bool IsNumberCid(intptr_t cid) {
bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
- // TODO(srdjan): Investigate failures in:
- // corelib/big_integer_arith_vm_test
- // dart2js/members_test
- // language/try_catch_optimized1_test
ASSERT(call->HasICData());
if (call->ic_data()->NumberOfUsedChecks() > 0) {
// This occurs when an instance call has too many checks, will be converted
@@ -214,44 +210,73 @@ bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
}
}
+ bool all_cids_known = true;
for (intptr_t i = 0; i < class_ids.length(); i++) {
if (class_ids[i] == kDynamicCid) {
// Not all cid-s known.
- return false;
+ all_cids_known = false;
+ break;
}
}
- const Array& args_desc_array = Array::Handle(Z,
- ArgumentsDescriptor::New(call->ArgumentCount(), call->argument_names()));
- ArgumentsDescriptor args_desc(args_desc_array);
- const Class& receiver_class = Class::Handle(Z,
- isolate()->class_table()->At(class_ids[0]));
- const Function& function = Function::Handle(Z,
- Resolver::ResolveDynamicForReceiverClass(
- receiver_class,
- call->function_name(),
- args_desc));
- if (function.IsNull()) {
- return false;
+ if (all_cids_known) {
+ const Array& args_desc_array = Array::Handle(Z,
+ ArgumentsDescriptor::New(call->ArgumentCount(),
+ call->argument_names()));
+ ArgumentsDescriptor args_desc(args_desc_array);
+ const Class& receiver_class = Class::Handle(Z,
+ isolate()->class_table()->At(class_ids[0]));
+ const Function& function = Function::Handle(Z,
+ Resolver::ResolveDynamicForReceiverClass(
+ receiver_class,
+ call->function_name(),
+ args_desc));
+ if (function.IsNull()) {
+ return false;
+ }
+
+ // Create new ICData, do not modify the one attached to the instruction
+ // since it is attached to the assembly instruction itself.
+ // TODO(srdjan): Prevent modification of ICData object that is
+ // referenced in assembly code.
+ const ICData& ic_data = ICData::ZoneHandle(Z,
+ ICData::NewFrom(*call->ic_data(), class_ids.length()));
+ if (class_ids.length() > 1) {
+ ic_data.AddCheck(class_ids, function);
+ } else {
+ ASSERT(class_ids.length() == 1);
+ ic_data.AddReceiverCheck(class_ids[0], function);
+ }
+ call->set_ic_data(&ic_data);
+ return true;
}
- // Create new ICData, do not modify the one attached to the instruction
- // since it is attached to the assembly instruction itself.
- // TODO(srdjan): Prevent modification of ICData object that is
- // referenced in assembly code.
- ICData& ic_data = ICData::ZoneHandle(Z, ICData::New(
- flow_graph_->function(),
- call->function_name(),
- args_desc_array,
- call->deopt_id(),
- class_ids.length()));
- if (class_ids.length() > 1) {
- ic_data.AddCheck(class_ids, function);
- } else {
- ASSERT(class_ids.length() == 1);
- ic_data.AddReceiverCheck(class_ids[0], function);
+
+ // Check if getter or setter in function's class and class is currently leaf.
+ if ((call->token_kind() == Token::kGET) ||
+ (call->token_kind() == Token::kSET)) {
+ const Class& owner_class = Class::Handle(Z, function().Owner());
+ if (!owner_class.is_abstract() &&
+ !CHA::HasSubclasses(owner_class) &&
+ !CHA::IsImplemented(owner_class)) {
+ const Array& args_desc_array = Array::Handle(Z,
+ ArgumentsDescriptor::New(call->ArgumentCount(),
+ call->argument_names()));
+ ArgumentsDescriptor args_desc(args_desc_array);
+ const Function& function = Function::Handle(Z,
+ Resolver::ResolveDynamicForReceiverClass(owner_class,
+ call->function_name(),
+ args_desc));
+ if (!function.IsNull()) {
Cutch 2015/06/24 22:17:18 to match the style above: if (function.IsNull())
srdjan 2015/06/24 22:29:26 Done.
+ const ICData& ic_data = ICData::ZoneHandle(Z,
+ ICData::NewFrom(*call->ic_data(), class_ids.length()));
+ ic_data.AddReceiverCheck(owner_class.id(), function);
+ call->set_ic_data(&ic_data);
+ return true;
+ }
+ }
}
- call->set_ic_data(&ic_data);
- return true;
+
+ return false;
}
« 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