Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: runtime/vm/compiler.cc

Issue 1419533011: Redo background compilation queues to allocate queue and its element in the C-heap (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 const Object& result = 1459 const Object& result =
1460 PassiveObject::Handle(isolate->object_store()->sticky_error()); 1460 PassiveObject::Handle(isolate->object_store()->sticky_error());
1461 isolate->object_store()->clear_sticky_error(); 1461 isolate->object_store()->clear_sticky_error();
1462 return result.raw(); 1462 return result.raw();
1463 } 1463 }
1464 UNREACHABLE(); 1464 UNREACHABLE();
1465 return Object::null(); 1465 return Object::null();
1466 } 1466 }
1467 1467
1468 1468
1469 // A simple work queue containing functions to be optimized or code generated. 1469 // C-heap allocated background compilation queue element.
1470 // Use PushFrontFunction and PopBackFunction to add and remove from the function 1470 class QueueElement {
1471 // queue and PushBackCode and PopBackCode to add and remove from the code queue.
1472 // TODO(srdjan): Write a more efficient implementation.
1473 class CompilationWorkQueue : public ValueObject {
1474 public: 1471 public:
1475 explicit CompilationWorkQueue(GrowableObjectArray* data) : data_(data) {} 1472 explicit QueueElement(const Function& function)
1473 : next_(NULL),
1474 obj_(function.raw()),
1475 cha_invalidation_gen_(Isolate::kInvalidGen),
1476 field_invalidation_gen_(Isolate::kInvalidGen),
1477 prefix_invalidation_gen_(Isolate::kInvalidGen) {
1478 ASSERT(Thread::Current()->IsMutatorThread());
1479 }
1476 1480
1477 intptr_t IsEmpty() const { return data_->Length() == 0; } 1481 ~QueueElement() {
1478 intptr_t Length() const { return data_->Length(); } 1482 ASSERT(Thread::Current()->IsMutatorThread());
1483 obj_ = Object::null();
1484 }
1479 1485
1480 void PushFrontFunction(const Function& function) { PushFront(function); } 1486 void Clear() {
1481 RawFunction* PopBackFunction() { return Function::RawCast(PopBack()); } 1487 next_ = NULL;
1482 RawFunction* LastFunction() { return Function::RawCast(Last()); } 1488 obj_ = Object::null();
1489 cha_invalidation_gen_ = Isolate::kInvalidGen;
1490 field_invalidation_gen_ = Isolate::kInvalidGen;
1491 prefix_invalidation_gen_ = Isolate::kInvalidGen;
1492 }
1483 1493
1484 void PushBackCode(const Code& code) { PushBack(code); } 1494 RawFunction* Function() const { return Function::RawCast(obj_); }
1485 void PushBackInteger(const Integer& value) { PushBack(value); } 1495 RawCode* Code() const {
1486 RawCode* PopBackCode() { return Code::RawCast(PopBack()); } 1496 return (obj_ == Object::null()) ? Code::null() : Code::RawCast(obj_);
1487 RawInteger* PopBackInteger() { 1497 }
1488 Object& o = Object::Handle(PopBack()); 1498
1489 if (o.IsNull()) { 1499 uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; }
1490 return Integer::null(); 1500 uint32_t field_invalidation_gen() const { return field_invalidation_gen_; }
1491 } else { 1501 uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; }
1492 return Integer::Cast(o).raw(); 1502
1503 void set_next(QueueElement* elem) { next_ = elem; }
1504 QueueElement* next() const { return next_; }
1505
1506 RawObject** obj_ptr() { return &obj_; }
1507 RawObject* obj() const { return obj_; }
1508
1509 void SetFromResult(const BackgroundCompilationResult& value) {
1510 ASSERT(!value.result_code().IsNull());
1511 obj_ = value.result_code().raw();
1512 cha_invalidation_gen_ = value.cha_invalidation_gen();
1513 field_invalidation_gen_ = value.field_invalidation_gen();
1514 prefix_invalidation_gen_ = value.prefix_invalidation_gen();
1515 }
1516
1517 private:
1518 QueueElement* next_;
1519
1520 RawObject* obj_; // Code or Function.
1521 uint32_t cha_invalidation_gen_;
1522 uint32_t field_invalidation_gen_;
1523 uint32_t prefix_invalidation_gen_;
1524
1525 DISALLOW_COPY_AND_ASSIGN(QueueElement);
1526 };
1527
1528
1529 // Allocated in C-heap. Handles both input and output of background compilation.
1530 // It implements a FIFO queue, using Peek, Add, Remove operations.
1531 class BackgroundCompilationQueue {
1532 public:
1533 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {}
1534 ~BackgroundCompilationQueue() {
1535 while (!IsEmpty()) {
1536 QueueElement* e = Remove();
1537 delete e;
1538 }
1539 ASSERT((first_ == NULL) && (last_ == NULL));
1540 }
1541
1542 void VisitObjectPointers(ObjectPointerVisitor* visitor) {
1543 ASSERT(visitor != NULL);
1544 QueueElement* p = first_;
1545 while (p != NULL) {
1546 visitor->VisitPointer(p->obj_ptr());
1547 p = p->next();
1493 } 1548 }
1494 } 1549 }
1495 1550
1496 private: 1551 bool IsEmpty() const { return first_ == NULL; }
1497 // Adds to the queue only if 'function' is not already in there. 1552
1498 void PushFront(const Object& value) { 1553 void Add(QueueElement* value) {
1499 for (intptr_t i = 0; i < data_->Length(); i++) { 1554 ASSERT(value != NULL);
1500 if (data_->At(i) == value.raw()) { 1555 if (first_ == NULL) {
1501 return; 1556 first_ = value;
1502 } 1557 } else {
1558 last_->set_next(value);
1503 } 1559 }
1504 // Insert new element in front. 1560 value->set_next(NULL);
1505 Object& f = Object::Handle(); 1561 last_ = value;
1506 data_->Add(f, Heap::kOld);
1507 for (intptr_t i = data_->Length() - 1; i > 0; i--) {
1508 f = data_->At(i - 1);
1509 data_->SetAt(i, f);
1510 }
1511 data_->SetAt(0, value);
1512 } 1562 }
1513 1563
1514 1564 QueueElement* Peek() const {
1515 void PushBack(const Object& value) { 1565 return first_;
1516 data_->Add(value, Heap::kOld);
1517 } 1566 }
1518 1567
1519 1568 RawFunction* PeekFunction() const {
1520 RawObject* PopBack() { 1569 QueueElement* e = Peek();
1521 ASSERT(!IsEmpty()); 1570 if (e == NULL) {
1522 Object& result = Object::Handle(); 1571 return Function::null();
1523 result = data_->At(data_->Length() - 1); 1572 } else {
1524 data_->SetLength(data_->Length() - 1); 1573 return e->Function();
1525 return result.raw(); 1574 }
1526 } 1575 }
1527 1576
1528 RawObject* Last() { 1577 QueueElement* Remove() {
1529 ASSERT(!IsEmpty()); 1578 ASSERT(first_ != NULL);
1530 return data_->At(data_->Length() - 1); 1579 QueueElement* result = first_;
1580 first_ = first_->next();
1581 if (first_ == NULL) {
1582 last_ = NULL;
1583 }
1584 return result;
1531 } 1585 }
1532 1586
1533 GrowableObjectArray* data_; 1587 bool ContainsObj(const Object& obj) const {
1588 QueueElement* p = first_;
1589 while (p != NULL) {
1590 if (p->obj() == obj.raw()) {
1591 return true;
1592 }
1593 p = p->next();
1594 }
1595 return false;
1596 }
1534 1597
1535 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); 1598 private:
1599 QueueElement* first_;
1600 QueueElement* last_;
1601
1602 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue);
1536 }; 1603 };
1537 1604
1538 1605
1539
1540 BackgroundCompilationResult::BackgroundCompilationResult() 1606 BackgroundCompilationResult::BackgroundCompilationResult()
1541 : result_code_(Code::Handle()), 1607 : result_code_(Code::Handle()),
1542 cha_invalidation_gen_(Integer::Handle()), 1608 cha_invalidation_gen_(Isolate::kInvalidGen),
1543 field_invalidation_gen_(Integer::Handle()), 1609 field_invalidation_gen_(Isolate::kInvalidGen),
1544 prefix_invalidation_gen_(Integer::Handle()) { 1610 prefix_invalidation_gen_(Isolate::kInvalidGen) {
1545 } 1611 }
1546 1612
1547 1613
1548 void BackgroundCompilationResult::Init() { 1614 void BackgroundCompilationResult::Init() {
1549 Isolate* i = Isolate::Current(); 1615 Isolate* i = Isolate::Current();
1550 result_code_ = Code::null(); 1616 result_code_ = Code::null();
1551 cha_invalidation_gen_ = Integer::New(i->cha_invalidation_gen(), Heap::kOld); 1617 cha_invalidation_gen_ = i->cha_invalidation_gen();
1552 field_invalidation_gen_ = 1618 field_invalidation_gen_ = i->field_invalidation_gen();
1553 Integer::New(i->field_invalidation_gen(), Heap::kOld); 1619 prefix_invalidation_gen_ = i->prefix_invalidation_gen();
1554 prefix_invalidation_gen_ =
1555 Integer::New(i->prefix_invalidation_gen(), Heap::kOld);
1556 } 1620 }
1557 1621
1558 1622
1623 void BackgroundCompilationResult::SetFromQElement(QueueElement* value) {
1624 ASSERT(value != NULL);
1625 result_code_ = value->Code();
1626 cha_invalidation_gen_ = value->cha_invalidation_gen();
1627 field_invalidation_gen_ = value->field_invalidation_gen();
1628 prefix_invalidation_gen_ = value->prefix_invalidation_gen();
1629 }
1630
1631
1559 bool BackgroundCompilationResult::IsValid() const { 1632 bool BackgroundCompilationResult::IsValid() const {
1560 if (result_code().IsNull() || result_code().IsDisabled()) { 1633 if (result_code().IsNull() || result_code().IsDisabled()) {
1561 return false; 1634 return false;
1562 } 1635 }
1563 Isolate* i = Isolate::Current(); 1636 Isolate* i = Isolate::Current();
1564 if (!cha_invalidation_gen_.IsNull() && 1637 if ((cha_invalidation_gen_ != Isolate::kInvalidGen) &&
1565 (cha_invalidation_gen_.AsInt64Value() != i->cha_invalidation_gen())) { 1638 (cha_invalidation_gen_ != i->cha_invalidation_gen())) {
1566 return false; 1639 return false;
1567 } 1640 }
1568 if (!field_invalidation_gen_.IsNull() && 1641 if ((field_invalidation_gen_ != Isolate::kInvalidGen) &&
1569 (field_invalidation_gen_.AsInt64Value() != i->field_invalidation_gen())) { 1642 (field_invalidation_gen_ != i->field_invalidation_gen())) {
1570 return false; 1643 return false;
1571 } 1644 }
1572 if (!prefix_invalidation_gen_.IsNull() && 1645 if ((prefix_invalidation_gen_ != Isolate::kInvalidGen) &&
1573 (prefix_invalidation_gen_.AsInt64Value() != 1646 (prefix_invalidation_gen_ != i->prefix_invalidation_gen())) {
1574 i->prefix_invalidation_gen())) {
1575 return false; 1647 return false;
1576 } 1648 }
1577 return true; 1649 return true;
1578 } 1650 }
1579 1651
1580 1652
1581 void BackgroundCompilationResult::PrintValidity() const { 1653 void BackgroundCompilationResult::PrintValidity() const {
1582 Object& o = Object::Handle(result_code().owner()); 1654 Object& o = Object::Handle(result_code().owner());
1583 THR_Print("BackgroundCompilationResult: %s\n", 1655 THR_Print("BackgroundCompilationResult: %s\n",
1584 Function::Cast(o).ToQualifiedCString()); 1656 Function::Cast(o).ToQualifiedCString());
1585 if (result_code().IsNull()) { 1657 if (result_code().IsNull()) {
1586 THR_Print(" result_code is NULL\n"); 1658 THR_Print(" result_code is NULL\n");
1587 return; 1659 return;
1588 } 1660 }
1589 if (result_code().IsDisabled()) { 1661 if (result_code().IsDisabled()) {
1590 THR_Print(" result_code is disabled\n"); 1662 THR_Print(" result_code is disabled\n");
1591 return; 1663 return;
1592 } 1664 }
1593 Isolate* i = Isolate::Current(); 1665 Isolate* i = Isolate::Current();
1594 THR_Print(" cha_invalidation_gen: %s (current: %u)\n", 1666 THR_Print(" cha_invalidation_gen: %u (current: %u)\n",
1595 cha_invalidation_gen_.ToCString(), i->cha_invalidation_gen()); 1667 cha_invalidation_gen_, i->cha_invalidation_gen());
1596 THR_Print(" field_invalidation_gen: %s (current: %u)\n", 1668 THR_Print(" field_invalidation_gen: %u (current: %u)\n",
1597 field_invalidation_gen_.ToCString(), i->field_invalidation_gen()); 1669 field_invalidation_gen_, i->field_invalidation_gen());
1598 THR_Print(" prefix_invalidation_gen: %s (current: %u)\n", 1670 THR_Print(" prefix_invalidation_gen: %u (current: %u)\n",
1599 prefix_invalidation_gen_.ToCString(), i->prefix_invalidation_gen()); 1671 prefix_invalidation_gen_, i->prefix_invalidation_gen());
1600 }
1601
1602
1603 void BackgroundCompilationResult::PushOnQueue(
1604 CompilationWorkQueue* queue) const {
1605 queue->PushBackCode(result_code());
1606 queue->PushBackInteger(cha_invalidation_gen_);
1607 queue->PushBackInteger(field_invalidation_gen_);
1608 queue->PushBackInteger(prefix_invalidation_gen_);
1609 }
1610
1611
1612 void BackgroundCompilationResult::PopFromQueue(CompilationWorkQueue* queue) {
1613 prefix_invalidation_gen_ = queue->PopBackInteger();
1614 field_invalidation_gen_ = queue->PopBackInteger();
1615 cha_invalidation_gen_ = queue->PopBackInteger();
1616 result_code_ = queue->PopBackCode();
1617 } 1672 }
1618 1673
1619 1674
1620 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) 1675 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
1621 : isolate_(isolate), running_(true), done_(new bool()), 1676 : isolate_(isolate), running_(true), done_(new bool()),
1622 queue_monitor_(new Monitor()), done_monitor_(new Monitor()), 1677 queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
1623 function_queue_length_(0), 1678 function_queue_(new BackgroundCompilationQueue()),
1624 compilation_function_queue_(GrowableObjectArray::null()), 1679 result_queue_(new BackgroundCompilationQueue()) {
1625 compilation_result_queue_(GrowableObjectArray::null()) {
1626 *done_ = false; 1680 *done_ = false;
1627 } 1681 }
1628 1682
1629 1683
1630 void BackgroundCompiler::Run() { 1684 void BackgroundCompiler::Run() {
1631 while (running_) { 1685 while (running_) {
1632 // Maybe something is already in the queue, check first before waiting 1686 // Maybe something is already in the queue, check first before waiting
1633 // to be notified. 1687 // to be notified.
1634 Thread::EnterIsolateAsHelper(isolate_); 1688 Thread::EnterIsolateAsHelper(isolate_);
1635 { 1689 {
1636 Thread* thread = Thread::Current(); 1690 Thread* thread = Thread::Current();
1637 StackZone stack_zone(thread); 1691 StackZone stack_zone(thread);
1638 Zone* zone = stack_zone.GetZone(); 1692 Zone* zone = stack_zone.GetZone();
1639 HANDLESCOPE(thread); 1693 HANDLESCOPE(thread);
1640 Function& function = Function::Handle(zone); 1694 Function& function = Function::Handle(zone);
1641 Function& temp_function = Function::Handle(zone); 1695 function = function_queue()->PeekFunction();
1642 function = LastFunctionOrNull();
1643 BackgroundCompilationResult result; 1696 BackgroundCompilationResult result;
1644 // Finish all compilation before exiting (even if running_ is changed to 1697 while (running_ && !function.IsNull()) {
1645 // false).
1646 while (!function.IsNull()) {
1647 result.Init(); 1698 result.Init();
1648 const Error& error = Error::Handle(zone, 1699 const Error& error = Error::Handle(zone,
1649 Compiler::CompileOptimizedFunction(thread, 1700 Compiler::CompileOptimizedFunction(thread,
1650 function, 1701 function,
1651 Compiler::kNoOSRDeoptId, 1702 Compiler::kNoOSRDeoptId,
1652 &result)); 1703 &result));
1653 // TODO(srdjan): We do not expect errors while compiling optimized 1704 // TODO(srdjan): We do not expect errors while compiling optimized
1654 // code, any errors should have been caught when compiling 1705 // code, any errors should have been caught when compiling
1655 // unoptimized code. 1706 // unoptimized code.
1656 // If it still happens mark function as not optimizable. 1707 // If it still happens mark function as not optimizable.
1657 ASSERT(error.IsNull()); 1708 ASSERT(error.IsNull());
1658 temp_function = RemoveFunctionOrNull(); 1709 // Reuse the input QueueElement to return the result.
1659 ASSERT(temp_function.raw() == function.raw()); 1710 QueueElement* qelem = function_queue()->Remove();
1660 function = LastFunctionOrNull(); 1711 qelem->Clear();
1661 ASSERT(!result.result_code().IsNull()); 1712 result_queue()->Add(qelem);
1662 AddResult(result); 1713 // Add 'qelem' to the queue first so that it gets visited by GC.
1714 qelem->SetFromResult(result);
1715 function = function_queue()->PeekFunction();
1663 } 1716 }
1664 } 1717 }
1665 Thread::ExitIsolateAsHelper(); 1718 Thread::ExitIsolateAsHelper();
1666 { 1719 {
1667 // Wait to be notified when the work queue is not empty. 1720 // Wait to be notified when the work queue is not empty.
1668 MonitorLocker ml(queue_monitor_); 1721 MonitorLocker ml(queue_monitor_);
1669 while ((function_queue_length() == 0) && running_) { 1722 while (function_queue()->IsEmpty() && running_) {
1670 ml.Wait(); 1723 ml.Wait();
1671 } 1724 }
1672 } 1725 }
1673 } // while running 1726 } // while running
1674 1727
1675 compilation_function_queue_ = GrowableObjectArray::null();
1676 compilation_result_queue_ = GrowableObjectArray::null();
1677 { 1728 {
1678 // Notify that the thread is done. 1729 // Notify that the thread is done.
1679 MonitorLocker ml_done(done_monitor_); 1730 MonitorLocker ml_done(done_monitor_);
1680 *done_ = true; 1731 *done_ = true;
1681 ml_done.Notify(); 1732 ml_done.Notify();
1682 } 1733 }
1683 } 1734 }
1684 1735
1685 1736
1686 void BackgroundCompiler::CompileOptimized(const Function& function) { 1737 void BackgroundCompiler::CompileOptimized(const Function& function) {
1687 AddFunction(function); 1738 ASSERT(Thread::Current()->IsMutatorThread());
1739 MonitorLocker ml(queue_monitor_);
1740 if (function_queue()->ContainsObj(function)) {
1741 return;
1742 }
1743 QueueElement* elem = new QueueElement(function);
1744 function_queue()->Add(elem);
1745 ml.Notify();
1688 } 1746 }
1689 1747
1690 1748
1691 void BackgroundCompiler::InstallGeneratedCode() { 1749 void BackgroundCompiler::InstallGeneratedCode() {
1692 ASSERT(Thread::Current()->IsMutatorThread()); 1750 ASSERT(Thread::Current()->IsMutatorThread());
1693 MonitorLocker ml(queue_monitor_); 1751 MonitorLocker ml(queue_monitor_);
1694 CompilationWorkQueue queue(ResultQueue());
1695 Object& owner = Object::Handle(); 1752 Object& owner = Object::Handle();
1696 for (intptr_t i = 0; i < queue.Length(); i++) { 1753 while (result_queue()->Peek() != NULL) {
1697 BackgroundCompilationResult result; 1754 BackgroundCompilationResult result;
1698 result.PopFromQueue(&queue); 1755 QueueElement* elem = result_queue()->Remove();
1756 ASSERT(elem != NULL);
1757 result.SetFromQElement(elem);
1758 delete elem;
1759
1699 owner = result.result_code().owner(); 1760 owner = result.result_code().owner();
1700 const Function& function = Function::Cast(owner); 1761 const Function& function = Function::Cast(owner);
1701 if (result.IsValid()) { 1762 if (result.IsValid()) {
1702 function.InstallOptimizedCode(result.result_code(), false /* not OSR */); 1763 function.InstallOptimizedCode(result.result_code(), false /* not OSR */);
1703 } else if (FLAG_trace_compiler) { 1764 } else if (FLAG_trace_compiler) {
1704 THR_Print("Drop code generated in the background compiler:\n"); 1765 THR_Print("Drop code generated in the background compiler:\n");
1705 result.PrintValidity(); 1766 result.PrintValidity();
1706 } 1767 }
1707 if (function.usage_counter() < 0) { 1768 if (function.usage_counter() < 0) {
1708 // Reset to 0 so that it can be recompiled if needed. 1769 // Reset to 0 so that it can be recompiled if needed.
1709 function.set_usage_counter(0); 1770 function.set_usage_counter(0);
1710 } 1771 }
1711 } 1772 }
1712 } 1773 }
1713 1774
1714 1775
1715 GrowableObjectArray* BackgroundCompiler::FunctionsQueue() const {
1716 return &GrowableObjectArray::ZoneHandle(compilation_function_queue_);
1717 }
1718
1719
1720 GrowableObjectArray* BackgroundCompiler::ResultQueue() const {
1721 return &GrowableObjectArray::ZoneHandle(compilation_result_queue_);
1722 }
1723
1724
1725 void BackgroundCompiler::AddFunction(const Function& f) {
1726 MonitorLocker ml(queue_monitor_);
1727 CompilationWorkQueue queue(FunctionsQueue());
1728 queue.PushFrontFunction(f);
1729 set_function_queue_length(queue.Length());
1730 // Notify waiting background compiler task.
1731 ml.Notify();
1732 }
1733
1734
1735 RawFunction* BackgroundCompiler::RemoveFunctionOrNull() {
1736 MonitorLocker ml(queue_monitor_);
1737 CompilationWorkQueue queue(FunctionsQueue());
1738 if (queue.IsEmpty()) return Function::null();
1739 set_function_queue_length(queue.Length() - 1);
1740 return queue.PopBackFunction();
1741 }
1742
1743
1744 RawFunction* BackgroundCompiler::LastFunctionOrNull() const {
1745 MonitorLocker ml(queue_monitor_);
1746 CompilationWorkQueue queue(FunctionsQueue());
1747 return queue.IsEmpty() ? Function::null() : queue.LastFunction();
1748 }
1749
1750
1751 void BackgroundCompiler::AddResult(const BackgroundCompilationResult& value) {
1752 MonitorLocker ml(queue_monitor_);
1753 CompilationWorkQueue queue(ResultQueue());
1754 value.PushOnQueue(&queue);
1755 }
1756
1757
1758 void BackgroundCompiler::set_compilation_function_queue(
1759 const GrowableObjectArray& value) {
1760 compilation_function_queue_ = value.raw();
1761 }
1762
1763
1764 void BackgroundCompiler::set_compilation_result_queue(
1765 const GrowableObjectArray& value) {
1766 compilation_result_queue_ = value.raw();
1767 }
1768
1769
1770 void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) { 1776 void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
1771 visitor->VisitPointer(reinterpret_cast<RawObject**>( 1777 function_queue_->VisitObjectPointers(visitor);
1772 &compilation_function_queue_)); 1778 result_queue_->VisitObjectPointers(visitor);
1773
1774 visitor->VisitPointer(reinterpret_cast<RawObject**>(
1775 &compilation_result_queue_));
1776 } 1779 }
1777 1780
1778 1781
1779 void BackgroundCompiler::Stop(BackgroundCompiler* task) { 1782 void BackgroundCompiler::Stop(BackgroundCompiler* task) {
1780 ASSERT(Isolate::Current()->background_compiler() == task); 1783 ASSERT(Isolate::Current()->background_compiler() == task);
1781 if (task == NULL) { 1784 if (task == NULL) {
1782 return; 1785 return;
1783 } 1786 }
1787 BackgroundCompilationQueue* function_queue = task->function_queue();
1788 BackgroundCompilationQueue* result_queue = task->result_queue();
1789
1784 Monitor* queue_monitor = task->queue_monitor_; 1790 Monitor* queue_monitor = task->queue_monitor_;
1785 Monitor* done_monitor = task->done_monitor_; 1791 Monitor* done_monitor = task->done_monitor_;
1786 bool* task_done = task->done_; 1792 bool* task_done = task->done_;
1787 // Wake up compiler task and stop it. 1793 // Wake up compiler task and stop it.
1788 { 1794 {
1789 MonitorLocker ml(task->queue_monitor_); 1795 MonitorLocker ml(task->queue_monitor_);
1790 task->running_ = false; 1796 task->running_ = false;
1791 // 'task' will be deleted by thread pool. 1797 // 'task' will be deleted by thread pool.
1792 task = NULL; 1798 task = NULL;
1793 ml.Notify(); // Stop waiting for the queue. 1799 ml.Notify(); // Stop waiting for the queue.
1794 } 1800 }
1795 1801
1796 { 1802 {
1797 MonitorLocker ml_done(done_monitor); 1803 MonitorLocker ml_done(done_monitor);
1798 while (!(*task_done)) { 1804 while (!(*task_done)) {
1799 ml_done.Wait(); 1805 ml_done.Wait();
1800 } 1806 }
1801 } 1807 }
1802 delete task_done; 1808 delete task_done;
1803 delete done_monitor; 1809 delete done_monitor;
1804 delete queue_monitor; 1810 delete queue_monitor;
1811 delete function_queue;
1812 delete result_queue;
1805 Isolate::Current()->set_background_compiler(NULL); 1813 Isolate::Current()->set_background_compiler(NULL);
1806 } 1814 }
1807 1815
1808 1816
1809 void BackgroundCompiler::EnsureInit(Thread* thread) { 1817 void BackgroundCompiler::EnsureInit(Thread* thread) {
1810 bool start_task = false; 1818 bool start_task = false;
1811 Isolate* isolate = thread->isolate(); 1819 Isolate* isolate = thread->isolate();
1812 { 1820 {
1813 MutexLocker ml(isolate->mutex()); 1821 MutexLocker ml(isolate->mutex());
1814 if (isolate->background_compiler() == NULL) { 1822 if (isolate->background_compiler() == NULL) {
1815 BackgroundCompiler* task = new BackgroundCompiler(isolate); 1823 BackgroundCompiler* task = new BackgroundCompiler(isolate);
1816 isolate->set_background_compiler(task); 1824 isolate->set_background_compiler(task);
1817 // TODO(srdjan): Temporary fix to prevent growing (and thus GC-ing) of
1818 // queues while inside a MonitorLocker. Will replace GrowableObjectArray
1819 // with C heap allocated linked list.
1820 GrowableObjectArray& a = GrowableObjectArray::Handle(
1821 thread->zone(), GrowableObjectArray::New(Heap::kOld));
1822 a.Grow(1000, Heap::kOld);
1823 task->set_compilation_function_queue(a);
1824
1825 a = GrowableObjectArray::New(Heap::kOld);
1826 a.Grow(1000, Heap::kOld);
1827 task->set_compilation_result_queue(a);
1828 start_task = true; 1825 start_task = true;
1829 } 1826 }
1830 } 1827 }
1831 if (start_task) { 1828 if (start_task) {
1832 Dart::thread_pool()->Run(isolate->background_compiler()); 1829 Dart::thread_pool()->Run(isolate->background_compiler());
1833 } 1830 }
1834 } 1831 }
1835 1832
1836 } // namespace dart 1833 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698