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