| 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/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
| 11 #include "vm/compiler.h" |
| 11 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 12 #include "vm/debugger.h" | 13 #include "vm/debugger.h" |
| 13 #include "vm/deopt_instructions.h" | 14 #include "vm/deopt_instructions.h" |
| 14 #include "vm/exceptions.h" | 15 #include "vm/exceptions.h" |
| 15 #include "vm/flow_graph_allocator.h" | 16 #include "vm/flow_graph_allocator.h" |
| 16 #include "vm/il_printer.h" | 17 #include "vm/il_printer.h" |
| 17 #include "vm/intrinsifier.h" | 18 #include "vm/intrinsifier.h" |
| 18 #include "vm/locations.h" | 19 #include "vm/locations.h" |
| 19 #include "vm/log.h" | 20 #include "vm/log.h" |
| 20 #include "vm/longjump.h" | 21 #include "vm/longjump.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 34 DEFINE_FLAG(bool, enable_simd_inline, true, | 35 DEFINE_FLAG(bool, enable_simd_inline, true, |
| 35 "Enable inlining of SIMD related method calls."); | 36 "Enable inlining of SIMD related method calls."); |
| 36 DEFINE_FLAG(int, min_optimization_counter_threshold, 5000, | 37 DEFINE_FLAG(int, min_optimization_counter_threshold, 5000, |
| 37 "The minimum invocation count for a function."); | 38 "The minimum invocation count for a function."); |
| 38 DEFINE_FLAG(int, optimization_counter_scale, 2000, | 39 DEFINE_FLAG(int, optimization_counter_scale, 2000, |
| 39 "The scale of invocation count, by size of the function."); | 40 "The scale of invocation count, by size of the function."); |
| 40 DEFINE_FLAG(bool, source_lines, false, "Emit source line as assembly comment."); | 41 DEFINE_FLAG(bool, source_lines, false, "Emit source line as assembly comment."); |
| 41 DEFINE_FLAG(bool, use_megamorphic_stub, true, "Out of line megamorphic lookup"); | 42 DEFINE_FLAG(bool, use_megamorphic_stub, true, "Out of line megamorphic lookup"); |
| 42 | 43 |
| 43 DECLARE_FLAG(bool, code_comments); | 44 DECLARE_FLAG(bool, code_comments); |
| 44 DECLARE_FLAG(int, deoptimize_every); | 45 DECLARE_FLAG(bool, deoptimize_alot); |
| 46 DECLARE_FLAG(bool, deoptimize_every); |
| 45 DECLARE_FLAG(charp, deoptimize_filter); | 47 DECLARE_FLAG(charp, deoptimize_filter); |
| 46 DECLARE_FLAG(bool, disassemble); | 48 DECLARE_FLAG(bool, disassemble); |
| 47 DECLARE_FLAG(bool, disassemble_optimized); | 49 DECLARE_FLAG(bool, disassemble_optimized); |
| 48 DECLARE_FLAG(bool, emit_edge_counters); | 50 DECLARE_FLAG(bool, emit_edge_counters); |
| 51 DECLARE_FLAG(bool, ic_range_profiling); |
| 49 DECLARE_FLAG(bool, intrinsify); | 52 DECLARE_FLAG(bool, intrinsify); |
| 53 DECLARE_FLAG(bool, load_deferred_eagerly); |
| 50 DECLARE_FLAG(int, optimization_counter_threshold); | 54 DECLARE_FLAG(int, optimization_counter_threshold); |
| 51 DECLARE_FLAG(bool, propagate_ic_data); | 55 DECLARE_FLAG(bool, propagate_ic_data); |
| 52 DECLARE_FLAG(int, regexp_optimization_counter_threshold); | 56 DECLARE_FLAG(int, regexp_optimization_counter_threshold); |
| 53 DECLARE_FLAG(int, reoptimization_counter_threshold); | 57 DECLARE_FLAG(int, reoptimization_counter_threshold); |
| 54 DECLARE_FLAG(int, stacktrace_every); | 58 DECLARE_FLAG(int, stacktrace_every); |
| 55 DECLARE_FLAG(charp, stacktrace_filter); | 59 DECLARE_FLAG(charp, stacktrace_filter); |
| 56 DECLARE_FLAG(bool, support_debugger); | 60 DECLARE_FLAG(bool, support_debugger); |
| 61 DECLARE_FLAG(bool, use_field_guards); |
| 57 DECLARE_FLAG(bool, use_cha); | 62 DECLARE_FLAG(bool, use_cha); |
| 58 DECLARE_FLAG(bool, use_field_guards); | |
| 59 DECLARE_FLAG(bool, use_osr); | 63 DECLARE_FLAG(bool, use_osr); |
| 60 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 64 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 61 DECLARE_FLAG(bool, ic_range_profiling); | 65 |
| 62 | 66 |
| 63 static void NooptModeHandler(bool value) { | 67 static void NooptModeHandler(bool value) { |
| 64 if (value) { | 68 if (value) { |
| 65 FLAG_always_megamorphic_calls = value; | 69 FLAG_always_megamorphic_calls = value; |
| 66 FLAG_optimization_counter_threshold = -1; | 70 FLAG_optimization_counter_threshold = -1; |
| 67 FLAG_use_field_guards = false; | 71 FLAG_use_field_guards = false; |
| 68 FLAG_use_osr = false; | 72 FLAG_use_osr = false; |
| 69 FLAG_emit_edge_counters = false; | 73 FLAG_emit_edge_counters = false; |
| 70 FLAG_support_debugger = false; | 74 FLAG_support_debugger = false; |
| 71 FLAG_ic_range_profiling = false; | 75 FLAG_ic_range_profiling = false; |
| 72 FLAG_collect_code = false; | 76 FLAG_collect_code = false; |
| 77 FLAG_load_deferred_eagerly = true; |
| 78 FLAG_deoptimize_alot = false; // Used in some tests. |
| 79 FLAG_deoptimize_every = 0; // Used in some tests. |
| 80 FLAG_collect_code = false; |
| 81 Compiler::set_always_optimize(true); |
| 82 Compiler::set_guess_other_cid(false); |
| 83 // TODO(srdjan): Enable CHA when eager class finalization is |
| 84 // implemented, either with precompilation or as a special pass. |
| 85 FLAG_use_cha = false; |
| 73 } | 86 } |
| 74 } | 87 } |
| 75 | 88 |
| 76 | 89 |
| 77 // --noopt disables optimizer and tunes unoptimized code to run as fast | 90 // --noopt disables optimizer and tunes unoptimized code to run as fast |
| 78 // as possible. | 91 // as possible. |
| 79 DEFINE_FLAG_HANDLER(NooptModeHandler, | 92 DEFINE_FLAG_HANDLER(NooptModeHandler, |
| 80 noopt, | 93 noopt, |
| 81 "Run fast unoptimized code only."); | 94 "Run fast unoptimized code only."); |
| 82 | 95 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 BlockEntryInstr* entry = block_order_[i]; | 212 BlockEntryInstr* entry = block_order_[i]; |
| 200 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 213 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 201 Instruction* current = it.Current(); | 214 Instruction* current = it.Current(); |
| 202 if (current->IsBranch()) { | 215 if (current->IsBranch()) { |
| 203 current = current->AsBranch()->comparison(); | 216 current = current->AsBranch()->comparison(); |
| 204 } | 217 } |
| 205 // In optimized code, ICData is always set in the instructions. | 218 // In optimized code, ICData is always set in the instructions. |
| 206 const ICData* ic_data = NULL; | 219 const ICData* ic_data = NULL; |
| 207 if (current->IsInstanceCall()) { | 220 if (current->IsInstanceCall()) { |
| 208 ic_data = current->AsInstanceCall()->ic_data(); | 221 ic_data = current->AsInstanceCall()->ic_data(); |
| 209 ASSERT(ic_data != NULL); | |
| 210 } | 222 } |
| 211 if ((ic_data != NULL) && (ic_data->NumberOfUsedChecks() == 0)) { | 223 if ((ic_data != NULL) && (ic_data->NumberOfUsedChecks() == 0)) { |
| 212 may_reoptimize_ = true; | 224 may_reoptimize_ = true; |
| 213 } | 225 } |
| 214 if (is_leaf && | 226 if (is_leaf && |
| 215 !current->IsCheckStackOverflow() && | 227 !current->IsCheckStackOverflow() && |
| 216 !current->IsParallelMove()) { | 228 !current->IsParallelMove()) { |
| 217 // Note that we do not care if the code contains instructions that | 229 // Note that we do not care if the code contains instructions that |
| 218 // can deoptimize. | 230 // can deoptimize. |
| 219 LocationSummary* locs = current->locs(); | 231 LocationSummary* locs = current->locs(); |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 } | 851 } |
| 840 | 852 |
| 841 | 853 |
| 842 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, | 854 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, |
| 843 ICData::DeoptReasonId reason, | 855 ICData::DeoptReasonId reason, |
| 844 uint32_t flags) { | 856 uint32_t flags) { |
| 845 if (intrinsic_mode()) { | 857 if (intrinsic_mode()) { |
| 846 return &intrinsic_slow_path_label_; | 858 return &intrinsic_slow_path_label_; |
| 847 } | 859 } |
| 848 | 860 |
| 861 // No deoptimization allowed when 'always_optimize' is set. |
| 862 ASSERT(!Compiler::always_optimize()); |
| 849 ASSERT(is_optimizing_); | 863 ASSERT(is_optimizing_); |
| 850 CompilerDeoptInfoWithStub* stub = | 864 CompilerDeoptInfoWithStub* stub = |
| 851 new CompilerDeoptInfoWithStub(deopt_id, | 865 new CompilerDeoptInfoWithStub(deopt_id, |
| 852 reason, | 866 reason, |
| 853 flags, | 867 flags, |
| 854 pending_deoptimization_env_); | 868 pending_deoptimization_env_); |
| 855 deopt_infos_.Add(stub); | 869 deopt_infos_.Add(stub); |
| 856 return stub->entry_label(); | 870 return stub->entry_label(); |
| 857 } | 871 } |
| 858 | 872 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 874 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); | 888 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); |
| 875 if (!is_optimizing_) descriptors.Verify(parsed_function_.function()); | 889 if (!is_optimizing_) descriptors.Verify(parsed_function_.function()); |
| 876 code.set_pc_descriptors(descriptors); | 890 code.set_pc_descriptors(descriptors); |
| 877 code.set_entry_patch_pc_offset(entry_patch_pc_offset_); | 891 code.set_entry_patch_pc_offset(entry_patch_pc_offset_); |
| 878 code.set_patch_code_pc_offset(patch_code_pc_offset_); | 892 code.set_patch_code_pc_offset(patch_code_pc_offset_); |
| 879 code.set_lazy_deopt_pc_offset(lazy_deopt_pc_offset_); | 893 code.set_lazy_deopt_pc_offset(lazy_deopt_pc_offset_); |
| 880 } | 894 } |
| 881 | 895 |
| 882 | 896 |
| 883 RawArray* FlowGraphCompiler::CreateDeoptInfo(Assembler* assembler) { | 897 RawArray* FlowGraphCompiler::CreateDeoptInfo(Assembler* assembler) { |
| 898 // No deopt information if we 'always_optimize' (no deoptimization allowed). |
| 899 if (Compiler::always_optimize()) { |
| 900 return Array::empty_array().raw(); |
| 901 } |
| 884 // For functions with optional arguments, all incoming arguments are copied | 902 // For functions with optional arguments, all incoming arguments are copied |
| 885 // to spill slots. The deoptimization environment does not track them. | 903 // to spill slots. The deoptimization environment does not track them. |
| 886 const Function& function = parsed_function().function(); | 904 const Function& function = parsed_function().function(); |
| 887 const intptr_t incoming_arg_count = | 905 const intptr_t incoming_arg_count = |
| 888 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 906 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
| 889 DeoptInfoBuilder builder(zone(), incoming_arg_count, assembler); | 907 DeoptInfoBuilder builder(zone(), incoming_arg_count, assembler); |
| 890 | 908 |
| 891 intptr_t deopt_info_table_size = DeoptTable::SizeFor(deopt_infos_.length()); | 909 intptr_t deopt_info_table_size = DeoptTable::SizeFor(deopt_infos_.length()); |
| 892 if (deopt_info_table_size == 0) { | 910 if (deopt_info_table_size == 0) { |
| 893 return Object::empty_array().raw(); | 911 return Object::empty_array().raw(); |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1719 | 1737 |
| 1720 | 1738 |
| 1721 void FlowGraphCompiler::FrameStateClear() { | 1739 void FlowGraphCompiler::FrameStateClear() { |
| 1722 ASSERT(!is_optimizing()); | 1740 ASSERT(!is_optimizing()); |
| 1723 frame_state_.TruncateTo(0); | 1741 frame_state_.TruncateTo(0); |
| 1724 } | 1742 } |
| 1725 #endif | 1743 #endif |
| 1726 | 1744 |
| 1727 | 1745 |
| 1728 } // namespace dart | 1746 } // namespace dart |
| OLD | NEW |