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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11642003: Create and cache method extraction stub in the ICData. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: ready for review. Created 8 years 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_optimizer.h ('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
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 40a36f8a6b4428f559284525b86c24e44a417899..87a1ebdfcd3dd593e66a074db273cdd5fb6afd10 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -572,10 +572,8 @@ bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
}
case kFloat32ArrayCid:
case kFloat64ArrayCid: {
- ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle());
- InsertBefore(call, null_constant, NULL, Definition::kValue);
- instantiator = new Value(null_constant);
- type_args = new Value(null_constant);
+ instantiator = new Value(flow_graph_->constant_null());
+ type_args = new Value(flow_graph_->constant_null());
ASSERT(value_type.IsDoubleType());
ASSERT(value_type.IsInstantiated());
break;
@@ -927,6 +925,23 @@ bool FlowGraphOptimizer::InstanceCallNeedsClassCheck(
}
+bool FlowGraphOptimizer::MethodExtractorNeedsClassCheck(
+ InstanceCallInstr* call) const {
+ if (!FLAG_use_cha) return true;
+ Definition* callee_receiver = call->ArgumentAt(0)->value()->definition();
+ ASSERT(callee_receiver != NULL);
+ const Function& function = flow_graph_->parsed_function().function();
+ if (function.IsDynamicFunction() &&
+ callee_receiver->IsParameter() &&
+ (callee_receiver->AsParameter()->index() == 0)) {
+ const String& field_name =
+ String::Handle(Field::NameFromGetter(call->function_name()));
srdjan 2013/01/16 22:08:56 indent 4 spaces
+ return CHA::HasOverride(Class::Handle(function.Owner()), field_name);
+ }
+ return true;
+}
+
+
void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
ASSERT(call->HasICData());
const ICData& ic_data = *call->ic_data();
@@ -1040,6 +1055,49 @@ void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) {
}
+void FlowGraphOptimizer::InlineMethodExtractor(InstanceCallInstr* call) {
+ Value* receiver = call->ArgumentAt(0)->value();
+ if (MethodExtractorNeedsClassCheck(call)) {
+ AddCheckClass(call, receiver->Copy());
+ }
+
+ // Load and push type arguments.
+ Definition* type_arguments = NULL;
+
+ const Class& receiver_class = Class::Handle(
+ Isolate::Current()->class_table()->At(ReceiverClassId(call)));
+ const intptr_t type_arguments_field_offset =
+ receiver_class.type_arguments_field_offset();
+ if (type_arguments_field_offset != Class::kNoTypeArguments) {
+ type_arguments = new LoadFieldInstr(receiver->Copy(),
+ type_arguments_field_offset,
+ Type::ZoneHandle()); // No type.
+ InsertBefore(call, type_arguments, NULL, Definition::kValue);
+ } else {
+ type_arguments = flow_graph_->constant_null();
+ }
+
+ PushArgumentInstr* push_type_arguments =
+ new PushArgumentInstr(new Value(type_arguments));
+ InsertBefore(call, push_type_arguments, NULL, Definition::kEffect);
+
+ ZoneGrowableArray<PushArgumentInstr*>* args =
+ new ZoneGrowableArray<PushArgumentInstr*>(2);
+
+ args->Add(call->ArgumentAt(0));
+ args->Add(push_type_arguments);
+
+ const Function& extractor = Function::Handle(call->ic_data()->GetTargetAt(0));
+ const Function& function =
+ Function::ZoneHandle(extractor.extracted_method_closure());
+ ASSERT(function.IsImplicitInstanceClosureFunction());
+ call->set_env(NULL);
+ CreateClosureInstr* create_closure =
+ new CreateClosureInstr(function, args, call->token_pos());
+ call->ReplaceWith(create_closure, current_iterator());
+}
+
+
// Only unique implicit instance getters can be currently handled.
bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
ASSERT(call->HasICData());
@@ -1056,6 +1114,12 @@ bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
}
InlineImplicitInstanceGetter(call);
return true;
+ } else if (target.kind() == RawFunction::kMethodExtractor) {
+ if (!ic_data.HasOneTarget()) {
+ return false;
+ }
+ InlineMethodExtractor(call);
+ return true;
}
// Not an implicit getter.
@@ -1224,6 +1288,7 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
const ICData& unary_checks =
ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
+ const bool has_one_target = unary_checks.HasOneTarget();
if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) &&
InstanceCallNeedsClassCheck(instr)) {
// Too many checks, it will be megamorphic which needs unary checks.
@@ -1257,7 +1322,8 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
if (TryInlineInstanceMethod(instr)) {
return;
}
- if (!InstanceCallNeedsClassCheck(instr)) {
+ if (has_one_target && !InstanceCallNeedsClassCheck(instr)) {
+ ASSERT(!Function::Handle(unary_checks.GetTargetAt(0)).IsMethodExtractor());
const bool call_with_checks = false;
PolymorphicInstanceCallInstr* call =
new PolymorphicInstanceCallInstr(instr, unary_checks,
@@ -1267,7 +1333,7 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
}
if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
bool call_with_checks;
- if (unary_checks.HasOneTarget()) {
+ if (has_one_target) {
// 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.
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698