| 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 |