| 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/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 CheckArrayBoundInstr::LengthOffsetFor(class_id), | 750 CheckArrayBoundInstr::LengthOffsetFor(class_id), |
| 751 Type::ZoneHandle(Type::SmiType()), | 751 Type::ZoneHandle(Type::SmiType()), |
| 752 is_immutable); | 752 is_immutable); |
| 753 length->set_result_cid(kSmiCid); | 753 length->set_result_cid(kSmiCid); |
| 754 length->set_recognized_kind( | 754 length->set_recognized_kind( |
| 755 LoadFieldInstr::RecognizedKindFromArrayCid(class_id)); | 755 LoadFieldInstr::RecognizedKindFromArrayCid(class_id)); |
| 756 InsertBefore(call, length, NULL, Definition::kValue); | 756 InsertBefore(call, length, NULL, Definition::kValue); |
| 757 InsertBefore(call, | 757 InsertBefore(call, |
| 758 new CheckArrayBoundInstr(new Value(length), | 758 new CheckArrayBoundInstr(new Value(length), |
| 759 new Value(*index), | 759 new Value(*index), |
| 760 class_id, | |
| 761 call), | 760 call), |
| 762 call->env(), | 761 call->env(), |
| 763 Definition::kEffect); | 762 Definition::kEffect); |
| 764 | 763 |
| 765 if (class_id == kGrowableObjectArrayCid) { | 764 if (class_id == kGrowableObjectArrayCid) { |
| 766 // Insert data elements load. | 765 // Insert data elements load. |
| 767 LoadFieldInstr* elements = | 766 LoadFieldInstr* elements = |
| 768 new LoadFieldInstr(new Value(*array), | 767 new LoadFieldInstr(new Value(*array), |
| 769 GrowableObjectArray::data_offset(), | 768 GrowableObjectArray::data_offset(), |
| 770 Type::ZoneHandle(Type::DynamicType())); | 769 Type::ZoneHandle(Type::DynamicType())); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1630 skip_check = constant_index.IsSmi() && | 1629 skip_check = constant_index.IsSmi() && |
| 1631 (Smi::Cast(constant_index).Value() < constant_string.Length()); | 1630 (Smi::Cast(constant_index).Value() < constant_string.Length()); |
| 1632 } | 1631 } |
| 1633 if (!skip_check) { | 1632 if (!skip_check) { |
| 1634 // Insert bounds check. | 1633 // Insert bounds check. |
| 1635 LoadFieldInstr* length = BuildLoadStringLength(str); | 1634 LoadFieldInstr* length = BuildLoadStringLength(str); |
| 1636 InsertBefore(call, length, NULL, Definition::kValue); | 1635 InsertBefore(call, length, NULL, Definition::kValue); |
| 1637 InsertBefore(call, | 1636 InsertBefore(call, |
| 1638 new CheckArrayBoundInstr(new Value(length), | 1637 new CheckArrayBoundInstr(new Value(length), |
| 1639 new Value(index), | 1638 new Value(index), |
| 1640 cid, | |
| 1641 call), | 1639 call), |
| 1642 call->env(), | 1640 call->env(), |
| 1643 Definition::kEffect); | 1641 Definition::kEffect); |
| 1644 } | 1642 } |
| 1645 return new LoadIndexedInstr(new Value(str), | 1643 return new LoadIndexedInstr(new Value(str), |
| 1646 new Value(index), | 1644 new Value(index), |
| 1647 FlowGraphCompiler::ElementSizeFor(cid), | 1645 FlowGraphCompiler::ElementSizeFor(cid), |
| 1648 cid, | 1646 cid, |
| 1649 Isolate::kNoDeoptId); // Can't deoptimize. | 1647 Isolate::kNoDeoptId); // Can't deoptimize. |
| 1650 } | 1648 } |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 new BinarySmiOpInstr(Token::kMUL, | 2227 new BinarySmiOpInstr(Token::kMUL, |
| 2230 call, | 2228 call, |
| 2231 new Value(length), | 2229 new Value(length), |
| 2232 new Value(bytes_per_element)); | 2230 new Value(bytes_per_element)); |
| 2233 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue); | 2231 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue); |
| 2234 | 2232 |
| 2235 // Check byte_index < len_in_bytes. | 2233 // Check byte_index < len_in_bytes. |
| 2236 InsertBefore(call, | 2234 InsertBefore(call, |
| 2237 new CheckArrayBoundInstr(new Value(len_in_bytes), | 2235 new CheckArrayBoundInstr(new Value(len_in_bytes), |
| 2238 new Value(byte_index), | 2236 new Value(byte_index), |
| 2239 receiver_cid, | |
| 2240 call), | 2237 call), |
| 2241 call->env(), | 2238 call->env(), |
| 2242 Definition::kEffect); | 2239 Definition::kEffect); |
| 2243 | 2240 |
| 2244 // Insert load of elements for external typed arrays. | 2241 // Insert load of elements for external typed arrays. |
| 2245 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) { | 2242 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) { |
| 2246 LoadUntaggedInstr* elements = | 2243 LoadUntaggedInstr* elements = |
| 2247 new LoadUntaggedInstr(new Value(*array), | 2244 new LoadUntaggedInstr(new Value(*array), |
| 2248 ExternalTypedData::data_offset()); | 2245 ExternalTypedData::data_offset()); |
| 2249 InsertBefore(call, elements, NULL, Definition::kValue); | 2246 InsertBefore(call, elements, NULL, Definition::kValue); |
| (...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3114 ConstrainValueAfterCheckArrayBound( | 3111 ConstrainValueAfterCheckArrayBound( |
| 3115 defn, | 3112 defn, |
| 3116 use->instruction()->AsCheckArrayBound()); | 3113 use->instruction()->AsCheckArrayBound()); |
| 3117 } | 3114 } |
| 3118 } | 3115 } |
| 3119 } | 3116 } |
| 3120 | 3117 |
| 3121 | 3118 |
| 3122 void RangeAnalysis::ConstrainValueAfterCheckArrayBound( | 3119 void RangeAnalysis::ConstrainValueAfterCheckArrayBound( |
| 3123 Definition* defn, CheckArrayBoundInstr* check) { | 3120 Definition* defn, CheckArrayBoundInstr* check) { |
| 3124 if (!CheckArrayBoundInstr::IsFixedLengthArrayType(check->array_type())) { | |
| 3125 return; | |
| 3126 } | |
| 3127 | |
| 3128 Definition* length = check->length()->definition(); | 3121 Definition* length = check->length()->definition(); |
| 3129 | 3122 |
| 3130 Range* constraint_range = new Range( | 3123 Range* constraint_range = new Range( |
| 3131 RangeBoundary::FromConstant(0), | 3124 RangeBoundary::FromConstant(0), |
| 3132 RangeBoundary::FromDefinition(length, -1)); | 3125 RangeBoundary::FromDefinition(length, -1)); |
| 3133 InsertConstraintFor(defn, constraint_range, check); | 3126 InsertConstraintFor(defn, constraint_range, check); |
| 3134 } | 3127 } |
| 3135 | 3128 |
| 3136 | 3129 |
| 3137 void RangeAnalysis::InsertConstraints() { | 3130 void RangeAnalysis::InsertConstraints() { |
| (...skipping 3461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6599 | 6592 |
| 6600 // Insert materializations at environment uses. | 6593 // Insert materializations at environment uses. |
| 6601 const Class& cls = Class::Handle(alloc->constructor().Owner()); | 6594 const Class& cls = Class::Handle(alloc->constructor().Owner()); |
| 6602 for (intptr_t i = 0; i < exits.length(); i++) { | 6595 for (intptr_t i = 0; i < exits.length(); i++) { |
| 6603 CreateMaterializationAt(exits[i], alloc, cls, *fields); | 6596 CreateMaterializationAt(exits[i], alloc, cls, *fields); |
| 6604 } | 6597 } |
| 6605 } | 6598 } |
| 6606 | 6599 |
| 6607 | 6600 |
| 6608 } // namespace dart | 6601 } // namespace dart |
| OLD | NEW |