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