| 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/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 4486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4497 break; | 4497 break; |
| 4498 } | 4498 } |
| 4499 } | 4499 } |
| 4500 } | 4500 } |
| 4501 } | 4501 } |
| 4502 | 4502 |
| 4503 | 4503 |
| 4504 void FlowGraphOptimizer::VisitStoreInstanceField( | 4504 void FlowGraphOptimizer::VisitStoreInstanceField( |
| 4505 StoreInstanceFieldInstr* instr) { | 4505 StoreInstanceFieldInstr* instr) { |
| 4506 if (instr->IsUnboxedStore()) { | 4506 if (instr->IsUnboxedStore()) { |
| 4507 ASSERT(instr->is_initialization_); | 4507 ASSERT(instr->is_potential_unboxed_initialization_); |
| 4508 // Determine if this field should be unboxed based on the usage of getter | 4508 // Determine if this field should be unboxed based on the usage of getter |
| 4509 // and setter functions: The heuristic requires that the setter has a | 4509 // and setter functions: The heuristic requires that the setter has a |
| 4510 // usage count of at least 1/kGetterSetterRatio of the getter usage count. | 4510 // usage count of at least 1/kGetterSetterRatio of the getter usage count. |
| 4511 // This is to avoid unboxing fields where the setter is never or rarely | 4511 // This is to avoid unboxing fields where the setter is never or rarely |
| 4512 // executed. | 4512 // executed. |
| 4513 const Field& field = Field::ZoneHandle(I, instr->field().raw()); | 4513 const Field& field = Field::ZoneHandle(I, instr->field().raw()); |
| 4514 const String& field_name = String::Handle(I, field.name()); | 4514 const String& field_name = String::Handle(I, field.name()); |
| 4515 const Class& owner = Class::Handle(I, field.owner()); | 4515 const Class& owner = Class::Handle(I, field.owner()); |
| 4516 const Function& getter = | 4516 const Function& getter = |
| 4517 Function::Handle(I, owner.LookupGetterFunction(field_name)); | 4517 Function::Handle(I, owner.LookupGetterFunction(field_name)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4542 new AllocateUninitializedContextInstr(instr->token_pos(), | 4542 new AllocateUninitializedContextInstr(instr->token_pos(), |
| 4543 instr->num_context_variables()); | 4543 instr->num_context_variables()); |
| 4544 instr->ReplaceWith(replacement, current_iterator()); | 4544 instr->ReplaceWith(replacement, current_iterator()); |
| 4545 | 4545 |
| 4546 StoreInstanceFieldInstr* store = | 4546 StoreInstanceFieldInstr* store = |
| 4547 new(I) StoreInstanceFieldInstr(Context::parent_offset(), | 4547 new(I) StoreInstanceFieldInstr(Context::parent_offset(), |
| 4548 new Value(replacement), | 4548 new Value(replacement), |
| 4549 new Value(flow_graph_->constant_null()), | 4549 new Value(flow_graph_->constant_null()), |
| 4550 kNoStoreBarrier, | 4550 kNoStoreBarrier, |
| 4551 instr->token_pos()); | 4551 instr->token_pos()); |
| 4552 store->set_is_initialization(true); // Won't be eliminated by DSE. | 4552 // Storing into uninitialized memory; remember to prevent dead store |
| 4553 // elimination and ensure proper GC barrier. |
| 4554 store->set_is_object_reference_initialization(true); |
| 4553 flow_graph_->InsertAfter(replacement, store, NULL, FlowGraph::kEffect); | 4555 flow_graph_->InsertAfter(replacement, store, NULL, FlowGraph::kEffect); |
| 4554 Definition* cursor = store; | 4556 Definition* cursor = store; |
| 4555 for (intptr_t i = 0; i < instr->num_context_variables(); ++i) { | 4557 for (intptr_t i = 0; i < instr->num_context_variables(); ++i) { |
| 4556 store = | 4558 store = |
| 4557 new(I) StoreInstanceFieldInstr(Context::variable_offset(i), | 4559 new(I) StoreInstanceFieldInstr(Context::variable_offset(i), |
| 4558 new Value(replacement), | 4560 new Value(replacement), |
| 4559 new Value(flow_graph_->constant_null()), | 4561 new Value(flow_graph_->constant_null()), |
| 4560 kNoStoreBarrier, | 4562 kNoStoreBarrier, |
| 4561 instr->token_pos()); | 4563 instr->token_pos()); |
| 4562 store->set_is_initialization(true); // Won't be eliminated by DSE. | 4564 // Storing into uninitialized memory; remember to prevent dead store |
| 4565 // elimination and ensure proper GC barrier. |
| 4566 store->set_is_object_reference_initialization(true); |
| 4563 flow_graph_->InsertAfter(cursor, store, NULL, FlowGraph::kEffect); | 4567 flow_graph_->InsertAfter(cursor, store, NULL, FlowGraph::kEffect); |
| 4564 cursor = store; | 4568 cursor = store; |
| 4565 } | 4569 } |
| 4566 } | 4570 } |
| 4567 | 4571 |
| 4568 | 4572 |
| 4569 void FlowGraphOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { | 4573 void FlowGraphOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
| 4570 // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized. | 4574 // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized. |
| 4571 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) | 4575 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) |
| 4572 if (!instr->can_pack_into_smi()) | 4576 if (!instr->can_pack_into_smi()) |
| (...skipping 2552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7125 Dump(); | 7129 Dump(); |
| 7126 } | 7130 } |
| 7127 EliminateDeadStores(); | 7131 EliminateDeadStores(); |
| 7128 if (FLAG_trace_load_optimization) { | 7132 if (FLAG_trace_load_optimization) { |
| 7129 FlowGraphPrinter::PrintGraph("After StoreOptimizer", graph_); | 7133 FlowGraphPrinter::PrintGraph("After StoreOptimizer", graph_); |
| 7130 } | 7134 } |
| 7131 } | 7135 } |
| 7132 | 7136 |
| 7133 bool CanEliminateStore(Instruction* instr) { | 7137 bool CanEliminateStore(Instruction* instr) { |
| 7134 switch (instr->tag()) { | 7138 switch (instr->tag()) { |
| 7135 case Instruction::kStoreInstanceField: | 7139 case Instruction::kStoreInstanceField: { |
| 7136 if (instr->AsStoreInstanceField()->is_initialization()) { | 7140 StoreInstanceFieldInstr* store_instance = instr->AsStoreInstanceField(); |
| 7137 // Can't eliminate stores that initialized unboxed fields. | 7141 // Can't eliminate stores that initialize fields. |
| 7138 return false; | 7142 return !(store_instance->is_potential_unboxed_initialization() || |
| 7139 } | 7143 store_instance->is_object_reference_initialization()); |
| 7144 } |
| 7140 case Instruction::kStoreIndexed: | 7145 case Instruction::kStoreIndexed: |
| 7141 case Instruction::kStoreStaticField: | 7146 case Instruction::kStoreStaticField: |
| 7142 return true; | 7147 return true; |
| 7143 default: | 7148 default: |
| 7144 UNREACHABLE(); | 7149 UNREACHABLE(); |
| 7145 return false; | 7150 return false; |
| 7146 } | 7151 } |
| 7147 } | 7152 } |
| 7148 | 7153 |
| 7149 virtual void ComputeInitialSets() { | 7154 virtual void ComputeInitialSets() { |
| (...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8462 | 8467 |
| 8463 // Insert materializations at environment uses. | 8468 // Insert materializations at environment uses. |
| 8464 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8469 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 8465 CreateMaterializationAt( | 8470 CreateMaterializationAt( |
| 8466 exits_collector_.exits()[i], alloc, *slots); | 8471 exits_collector_.exits()[i], alloc, *slots); |
| 8467 } | 8472 } |
| 8468 } | 8473 } |
| 8469 | 8474 |
| 8470 | 8475 |
| 8471 } // namespace dart | 8476 } // namespace dart |
| OLD | NEW |