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 |