| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/precompiler.h" | 5 #include "vm/precompiler.h" |
| 6 | 6 |
| 7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 DECLARE_FLAG(bool, trace_bailout); | 68 DECLARE_FLAG(bool, trace_bailout); |
| 69 DECLARE_FLAG(bool, use_inlining); | 69 DECLARE_FLAG(bool, use_inlining); |
| 70 DECLARE_FLAG(bool, verify_compiler); | 70 DECLARE_FLAG(bool, verify_compiler); |
| 71 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); | 71 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); |
| 72 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 72 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| 73 DECLARE_FLAG(bool, trace_inlining_intervals); | 73 DECLARE_FLAG(bool, trace_inlining_intervals); |
| 74 DECLARE_FLAG(bool, trace_irregexp); | 74 DECLARE_FLAG(bool, trace_irregexp); |
| 75 | 75 |
| 76 #ifdef DART_PRECOMPILER | 76 #ifdef DART_PRECOMPILER |
| 77 | 77 |
| 78 class DartPrecompilationPipeline : public DartCompilationPipeline { |
| 79 public: |
| 80 DartPrecompilationPipeline() : result_type_(CompileType::None()) { } |
| 81 |
| 82 virtual void FinalizeCompilation(FlowGraph* flow_graph) { |
| 83 CompileType result_type = CompileType::None(); |
| 84 for (BlockIterator block_it = flow_graph->reverse_postorder_iterator(); |
| 85 !block_it.Done(); |
| 86 block_it.Advance()) { |
| 87 ForwardInstructionIterator it(block_it.Current()); |
| 88 for (; !it.Done(); it.Advance()) { |
| 89 ReturnInstr* return_instr = it.Current()->AsReturn(); |
| 90 if (return_instr != NULL) { |
| 91 result_type.Union(return_instr->InputAt(0)->Type()); |
| 92 } |
| 93 } |
| 94 } |
| 95 result_type_ = result_type; |
| 96 } |
| 97 |
| 98 CompileType result_type() { return result_type_; } |
| 99 |
| 100 private: |
| 101 CompileType result_type_; |
| 102 }; |
| 103 |
| 104 |
| 78 class PrecompileParsedFunctionHelper : public ValueObject { | 105 class PrecompileParsedFunctionHelper : public ValueObject { |
| 79 public: | 106 public: |
| 80 PrecompileParsedFunctionHelper(ParsedFunction* parsed_function, | 107 PrecompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| 81 bool optimized) | 108 bool optimized) |
| 82 : parsed_function_(parsed_function), | 109 : parsed_function_(parsed_function), |
| 83 optimized_(optimized), | 110 optimized_(optimized), |
| 84 thread_(Thread::Current()) { | 111 thread_(Thread::Current()) { |
| 85 } | 112 } |
| 86 | 113 |
| 87 bool Compile(CompilationPipeline* pipeline); | 114 bool Compile(CompilationPipeline* pipeline); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 | 189 |
| 163 { | 190 { |
| 164 StackZone stack_zone(T); | 191 StackZone stack_zone(T); |
| 165 zone_ = stack_zone.GetZone(); | 192 zone_ = stack_zone.GetZone(); |
| 166 | 193 |
| 167 // Make sure class hierarchy is stable before compilation so that CHA | 194 // Make sure class hierarchy is stable before compilation so that CHA |
| 168 // can be used. Also ensures lookup of entry points won't miss functions | 195 // can be used. Also ensures lookup of entry points won't miss functions |
| 169 // because their class hasn't been finalized yet. | 196 // because their class hasn't been finalized yet. |
| 170 FinalizeAllClasses(); | 197 FinalizeAllClasses(); |
| 171 | 198 |
| 199 // Precompile static initializers to compute result type information. |
| 200 PrecompileStaticInitializers(); |
| 201 |
| 172 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { | 202 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { |
| 173 if (FLAG_trace_precompiler) { | 203 if (FLAG_trace_precompiler) { |
| 174 THR_Print("Precompiler round %" Pd "\n", round); | 204 THR_Print("Precompiler round %" Pd "\n", round); |
| 175 } | 205 } |
| 176 | 206 |
| 177 if (round > 0) { | 207 if (round > 0) { |
| 178 ResetPrecompilerState(); | 208 ResetPrecompilerState(); |
| 179 } | 209 } |
| 180 | 210 |
| 181 // TODO(rmacnak): We should be able to do a more thorough job and drop | 211 // TODO(rmacnak): We should be able to do a more thorough job and drop |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 THR_Print(" %" Pd " fields,", dropped_field_count_); | 278 THR_Print(" %" Pd " fields,", dropped_field_count_); |
| 249 THR_Print(" %" Pd " symbols,", symbols_before - symbols_after); | 279 THR_Print(" %" Pd " symbols,", symbols_before - symbols_after); |
| 250 THR_Print(" %" Pd " types,", dropped_type_count_); | 280 THR_Print(" %" Pd " types,", dropped_type_count_); |
| 251 THR_Print(" %" Pd " type arguments,", dropped_typearg_count_); | 281 THR_Print(" %" Pd " type arguments,", dropped_typearg_count_); |
| 252 THR_Print(" %" Pd " classes,", dropped_class_count_); | 282 THR_Print(" %" Pd " classes,", dropped_class_count_); |
| 253 THR_Print(" %" Pd " libraries.\n", dropped_library_count_); | 283 THR_Print(" %" Pd " libraries.\n", dropped_library_count_); |
| 254 } | 284 } |
| 255 } | 285 } |
| 256 | 286 |
| 257 | 287 |
| 288 static void CompileStaticInitializerIgnoreErrors(const Field& field) { |
| 289 LongJumpScope jump; |
| 290 if (setjmp(*jump.Set()) == 0) { |
| 291 Precompiler::CompileStaticInitializer(field, /* compute_type = */ true); |
| 292 } else { |
| 293 // Ignore compile-time errors here. If the field is actually used, |
| 294 // the error will be reported later during Iterate(). |
| 295 } |
| 296 } |
| 297 |
| 298 |
| 299 void Precompiler::PrecompileStaticInitializers() { |
| 300 class StaticInitializerVisitor : public ClassVisitor { |
| 301 public: |
| 302 explicit StaticInitializerVisitor(Zone* zone) |
| 303 : fields_(Array::Handle(zone)), |
| 304 field_(Field::Handle(zone)), |
| 305 function_(Function::Handle(zone)) { } |
| 306 void Visit(const Class& cls) { |
| 307 fields_ = cls.fields(); |
| 308 for (intptr_t j = 0; j < fields_.Length(); j++) { |
| 309 field_ ^= fields_.At(j); |
| 310 if (field_.is_static() && |
| 311 field_.is_final() && |
| 312 field_.has_initializer()) { |
| 313 if (FLAG_trace_precompiler) { |
| 314 THR_Print("Precompiling initializer for %s\n", field_.ToCString()); |
| 315 } |
| 316 CompileStaticInitializerIgnoreErrors(field_); |
| 317 } |
| 318 } |
| 319 } |
| 320 |
| 321 private: |
| 322 Array& fields_; |
| 323 Field& field_; |
| 324 Function& function_; |
| 325 }; |
| 326 StaticInitializerVisitor visitor(Z); |
| 327 VisitClasses(&visitor); |
| 328 } |
| 329 |
| 330 |
| 258 void Precompiler::ClearAllCode() { | 331 void Precompiler::ClearAllCode() { |
| 259 class ClearCodeFunctionVisitor : public FunctionVisitor { | 332 class ClearCodeFunctionVisitor : public FunctionVisitor { |
| 260 void VisitFunction(const Function& function) { | 333 void Visit(const Function& function) { |
| 261 function.ClearCode(); | 334 function.ClearCode(); |
| 262 function.ClearICDataArray(); | 335 function.ClearICDataArray(); |
| 263 } | 336 } |
| 264 }; | 337 }; |
| 265 ClearCodeFunctionVisitor visitor; | 338 ClearCodeFunctionVisitor visitor; |
| 266 VisitFunctions(&visitor); | 339 VisitFunctions(&visitor); |
| 267 } | 340 } |
| 268 | 341 |
| 269 | 342 |
| 270 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { | 343 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 | 834 |
| 762 const bool is_initialized = value.raw() != Object::sentinel().raw(); | 835 const bool is_initialized = value.raw() != Object::sentinel().raw(); |
| 763 if (is_initialized && !reset_fields_) return; | 836 if (is_initialized && !reset_fields_) return; |
| 764 | 837 |
| 765 if (!field.HasPrecompiledInitializer() || | 838 if (!field.HasPrecompiledInitializer() || |
| 766 !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) { | 839 !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) { |
| 767 if (FLAG_trace_precompiler) { | 840 if (FLAG_trace_precompiler) { |
| 768 THR_Print("Precompiling initializer for %s\n", field.ToCString()); | 841 THR_Print("Precompiling initializer for %s\n", field.ToCString()); |
| 769 } | 842 } |
| 770 ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT); | 843 ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT); |
| 771 const Function& initializer = | 844 const Function& initializer = Function::Handle(Z, |
| 772 Function::Handle(Z, CompileStaticInitializer(field)); | 845 CompileStaticInitializer(field, /* compute_type = */ true)); |
| 773 ASSERT(!initializer.IsNull()); | 846 ASSERT(!initializer.IsNull()); |
| 774 field.SetPrecompiledInitializer(initializer); | 847 field.SetPrecompiledInitializer(initializer); |
| 775 AddCalleesOf(initializer); | 848 AddCalleesOf(initializer); |
| 776 } | 849 } |
| 777 } | 850 } |
| 778 } | 851 } |
| 779 } | 852 } |
| 780 | 853 |
| 781 | 854 |
| 782 RawFunction* Precompiler::CompileStaticInitializer(const Field& field) { | 855 RawFunction* Precompiler::CompileStaticInitializer(const Field& field, |
| 856 bool compute_type) { |
| 783 ASSERT(field.is_static()); | 857 ASSERT(field.is_static()); |
| 784 Thread* thread = Thread::Current(); | 858 Thread* thread = Thread::Current(); |
| 785 StackZone zone(thread); | 859 StackZone zone(thread); |
| 786 | 860 |
| 787 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); | 861 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); |
| 788 | 862 |
| 789 parsed_function->AllocateVariables(); | 863 parsed_function->AllocateVariables(); |
| 790 DartCompilationPipeline pipeline; | 864 DartPrecompilationPipeline pipeline; |
| 791 PrecompileParsedFunctionHelper helper(parsed_function, | 865 PrecompileParsedFunctionHelper helper(parsed_function, |
| 792 /* optimized = */ true); | 866 /* optimized = */ true); |
| 793 bool success = helper.Compile(&pipeline); | 867 bool success = helper.Compile(&pipeline); |
| 794 ASSERT(success); | 868 ASSERT(success); |
| 795 | 869 |
| 870 if (compute_type && field.is_final()) { |
| 871 intptr_t result_cid = pipeline.result_type().ToCid(); |
| 872 if (result_cid != kDynamicCid) { |
| 873 if (FLAG_trace_precompiler) { |
| 874 THR_Print("Setting guarded_cid of %s to %s\n", field.ToCString(), |
| 875 pipeline.result_type().ToCString()); |
| 876 } |
| 877 field.set_guarded_cid(result_cid); |
| 878 } |
| 879 } |
| 880 |
| 796 if ((FLAG_disassemble || FLAG_disassemble_optimized) && | 881 if ((FLAG_disassemble || FLAG_disassemble_optimized) && |
| 797 FlowGraphPrinter::ShouldPrint(parsed_function->function())) { | 882 FlowGraphPrinter::ShouldPrint(parsed_function->function())) { |
| 798 Disassembler::DisassembleCode(parsed_function->function(), | 883 Disassembler::DisassembleCode(parsed_function->function(), |
| 799 /* optimized = */ true); | 884 /* optimized = */ true); |
| 800 } | 885 } |
| 801 return parsed_function->function().raw(); | 886 return parsed_function->function().raw(); |
| 802 } | 887 } |
| 803 | 888 |
| 804 | 889 |
| 805 RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) { | 890 RawObject* Precompiler::EvaluateStaticInitializer(const Field& field) { |
| 806 ASSERT(field.is_static()); | 891 ASSERT(field.is_static()); |
| 807 // The VM sets the field's value to transiton_sentinel prior to | 892 // The VM sets the field's value to transiton_sentinel prior to |
| 808 // evaluating the initializer value. | 893 // evaluating the initializer value. |
| 809 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); | 894 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); |
| 810 LongJumpScope jump; | 895 LongJumpScope jump; |
| 811 if (setjmp(*jump.Set()) == 0) { | 896 if (setjmp(*jump.Set()) == 0) { |
| 812 // Under precompilation, the initializer may have already been compiled, in | 897 // Under precompilation, the initializer may have already been compiled, in |
| 813 // which case use it. Under lazy compilation or early in precompilation, the | 898 // which case use it. Under lazy compilation or early in precompilation, the |
| 814 // initializer has not yet been created, so create it now, but don't bother | 899 // initializer has not yet been created, so create it now, but don't bother |
| 815 // remembering it because it won't be used again. | 900 // remembering it because it won't be used again. |
| 816 Function& initializer = Function::Handle(); | 901 Function& initializer = Function::Handle(); |
| 817 if (!field.HasPrecompiledInitializer()) { | 902 if (!field.HasPrecompiledInitializer()) { |
| 818 initializer = CompileStaticInitializer(field); | 903 initializer = CompileStaticInitializer(field, /* compute_type = */ false); |
| 819 } else { | 904 } else { |
| 820 initializer ^= field.PrecompiledInitializer(); | 905 initializer ^= field.PrecompiledInitializer(); |
| 821 } | 906 } |
| 822 // Invoke the function to evaluate the expression. | 907 // Invoke the function to evaluate the expression. |
| 823 return DartEntry::InvokeFunction(initializer, Object::empty_array()); | 908 return DartEntry::InvokeFunction(initializer, Object::empty_array()); |
| 824 } else { | 909 } else { |
| 825 Thread* const thread = Thread::Current(); | 910 Thread* const thread = Thread::Current(); |
| 826 StackZone zone(thread); | 911 StackZone zone(thread); |
| 827 const Error& error = | 912 const Error& error = |
| 828 Error::Handle(thread->zone(), thread->sticky_error()); | 913 Error::Handle(thread->zone(), thread->sticky_error()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 // would compile func automatically. We are checking fewer invariants | 954 // would compile func automatically. We are checking fewer invariants |
| 870 // here. | 955 // here. |
| 871 ParsedFunction* parsed_function = new ParsedFunction(thread, func); | 956 ParsedFunction* parsed_function = new ParsedFunction(thread, func); |
| 872 parsed_function->SetNodeSequence(fragment); | 957 parsed_function->SetNodeSequence(fragment); |
| 873 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); | 958 fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp()); |
| 874 fragment->scope()->AddVariable( | 959 fragment->scope()->AddVariable( |
| 875 parsed_function->current_context_var()); | 960 parsed_function->current_context_var()); |
| 876 parsed_function->AllocateVariables(); | 961 parsed_function->AllocateVariables(); |
| 877 | 962 |
| 878 // Non-optimized code generator. | 963 // Non-optimized code generator. |
| 879 DartCompilationPipeline pipeline; | 964 DartPrecompilationPipeline pipeline; |
| 880 PrecompileParsedFunctionHelper helper(parsed_function, | 965 PrecompileParsedFunctionHelper helper(parsed_function, |
| 881 /* optimized = */ false); | 966 /* optimized = */ false); |
| 882 helper.Compile(&pipeline); | 967 helper.Compile(&pipeline); |
| 883 Code::Handle(func.unoptimized_code()).set_var_descriptors( | 968 Code::Handle(func.unoptimized_code()).set_var_descriptors( |
| 884 Object::empty_var_descriptors()); | 969 Object::empty_var_descriptors()); |
| 885 | 970 |
| 886 const Object& result = PassiveObject::Handle( | 971 const Object& result = PassiveObject::Handle( |
| 887 DartEntry::InvokeFunction(func, Object::empty_array())); | 972 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 888 return result.raw(); | 973 return result.raw(); |
| 889 } else { | 974 } else { |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 class BindStaticCallsVisitor : public FunctionVisitor { | 1750 class BindStaticCallsVisitor : public FunctionVisitor { |
| 1666 public: | 1751 public: |
| 1667 explicit BindStaticCallsVisitor(Zone* zone) : | 1752 explicit BindStaticCallsVisitor(Zone* zone) : |
| 1668 code_(Code::Handle(zone)), | 1753 code_(Code::Handle(zone)), |
| 1669 table_(Array::Handle(zone)), | 1754 table_(Array::Handle(zone)), |
| 1670 pc_offset_(Smi::Handle(zone)), | 1755 pc_offset_(Smi::Handle(zone)), |
| 1671 target_(Function::Handle(zone)), | 1756 target_(Function::Handle(zone)), |
| 1672 target_code_(Code::Handle(zone)) { | 1757 target_code_(Code::Handle(zone)) { |
| 1673 } | 1758 } |
| 1674 | 1759 |
| 1675 void VisitFunction(const Function& function) { | 1760 void Visit(const Function& function) { |
| 1676 if (!function.HasCode()) { | 1761 if (!function.HasCode()) { |
| 1677 return; | 1762 return; |
| 1678 } | 1763 } |
| 1679 code_ = function.CurrentCode(); | 1764 code_ = function.CurrentCode(); |
| 1680 table_ = code_.static_calls_target_table(); | 1765 table_ = code_.static_calls_target_table(); |
| 1681 | 1766 |
| 1682 for (intptr_t i = 0; | 1767 for (intptr_t i = 0; |
| 1683 i < table_.Length(); | 1768 i < table_.Length(); |
| 1684 i += Code::kSCallTableEntryLength) { | 1769 i += Code::kSCallTableEntryLength) { |
| 1685 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); | 1770 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1734 explicit SwitchICCallsVisitor(Zone* zone) : | 1819 explicit SwitchICCallsVisitor(Zone* zone) : |
| 1735 code_(Code::Handle(zone)), | 1820 code_(Code::Handle(zone)), |
| 1736 pool_(ObjectPool::Handle(zone)), | 1821 pool_(ObjectPool::Handle(zone)), |
| 1737 entry_(Object::Handle(zone)), | 1822 entry_(Object::Handle(zone)), |
| 1738 ic_(ICData::Handle(zone)), | 1823 ic_(ICData::Handle(zone)), |
| 1739 target_(Function::Handle(zone)), | 1824 target_(Function::Handle(zone)), |
| 1740 target_code_(Code::Handle(zone)), | 1825 target_code_(Code::Handle(zone)), |
| 1741 entry_point_(Smi::Handle(zone)) { | 1826 entry_point_(Smi::Handle(zone)) { |
| 1742 } | 1827 } |
| 1743 | 1828 |
| 1744 void VisitFunction(const Function& function) { | 1829 void Visit(const Function& function) { |
| 1745 if (!function.HasCode()) { | 1830 if (!function.HasCode()) { |
| 1746 return; | 1831 return; |
| 1747 } | 1832 } |
| 1748 | 1833 |
| 1749 code_ = function.CurrentCode(); | 1834 code_ = function.CurrentCode(); |
| 1750 pool_ = code_.object_pool(); | 1835 pool_ = code_.object_pool(); |
| 1751 for (intptr_t i = 0; i < pool_.Length(); i++) { | 1836 for (intptr_t i = 0; i < pool_.Length(); i++) { |
| 1752 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; | 1837 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; |
| 1753 entry_ = pool_.ObjectAt(i); | 1838 entry_ = pool_.ObjectAt(i); |
| 1754 if (entry_.IsICData()) { | 1839 if (entry_.IsICData()) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1803 class DedupStackmapsVisitor : public FunctionVisitor { | 1888 class DedupStackmapsVisitor : public FunctionVisitor { |
| 1804 public: | 1889 public: |
| 1805 explicit DedupStackmapsVisitor(Zone* zone) : | 1890 explicit DedupStackmapsVisitor(Zone* zone) : |
| 1806 zone_(zone), | 1891 zone_(zone), |
| 1807 canonical_stackmaps_(), | 1892 canonical_stackmaps_(), |
| 1808 code_(Code::Handle(zone)), | 1893 code_(Code::Handle(zone)), |
| 1809 stackmaps_(Array::Handle(zone)), | 1894 stackmaps_(Array::Handle(zone)), |
| 1810 stackmap_(Stackmap::Handle(zone)) { | 1895 stackmap_(Stackmap::Handle(zone)) { |
| 1811 } | 1896 } |
| 1812 | 1897 |
| 1813 void VisitFunction(const Function& function) { | 1898 void Visit(const Function& function) { |
| 1814 if (!function.HasCode()) { | 1899 if (!function.HasCode()) { |
| 1815 return; | 1900 return; |
| 1816 } | 1901 } |
| 1817 code_ = function.CurrentCode(); | 1902 code_ = function.CurrentCode(); |
| 1818 stackmaps_ = code_.stackmaps(); | 1903 stackmaps_ = code_.stackmaps(); |
| 1819 if (stackmaps_.IsNull()) return; | 1904 if (stackmaps_.IsNull()) return; |
| 1820 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { | 1905 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { |
| 1821 stackmap_ ^= stackmaps_.At(i); | 1906 stackmap_ ^= stackmaps_.At(i); |
| 1822 stackmap_ = DedupStackmap(stackmap_); | 1907 stackmap_ = DedupStackmap(stackmap_); |
| 1823 stackmaps_.SetAt(i, stackmap_); | 1908 stackmaps_.SetAt(i, stackmap_); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1853 class DedupStackmapListsVisitor : public FunctionVisitor { | 1938 class DedupStackmapListsVisitor : public FunctionVisitor { |
| 1854 public: | 1939 public: |
| 1855 explicit DedupStackmapListsVisitor(Zone* zone) : | 1940 explicit DedupStackmapListsVisitor(Zone* zone) : |
| 1856 zone_(zone), | 1941 zone_(zone), |
| 1857 canonical_stackmap_lists_(), | 1942 canonical_stackmap_lists_(), |
| 1858 code_(Code::Handle(zone)), | 1943 code_(Code::Handle(zone)), |
| 1859 stackmaps_(Array::Handle(zone)), | 1944 stackmaps_(Array::Handle(zone)), |
| 1860 stackmap_(Stackmap::Handle(zone)) { | 1945 stackmap_(Stackmap::Handle(zone)) { |
| 1861 } | 1946 } |
| 1862 | 1947 |
| 1863 void VisitFunction(const Function& function) { | 1948 void Visit(const Function& function) { |
| 1864 if (!function.HasCode()) { | 1949 if (!function.HasCode()) { |
| 1865 return; | 1950 return; |
| 1866 } | 1951 } |
| 1867 code_ = function.CurrentCode(); | 1952 code_ = function.CurrentCode(); |
| 1868 stackmaps_ = code_.stackmaps(); | 1953 stackmaps_ = code_.stackmaps(); |
| 1869 if (stackmaps_.IsNull()) return; | 1954 if (stackmaps_.IsNull()) return; |
| 1870 | 1955 |
| 1871 stackmaps_ = DedupStackmapList(stackmaps_); | 1956 stackmaps_ = DedupStackmapList(stackmaps_); |
| 1872 code_.set_stackmaps(stackmaps_); | 1957 code_.set_stackmaps(stackmaps_); |
| 1873 } | 1958 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1900 void Precompiler::DedupInstructions() { | 1985 void Precompiler::DedupInstructions() { |
| 1901 class DedupInstructionsVisitor : public FunctionVisitor { | 1986 class DedupInstructionsVisitor : public FunctionVisitor { |
| 1902 public: | 1987 public: |
| 1903 explicit DedupInstructionsVisitor(Zone* zone) : | 1988 explicit DedupInstructionsVisitor(Zone* zone) : |
| 1904 zone_(zone), | 1989 zone_(zone), |
| 1905 canonical_instructions_set_(), | 1990 canonical_instructions_set_(), |
| 1906 code_(Code::Handle(zone)), | 1991 code_(Code::Handle(zone)), |
| 1907 instructions_(Instructions::Handle(zone)) { | 1992 instructions_(Instructions::Handle(zone)) { |
| 1908 } | 1993 } |
| 1909 | 1994 |
| 1910 void VisitFunction(const Function& function) { | 1995 void Visit(const Function& function) { |
| 1911 if (!function.HasCode()) { | 1996 if (!function.HasCode()) { |
| 1912 ASSERT(function.HasImplicitClosureFunction()); | 1997 ASSERT(function.HasImplicitClosureFunction()); |
| 1913 return; | 1998 return; |
| 1914 } | 1999 } |
| 1915 code_ = function.CurrentCode(); | 2000 code_ = function.CurrentCode(); |
| 1916 instructions_ = code_.instructions(); | 2001 instructions_ = code_.instructions(); |
| 1917 instructions_ = DedupOneInstructions(instructions_); | 2002 instructions_ = DedupOneInstructions(instructions_); |
| 1918 code_.SetActiveInstructions(instructions_.raw()); | 2003 code_.SetActiveInstructions(instructions_.raw()); |
| 1919 code_.set_instructions(instructions_.raw()); | 2004 code_.set_instructions(instructions_.raw()); |
| 1920 function.SetInstructions(code_); // Update cached entry point. | 2005 function.SetInstructions(code_); // Update cached entry point. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1936 Zone* zone_; | 2021 Zone* zone_; |
| 1937 InstructionsSet canonical_instructions_set_; | 2022 InstructionsSet canonical_instructions_set_; |
| 1938 Code& code_; | 2023 Code& code_; |
| 1939 Instructions& instructions_; | 2024 Instructions& instructions_; |
| 1940 }; | 2025 }; |
| 1941 | 2026 |
| 1942 DedupInstructionsVisitor visitor(Z); | 2027 DedupInstructionsVisitor visitor(Z); |
| 1943 VisitFunctions(&visitor); | 2028 VisitFunctions(&visitor); |
| 1944 } | 2029 } |
| 1945 | 2030 |
| 2031 |
| 2032 void Precompiler::VisitClasses(ClassVisitor* visitor) { |
| 2033 Library& lib = Library::Handle(Z); |
| 2034 Class& cls = Class::Handle(Z); |
| 2035 |
| 2036 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 2037 lib ^= libraries_.At(i); |
| 2038 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 2039 while (it.HasNext()) { |
| 2040 cls = it.GetNextClass(); |
| 2041 if (cls.IsDynamicClass()) { |
| 2042 continue; // class 'dynamic' is in the read-only VM isolate. |
| 2043 } |
| 2044 visitor->Visit(cls); |
| 2045 } |
| 2046 } |
| 2047 } |
| 2048 |
| 2049 |
| 1946 void Precompiler::VisitFunctions(FunctionVisitor* visitor) { | 2050 void Precompiler::VisitFunctions(FunctionVisitor* visitor) { |
| 1947 Library& lib = Library::Handle(Z); | 2051 Library& lib = Library::Handle(Z); |
| 1948 Class& cls = Class::Handle(Z); | 2052 Class& cls = Class::Handle(Z); |
| 1949 Array& functions = Array::Handle(Z); | 2053 Array& functions = Array::Handle(Z); |
| 1950 Array& fields = Array::Handle(Z); | 2054 Array& fields = Array::Handle(Z); |
| 1951 Field& field = Field::Handle(Z); | 2055 Field& field = Field::Handle(Z); |
| 1952 Object& object = Object::Handle(Z); | 2056 Object& object = Object::Handle(Z); |
| 1953 Function& function = Function::Handle(Z); | 2057 Function& function = Function::Handle(Z); |
| 1954 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 2058 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
| 1955 | 2059 |
| 1956 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 2060 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1957 lib ^= libraries_.At(i); | 2061 lib ^= libraries_.At(i); |
| 1958 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 2062 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 1959 while (it.HasNext()) { | 2063 while (it.HasNext()) { |
| 1960 cls = it.GetNextClass(); | 2064 cls = it.GetNextClass(); |
| 1961 if (cls.IsDynamicClass()) { | 2065 if (cls.IsDynamicClass()) { |
| 1962 continue; // class 'dynamic' is in the read-only VM isolate. | 2066 continue; // class 'dynamic' is in the read-only VM isolate. |
| 1963 } | 2067 } |
| 1964 | 2068 |
| 1965 functions = cls.functions(); | 2069 functions = cls.functions(); |
| 1966 for (intptr_t j = 0; j < functions.Length(); j++) { | 2070 for (intptr_t j = 0; j < functions.Length(); j++) { |
| 1967 function ^= functions.At(j); | 2071 function ^= functions.At(j); |
| 1968 visitor->VisitFunction(function); | 2072 visitor->Visit(function); |
| 1969 if (function.HasImplicitClosureFunction()) { | 2073 if (function.HasImplicitClosureFunction()) { |
| 1970 function = function.ImplicitClosureFunction(); | 2074 function = function.ImplicitClosureFunction(); |
| 1971 visitor->VisitFunction(function); | 2075 visitor->Visit(function); |
| 1972 } | 2076 } |
| 1973 } | 2077 } |
| 1974 | 2078 |
| 1975 functions = cls.invocation_dispatcher_cache(); | 2079 functions = cls.invocation_dispatcher_cache(); |
| 1976 for (intptr_t j = 0; j < functions.Length(); j++) { | 2080 for (intptr_t j = 0; j < functions.Length(); j++) { |
| 1977 object = functions.At(j); | 2081 object = functions.At(j); |
| 1978 if (object.IsFunction()) { | 2082 if (object.IsFunction()) { |
| 1979 function ^= functions.At(j); | 2083 function ^= functions.At(j); |
| 1980 visitor->VisitFunction(function); | 2084 visitor->Visit(function); |
| 1981 } | 2085 } |
| 1982 } | 2086 } |
| 1983 fields = cls.fields(); | 2087 fields = cls.fields(); |
| 1984 for (intptr_t j = 0; j < fields.Length(); j++) { | 2088 for (intptr_t j = 0; j < fields.Length(); j++) { |
| 1985 field ^= fields.At(j); | 2089 field ^= fields.At(j); |
| 1986 if (field.is_static() && field.HasPrecompiledInitializer()) { | 2090 if (field.is_static() && field.HasPrecompiledInitializer()) { |
| 1987 function ^= field.PrecompiledInitializer(); | 2091 function ^= field.PrecompiledInitializer(); |
| 1988 visitor->VisitFunction(function); | 2092 visitor->Visit(function); |
| 1989 } | 2093 } |
| 1990 } | 2094 } |
| 1991 } | 2095 } |
| 1992 } | 2096 } |
| 1993 closures = isolate()->object_store()->closure_functions(); | 2097 closures = isolate()->object_store()->closure_functions(); |
| 1994 for (intptr_t j = 0; j < closures.Length(); j++) { | 2098 for (intptr_t j = 0; j < closures.Length(); j++) { |
| 1995 function ^= closures.At(j); | 2099 function ^= closures.At(j); |
| 1996 visitor->VisitFunction(function); | 2100 visitor->Visit(function); |
| 1997 ASSERT(!function.HasImplicitClosureFunction()); | 2101 ASSERT(!function.HasImplicitClosureFunction()); |
| 1998 } | 2102 } |
| 1999 } | 2103 } |
| 2000 | 2104 |
| 2001 | 2105 |
| 2002 void Precompiler::FinalizeAllClasses() { | 2106 void Precompiler::FinalizeAllClasses() { |
| 2003 Library& lib = Library::Handle(Z); | 2107 Library& lib = Library::Handle(Z); |
| 2004 Class& cls = Class::Handle(Z); | 2108 Class& cls = Class::Handle(Z); |
| 2005 | 2109 |
| 2006 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 2110 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2572 inline_id_to_token_pos, | 2676 inline_id_to_token_pos, |
| 2573 caller_inline_id); | 2677 caller_inline_id); |
| 2574 { | 2678 { |
| 2575 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); | 2679 CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer); |
| 2576 #ifndef PRODUCT | 2680 #ifndef PRODUCT |
| 2577 TimelineDurationScope tds(thread(), | 2681 TimelineDurationScope tds(thread(), |
| 2578 compiler_timeline, | 2682 compiler_timeline, |
| 2579 "CompileGraph"); | 2683 "CompileGraph"); |
| 2580 #endif // !PRODUCT | 2684 #endif // !PRODUCT |
| 2581 graph_compiler.CompileGraph(); | 2685 graph_compiler.CompileGraph(); |
| 2582 pipeline->FinalizeCompilation(); | 2686 pipeline->FinalizeCompilation(flow_graph); |
| 2583 } | 2687 } |
| 2584 { | 2688 { |
| 2585 #ifndef PRODUCT | 2689 #ifndef PRODUCT |
| 2586 TimelineDurationScope tds(thread(), | 2690 TimelineDurationScope tds(thread(), |
| 2587 compiler_timeline, | 2691 compiler_timeline, |
| 2588 "FinalizeCompilation"); | 2692 "FinalizeCompilation"); |
| 2589 #endif // !PRODUCT | 2693 #endif // !PRODUCT |
| 2590 ASSERT(thread()->IsMutatorThread()); | 2694 ASSERT(thread()->IsMutatorThread()); |
| 2591 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); | 2695 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); |
| 2592 } | 2696 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2747 CompilationPipeline::New(thread->zone(), function); | 2851 CompilationPipeline::New(thread->zone(), function); |
| 2748 | 2852 |
| 2749 ASSERT(FLAG_precompiled_mode); | 2853 ASSERT(FLAG_precompiled_mode); |
| 2750 const bool optimized = function.IsOptimizable(); // False for natives. | 2854 const bool optimized = function.IsOptimizable(); // False for natives. |
| 2751 return PrecompileFunctionHelper(pipeline, function, optimized); | 2855 return PrecompileFunctionHelper(pipeline, function, optimized); |
| 2752 } | 2856 } |
| 2753 | 2857 |
| 2754 #endif // DART_PRECOMPILER | 2858 #endif // DART_PRECOMPILER |
| 2755 | 2859 |
| 2756 } // namespace dart | 2860 } // namespace dart |
| OLD | NEW |