| 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 |