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/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.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" |
11 #include "vm/flow_graph_builder.h" | 11 #include "vm/flow_graph_builder.h" |
12 #include "vm/flow_graph_compiler.h" | 12 #include "vm/flow_graph_compiler.h" |
13 #include "vm/flow_graph_optimizer.h" | 13 #include "vm/flow_graph_optimizer.h" |
14 #include "vm/locations.h" | 14 #include "vm/locations.h" |
15 #include "vm/object.h" | 15 #include "vm/object.h" |
16 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
17 #include "vm/os.h" | 17 #include "vm/os.h" |
18 #include "vm/resolver.h" | 18 #include "vm/resolver.h" |
19 #include "vm/scopes.h" | 19 #include "vm/scopes.h" |
20 #include "vm/stub_code.h" | 20 #include "vm/stub_code.h" |
21 #include "vm/symbols.h" | 21 #include "vm/symbols.h" |
22 | 22 |
| 23 #include "vm/il_printer.h" |
| 24 |
23 namespace dart { | 25 namespace dart { |
24 | 26 |
25 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, | 27 DEFINE_FLAG(int, max_equality_polymorphic_checks, 32, |
26 "Maximum number of polymorphic checks in equality operator," | 28 "Maximum number of polymorphic checks in equality operator," |
27 " otherwise use megamorphic dispatch."); | 29 " otherwise use megamorphic dispatch."); |
28 DEFINE_FLAG(bool, new_identity_spec, true, | 30 DEFINE_FLAG(bool, new_identity_spec, true, |
29 "Use new identity check rules for numbers."); | 31 "Use new identity check rules for numbers."); |
30 DEFINE_FLAG(bool, propagate_ic_data, true, | 32 DEFINE_FLAG(bool, propagate_ic_data, true, |
31 "Propagate IC data from unoptimized to optimized IC calls."); | 33 "Propagate IC data from unoptimized to optimized IC calls."); |
32 DECLARE_FLAG(bool, enable_type_checks); | 34 DECLARE_FLAG(bool, enable_type_checks); |
(...skipping 2679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 Library::PrivateCoreLibName(Symbols::Interpolate()), | 2714 Library::PrivateCoreLibName(Symbols::Interpolate()), |
2713 kNumberOfArguments, | 2715 kNumberOfArguments, |
2714 kNoArgumentNames, | 2716 kNoArgumentNames, |
2715 Resolver::kIsQualified); | 2717 Resolver::kIsQualified); |
2716 } | 2718 } |
2717 ASSERT(!function_.IsNull()); | 2719 ASSERT(!function_.IsNull()); |
2718 return function_; | 2720 return function_; |
2719 } | 2721 } |
2720 | 2722 |
2721 | 2723 |
| 2724 // Replace StringInterpolateInstr with a constant string if all inputs are |
| 2725 // constant of [string, number, boolean, null]. |
| 2726 // Leave the CreateArrayInstr and StoreIndexedInstr in the stream in case |
| 2727 // deoptimization occurs. |
| 2728 Definition* StringInterpolateInstr::Canonicalize(FlowGraph* flow_graph) { |
| 2729 // The following graph structure is generated by the graph builder: |
| 2730 // v2 <- CreateArray(v0) |
| 2731 // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value. |
| 2732 // .. |
| 2733 // v8 <- StringInterpolate(v2) |
| 2734 CreateArrayInstr* create_array = value()->definition()->AsCreateArray(); |
| 2735 ASSERT(create_array != NULL); |
| 2736 // Check if the string interpolation has only constant inputs. |
| 2737 GrowableArray<ConstantInstr*> constants(create_array->num_elements()); |
| 2738 for (intptr_t i = 0; i < create_array->num_elements(); i++) { |
| 2739 constants.Add(NULL); |
| 2740 } |
| 2741 for (Value::Iterator it(create_array->input_use_list()); |
| 2742 !it.Done(); |
| 2743 it.Advance()) { |
| 2744 Instruction* curr = it.Current()->instruction(); |
| 2745 if (curr != this) { |
| 2746 StoreIndexedInstr* store = curr->AsStoreIndexed(); |
| 2747 ASSERT(store != NULL); |
| 2748 if (store->value()->definition()->IsConstant()) { |
| 2749 ASSERT(store->index()->BindsToConstant()); |
| 2750 const Object& obj = store->value()->definition()->AsConstant()->value(); |
| 2751 if (obj.IsNumber() || obj.IsString() || obj.IsBool() || obj.IsNull()) { |
| 2752 constants[Smi::Cast(store->index()->BoundConstant()).Value()] = |
| 2753 store->value()->definition()->AsConstant(); |
| 2754 } else { |
| 2755 return this; |
| 2756 } |
| 2757 } else { |
| 2758 return this; |
| 2759 } |
| 2760 } |
| 2761 } |
| 2762 // Interpolate string at compile time. |
| 2763 const Array& array_argument = |
| 2764 Array::Handle(Array::New(create_array->num_elements())); |
| 2765 for (intptr_t i = 0; i < constants.length(); i++) { |
| 2766 array_argument.SetAt(i, constants[i]->value()); |
| 2767 } |
| 2768 // Build argument array to pass to the interpolation function. |
| 2769 const Array& interpolate_arg = Array::Handle(Array::New(1)); |
| 2770 interpolate_arg.SetAt(0, array_argument); |
| 2771 // Call interpolation function. |
| 2772 String& concatenated = String::ZoneHandle(); |
| 2773 concatenated ^= |
| 2774 DartEntry::InvokeFunction(CallFunction(), interpolate_arg); |
| 2775 if (concatenated.IsUnhandledException()) { |
| 2776 return this; |
| 2777 } |
| 2778 concatenated = Symbols::New(concatenated); |
| 2779 return flow_graph->GetConstant(concatenated); |
| 2780 } |
| 2781 |
| 2782 |
2722 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( | 2783 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( |
2723 ZoneGrowableArray<Value*>* inputs, | 2784 ZoneGrowableArray<Value*>* inputs, |
2724 intptr_t original_deopt_id, | 2785 intptr_t original_deopt_id, |
2725 MethodRecognizer::Kind recognized_kind) | 2786 MethodRecognizer::Kind recognized_kind) |
2726 : inputs_(inputs), | 2787 : inputs_(inputs), |
2727 locs_(NULL), | 2788 locs_(NULL), |
2728 recognized_kind_(recognized_kind) { | 2789 recognized_kind_(recognized_kind) { |
2729 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); | 2790 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); |
2730 for (intptr_t i = 0; i < inputs_->length(); ++i) { | 2791 for (intptr_t i = 0; i < inputs_->length(); ++i) { |
2731 ASSERT((*inputs)[i] != NULL); | 2792 ASSERT((*inputs)[i] != NULL); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2823 return kCosRuntimeEntry; | 2884 return kCosRuntimeEntry; |
2824 default: | 2885 default: |
2825 UNREACHABLE(); | 2886 UNREACHABLE(); |
2826 } | 2887 } |
2827 return kSinRuntimeEntry; | 2888 return kSinRuntimeEntry; |
2828 } | 2889 } |
2829 | 2890 |
2830 #undef __ | 2891 #undef __ |
2831 | 2892 |
2832 } // namespace dart | 2893 } // namespace dart |
OLD | NEW |