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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 16799003: Support type arguments for allocation sinking in certain conditions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | tests/language/allocation_sinking_vm_test.dart » ('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 23902)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -4097,6 +4097,18 @@
}
+static bool HasSupportedArguments(AllocateObjectInstr* alloc) {
Vyacheslav Egorov (Google) 2013/06/12 13:26:17 The name is a bit confusing. Maybe AllocationHasSi
Florian Schneider 2013/06/13 14:38:39 Done.
+ if (alloc->ArgumentCount() == 0) return true;
srdjan 2013/06/12 16:22:07 What Slava said and maybe add an itty-bitty commen
+ ASSERT(alloc->ArgumentCount() == 2);
+ Value* arg1 = alloc->PushArgumentAt(1)->value();
+ if (!arg1->BindsToConstant()) return false;
+
+ const Object& obj = arg1->BoundConstant();
+ return obj.IsSmi()
+ && (Smi::Cast(obj).Value() == StubCode::kNoInstantiator);
+}
+
+
class LoadOptimizer : public ValueObject {
public:
LoadOptimizer(FlowGraph* graph,
@@ -4242,11 +4254,10 @@
// constructor invocation.
// TODO(vegorov): record null-values at least for not final fields of
// escaping object.
- // TODO(vegorov): enable forwarding of type arguments.
AllocateObjectInstr* alloc = instr->AsAllocateObject();
if ((alloc != NULL) &&
(alloc->identity() == AllocateObjectInstr::kNotAliased) &&
- (alloc->ArgumentCount() == 0)) {
+ HasSupportedArguments(alloc)) {
for (Value* use = alloc->input_use_list();
use != NULL;
use = use->next_use()) {
@@ -4257,9 +4268,20 @@
LoadFieldInstr* load = use->instruction()->AsLoadField();
if (load != NULL) {
- // Found a load. Initialize current value of the field to null.
+ // Found a load. Initialize current value of the field to null for
+ // normal fields, or with type arguments.
gen->Add(load->expr_id());
if (out_values == NULL) out_values = CreateBlockOutValues();
+
+ if (alloc->ArgumentCount() > 0) {
Vyacheslav Egorov (Google) 2013/06/12 13:26:17 ASSERT(alloc->ArgumentCount() == 2);
Florian Schneider 2013/06/13 14:38:39 Done.
+ const Class& cls = Class::Handle(alloc->constructor().Owner());
srdjan 2013/06/12 16:22:07 We have alloc->ArgumentCount() > 0 (or its variati
Florian Schneider 2013/06/20 14:06:26 Done. I guess it does not hurt to have more assert
+ intptr_t type_args_offset = cls.type_arguments_field_offset();
+ if (load->offset_in_bytes() == type_args_offset) {
+ (*out_values)[load->expr_id()] =
+ alloc->PushArgumentAt(0)->value()->definition();
+ continue;
+ }
+ }
(*out_values)[load->expr_id()] = graph_->constant_null();
}
}
@@ -6377,10 +6399,7 @@
// instructions that write into fields of the allocated object.
// We do not support materialization of the object that has type arguments.
static bool IsAllocationSinkingCandidate(AllocateObjectInstr* alloc) {
- // TODO(vegorov): support AllocateObject with type arguments.
- if (alloc->ArgumentCount() > 0) {
- return false;
- }
+ if (!HasSupportedArguments(alloc)) return false;
for (Value* use = alloc->input_use_list();
use != NULL;
@@ -6418,6 +6437,12 @@
ASSERT(alloc->env_use_list() == NULL);
ASSERT(alloc->input_use_list() == NULL);
alloc->RemoveFromGraph();
+ if (alloc->ArgumentCount() > 0) {
+ ASSERT(alloc->ArgumentCount() == 2);
+ for (intptr_t i = 0; i < alloc->ArgumentCount(); ++i) {
+ alloc->PushArgumentAt(i)->RemoveFromGraph();
+ }
+ }
}
@@ -6461,6 +6486,10 @@
// external effects from calls.
LoadOptimizer::OptimizeGraph(flow_graph_);
+ if (FLAG_trace_optimization) {
+ FlowGraphPrinter::PrintGraph("Sinking", flow_graph_);
+ }
+
// At this point we have computed the state of object at each deoptimization
// point and we can eliminate it. Loads inserted above were forwarded so there
// are no uses of the allocation just as in the begging of the pass.
@@ -6576,6 +6605,21 @@
AddField(fields, use->instruction()->AsStoreInstanceField()->field());
}
+ if (alloc->ArgumentCount() > 0) {
+ const String& name = String::Handle(Symbols::New(":type_args"));
+ const Field& type_args_field =
+ Field::ZoneHandle(Field::New(
+ name,
+ false, // !static
+ false, // !final
+ false, // !const
+ Class::Handle(alloc->constructor().Owner()),
+ 0)); // No token position.
+ const Class& cls = Class::Handle(alloc->constructor().Owner());
+ type_args_field.SetOffset(cls.type_arguments_field_offset());
+ AddField(fields, type_args_field);
+ }
+
// Collect all instructions that mention this object in the environment.
GrowableArray<Instruction*> exits(10);
for (Value* use = alloc->env_use_list();
« no previous file with comments | « no previous file | tests/language/allocation_sinking_vm_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698