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 |
2124 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { | 2146 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { |
2125 if (!HasUses()) return NULL; | 2147 if (!HasUses()) return NULL; |
2126 if (!IsImmutableLengthLoad()) return this; | |
2127 | 2148 |
2128 // For fixed length arrays if the array is the result of a known constructor | 2149 if (IsImmutableLengthLoad()) { |
2129 // call we can replace the length load with the length argument passed to | 2150 // For fixed length arrays if the array is the result of a known constructor |
2130 // the constructor. | 2151 // call we can replace the length load with the length argument passed to |
2131 StaticCallInstr* call = | 2152 // the constructor. |
2132 instance()->definition()->OriginalDefinition()->AsStaticCall(); | 2153 StaticCallInstr* call = |
2133 if (call != NULL) { | 2154 instance()->definition()->OriginalDefinition()->AsStaticCall(); |
2134 if (call->is_known_list_constructor() && | 2155 if (call != NULL) { |
2135 IsFixedLengthArrayCid(call->Type()->ToCid())) { | 2156 if (call->is_known_list_constructor() && |
2136 return call->ArgumentAt(1); | 2157 IsFixedLengthArrayCid(call->Type()->ToCid())) { |
| 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 } |
2137 } | 2179 } |
2138 } | 2180 } |
2139 | 2181 |
2140 CreateArrayInstr* create_array = | 2182 // Try folding away loads from constant objects. |
2141 instance()->definition()->OriginalDefinition()->AsCreateArray(); | 2183 if (instance()->BindsToConstant()) { |
2142 if ((create_array != NULL) && | 2184 Object& result = Object::Handle(); |
2143 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) { | 2185 if (Evaluate(instance()->BoundConstant(), &result)) { |
2144 return create_array->num_elements()->definition(); | 2186 return flow_graph->GetConstant(result); |
| 2187 } |
2145 } | 2188 } |
2146 | 2189 |
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()))); | |
2156 } | |
2157 } | |
2158 return this; | 2190 return this; |
2159 } | 2191 } |
2160 | 2192 |
2161 | 2193 |
2162 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) { | 2194 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) { |
2163 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) { | 2195 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) { |
2164 return value()->definition(); | 2196 return value()->definition(); |
2165 } | 2197 } |
2166 | 2198 |
2167 return this; | 2199 return this; |
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4308 "native function '%s' (%" Pd " arguments) cannot be found", | 4340 "native function '%s' (%" Pd " arguments) cannot be found", |
4309 native_name().ToCString(), function().NumParameters()); | 4341 native_name().ToCString(), function().NumParameters()); |
4310 } | 4342 } |
4311 set_is_auto_scope(auto_setup_scope); | 4343 set_is_auto_scope(auto_setup_scope); |
4312 set_native_c_function(native_function); | 4344 set_native_c_function(native_function); |
4313 } | 4345 } |
4314 | 4346 |
4315 #undef __ | 4347 #undef __ |
4316 | 4348 |
4317 } // namespace dart | 4349 } // namespace dart |
OLD | NEW |