| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |