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