| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/compiler.h" | 5 #include "vm/compiler.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 if (Compiler::allow_recompilation()) { | 805 if (Compiler::allow_recompilation()) { |
| 806 if (result != NULL) { | 806 if (result != NULL) { |
| 807 // Background compilation: delay registering code until we are | 807 // Background compilation: delay registering code until we are |
| 808 // in the MutatorThread. | 808 // in the MutatorThread. |
| 809 result->SetLeafClasses(thread->cha()->leaf_classes()); | 809 result->SetLeafClasses(thread->cha()->leaf_classes()); |
| 810 result->SetGuardedFields(*flow_graph->guarded_fields()); | 810 result->SetGuardedFields(*flow_graph->guarded_fields()); |
| 811 result->SetDeoptimizeDependentFields( | 811 result->SetDeoptimizeDependentFields( |
| 812 flow_graph->deoptimize_dependent_code()); | 812 flow_graph->deoptimize_dependent_code()); |
| 813 } else { | 813 } else { |
| 814 for (intptr_t i = 0; | 814 for (intptr_t i = 0; |
| 815 i < flow_graph->deoptimize_dependent_code().length(); |
| 816 i++) { |
| 817 const Field* field = flow_graph->deoptimize_dependent_code()[i]; |
| 818 field->DeoptimizeDependentCode(); |
| 819 } |
| 820 for (intptr_t i = 0; |
| 815 i < thread->cha()->leaf_classes().length(); | 821 i < thread->cha()->leaf_classes().length(); |
| 816 ++i) { | 822 ++i) { |
| 817 thread->cha()->leaf_classes()[i]->RegisterCHACode(code); | 823 thread->cha()->leaf_classes()[i]->RegisterCHACode(code); |
| 818 } | 824 } |
| 819 for (intptr_t i = 0; | 825 for (intptr_t i = 0; |
| 820 i < flow_graph->guarded_fields()->length(); | 826 i < flow_graph->guarded_fields()->length(); |
| 821 i++) { | 827 i++) { |
| 822 const Field* field = (*flow_graph->guarded_fields())[i]; | 828 const Field* field = (*flow_graph->guarded_fields())[i]; |
| 823 field->RegisterDependentCode(code); | 829 field->RegisterDependentCode(code); |
| 824 } | 830 } |
| 825 for (intptr_t i = 0; | |
| 826 i < flow_graph->deoptimize_dependent_code().length(); | |
| 827 i++) { | |
| 828 const Field* field = flow_graph->deoptimize_dependent_code()[i]; | |
| 829 field->DeoptimizeDependentCode(); | |
| 830 } | |
| 831 } | 831 } |
| 832 } | 832 } |
| 833 } else { // not optimized. | 833 } else { // not optimized. |
| 834 if (!Compiler::always_optimize() && | 834 if (!Compiler::always_optimize() && |
| 835 (function.ic_data_array() == Array::null())) { | 835 (function.ic_data_array() == Array::null())) { |
| 836 function.SaveICDataMap( | 836 function.SaveICDataMap( |
| 837 graph_compiler.deopt_id_to_ic_data(), | 837 graph_compiler.deopt_id_to_ic_data(), |
| 838 Array::Handle(zone, graph_compiler.edge_counters_array())); | 838 Array::Handle(zone, graph_compiler.edge_counters_array())); |
| 839 } | 839 } |
| 840 function.set_unoptimized_code(code); | 840 function.set_unoptimized_code(code); |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 } | 1813 } |
| 1814 } | 1814 } |
| 1815 | 1815 |
| 1816 | 1816 |
| 1817 // Use to first queue element to form the result element. | 1817 // Use to first queue element to form the result element. |
| 1818 void BackgroundCompiler::AddResult(const BackgroundCompilationResult& result) { | 1818 void BackgroundCompiler::AddResult(const BackgroundCompilationResult& result) { |
| 1819 ASSERT(!Thread::Current()->IsMutatorThread()); | 1819 ASSERT(!Thread::Current()->IsMutatorThread()); |
| 1820 MonitorLocker ml(queue_monitor_); | 1820 MonitorLocker ml(queue_monitor_); |
| 1821 // Reuse the input QueueElement to return the result. | 1821 // Reuse the input QueueElement to return the result. |
| 1822 QueueElement* qelem = function_queue()->Remove(); | 1822 QueueElement* qelem = function_queue()->Remove(); |
| 1823 if (result.IsValid()) { | 1823 // Always add result, even if it is invalid, since the queue element is |
| 1824 qelem->SetFromResult(result); | 1824 // deleted in the mutator thread and potential field based deoptimizations |
| 1825 result_queue()->Add(qelem); | 1825 // (carried in the result) still must be done. |
| 1826 } | 1826 qelem->SetFromResult(result); |
| 1827 result_queue()->Add(qelem); |
| 1827 } | 1828 } |
| 1828 | 1829 |
| 1829 | 1830 |
| 1830 void BackgroundCompiler::CompileOptimized(const Function& function) { | 1831 void BackgroundCompiler::CompileOptimized(const Function& function) { |
| 1831 ASSERT(Thread::Current()->IsMutatorThread()); | 1832 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1832 MonitorLocker ml(queue_monitor_); | 1833 MonitorLocker ml(queue_monitor_); |
| 1833 if (function_queue()->ContainsObj(function)) { | 1834 if (function_queue()->ContainsObj(function)) { |
| 1834 return; | 1835 return; |
| 1835 } | 1836 } |
| 1836 QueueElement* elem = new QueueElement(function); | 1837 QueueElement* elem = new QueueElement(function); |
| 1837 function_queue()->Add(elem); | 1838 function_queue()->Add(elem); |
| 1838 ml.Notify(); | 1839 ml.Notify(); |
| 1839 } | 1840 } |
| 1840 | 1841 |
| 1841 | 1842 |
| 1842 void BackgroundCompiler::InstallGeneratedCode() { | 1843 void BackgroundCompiler::InstallGeneratedCode() { |
| 1843 ASSERT(Thread::Current()->IsMutatorThread()); | 1844 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1844 MonitorLocker ml(queue_monitor_); | 1845 MonitorLocker ml(queue_monitor_); |
| 1845 Function& function = Function::Handle(); | 1846 Function& function = Function::Handle(); |
| 1846 while (result_queue()->Peek() != NULL) { | 1847 while (result_queue()->Peek() != NULL) { |
| 1847 BackgroundCompilationResult result; | 1848 BackgroundCompilationResult result; |
| 1848 QueueElement* elem = result_queue()->Remove(); | 1849 QueueElement* qelem = result_queue()->Remove(); |
| 1849 ASSERT(elem != NULL); | 1850 ASSERT(qelem != NULL); |
| 1850 result.SetFromQElement(elem); | 1851 result.SetFromQElement(qelem); |
| 1851 delete elem; | 1852 delete qelem; |
| 1852 | 1853 |
| 1853 const Code& code = result.result_code(); | 1854 const Code& code = result.result_code(); |
| 1854 function ^= code.owner(); | 1855 function ^= code.owner(); |
| 1856 Field& field = Field::Handle(); |
| 1857 // Always execute necessary deoptimizations, even if the result is invalid. |
| 1858 for (intptr_t i = 0; i < result.deoptimize_dependent_fields().Length(); |
| 1859 i++) { |
| 1860 field ^= result.deoptimize_dependent_fields().At(i); |
| 1861 field.DeoptimizeDependentCode(); |
| 1862 } |
| 1855 if (result.IsValid()) { | 1863 if (result.IsValid()) { |
| 1856 function.InstallOptimizedCode(result.result_code(), false /* not OSR */); | 1864 function.InstallOptimizedCode(result.result_code(), false /* not OSR */); |
| 1857 // Install leaf classes and fields dependencies. | 1865 // Install leaf classes and fields dependencies. |
| 1858 Class& cls = Class::Handle(); | 1866 Class& cls = Class::Handle(); |
| 1859 for (intptr_t i = 0; i < result.leaf_classes().Length(); i++) { | 1867 for (intptr_t i = 0; i < result.leaf_classes().Length(); i++) { |
| 1860 cls ^= result.leaf_classes().At(i); | 1868 cls ^= result.leaf_classes().At(i); |
| 1861 cls.RegisterCHACode(code); | 1869 cls.RegisterCHACode(code); |
| 1862 } | 1870 } |
| 1863 Field& field = Field::Handle(); | |
| 1864 for (intptr_t i = 0; i < result.guarded_fields().Length(); i++) { | 1871 for (intptr_t i = 0; i < result.guarded_fields().Length(); i++) { |
| 1865 field ^= result.guarded_fields().At(i); | 1872 field ^= result.guarded_fields().At(i); |
| 1866 field.RegisterDependentCode(code); | 1873 field.RegisterDependentCode(code); |
| 1867 } | 1874 } |
| 1868 for (intptr_t i = 0; i < result.deoptimize_dependent_fields().Length(); | |
| 1869 i++) { | |
| 1870 field ^= result.deoptimize_dependent_fields().At(i); | |
| 1871 field.DeoptimizeDependentCode(); | |
| 1872 } | |
| 1873 } else if (FLAG_trace_compiler) { | 1875 } else if (FLAG_trace_compiler) { |
| 1874 THR_Print("Drop code generated in the background compiler:\n"); | 1876 THR_Print("Drop code generated in the background compiler:\n"); |
| 1875 result.PrintValidity(); | 1877 result.PrintValidity(); |
| 1876 } | 1878 } |
| 1877 if (function.usage_counter() < 0) { | 1879 if (function.usage_counter() < 0) { |
| 1878 // Reset to 0 so that it can be recompiled if needed. | 1880 // Reset to 0 so that it can be recompiled if needed. |
| 1879 function.set_usage_counter(0); | 1881 function.set_usage_counter(0); |
| 1880 } | 1882 } |
| 1881 } | 1883 } |
| 1882 } | 1884 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1945 isolate->set_background_compiler(task); | 1947 isolate->set_background_compiler(task); |
| 1946 start_task = true; | 1948 start_task = true; |
| 1947 } | 1949 } |
| 1948 } | 1950 } |
| 1949 if (start_task) { | 1951 if (start_task) { |
| 1950 Dart::thread_pool()->Run(isolate->background_compiler()); | 1952 Dart::thread_pool()->Run(isolate->background_compiler()); |
| 1951 } | 1953 } |
| 1952 } | 1954 } |
| 1953 | 1955 |
| 1954 } // namespace dart | 1956 } // namespace dart |
| OLD | NEW |