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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 19370003: Enable allocation sinking for closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed bug in polymorphic inliner Created 7 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 field.Offset(), 1320 field.Offset(),
1321 AbstractType::ZoneHandle(field.type()), 1321 AbstractType::ZoneHandle(field.type()),
1322 field.is_final()); 1322 field.is_final());
1323 load->set_field(&field); 1323 load->set_field(&field);
1324 if (field.guarded_cid() != kIllegalCid) { 1324 if (field.guarded_cid() != kIllegalCid) {
1325 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) { 1325 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
1326 load->set_result_cid(field.guarded_cid()); 1326 load->set_result_cid(field.guarded_cid());
1327 } 1327 }
1328 AddToGuardedFields(field); 1328 AddToGuardedFields(field);
1329 } 1329 }
1330 load->set_field_name(String::Handle(field.name()).ToCString());
1331 1330
1332 // Discard the environment from the original instruction because the load 1331 // Discard the environment from the original instruction because the load
1333 // can't deoptimize. 1332 // can't deoptimize.
1334 call->RemoveEnvironment(); 1333 call->RemoveEnvironment();
1335 ReplaceCall(call, load); 1334 ReplaceCall(call, load);
1336 1335
1337 if (load->result_cid() != kDynamicCid) { 1336 if (load->result_cid() != kDynamicCid) {
1338 // Reset value types if guarded_cid was used. 1337 // Reset value types if guarded_cid was used.
1339 for (Value::Iterator it(load->input_use_list()); 1338 for (Value::Iterator it(load->input_use_list());
1340 !it.Done(); 1339 !it.Done();
(...skipping 3432 matching lines...) Expand 10 before | Expand all | Expand 10 after
4773 4772
4774 LoadFieldInstr* load = use->instruction()->AsLoadField(); 4773 LoadFieldInstr* load = use->instruction()->AsLoadField();
4775 if (load != NULL) { 4774 if (load != NULL) {
4776 // Found a load. Initialize current value of the field to null for 4775 // Found a load. Initialize current value of the field to null for
4777 // normal fields, or with type arguments. 4776 // normal fields, or with type arguments.
4778 gen->Add(load->place_id()); 4777 gen->Add(load->place_id());
4779 if (out_values == NULL) out_values = CreateBlockOutValues(); 4778 if (out_values == NULL) out_values = CreateBlockOutValues();
4780 4779
4781 if (alloc->ArgumentCount() > 0) { 4780 if (alloc->ArgumentCount() > 0) {
4782 ASSERT(alloc->ArgumentCount() == 2); 4781 ASSERT(alloc->ArgumentCount() == 2);
4783 const Class& cls = Class::Handle(alloc->constructor().Owner()); 4782 intptr_t type_args_offset =
4784 intptr_t type_args_offset = cls.type_arguments_field_offset(); 4783 alloc->cls().type_arguments_field_offset();
4785 if (load->offset_in_bytes() == type_args_offset) { 4784 if (load->offset_in_bytes() == type_args_offset) {
4786 (*out_values)[load->place_id()] = 4785 (*out_values)[load->place_id()] =
4787 alloc->PushArgumentAt(0)->value()->definition(); 4786 alloc->PushArgumentAt(0)->value()->definition();
4788 continue; 4787 continue;
4789 } 4788 }
4790 } 4789 }
4791 (*out_values)[load->place_id()] = graph_->constant_null(); 4790 (*out_values)[load->place_id()] = graph_->constant_null();
4792 } 4791 }
4793 } 4792 }
4794 continue; 4793 continue;
(...skipping 2373 matching lines...) Expand 10 before | Expand all | Expand 10 after
7168 // deoptimization exit. So candidate should only be used in StoreInstanceField 7167 // deoptimization exit. So candidate should only be used in StoreInstanceField
7169 // instructions that write into fields of the allocated object. 7168 // instructions that write into fields of the allocated object.
7170 // We do not support materialization of the object that has type arguments. 7169 // We do not support materialization of the object that has type arguments.
7171 static bool IsAllocationSinkingCandidate(AllocateObjectInstr* alloc) { 7170 static bool IsAllocationSinkingCandidate(AllocateObjectInstr* alloc) {
7172 if (!HasSimpleTypeArguments(alloc)) return false; 7171 if (!HasSimpleTypeArguments(alloc)) return false;
7173 7172
7174 for (Value* use = alloc->input_use_list(); 7173 for (Value* use = alloc->input_use_list();
7175 use != NULL; 7174 use != NULL;
7176 use = use->next_use()) { 7175 use = use->next_use()) {
7177 if (!(use->instruction()->IsStoreInstanceField() && 7176 if (!(use->instruction()->IsStoreInstanceField() &&
7178 use->use_index() == 0)) { 7177 (use->use_index() == 0))) {
7179 return false; 7178 return false;
7180 } 7179 }
7181 } 7180 }
7182 7181
7183 return true; 7182 return true;
7184 } 7183 }
7185 7184
7186 7185
7187 // Remove the given allocation from the graph. It is not observable. 7186 // Remove the given allocation from the graph. It is not observable.
7188 // If deoptimization occurs the object will be materialized. 7187 // If deoptimization occurs the object will be materialized.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
7306 } 7305 }
7307 } 7306 }
7308 fields->Add(&field); 7307 fields->Add(&field);
7309 } 7308 }
7310 7309
7311 7310
7312 // Add given instruction to the list of the instructions if it is not yet 7311 // Add given instruction to the list of the instructions if it is not yet
7313 // present there. 7312 // present there.
7314 static void AddInstruction(GrowableArray<Instruction*>* exits, 7313 static void AddInstruction(GrowableArray<Instruction*>* exits,
7315 Instruction* exit) { 7314 Instruction* exit) {
7315 ASSERT(!exit->IsGraphEntry());
7316 for (intptr_t i = 0; i < exits->length(); i++) { 7316 for (intptr_t i = 0; i < exits->length(); i++) {
7317 if ((*exits)[i] == exit) { 7317 if ((*exits)[i] == exit) {
7318 return; 7318 return;
7319 } 7319 }
7320 } 7320 }
7321 exits->Add(exit); 7321 exits->Add(exit);
7322 } 7322 }
7323 7323
7324 7324
7325 // Insert MaterializeObject instruction for the given allocation before 7325 // Insert MaterializeObject instruction for the given allocation before
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
7381 7381
7382 if (alloc->ArgumentCount() > 0) { 7382 if (alloc->ArgumentCount() > 0) {
7383 ASSERT(alloc->ArgumentCount() == 2); 7383 ASSERT(alloc->ArgumentCount() == 2);
7384 const String& name = String::Handle(Symbols::New(":type_args")); 7384 const String& name = String::Handle(Symbols::New(":type_args"));
7385 const Field& type_args_field = 7385 const Field& type_args_field =
7386 Field::ZoneHandle(Field::New( 7386 Field::ZoneHandle(Field::New(
7387 name, 7387 name,
7388 false, // !static 7388 false, // !static
7389 false, // !final 7389 false, // !final
7390 false, // !const 7390 false, // !const
7391 Class::Handle(alloc->constructor().Owner()), 7391 alloc->cls(),
7392 0)); // No token position. 7392 0)); // No token position.
7393 const Class& cls = Class::Handle(alloc->constructor().Owner()); 7393 type_args_field.SetOffset(alloc->cls().type_arguments_field_offset());
7394 type_args_field.SetOffset(cls.type_arguments_field_offset());
7395 AddField(fields, type_args_field); 7394 AddField(fields, type_args_field);
7396 } 7395 }
7397 7396
7398 // Collect all instructions that mention this object in the environment. 7397 // Collect all instructions that mention this object in the environment.
7399 GrowableArray<Instruction*> exits(10); 7398 GrowableArray<Instruction*> exits(10);
7400 for (Value* use = alloc->env_use_list(); 7399 for (Value* use = alloc->env_use_list();
7401 use != NULL; 7400 use != NULL;
7402 use = use->next_use()) { 7401 use = use->next_use()) {
7403 AddInstruction(&exits, use->instruction()); 7402 AddInstruction(&exits, use->instruction());
7404 } 7403 }
7405 7404
7406 // Insert materializations at environment uses. 7405 // Insert materializations at environment uses.
7407 const Class& cls = Class::Handle(alloc->constructor().Owner());
7408 for (intptr_t i = 0; i < exits.length(); i++) { 7406 for (intptr_t i = 0; i < exits.length(); i++) {
7409 CreateMaterializationAt(exits[i], alloc, cls, *fields); 7407 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7410 } 7408 }
7411 } 7409 }
7412 7410
7413 7411
7414 } // namespace dart 7412 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698