| 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 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 graph_compiler.FinalizePcDescriptors(code); | 770 graph_compiler.FinalizePcDescriptors(code); |
| 771 code.set_deopt_info_array(deopt_info_array); | 771 code.set_deopt_info_array(deopt_info_array); |
| 772 | 772 |
| 773 graph_compiler.FinalizeStackmaps(code); | 773 graph_compiler.FinalizeStackmaps(code); |
| 774 graph_compiler.FinalizeVarDescriptors(code); | 774 graph_compiler.FinalizeVarDescriptors(code); |
| 775 graph_compiler.FinalizeExceptionHandlers(code); | 775 graph_compiler.FinalizeExceptionHandlers(code); |
| 776 graph_compiler.FinalizeStaticCallTargetsTable(code); | 776 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 777 | 777 |
| 778 if (optimized) { | 778 if (optimized) { |
| 779 if (result != NULL) { | 779 if (result != NULL) { |
| 780 // Background compilation, store compilation result in 'result'. |
| 780 ASSERT(!Thread::Current()->IsMutatorThread()); | 781 ASSERT(!Thread::Current()->IsMutatorThread()); |
| 781 // Do not install code, but return it instead. | 782 // Do not install code, but return it instead. |
| 782 // Since code dependencies (CHA, fields) are defined eagerly, | 783 // Since code dependencies (CHA, fields) are defined eagerly, |
| 783 // the code may be disabled before installing it. | 784 // the code may be disabled before installing it. |
| 784 code.set_owner(function); | 785 code.set_owner(function); |
| 785 result->set_result_code(code); | 786 result->set_result_code(code); |
| 786 // Disable invalidation counters that are not relevant. | 787 // Disable invalidation counters that are not relevant. |
| 787 if (thread->cha()->leaf_classes().is_empty()) { | 788 if (thread->cha()->leaf_classes().is_empty()) { |
| 788 result->ClearCHAInvalidationGen(); | 789 result->ClearCHAInvalidationGen(); |
| 789 } | 790 } |
| 790 if (flow_graph->guarded_fields()->is_empty()) { | 791 if (flow_graph->guarded_fields()->is_empty()) { |
| 791 result->ClearFieldInvalidationGen(); | 792 result->ClearFieldInvalidationGen(); |
| 792 } | 793 } |
| 793 if (!parsed_function->HasDeferredPrefixes()) { | 794 if (!parsed_function->HasDeferredPrefixes()) { |
| 794 result->ClearPrefixInvalidationGen(); | 795 result->ClearPrefixInvalidationGen(); |
| 795 } | 796 } |
| 796 } else { | 797 } else { |
| 797 const bool is_osr = osr_id != Compiler::kNoOSRDeoptId; | 798 const bool is_osr = osr_id != Compiler::kNoOSRDeoptId; |
| 798 function.InstallOptimizedCode(code, is_osr); | 799 function.InstallOptimizedCode(code, is_osr); |
| 799 } | 800 } |
| 800 | 801 |
| 801 // TODO(srdjan): In background compilation, verify that CHA and field | |
| 802 // guards have not been invalidated in the meantime. | |
| 803 // Register code with the classes it depends on because of CHA and | 802 // Register code with the classes it depends on because of CHA and |
| 804 // fields it depends on because of store guards, unless we cannot | 803 // fields it depends on because of store guards, unless we cannot |
| 805 // deopt. | 804 // deopt. |
| 806 if (Compiler::allow_recompilation()) { | 805 if (Compiler::allow_recompilation()) { |
| 807 for (intptr_t i = 0; | 806 if (result != NULL) { |
| 808 i < thread->cha()->leaf_classes().length(); | 807 // Background compilation: delay registering code until we are |
| 809 ++i) { | 808 // in the MutatorThread. |
| 810 thread->cha()->leaf_classes()[i]->RegisterCHACode(code); | 809 result->SetLeafClasses(thread->cha()->leaf_classes()); |
| 811 } | 810 result->SetGuardedFields(*flow_graph->guarded_fields()); |
| 812 for (intptr_t i = 0; | 811 result->SetDeoptimizeDependentFields( |
| 813 i < flow_graph->guarded_fields()->length(); | 812 flow_graph->deoptimize_dependent_code()); |
| 814 i++) { | 813 } else { |
| 815 const Field* field = (*flow_graph->guarded_fields())[i]; | 814 for (intptr_t i = 0; |
| 816 field->RegisterDependentCode(code); | 815 i < thread->cha()->leaf_classes().length(); |
| 816 ++i) { |
| 817 thread->cha()->leaf_classes()[i]->RegisterCHACode(code); |
| 818 } |
| 819 for (intptr_t i = 0; |
| 820 i < flow_graph->guarded_fields()->length(); |
| 821 i++) { |
| 822 const Field* field = (*flow_graph->guarded_fields())[i]; |
| 823 field->RegisterDependentCode(code); |
| 824 } |
| 825 for (intptr_t i = 0; |
| 826 i < flow_graph->deoptimize_dependent_code().length(); |
| 827 i++) { |
| 828 const Field* field = flow_graph->deoptimize_dependent_code()[i]; |
| 829 field->DeoptimizeDependentCode(); |
| 830 } |
| 817 } | 831 } |
| 818 } | 832 } |
| 819 } else { // not optimized. | 833 } else { // not optimized. |
| 820 if (!Compiler::always_optimize() && | 834 if (!Compiler::always_optimize() && |
| 821 (function.ic_data_array() == Array::null())) { | 835 (function.ic_data_array() == Array::null())) { |
| 822 function.SaveICDataMap( | 836 function.SaveICDataMap( |
| 823 graph_compiler.deopt_id_to_ic_data(), | 837 graph_compiler.deopt_id_to_ic_data(), |
| 824 Array::Handle(zone, graph_compiler.edge_counters_array())); | 838 Array::Handle(zone, graph_compiler.edge_counters_array())); |
| 825 } | 839 } |
| 826 function.set_unoptimized_code(code); | 840 function.set_unoptimized_code(code); |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1474 return Object::null(); | 1488 return Object::null(); |
| 1475 } | 1489 } |
| 1476 | 1490 |
| 1477 | 1491 |
| 1478 // C-heap allocated background compilation queue element. | 1492 // C-heap allocated background compilation queue element. |
| 1479 class QueueElement { | 1493 class QueueElement { |
| 1480 public: | 1494 public: |
| 1481 explicit QueueElement(const Function& function) | 1495 explicit QueueElement(const Function& function) |
| 1482 : next_(NULL), | 1496 : next_(NULL), |
| 1483 obj_(function.raw()), | 1497 obj_(function.raw()), |
| 1498 leaf_classes_(Array::null()), |
| 1499 guarded_fields_(Array::null()), |
| 1500 deoptimize_dependent_fields_(Array::null()), |
| 1484 cha_invalidation_gen_(Isolate::kInvalidGen), | 1501 cha_invalidation_gen_(Isolate::kInvalidGen), |
| 1485 field_invalidation_gen_(Isolate::kInvalidGen), | 1502 field_invalidation_gen_(Isolate::kInvalidGen), |
| 1486 prefix_invalidation_gen_(Isolate::kInvalidGen) { | 1503 prefix_invalidation_gen_(Isolate::kInvalidGen) { |
| 1487 ASSERT(Thread::Current()->IsMutatorThread()); | 1504 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1488 } | 1505 } |
| 1489 | 1506 |
| 1490 ~QueueElement() { | 1507 ~QueueElement() { |
| 1491 ASSERT(Thread::Current()->IsMutatorThread()); | 1508 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1492 obj_ = Object::null(); | 1509 obj_ = Object::null(); |
| 1493 } | 1510 } |
| 1494 | 1511 |
| 1495 RawFunction* Function() const { return Function::RawCast(obj_); } | 1512 RawFunction* Function() const { return Function::RawCast(obj_); } |
| 1496 RawCode* Code() const { return Code::RawCast(obj_); } | 1513 RawCode* Code() const { return Code::RawCast(obj_); } |
| 1497 | 1514 |
| 1515 RawArray* leaf_classes() const { return leaf_classes_; } |
| 1516 RawArray* guarded_fields() const { return guarded_fields_; } |
| 1517 RawArray* deoptimize_dependent_fields() const { |
| 1518 return deoptimize_dependent_fields_; |
| 1519 } |
| 1520 |
| 1498 uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; } | 1521 uint32_t cha_invalidation_gen() const { return cha_invalidation_gen_; } |
| 1499 uint32_t field_invalidation_gen() const { return field_invalidation_gen_; } | 1522 uint32_t field_invalidation_gen() const { return field_invalidation_gen_; } |
| 1500 uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; } | 1523 uint32_t prefix_invalidation_gen() const { return prefix_invalidation_gen_; } |
| 1501 | 1524 |
| 1502 void set_next(QueueElement* elem) { next_ = elem; } | 1525 void set_next(QueueElement* elem) { next_ = elem; } |
| 1503 QueueElement* next() const { return next_; } | 1526 QueueElement* next() const { return next_; } |
| 1504 | 1527 |
| 1528 RawObject* obj() const { return obj_; } |
| 1505 RawObject** obj_ptr() { return &obj_; } | 1529 RawObject** obj_ptr() { return &obj_; } |
| 1506 RawObject* obj() const { return obj_; } | 1530 |
| 1531 RawObject** leaf_classses_ptr() { |
| 1532 return reinterpret_cast<RawObject**>(&leaf_classes_); |
| 1533 } |
| 1534 |
| 1535 RawObject** guarded_fields_ptr() { |
| 1536 return reinterpret_cast<RawObject**>(&guarded_fields_); |
| 1537 } |
| 1538 |
| 1539 RawObject** deoptimize_dependent_fields_ptr() { |
| 1540 return reinterpret_cast<RawObject**>(&deoptimize_dependent_fields_); |
| 1541 } |
| 1507 | 1542 |
| 1508 void SetFromResult(const BackgroundCompilationResult& value) { | 1543 void SetFromResult(const BackgroundCompilationResult& value) { |
| 1509 ASSERT(!value.result_code().IsNull()); | 1544 ASSERT(!value.result_code().IsNull()); |
| 1510 obj_ = value.result_code().raw(); | 1545 obj_ = value.result_code().raw(); |
| 1546 leaf_classes_ = value.leaf_classes().raw(); |
| 1547 guarded_fields_ = value.guarded_fields().raw(); |
| 1548 deoptimize_dependent_fields_ = value.deoptimize_dependent_fields().raw(); |
| 1511 cha_invalidation_gen_ = value.cha_invalidation_gen(); | 1549 cha_invalidation_gen_ = value.cha_invalidation_gen(); |
| 1512 field_invalidation_gen_ = value.field_invalidation_gen(); | 1550 field_invalidation_gen_ = value.field_invalidation_gen(); |
| 1513 prefix_invalidation_gen_ = value.prefix_invalidation_gen(); | 1551 prefix_invalidation_gen_ = value.prefix_invalidation_gen(); |
| 1514 } | 1552 } |
| 1515 | 1553 |
| 1516 private: | 1554 private: |
| 1517 QueueElement* next_; | 1555 QueueElement* next_; |
| 1518 | 1556 |
| 1519 RawObject* obj_; // Code or Function. | 1557 RawObject* obj_; // Code or Function. |
| 1558 RawArray* leaf_classes_; |
| 1559 RawArray* guarded_fields_; |
| 1560 RawArray* deoptimize_dependent_fields_; |
| 1520 uint32_t cha_invalidation_gen_; | 1561 uint32_t cha_invalidation_gen_; |
| 1521 uint32_t field_invalidation_gen_; | 1562 uint32_t field_invalidation_gen_; |
| 1522 uint32_t prefix_invalidation_gen_; | 1563 uint32_t prefix_invalidation_gen_; |
| 1523 | 1564 |
| 1524 DISALLOW_COPY_AND_ASSIGN(QueueElement); | 1565 DISALLOW_COPY_AND_ASSIGN(QueueElement); |
| 1525 }; | 1566 }; |
| 1526 | 1567 |
| 1527 | 1568 |
| 1528 // Allocated in C-heap. Handles both input and output of background compilation. | 1569 // Allocated in C-heap. Handles both input and output of background compilation. |
| 1529 // It implements a FIFO queue, using Peek, Add, Remove operations. | 1570 // It implements a FIFO queue, using Peek, Add, Remove operations. |
| 1530 class BackgroundCompilationQueue { | 1571 class BackgroundCompilationQueue { |
| 1531 public: | 1572 public: |
| 1532 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} | 1573 BackgroundCompilationQueue() : first_(NULL), last_(NULL) {} |
| 1533 ~BackgroundCompilationQueue() { | 1574 ~BackgroundCompilationQueue() { |
| 1534 while (!IsEmpty()) { | 1575 while (!IsEmpty()) { |
| 1535 QueueElement* e = Remove(); | 1576 QueueElement* e = Remove(); |
| 1536 delete e; | 1577 delete e; |
| 1537 } | 1578 } |
| 1538 ASSERT((first_ == NULL) && (last_ == NULL)); | 1579 ASSERT((first_ == NULL) && (last_ == NULL)); |
| 1539 } | 1580 } |
| 1540 | 1581 |
| 1541 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 1582 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 1542 ASSERT(visitor != NULL); | 1583 ASSERT(visitor != NULL); |
| 1543 QueueElement* p = first_; | 1584 QueueElement* p = first_; |
| 1544 while (p != NULL) { | 1585 while (p != NULL) { |
| 1545 visitor->VisitPointer(p->obj_ptr()); | 1586 visitor->VisitPointer(p->obj_ptr()); |
| 1587 visitor->VisitPointer(p->leaf_classses_ptr()); |
| 1588 visitor->VisitPointer(p->guarded_fields_ptr()); |
| 1589 visitor->VisitPointer(p->deoptimize_dependent_fields_ptr()); |
| 1546 p = p->next(); | 1590 p = p->next(); |
| 1547 } | 1591 } |
| 1548 } | 1592 } |
| 1549 | 1593 |
| 1550 bool IsEmpty() const { return first_ == NULL; } | 1594 bool IsEmpty() const { return first_ == NULL; } |
| 1551 | 1595 |
| 1552 void Add(QueueElement* value) { | 1596 void Add(QueueElement* value) { |
| 1553 ASSERT(value != NULL); | 1597 ASSERT(value != NULL); |
| 1554 if (first_ == NULL) { | 1598 if (first_ == NULL) { |
| 1555 first_ = value; | 1599 first_ = value; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 private: | 1641 private: |
| 1598 QueueElement* first_; | 1642 QueueElement* first_; |
| 1599 QueueElement* last_; | 1643 QueueElement* last_; |
| 1600 | 1644 |
| 1601 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue); | 1645 DISALLOW_COPY_AND_ASSIGN(BackgroundCompilationQueue); |
| 1602 }; | 1646 }; |
| 1603 | 1647 |
| 1604 | 1648 |
| 1605 BackgroundCompilationResult::BackgroundCompilationResult() | 1649 BackgroundCompilationResult::BackgroundCompilationResult() |
| 1606 : result_code_(Code::Handle()), | 1650 : result_code_(Code::Handle()), |
| 1651 leaf_classes_(Array::Handle()), |
| 1652 guarded_fields_(Array::Handle()), |
| 1653 deoptimize_dependent_fields_(Array::Handle()), |
| 1607 cha_invalidation_gen_(Isolate::kInvalidGen), | 1654 cha_invalidation_gen_(Isolate::kInvalidGen), |
| 1608 field_invalidation_gen_(Isolate::kInvalidGen), | 1655 field_invalidation_gen_(Isolate::kInvalidGen), |
| 1609 prefix_invalidation_gen_(Isolate::kInvalidGen) { | 1656 prefix_invalidation_gen_(Isolate::kInvalidGen) { |
| 1610 } | 1657 } |
| 1611 | 1658 |
| 1612 | 1659 |
| 1613 void BackgroundCompilationResult::Init() { | 1660 void BackgroundCompilationResult::Init() { |
| 1614 Isolate* i = Isolate::Current(); | 1661 Isolate* i = Isolate::Current(); |
| 1615 result_code_ = Code::null(); | 1662 result_code_ = Code::null(); |
| 1663 leaf_classes_ = Array::null(); |
| 1664 guarded_fields_ = Array::null(); |
| 1665 deoptimize_dependent_fields_ = Array::null(); |
| 1616 cha_invalidation_gen_ = i->cha_invalidation_gen(); | 1666 cha_invalidation_gen_ = i->cha_invalidation_gen(); |
| 1617 field_invalidation_gen_ = i->field_invalidation_gen(); | 1667 field_invalidation_gen_ = i->field_invalidation_gen(); |
| 1618 prefix_invalidation_gen_ = i->prefix_invalidation_gen(); | 1668 prefix_invalidation_gen_ = i->prefix_invalidation_gen(); |
| 1619 } | 1669 } |
| 1620 | 1670 |
| 1621 | 1671 |
| 1622 void BackgroundCompilationResult::SetFromQElement(QueueElement* value) { | 1672 void BackgroundCompilationResult::SetFromQElement(QueueElement* value) { |
| 1623 ASSERT(value != NULL); | 1673 ASSERT(value != NULL); |
| 1624 result_code_ = value->Code(); | 1674 result_code_ = value->Code(); |
| 1675 leaf_classes_ = value->leaf_classes(); |
| 1676 guarded_fields_ = value->guarded_fields(); |
| 1677 deoptimize_dependent_fields_ = value->deoptimize_dependent_fields(); |
| 1625 cha_invalidation_gen_ = value->cha_invalidation_gen(); | 1678 cha_invalidation_gen_ = value->cha_invalidation_gen(); |
| 1626 field_invalidation_gen_ = value->field_invalidation_gen(); | 1679 field_invalidation_gen_ = value->field_invalidation_gen(); |
| 1627 prefix_invalidation_gen_ = value->prefix_invalidation_gen(); | 1680 prefix_invalidation_gen_ = value->prefix_invalidation_gen(); |
| 1628 } | 1681 } |
| 1629 | 1682 |
| 1630 | 1683 |
| 1684 void BackgroundCompilationResult::SetLeafClasses( |
| 1685 const GrowableArray<Class*>& leaf_classes) { |
| 1686 const Array& a = Array::Handle(Array::New(leaf_classes.length(), Heap::kOld)); |
| 1687 for (intptr_t i = 0; i < leaf_classes.length(); i++) { |
| 1688 a.SetAt(i, *leaf_classes[i]); |
| 1689 } |
| 1690 leaf_classes_ = a.raw(); |
| 1691 } |
| 1692 |
| 1693 |
| 1694 void BackgroundCompilationResult::SetGuardedFields( |
| 1695 const ZoneGrowableArray<const Field*>& guarded_fields) { |
| 1696 const Array& a = |
| 1697 Array::Handle(Array::New(guarded_fields.length(), Heap::kOld)); |
| 1698 for (intptr_t i = 0; i < guarded_fields.length(); i++) { |
| 1699 a.SetAt(i, *guarded_fields[i]); |
| 1700 } |
| 1701 guarded_fields_ = a.raw(); |
| 1702 } |
| 1703 |
| 1704 |
| 1705 void BackgroundCompilationResult::SetDeoptimizeDependentFields( |
| 1706 const GrowableArray<const Field*>& fields) { |
| 1707 const Array& a = Array::Handle(Array::New(fields.length(), Heap::kOld)); |
| 1708 for (intptr_t i = 0; i < fields.length(); i++) { |
| 1709 a.SetAt(i, *fields[i]); |
| 1710 } |
| 1711 deoptimize_dependent_fields_ = a.raw(); |
| 1712 } |
| 1713 |
| 1714 |
| 1631 bool BackgroundCompilationResult::IsValid() const { | 1715 bool BackgroundCompilationResult::IsValid() const { |
| 1632 if (result_code().IsNull() || result_code().IsDisabled()) { | 1716 if (result_code().IsNull() || result_code().IsDisabled()) { |
| 1633 return false; | 1717 return false; |
| 1634 } | 1718 } |
| 1635 Isolate* i = Isolate::Current(); | 1719 Isolate* i = Isolate::Current(); |
| 1636 if ((cha_invalidation_gen_ != Isolate::kInvalidGen) && | 1720 if ((cha_invalidation_gen_ != Isolate::kInvalidGen) && |
| 1637 (cha_invalidation_gen_ != i->cha_invalidation_gen())) { | 1721 (cha_invalidation_gen_ != i->cha_invalidation_gen())) { |
| 1638 return false; | 1722 return false; |
| 1639 } | 1723 } |
| 1640 if ((field_invalidation_gen_ != Isolate::kInvalidGen) && | 1724 if ((field_invalidation_gen_ != Isolate::kInvalidGen) && |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1749 } | 1833 } |
| 1750 QueueElement* elem = new QueueElement(function); | 1834 QueueElement* elem = new QueueElement(function); |
| 1751 function_queue()->Add(elem); | 1835 function_queue()->Add(elem); |
| 1752 ml.Notify(); | 1836 ml.Notify(); |
| 1753 } | 1837 } |
| 1754 | 1838 |
| 1755 | 1839 |
| 1756 void BackgroundCompiler::InstallGeneratedCode() { | 1840 void BackgroundCompiler::InstallGeneratedCode() { |
| 1757 ASSERT(Thread::Current()->IsMutatorThread()); | 1841 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1758 MonitorLocker ml(queue_monitor_); | 1842 MonitorLocker ml(queue_monitor_); |
| 1759 Object& owner = Object::Handle(); | 1843 Function& function = Function::Handle(); |
| 1760 while (result_queue()->Peek() != NULL) { | 1844 while (result_queue()->Peek() != NULL) { |
| 1761 BackgroundCompilationResult result; | 1845 BackgroundCompilationResult result; |
| 1762 QueueElement* elem = result_queue()->Remove(); | 1846 QueueElement* elem = result_queue()->Remove(); |
| 1763 ASSERT(elem != NULL); | 1847 ASSERT(elem != NULL); |
| 1764 result.SetFromQElement(elem); | 1848 result.SetFromQElement(elem); |
| 1765 delete elem; | 1849 delete elem; |
| 1766 | 1850 |
| 1767 owner = result.result_code().owner(); | 1851 const Code& code = result.result_code(); |
| 1768 const Function& function = Function::Cast(owner); | 1852 function ^= code.owner(); |
| 1769 if (result.IsValid()) { | 1853 if (result.IsValid()) { |
| 1770 function.InstallOptimizedCode(result.result_code(), false /* not OSR */); | 1854 function.InstallOptimizedCode(result.result_code(), false /* not OSR */); |
| 1855 // Install leaf classes and fields dependencies. |
| 1856 Class& cls = Class::Handle(); |
| 1857 for (intptr_t i = 0; i < result.leaf_classes().Length(); i++) { |
| 1858 cls ^= result.leaf_classes().At(i); |
| 1859 cls.RegisterCHACode(code); |
| 1860 } |
| 1861 Field& field = Field::Handle(); |
| 1862 for (intptr_t i = 0; i < result.guarded_fields().Length(); i++) { |
| 1863 field ^= result.guarded_fields().At(i); |
| 1864 field.RegisterDependentCode(code); |
| 1865 } |
| 1866 for (intptr_t i = 0; i < result.deoptimize_dependent_fields().Length(); |
| 1867 i++) { |
| 1868 field ^= result.deoptimize_dependent_fields().At(i); |
| 1869 field.DeoptimizeDependentCode(); |
| 1870 } |
| 1771 } else if (FLAG_trace_compiler) { | 1871 } else if (FLAG_trace_compiler) { |
| 1772 THR_Print("Drop code generated in the background compiler:\n"); | 1872 THR_Print("Drop code generated in the background compiler:\n"); |
| 1773 result.PrintValidity(); | 1873 result.PrintValidity(); |
| 1774 } | 1874 } |
| 1775 if (function.usage_counter() < 0) { | 1875 if (function.usage_counter() < 0) { |
| 1776 // Reset to 0 so that it can be recompiled if needed. | 1876 // Reset to 0 so that it can be recompiled if needed. |
| 1777 function.set_usage_counter(0); | 1877 function.set_usage_counter(0); |
| 1778 } | 1878 } |
| 1779 } | 1879 } |
| 1780 } | 1880 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1815 delete task_done; | 1915 delete task_done; |
| 1816 delete done_monitor; | 1916 delete done_monitor; |
| 1817 delete queue_monitor; | 1917 delete queue_monitor; |
| 1818 delete function_queue; | 1918 delete function_queue; |
| 1819 delete result_queue; | 1919 delete result_queue; |
| 1820 Isolate::Current()->set_background_compiler(NULL); | 1920 Isolate::Current()->set_background_compiler(NULL); |
| 1821 } | 1921 } |
| 1822 | 1922 |
| 1823 | 1923 |
| 1824 void BackgroundCompiler::EnsureInit(Thread* thread) { | 1924 void BackgroundCompiler::EnsureInit(Thread* thread) { |
| 1925 ASSERT(thread->IsMutatorThread()); |
| 1926 // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized |
| 1927 // compilation. |
| 1928 Class& cls = Class::Handle(thread->zone(), |
| 1929 Library::LookupCoreClass(Symbols::NoSuchMethodError())); |
| 1930 Error& error = Error::Handle(thread->zone(), |
| 1931 cls.EnsureIsFinalized(thread)); |
| 1932 ASSERT(error.IsNull()); |
| 1933 cls = Library::LookupCoreClass(Symbols::_Mint()); |
| 1934 error = cls.EnsureIsFinalized(thread); |
| 1935 ASSERT(error.IsNull()); |
| 1936 |
| 1825 bool start_task = false; | 1937 bool start_task = false; |
| 1826 Isolate* isolate = thread->isolate(); | 1938 Isolate* isolate = thread->isolate(); |
| 1827 { | 1939 { |
| 1828 MutexLocker ml(isolate->mutex()); | 1940 MutexLocker ml(isolate->mutex()); |
| 1829 if (isolate->background_compiler() == NULL) { | 1941 if (isolate->background_compiler() == NULL) { |
| 1830 BackgroundCompiler* task = new BackgroundCompiler(isolate); | 1942 BackgroundCompiler* task = new BackgroundCompiler(isolate); |
| 1831 isolate->set_background_compiler(task); | 1943 isolate->set_background_compiler(task); |
| 1832 start_task = true; | 1944 start_task = true; |
| 1833 } | 1945 } |
| 1834 } | 1946 } |
| 1835 if (start_task) { | 1947 if (start_task) { |
| 1836 Dart::thread_pool()->Run(isolate->background_compiler()); | 1948 Dart::thread_pool()->Run(isolate->background_compiler()); |
| 1837 } | 1949 } |
| 1838 } | 1950 } |
| 1839 | 1951 |
| 1840 } // namespace dart | 1952 } // namespace dart |
| OLD | NEW |