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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/constant_propagator.h" | 10 #include "vm/constant_propagator.h" |
(...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2114 | 2114 |
2115 | 2115 |
2116 // A math unary instruction has a side effect (exception | 2116 // A math unary instruction has a side effect (exception |
2117 // thrown) if the argument is not a number. | 2117 // thrown) if the argument is not a number. |
2118 // TODO(srdjan): eliminate if has no uses and input is guaranteed to be number. | 2118 // TODO(srdjan): eliminate if has no uses and input is guaranteed to be number. |
2119 Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) { | 2119 Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) { |
2120 return this; | 2120 return this; |
2121 } | 2121 } |
2122 | 2122 |
2123 | 2123 |
2124 bool LoadFieldInstr::Evaluate(const Object& instance, Object* result) { | |
2125 if (field() == NULL || !field()->is_final() || !instance.IsInstance()) { | |
2126 return false; | |
2127 } | |
2128 | |
2129 // Check that instance really has the field which we | |
2130 // are trying to load from. | |
2131 Class& cls = Class::Handle(instance.clazz()); | |
2132 while (cls.raw() != Class::null() && cls.raw() != field()->Owner()) { | |
2133 cls = cls.SuperClass(); | |
2134 } | |
2135 if (cls.raw() != field()->Owner()) { | |
2136 // Failed to find the field in class or its superclasses. | |
2137 return false; | |
2138 } | |
2139 | |
2140 // Object has the field: execute the load. | |
2141 *result = Instance::Cast(instance).GetField(*field()); | |
2142 return true; | |
2143 } | |
2144 | |
2145 | |
2146 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { | 2124 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { |
2147 if (!HasUses()) return NULL; | 2125 if (!HasUses()) return NULL; |
| 2126 if (!IsImmutableLengthLoad()) return this; |
2148 | 2127 |
2149 if (IsImmutableLengthLoad()) { | 2128 // For fixed length arrays if the array is the result of a known constructor |
2150 // For fixed length arrays if the array is the result of a known constructor | 2129 // call we can replace the length load with the length argument passed to |
2151 // call we can replace the length load with the length argument passed to | 2130 // the constructor. |
2152 // the constructor. | 2131 StaticCallInstr* call = |
2153 StaticCallInstr* call = | 2132 instance()->definition()->OriginalDefinition()->AsStaticCall(); |
2154 instance()->definition()->OriginalDefinition()->AsStaticCall(); | 2133 if (call != NULL) { |
2155 if (call != NULL) { | 2134 if (call->is_known_list_constructor() && |
2156 if (call->is_known_list_constructor() && | 2135 IsFixedLengthArrayCid(call->Type()->ToCid())) { |
2157 IsFixedLengthArrayCid(call->Type()->ToCid())) { | 2136 return call->ArgumentAt(1); |
2158 return call->ArgumentAt(1); | |
2159 } | |
2160 } | |
2161 | |
2162 CreateArrayInstr* create_array = | |
2163 instance()->definition()->OriginalDefinition()->AsCreateArray(); | |
2164 if ((create_array != NULL) && | |
2165 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) { | |
2166 return create_array->num_elements()->definition(); | |
2167 } | |
2168 | |
2169 // For arrays with guarded lengths, replace the length load | |
2170 // with a constant. | |
2171 LoadFieldInstr* load_array = | |
2172 instance()->definition()->OriginalDefinition()->AsLoadField(); | |
2173 if (load_array != NULL) { | |
2174 const Field* field = load_array->field(); | |
2175 if ((field != NULL) && (field->guarded_list_length() >= 0)) { | |
2176 return flow_graph->GetConstant( | |
2177 Smi::Handle(Smi::New(field->guarded_list_length()))); | |
2178 } | |
2179 } | 2137 } |
2180 } | 2138 } |
2181 | 2139 |
2182 // Try folding away loads from constant objects. | 2140 CreateArrayInstr* create_array = |
2183 if (instance()->BindsToConstant()) { | 2141 instance()->definition()->OriginalDefinition()->AsCreateArray(); |
2184 Object& result = Object::Handle(); | 2142 if ((create_array != NULL) && |
2185 if (Evaluate(instance()->BoundConstant(), &result)) { | 2143 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) { |
2186 return flow_graph->GetConstant(result); | 2144 return create_array->num_elements()->definition(); |
| 2145 } |
| 2146 |
| 2147 // For arrays with guarded lengths, replace the length load |
| 2148 // with a constant. |
| 2149 LoadFieldInstr* load_array = |
| 2150 instance()->definition()->OriginalDefinition()->AsLoadField(); |
| 2151 if (load_array != NULL) { |
| 2152 const Field* field = load_array->field(); |
| 2153 if ((field != NULL) && (field->guarded_list_length() >= 0)) { |
| 2154 return flow_graph->GetConstant( |
| 2155 Smi::Handle(Smi::New(field->guarded_list_length()))); |
2187 } | 2156 } |
2188 } | 2157 } |
2189 | |
2190 return this; | 2158 return this; |
2191 } | 2159 } |
2192 | 2160 |
2193 | 2161 |
2194 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) { | 2162 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) { |
2195 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) { | 2163 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) { |
2196 return value()->definition(); | 2164 return value()->definition(); |
2197 } | 2165 } |
2198 | 2166 |
2199 return this; | 2167 return this; |
(...skipping 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4342 "native function '%s' (%" Pd " arguments) cannot be found", | 4310 "native function '%s' (%" Pd " arguments) cannot be found", |
4343 native_name().ToCString(), function().NumParameters()); | 4311 native_name().ToCString(), function().NumParameters()); |
4344 } | 4312 } |
4345 set_is_auto_scope(auto_setup_scope); | 4313 set_is_auto_scope(auto_setup_scope); |
4346 set_native_c_function(native_function); | 4314 set_native_c_function(native_function); |
4347 } | 4315 } |
4348 | 4316 |
4349 #undef __ | 4317 #undef __ |
4350 | 4318 |
4351 } // namespace dart | 4319 } // namespace dart |
OLD | NEW |