| 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/cpu.h" | 8 #include "vm/cpu.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_allocator.h" | 10 #include "vm/flow_graph_allocator.h" |
| (...skipping 2867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2878 const Function& StringInterpolateInstr::CallFunction() const { | 2878 const Function& StringInterpolateInstr::CallFunction() const { |
| 2879 if (function_.IsNull()) { | 2879 if (function_.IsNull()) { |
| 2880 const int kNumberOfArguments = 1; | 2880 const int kNumberOfArguments = 1; |
| 2881 const Array& kNoArgumentNames = Object::null_array(); | 2881 const Array& kNoArgumentNames = Object::null_array(); |
| 2882 const Class& cls = | 2882 const Class& cls = |
| 2883 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); | 2883 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); |
| 2884 ASSERT(!cls.IsNull()); | 2884 ASSERT(!cls.IsNull()); |
| 2885 function_ = | 2885 function_ = |
| 2886 Resolver::ResolveStatic( | 2886 Resolver::ResolveStatic( |
| 2887 cls, | 2887 cls, |
| 2888 Library::PrivateCoreLibName(Symbols::Interpolate()), | 2888 is_singleton_ |
| 2889 ? Library::PrivateCoreLibName(Symbols::InterpolateSingle()) |
| 2890 : Library::PrivateCoreLibName(Symbols::Interpolate()), |
| 2889 kNumberOfArguments, | 2891 kNumberOfArguments, |
| 2890 kNoArgumentNames); | 2892 kNoArgumentNames); |
| 2891 } | 2893 } |
| 2892 ASSERT(!function_.IsNull()); | 2894 ASSERT(!function_.IsNull()); |
| 2893 return function_; | 2895 return function_; |
| 2894 } | 2896 } |
| 2895 | 2897 |
| 2896 | 2898 |
| 2897 // Replace StringInterpolateInstr with a constant string if all inputs are | 2899 // Replace StringInterpolateInstr with a constant string if all inputs are |
| 2898 // constant of [string, number, boolean, null]. | 2900 // constant of [string, number, boolean, null]. |
| 2899 // Leave the CreateArrayInstr and StoreIndexedInstr in the stream in case | 2901 // Leave the CreateArrayInstr and StoreIndexedInstr in the stream in case |
| 2900 // deoptimization occurs. | 2902 // deoptimization occurs. |
| 2901 Definition* StringInterpolateInstr::Canonicalize(FlowGraph* flow_graph) { | 2903 Definition* StringInterpolateInstr::Canonicalize(FlowGraph* flow_graph) { |
| 2902 // The following graph structure is generated by the graph builder: | 2904 // The following graph structure is generated by the graph builder: |
| 2903 // v2 <- CreateArray(v0) | 2905 // v2 <- CreateArray(v0) |
| 2904 // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value. | 2906 // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value. |
| 2905 // .. | 2907 // .. |
| 2906 // v8 <- StringInterpolate(v2) | 2908 // v8 <- StringInterpolate(v2) |
| 2909 // or for a single element: |
| 2910 // v2 <- StringInterpolateSingle(v0) |
| 2907 | 2911 |
| 2908 // Don't compile-time fold when optimizing the interpolation function itself. | 2912 // Don't compile-time fold when optimizing the interpolation function itself. |
| 2909 if (flow_graph->parsed_function().function().raw() == CallFunction().raw()) { | 2913 if (flow_graph->parsed_function().function().raw() == CallFunction().raw()) { |
| 2910 return this; | 2914 return this; |
| 2911 } | 2915 } |
| 2912 | 2916 |
| 2917 if (is_singleton_) { |
| 2918 Value* value = this->value(); |
| 2919 if (!value->definition()->IsConstant()) return this; |
| 2920 const Object& obj = value->definition()->AsConstant()->value(); |
| 2921 if (!obj.IsNumber() && !obj.IsString() && !obj.IsBool() && !obj.IsNull()) { |
| 2922 return this; |
| 2923 } |
| 2924 // This is only really useful for numbers, so we don't bother optimizing |
| 2925 // for strings, bool or null. |
| 2926 const Array& interpolate_arg = Array::Handle(Array::New(1)); |
| 2927 interpolate_arg.SetAt(0, obj); |
| 2928 const Object& result = Object::Handle( |
| 2929 DartEntry::InvokeFunction(CallFunction(), interpolate_arg)); |
| 2930 if (result.IsUnhandledException()) { |
| 2931 return this; |
| 2932 } |
| 2933 ASSERT(result.IsString()); |
| 2934 const String& converted = |
| 2935 String::ZoneHandle(Symbols::New(String::Cast(result))); |
| 2936 return flow_graph->GetConstant(converted); |
| 2937 } |
| 2913 CreateArrayInstr* create_array = value()->definition()->AsCreateArray(); | 2938 CreateArrayInstr* create_array = value()->definition()->AsCreateArray(); |
| 2914 ASSERT(create_array != NULL); | 2939 ASSERT(create_array != NULL); |
| 2915 // Check if the string interpolation has only constant inputs. | 2940 // Check if the string interpolation has only constant inputs. |
| 2916 Value* num_elements = create_array->num_elements(); | 2941 Value* num_elements = create_array->num_elements(); |
| 2917 if (!num_elements->BindsToConstant() || | 2942 if (!num_elements->BindsToConstant() || |
| 2918 !num_elements->BoundConstant().IsSmi()) { | 2943 !num_elements->BoundConstant().IsSmi()) { |
| 2919 return this; | 2944 return this; |
| 2920 } | 2945 } |
| 2921 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); | 2946 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); |
| 2922 GrowableArray<ConstantInstr*> constants(length); | 2947 GrowableArray<ConstantInstr*> constants(length); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 case Token::kTRUNCDIV: return 0; | 3143 case Token::kTRUNCDIV: return 0; |
| 3119 case Token::kMOD: return 1; | 3144 case Token::kMOD: return 1; |
| 3120 default: UNIMPLEMENTED(); return -1; | 3145 default: UNIMPLEMENTED(); return -1; |
| 3121 } | 3146 } |
| 3122 } | 3147 } |
| 3123 | 3148 |
| 3124 | 3149 |
| 3125 #undef __ | 3150 #undef __ |
| 3126 | 3151 |
| 3127 } // namespace dart | 3152 } // namespace dart |
| OLD | NEW |