| 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 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 // installing code. | 1028 // installing code. |
| 1029 // Mutator thread may not run code while we are creating the | 1029 // Mutator thread may not run code while we are creating the |
| 1030 // instruction object, since the creation of instruction object | 1030 // instruction object, since the creation of instruction object |
| 1031 // changes code page access permissions (makes them temporary not | 1031 // changes code page access permissions (makes them temporary not |
| 1032 // executable). | 1032 // executable). |
| 1033 { | 1033 { |
| 1034 SafepointOperationScope safepoint_scope(thread()); | 1034 SafepointOperationScope safepoint_scope(thread()); |
| 1035 // Do not Garbage collect during this stage and instead allow the | 1035 // Do not Garbage collect during this stage and instead allow the |
| 1036 // heap to grow. | 1036 // heap to grow. |
| 1037 NoHeapGrowthControlScope no_growth_control; | 1037 NoHeapGrowthControlScope no_growth_control; |
| 1038 if (!isolate()->background_compiler()->is_running()) { |
| 1039 // The background compiler is being stopped. |
| 1040 Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId); |
| 1041 } |
| 1038 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); | 1042 FinalizeCompilation(&assembler, &graph_compiler, flow_graph); |
| 1039 } | 1043 } |
| 1040 if (isolate()->heap()->NeedsGarbageCollection()) { | 1044 if (isolate()->heap()->NeedsGarbageCollection()) { |
| 1041 isolate()->heap()->CollectAllGarbage(); | 1045 isolate()->heap()->CollectAllGarbage(); |
| 1042 } | 1046 } |
| 1043 } | 1047 } |
| 1044 } | 1048 } |
| 1045 // Mark that this isolate now has compiled code. | 1049 // Mark that this isolate now has compiled code. |
| 1046 isolate()->set_has_compiled_code(true); | 1050 isolate()->set_has_compiled_code(true); |
| 1047 // Exit the loop and the function with the correct result value. | 1051 // Exit the loop and the function with the correct result value. |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1587 DISALLOW_COPY_AND_ASSIGN(QueueElement); | 1591 DISALLOW_COPY_AND_ASSIGN(QueueElement); |
| 1588 }; | 1592 }; |
| 1589 | 1593 |
| 1590 | 1594 |
| 1591 // Allocated in C-heap. Handles both input and output of background compilation. | 1595 // Allocated in C-heap. Handles both input and output of background compilation. |
| 1592 // It implements a FIFO queue, using Peek, Add, Remove operations. | 1596 // It implements a FIFO queue, using Peek, Add, Remove operations. |
| 1593 class BackgroundCompilationQueue { | 1597 class BackgroundCompilationQueue { |
| 1594 public: | 1598 public: |
| 1595 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} | 1599 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} |
| 1596 virtual ~BackgroundCompilationQueue() { | 1600 virtual ~BackgroundCompilationQueue() { |
| 1597 while (!IsEmpty()) { | 1601 Clear(); |
| 1598 QueueElement* e = Remove(); | |
| 1599 delete e; | |
| 1600 } | |
| 1601 ASSERT((first_ == NULL) && (last_ == NULL)); | |
| 1602 } | 1602 } |
| 1603 | 1603 |
| 1604 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 1604 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 1605 ASSERT(visitor != NULL); | 1605 ASSERT(visitor != NULL); |
| 1606 QueueElement* p = first_; | 1606 QueueElement* p = first_; |
| 1607 while (p != NULL) { | 1607 while (p != NULL) { |
| 1608 visitor->VisitPointer(p->function_ptr()); | 1608 visitor->VisitPointer(p->function_ptr()); |
| 1609 p = p->next(); | 1609 p = p->next(); |
| 1610 } | 1610 } |
| 1611 } | 1611 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 QueueElement* p = first_; | 1653 QueueElement* p = first_; |
| 1654 while (p != NULL) { | 1654 while (p != NULL) { |
| 1655 if (p->function() == obj.raw()) { | 1655 if (p->function() == obj.raw()) { |
| 1656 return true; | 1656 return true; |
| 1657 } | 1657 } |
| 1658 p = p->next(); | 1658 p = p->next(); |
| 1659 } | 1659 } |
| 1660 return false; | 1660 return false; |
| 1661 } | 1661 } |
| 1662 | 1662 |
| 1663 void Clear() { |
| 1664 while (!IsEmpty()) { |
| 1665 QueueElement* e = Remove(); |
| 1666 delete e; |
| 1667 } |
| 1668 ASSERT((first_ == NULL) && (last_ == NULL)); |
| 1669 } |
| 1670 |
| 1663 private: | 1671 private: |
| 1664 QueueElement* first_; | 1672 QueueElement* first_; |
| 1665 QueueElement* last_; | 1673 QueueElement* last_; |
| 1666 | 1674 |
| 1667 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue); | 1675 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue); |
| 1668 }; | 1676 }; |
| 1669 | 1677 |
| 1670 | 1678 |
| 1671 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) | 1679 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) |
| 1672 : isolate_(isolate), running_(true), done_(new bool()), | 1680 : isolate_(isolate), running_(true), done_(new bool()), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 Isolate* isolate = thread->isolate(); | 1726 Isolate* isolate = thread->isolate(); |
| 1719 // We cannot aggregate stats if isolate is shutting down. | 1727 // We cannot aggregate stats if isolate is shutting down. |
| 1720 if (isolate->HasMutatorThread()) { | 1728 if (isolate->HasMutatorThread()) { |
| 1721 isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats()); | 1729 isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats()); |
| 1722 } | 1730 } |
| 1723 thread->compiler_stats()->Clear(); | 1731 thread->compiler_stats()->Clear(); |
| 1724 #endif // PRODUCT | 1732 #endif // PRODUCT |
| 1725 | 1733 |
| 1726 QueueElement* qelem = NULL; | 1734 QueueElement* qelem = NULL; |
| 1727 { MonitorLocker ml(queue_monitor_); | 1735 { MonitorLocker ml(queue_monitor_); |
| 1728 qelem = function_queue()->Remove(); | 1736 if (function_queue()->IsEmpty()) { |
| 1729 function = function_queue()->PeekFunction(); | 1737 // We are shutting down, queue was cleared. |
| 1738 function = Function::null(); |
| 1739 } else { |
| 1740 qelem = function_queue()->Remove(); |
| 1741 function = function_queue()->PeekFunction(); |
| 1742 } |
| 1730 } | 1743 } |
| 1731 delete qelem; | 1744 if (qelem != NULL) { |
| 1745 delete qelem; |
| 1746 } |
| 1732 } | 1747 } |
| 1733 } | 1748 } |
| 1734 Thread::ExitIsolateAsHelper(); | 1749 Thread::ExitIsolateAsHelper(); |
| 1735 { | 1750 { |
| 1736 // Wait to be notified when the work queue is not empty. | 1751 // Wait to be notified when the work queue is not empty. |
| 1737 MonitorLocker ml(queue_monitor_); | 1752 MonitorLocker ml(queue_monitor_); |
| 1738 while (function_queue()->IsEmpty() && running_) { | 1753 while (function_queue()->IsEmpty() && running_) { |
| 1739 ml.Wait(); | 1754 ml.Wait(); |
| 1740 } | 1755 } |
| 1741 } | 1756 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1771 void BackgroundCompiler::Stop(BackgroundCompiler* task) { | 1786 void BackgroundCompiler::Stop(BackgroundCompiler* task) { |
| 1772 ASSERT(Isolate::Current()->background_compiler() == task); | 1787 ASSERT(Isolate::Current()->background_compiler() == task); |
| 1773 ASSERT(task != NULL); | 1788 ASSERT(task != NULL); |
| 1774 BackgroundCompilationQueue* function_queue = task->function_queue(); | 1789 BackgroundCompilationQueue* function_queue = task->function_queue(); |
| 1775 | 1790 |
| 1776 Monitor* queue_monitor = task->queue_monitor_; | 1791 Monitor* queue_monitor = task->queue_monitor_; |
| 1777 Monitor* done_monitor = task->done_monitor_; | 1792 Monitor* done_monitor = task->done_monitor_; |
| 1778 bool* task_done = task->done_; | 1793 bool* task_done = task->done_; |
| 1779 // Wake up compiler task and stop it. | 1794 // Wake up compiler task and stop it. |
| 1780 { | 1795 { |
| 1781 MonitorLocker ml(task->queue_monitor_); | 1796 MonitorLocker ml(queue_monitor); |
| 1782 task->running_ = false; | 1797 task->running_ = false; |
| 1798 function_queue->Clear(); |
| 1783 // 'task' will be deleted by thread pool. | 1799 // 'task' will be deleted by thread pool. |
| 1784 task = NULL; | 1800 task = NULL; |
| 1785 ml.Notify(); // Stop waiting for the queue. | 1801 ml.Notify(); // Stop waiting for the queue. |
| 1786 } | 1802 } |
| 1787 | 1803 |
| 1788 { | 1804 { |
| 1789 MonitorLocker ml_done(done_monitor); | 1805 MonitorLocker ml_done(done_monitor); |
| 1790 while (!(*task_done)) { | 1806 while (!(*task_done)) { |
| 1791 ml_done.WaitWithSafepointCheck(Thread::Current()); | 1807 ml_done.WaitWithSafepointCheck(Thread::Current()); |
| 1792 } | 1808 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1941 } | 1957 } |
| 1942 | 1958 |
| 1943 | 1959 |
| 1944 void BackgroundCompiler::EnsureInit(Thread* thread) { | 1960 void BackgroundCompiler::EnsureInit(Thread* thread) { |
| 1945 UNREACHABLE(); | 1961 UNREACHABLE(); |
| 1946 } | 1962 } |
| 1947 | 1963 |
| 1948 #endif // DART_PRECOMPILED_RUNTIME | 1964 #endif // DART_PRECOMPILED_RUNTIME |
| 1949 | 1965 |
| 1950 } // namespace dart | 1966 } // namespace dart |
| OLD | NEW |