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 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 | 1557 |
1558 // C-heap allocated background compilation queue element. | 1558 // C-heap allocated background compilation queue element. |
1559 class QueueElement { | 1559 class QueueElement { |
1560 public: | 1560 public: |
1561 explicit QueueElement(const Function& function) | 1561 explicit QueueElement(const Function& function) |
1562 : next_(NULL), | 1562 : next_(NULL), |
1563 function_(function.raw()) { | 1563 function_(function.raw()) { |
1564 ASSERT(Thread::Current()->IsMutatorThread()); | 1564 ASSERT(Thread::Current()->IsMutatorThread()); |
1565 } | 1565 } |
1566 | 1566 |
1567 ~QueueElement() { | 1567 virtual ~QueueElement() { |
| 1568 next_ = NULL; |
1568 function_ = Function::null(); | 1569 function_ = Function::null(); |
1569 } | 1570 } |
1570 | 1571 |
1571 RawFunction* Function() const { return function_; } | 1572 RawFunction* Function() const { return function_; } |
1572 | 1573 |
1573 | 1574 |
1574 void set_next(QueueElement* elem) { next_ = elem; } | 1575 void set_next(QueueElement* elem) { next_ = elem; } |
1575 QueueElement* next() const { return next_; } | 1576 QueueElement* next() const { return next_; } |
1576 | 1577 |
1577 RawObject* function() const { return function_; } | 1578 RawObject* function() const { return function_; } |
1578 RawObject** function_ptr() { | 1579 RawObject** function_ptr() { |
1579 return reinterpret_cast<RawObject**>(&function_); | 1580 return reinterpret_cast<RawObject**>(&function_); |
1580 } | 1581 } |
1581 | 1582 |
1582 private: | 1583 private: |
1583 QueueElement* next_; | 1584 QueueElement* next_; |
1584 RawFunction* function_; | 1585 RawFunction* function_; |
1585 | 1586 |
1586 DISALLOW_COPY_AND_ASSIGN(QueueElement); | 1587 DISALLOW_COPY_AND_ASSIGN(QueueElement); |
1587 }; | 1588 }; |
1588 | 1589 |
1589 | 1590 |
1590 // Allocated in C-heap. Handles both input and output of background compilation. | 1591 // Allocated in C-heap. Handles both input and output of background compilation. |
1591 // It implements a FIFO queue, using Peek, Add, Remove operations. | 1592 // It implements a FIFO queue, using Peek, Add, Remove operations. |
1592 class BackgroundCompilationQueue { | 1593 class BackgroundCompilationQueue { |
1593 public: | 1594 public: |
1594 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} | 1595 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} |
1595 ~BackgroundCompilationQueue() { | 1596 virtual ~BackgroundCompilationQueue() { |
1596 while (!IsEmpty()) { | 1597 while (!IsEmpty()) { |
1597 QueueElement* e = Remove(); | 1598 QueueElement* e = Remove(); |
1598 delete e; | 1599 delete e; |
1599 } | 1600 } |
1600 ASSERT((first_ == NULL) && (last_ == NULL)); | 1601 ASSERT((first_ == NULL) && (last_ == NULL)); |
1601 } | 1602 } |
1602 | 1603 |
1603 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 1604 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
1604 ASSERT(visitor != NULL); | 1605 ASSERT(visitor != NULL); |
1605 QueueElement* p = first_; | 1606 QueueElement* p = first_; |
1606 while (p != NULL) { | 1607 while (p != NULL) { |
1607 visitor->VisitPointer(p->function_ptr()); | 1608 visitor->VisitPointer(p->function_ptr()); |
1608 p = p->next(); | 1609 p = p->next(); |
1609 } | 1610 } |
1610 } | 1611 } |
1611 | 1612 |
1612 bool IsEmpty() const { return first_ == NULL; } | 1613 bool IsEmpty() const { return first_ == NULL; } |
1613 | 1614 |
1614 void Add(QueueElement* value) { | 1615 void Add(QueueElement* value) { |
1615 ASSERT(value != NULL); | 1616 ASSERT(value != NULL); |
| 1617 ASSERT(value->next() == NULL); |
1616 if (first_ == NULL) { | 1618 if (first_ == NULL) { |
1617 first_ = value; | 1619 first_ = value; |
| 1620 ASSERT(last_ == NULL); |
1618 } else { | 1621 } else { |
1619 ASSERT(last_ != NULL); | 1622 ASSERT(last_ != NULL); |
1620 last_->set_next(value); | 1623 last_->set_next(value); |
1621 } | 1624 } |
1622 value->set_next(NULL); | |
1623 last_ = value; | 1625 last_ = value; |
| 1626 ASSERT(first_ != NULL && last_ != NULL); |
1624 } | 1627 } |
1625 | 1628 |
1626 QueueElement* Peek() const { | 1629 QueueElement* Peek() const { |
1627 return first_; | 1630 return first_; |
1628 } | 1631 } |
1629 | 1632 |
1630 RawFunction* PeekFunction() const { | 1633 RawFunction* PeekFunction() const { |
1631 QueueElement* e = Peek(); | 1634 QueueElement* e = Peek(); |
1632 if (e == NULL) { | 1635 if (e == NULL) { |
1633 return Function::null(); | 1636 return Function::null(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 | 1669 |
1667 | 1670 |
1668 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) | 1671 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) |
1669 : isolate_(isolate), running_(true), done_(new bool()), | 1672 : isolate_(isolate), running_(true), done_(new bool()), |
1670 queue_monitor_(new Monitor()), done_monitor_(new Monitor()), | 1673 queue_monitor_(new Monitor()), done_monitor_(new Monitor()), |
1671 function_queue_(new BackgroundCompilationQueue()) { | 1674 function_queue_(new BackgroundCompilationQueue()) { |
1672 *done_ = false; | 1675 *done_ = false; |
1673 } | 1676 } |
1674 | 1677 |
1675 | 1678 |
| 1679 // Fields all deleted in ::Stop; here clear them. |
| 1680 BackgroundCompiler::~BackgroundCompiler() { |
| 1681 isolate_ = NULL; |
| 1682 running_ = false; |
| 1683 done_ = NULL; |
| 1684 queue_monitor_ = NULL; |
| 1685 done_monitor_ = NULL; |
| 1686 function_queue_ = NULL; |
| 1687 } |
| 1688 |
| 1689 |
1676 void BackgroundCompiler::Run() { | 1690 void BackgroundCompiler::Run() { |
1677 while (running_) { | 1691 while (running_) { |
1678 // Maybe something is already in the queue, check first before waiting | 1692 // Maybe something is already in the queue, check first before waiting |
1679 // to be notified. | 1693 // to be notified. |
1680 bool result = Thread::EnterIsolateAsHelper(isolate_, Thread::kCompilerTask); | 1694 bool result = Thread::EnterIsolateAsHelper(isolate_, Thread::kCompilerTask); |
1681 ASSERT(result); | 1695 ASSERT(result); |
1682 { | 1696 { |
1683 Thread* thread = Thread::Current(); | 1697 Thread* thread = Thread::Current(); |
1684 StackZone stack_zone(thread); | 1698 StackZone stack_zone(thread); |
1685 Zone* zone = stack_zone.GetZone(); | 1699 Zone* zone = stack_zone.GetZone(); |
1686 HANDLESCOPE(thread); | 1700 HANDLESCOPE(thread); |
1687 Function& function = Function::Handle(zone); | 1701 Function& function = Function::Handle(zone); |
1688 function = function_queue()->PeekFunction(); | 1702 { MonitorLocker ml(queue_monitor_); |
| 1703 function = function_queue()->PeekFunction(); |
| 1704 } |
1689 while (running_ && !function.IsNull()) { | 1705 while (running_ && !function.IsNull()) { |
1690 // Check that we have aggregated and cleared the stats. | 1706 // Check that we have aggregated and cleared the stats. |
1691 ASSERT(thread->compiler_stats()->IsCleared()); | 1707 ASSERT(thread->compiler_stats()->IsCleared()); |
1692 const Error& error = Error::Handle(zone, | 1708 const Error& error = Error::Handle(zone, |
1693 Compiler::CompileOptimizedFunction(thread, | 1709 Compiler::CompileOptimizedFunction(thread, |
1694 function, | 1710 function, |
1695 Compiler::kNoOSRDeoptId)); | 1711 Compiler::kNoOSRDeoptId)); |
1696 // TODO(srdjan): We do not expect errors while compiling optimized | 1712 // TODO(srdjan): We do not expect errors while compiling optimized |
1697 // code, any errors should have been caught when compiling | 1713 // code, any errors should have been caught when compiling |
1698 // unoptimized code. Any issues while optimizing are flagged by | 1714 // unoptimized code. Any issues while optimizing are flagged by |
1699 // making the result invalid. | 1715 // making the result invalid. |
1700 ASSERT(error.IsNull()); | 1716 ASSERT(error.IsNull()); |
1701 #ifndef PRODUCT | 1717 #ifndef PRODUCT |
1702 Isolate* isolate = thread->isolate(); | 1718 Isolate* isolate = thread->isolate(); |
1703 // We cannot aggregate stats if isolate is shutting down. | 1719 // We cannot aggregate stats if isolate is shutting down. |
1704 if (isolate->HasMutatorThread()) { | 1720 if (isolate->HasMutatorThread()) { |
1705 isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats()); | 1721 isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats()); |
1706 } | 1722 } |
1707 thread->compiler_stats()->Clear(); | 1723 thread->compiler_stats()->Clear(); |
1708 #endif // PRODUCT | 1724 #endif // PRODUCT |
1709 QueueElement* qelem = function_queue()->Remove(); | 1725 |
| 1726 QueueElement* qelem = NULL; |
| 1727 { MonitorLocker ml(queue_monitor_); |
| 1728 qelem = function_queue()->Remove(); |
| 1729 function = function_queue()->PeekFunction(); |
| 1730 } |
1710 delete qelem; | 1731 delete qelem; |
1711 function = function_queue()->PeekFunction(); | |
1712 } | 1732 } |
1713 } | 1733 } |
1714 Thread::ExitIsolateAsHelper(); | 1734 Thread::ExitIsolateAsHelper(); |
1715 { | 1735 { |
1716 // Wait to be notified when the work queue is not empty. | 1736 // Wait to be notified when the work queue is not empty. |
1717 MonitorLocker ml(queue_monitor_); | 1737 MonitorLocker ml(queue_monitor_); |
1718 while (function_queue()->IsEmpty() && running_) { | 1738 while (function_queue()->IsEmpty() && running_) { |
1719 ml.Wait(); | 1739 ml.Wait(); |
1720 } | 1740 } |
1721 } | 1741 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 } | 1941 } |
1922 | 1942 |
1923 | 1943 |
1924 void BackgroundCompiler::EnsureInit(Thread* thread) { | 1944 void BackgroundCompiler::EnsureInit(Thread* thread) { |
1925 UNREACHABLE(); | 1945 UNREACHABLE(); |
1926 } | 1946 } |
1927 | 1947 |
1928 #endif // DART_PRECOMPILED_RUNTIME | 1948 #endif // DART_PRECOMPILED_RUNTIME |
1929 | 1949 |
1930 } // namespace dart | 1950 } // namespace dart |
OLD | NEW |