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 3662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3673 // Check for core library get:_classId. | 3673 // Check for core library get:_classId. |
3674 intptr_t cid = Class::Handle(call->function().Owner()).id(); | 3674 intptr_t cid = Class::Handle(call->function().Owner()).id(); |
3675 // Currently only implemented for a subset of classes. | 3675 // Currently only implemented for a subset of classes. |
3676 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || | 3676 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || |
3677 (cid == kExternalOneByteStringCid) || | 3677 (cid == kExternalOneByteStringCid) || |
3678 (cid == kGrowableObjectArrayCid) || | 3678 (cid == kGrowableObjectArrayCid) || |
3679 (cid == kImmutableArrayCid) || (cid == kArrayCid)); | 3679 (cid == kImmutableArrayCid) || (cid == kArrayCid)); |
3680 ConstantInstr* cid_instr = new ConstantInstr(Smi::Handle(Smi::New(cid))); | 3680 ConstantInstr* cid_instr = new ConstantInstr(Smi::Handle(Smi::New(cid))); |
3681 ReplaceCall(call, cid_instr); | 3681 ReplaceCall(call, cid_instr); |
3682 } | 3682 } |
| 3683 |
| 3684 if (call->function().IsFactory()) { |
| 3685 const Class& function_class = Class::Handle(call->function().Owner()); |
| 3686 if ((function_class.library() == Library::CoreLibrary()) || |
| 3687 (function_class.library() == Library::TypedDataLibrary())) { |
| 3688 intptr_t cid = FactoryRecognizer::ResultCid(call->function()); |
| 3689 switch (cid) { |
| 3690 case kArrayCid: { |
| 3691 Value* type = new Value(call->ArgumentAt(0)); |
| 3692 Value* num_elements = new Value(call->ArgumentAt(1)); |
| 3693 if (num_elements->BindsToConstant() && |
| 3694 num_elements->BoundConstant().IsSmi()) { |
| 3695 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); |
| 3696 if (length >= 0 && length <= Array::kMaxElements) { |
| 3697 CreateArrayInstr* create_array = |
| 3698 new CreateArrayInstr(call->token_pos(), type, num_elements); |
| 3699 ReplaceCall(call, create_array); |
| 3700 } |
| 3701 } |
| 3702 } |
| 3703 default: |
| 3704 break; |
| 3705 } |
| 3706 } |
| 3707 } |
3683 } | 3708 } |
3684 | 3709 |
3685 | 3710 |
3686 void FlowGraphOptimizer::VisitStoreInstanceField( | 3711 void FlowGraphOptimizer::VisitStoreInstanceField( |
3687 StoreInstanceFieldInstr* instr) { | 3712 StoreInstanceFieldInstr* instr) { |
3688 if (instr->IsUnboxedStore()) { | 3713 if (instr->IsUnboxedStore()) { |
3689 ASSERT(instr->is_initialization_); | 3714 ASSERT(instr->is_initialization_); |
3690 // Determine if this field should be unboxed based on the usage of getter | 3715 // Determine if this field should be unboxed based on the usage of getter |
3691 // and setter functions: The heuristic requires that the setter has a | 3716 // and setter functions: The heuristic requires that the setter has a |
3692 // usage count of at least 1/kGetterSetterRatio of the getter usage count. | 3717 // usage count of at least 1/kGetterSetterRatio of the getter usage count. |
(...skipping 3419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7112 SetValue(instr, Smi::ZoneHandle(Smi::New(object.GetClassId()))); | 7137 SetValue(instr, Smi::ZoneHandle(Smi::New(object.GetClassId()))); |
7113 return; | 7138 return; |
7114 } | 7139 } |
7115 SetValue(instr, non_constant_); | 7140 SetValue(instr, non_constant_); |
7116 } | 7141 } |
7117 | 7142 |
7118 | 7143 |
7119 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { | 7144 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { |
7120 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && | 7145 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && |
7121 (instr->instance()->definition()->IsCreateArray())) { | 7146 (instr->instance()->definition()->IsCreateArray())) { |
7122 const intptr_t length = | 7147 Value* num_elements = |
7123 instr->instance()->definition()->AsCreateArray()->num_elements(); | 7148 instr->instance()->definition()->AsCreateArray()->num_elements(); |
7124 const Object& result = Smi::ZoneHandle(Smi::New(length)); | 7149 if (num_elements->BindsToConstant() && |
7125 SetValue(instr, result); | 7150 num_elements->BoundConstant().IsSmi()) { |
7126 return; | 7151 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); |
| 7152 const Object& result = Smi::ZoneHandle(Smi::New(length)); |
| 7153 SetValue(instr, result); |
| 7154 return; |
| 7155 } |
7127 } | 7156 } |
7128 | 7157 |
7129 if (instr->IsImmutableLengthLoad()) { | 7158 if (instr->IsImmutableLengthLoad()) { |
7130 ConstantInstr* constant = instr->instance()->definition()->AsConstant(); | 7159 ConstantInstr* constant = instr->instance()->definition()->AsConstant(); |
7131 if (constant != NULL) { | 7160 if (constant != NULL) { |
7132 if (constant->value().IsString()) { | 7161 if (constant->value().IsString()) { |
7133 SetValue(instr, Smi::ZoneHandle( | 7162 SetValue(instr, Smi::ZoneHandle( |
7134 Smi::New(String::Cast(constant->value()).Length()))); | 7163 Smi::New(String::Cast(constant->value()).Length()))); |
7135 return; | 7164 return; |
7136 } | 7165 } |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8443 } | 8472 } |
8444 | 8473 |
8445 // Insert materializations at environment uses. | 8474 // Insert materializations at environment uses. |
8446 for (intptr_t i = 0; i < exits.length(); i++) { | 8475 for (intptr_t i = 0; i < exits.length(); i++) { |
8447 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 8476 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
8448 } | 8477 } |
8449 } | 8478 } |
8450 | 8479 |
8451 | 8480 |
8452 } // namespace dart | 8481 } // namespace dart |
OLD | NEW |