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

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: lazyly inject extractors as getters into class Created 7 years, 11 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_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 7096933a90cae095d5c24cab3825c965771c7431..ad05b66b5a364c90701f1b4b6590684e539b07a1 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -603,10 +603,8 @@ bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
case kUint8ArrayCid:
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((class_id != kUint8ArrayCid) || value_type.IsIntType());
ASSERT((class_id != kFloat32ArrayCid && class_id != kFloat64ArrayCid) ||
value_type.IsDoubleType());
@@ -964,6 +962,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()));
+ 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();
@@ -1111,6 +1126,8 @@ bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
}
InlineImplicitInstanceGetter(call);
return true;
+ } else if (target.kind() == RawFunction::kMethodExtractor) {
+ return false;
}
// Not an implicit getter.
@@ -1363,6 +1380,7 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
const ICData& unary_checks =
ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
+
if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) &&
InstanceCallNeedsClassCheck(instr)) {
// Too many checks, it will be megamorphic which needs unary checks.
@@ -1395,17 +1413,27 @@ void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
if (TryInlineInstanceMethod(instr)) {
return;
}
- if (!InstanceCallNeedsClassCheck(instr)) {
- const bool call_with_checks = false;
- PolymorphicInstanceCallInstr* call =
- new PolymorphicInstanceCallInstr(instr, unary_checks,
- call_with_checks);
- instr->ReplaceWith(call, current_iterator());
- return;
+
+ const bool has_one_target = unary_checks.HasOneTarget();
+
+ if (has_one_target) {
+ const bool is_method_extraction =
+ Function::Handle(unary_checks.GetTargetAt(0)).IsMethodExtractor();
+
+ if ((is_method_extraction && !MethodExtractorNeedsClassCheck(instr)) ||
+ (!is_method_extraction && !InstanceCallNeedsClassCheck(instr))) {
+ const bool call_with_checks = false;
+ PolymorphicInstanceCallInstr* call =
+ new PolymorphicInstanceCallInstr(instr, unary_checks,
+ call_with_checks);
+ instr->ReplaceWith(call, current_iterator());
+ return;
+ }
}
+
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