OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 | 172 |
173 if (max_virtual > 0) { | 173 if (max_virtual > 0) { |
174 if (code_range_size_ > 0) { | 174 if (code_range_size_ > 0) { |
175 // Reserve no more than 1/8 of the memory for the code range. | 175 // Reserve no more than 1/8 of the memory for the code range. |
176 code_range_size_ = Min(code_range_size_, max_virtual >> 3); | 176 code_range_size_ = Min(code_range_size_, max_virtual >> 3); |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); | 180 memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); |
181 native_contexts_list_ = NULL; | 181 native_contexts_list_ = NULL; |
182 array_buffers_list_ = Smi::FromInt(0); | |
182 mark_compact_collector_.heap_ = this; | 183 mark_compact_collector_.heap_ = this; |
183 external_string_table_.heap_ = this; | 184 external_string_table_.heap_ = this; |
184 // Put a dummy entry in the remembered pages so we can find the list the | 185 // Put a dummy entry in the remembered pages so we can find the list the |
185 // minidump even if there are no real unmapped pages. | 186 // minidump even if there are no real unmapped pages. |
186 RememberUnmappedPage(NULL, false); | 187 RememberUnmappedPage(NULL, false); |
187 | 188 |
188 ClearObjectStats(true); | 189 ClearObjectStats(true); |
189 } | 190 } |
190 | 191 |
191 | 192 |
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1531 // Terminate the list if there is one or more elements. | 1532 // Terminate the list if there is one or more elements. |
1532 if (tail != NULL) { | 1533 if (tail != NULL) { |
1533 tail->set_next_function_link(undefined); | 1534 tail->set_next_function_link(undefined); |
1534 } | 1535 } |
1535 | 1536 |
1536 return head; | 1537 return head; |
1537 } | 1538 } |
1538 | 1539 |
1539 | 1540 |
1540 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { | 1541 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
1541 Object* undefined = undefined_value(); | |
1542 Object* head = undefined; | |
1543 Context* tail = NULL; | |
1544 Object* candidate = native_contexts_list_; | |
1545 | |
1546 // We don't record weak slots during marking or scavenges. | 1542 // We don't record weak slots during marking or scavenges. |
1547 // Instead we do it once when we complete mark-compact cycle. | 1543 // Instead we do it once when we complete mark-compact cycle. |
1548 // Note that write barrier has no effect if we are already in the middle of | 1544 // Note that write barrier has no effect if we are already in the middle of |
1549 // compacting mark-sweep cycle and we have to record slots manually. | 1545 // compacting mark-sweep cycle and we have to record slots manually. |
1550 bool record_slots = | 1546 bool record_slots = |
1551 gc_state() == MARK_COMPACT && | 1547 gc_state() == MARK_COMPACT && |
1552 mark_compact_collector()->is_compacting(); | 1548 mark_compact_collector()->is_compacting(); |
1549 ProcessArrayBuffers(retainer, record_slots); | |
1550 ProcessNativeContexts(retainer, record_slots); | |
1551 } | |
1552 | |
1553 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer, | |
1554 bool record_slots) { | |
1555 Object* undefined = undefined_value(); | |
1556 Object* head = undefined; | |
1557 Context* tail = NULL; | |
1558 Object* candidate = native_contexts_list_; | |
1553 | 1559 |
1554 while (candidate != undefined) { | 1560 while (candidate != undefined) { |
1555 // Check whether to keep the candidate in the list. | 1561 // Check whether to keep the candidate in the list. |
1556 Context* candidate_context = reinterpret_cast<Context*>(candidate); | 1562 Context* candidate_context = reinterpret_cast<Context*>(candidate); |
1557 Object* retain = retainer->RetainAs(candidate); | 1563 Object* retain = retainer->RetainAs(candidate); |
1558 if (retain != NULL) { | 1564 if (retain != NULL) { |
1559 if (head == undefined) { | 1565 if (head == undefined) { |
1560 // First element in the list. | 1566 // First element in the list. |
1561 head = retain; | 1567 head = retain; |
1562 } else { | 1568 } else { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1611 Context::NEXT_CONTEXT_LINK, | 1617 Context::NEXT_CONTEXT_LINK, |
1612 Heap::undefined_value(), | 1618 Heap::undefined_value(), |
1613 UPDATE_WRITE_BARRIER); | 1619 UPDATE_WRITE_BARRIER); |
1614 } | 1620 } |
1615 | 1621 |
1616 // Update the head of the list of contexts. | 1622 // Update the head of the list of contexts. |
1617 native_contexts_list_ = head; | 1623 native_contexts_list_ = head; |
1618 } | 1624 } |
1619 | 1625 |
1620 | 1626 |
1627 template <class T> | |
1628 struct WeakListVisitor; | |
1629 | |
1630 | |
1631 template <class T> | |
1632 static Object* VisitWeakList(Object* list, | |
Dmitry Lomov (no reviews)
2013/06/04 15:15:52
This is a unified weak list visitor.
I hope to sw
| |
1633 MarkCompactCollector* collector, | |
1634 WeakObjectRetainer* retainer, bool record_slots) { | |
1635 Object* head = Smi::FromInt(0); | |
1636 T* tail = NULL; | |
1637 while (list != Smi::FromInt(0)) { | |
1638 Object* retained = retainer->RetainAs(list); | |
1639 if (retained != NULL) { | |
1640 if (head == Smi::FromInt(0)) { | |
1641 head = retained; | |
1642 } else { | |
1643 ASSERT(tail != NULL); | |
1644 WeakListVisitor<T>::set_weak_next(tail, retained); | |
1645 if (record_slots) { | |
1646 Object** next_slot = | |
1647 HeapObject::RawField(tail, WeakListVisitor<T>::kWeakNextOffset); | |
1648 collector->RecordSlot(next_slot, next_slot, retained); | |
1649 } | |
1650 } | |
1651 tail = reinterpret_cast<T*>(retained); | |
1652 WeakListVisitor<T>::VisitLiveObject( | |
1653 tail, collector, retainer, record_slots); | |
1654 } | |
1655 list = WeakListVisitor<T>::get_weak_next(reinterpret_cast<T*>(list)); | |
1656 } | |
1657 if (tail != NULL) { | |
1658 tail->set_weak_next(Smi::FromInt(0)); | |
1659 } | |
1660 return head; | |
1661 } | |
1662 | |
1663 | |
1664 template<> | |
1665 struct WeakListVisitor<JSTypedArray> { | |
1666 static void set_weak_next(JSTypedArray* obj, Object* next) { | |
1667 obj->set_weak_next(next); | |
1668 } | |
1669 | |
1670 static Object* get_weak_next(JSTypedArray* obj) { | |
1671 return obj->weak_next(); | |
1672 } | |
1673 | |
1674 static void VisitLiveObject(JSTypedArray* obj, | |
1675 MarkCompactCollector* collector, | |
1676 WeakObjectRetainer* retainer, | |
1677 bool record_slots) {} | |
1678 | |
1679 static const int kWeakNextOffset = JSTypedArray::kWeakNextOffset; | |
1680 }; | |
1681 | |
1682 | |
1683 template<> | |
1684 struct WeakListVisitor<JSArrayBuffer> { | |
1685 static void set_weak_next(JSArrayBuffer* obj, Object* next) { | |
1686 obj->set_weak_next(next); | |
1687 } | |
1688 | |
1689 static Object* get_weak_next(JSArrayBuffer* obj) { | |
1690 return obj->weak_next(); | |
1691 } | |
1692 | |
1693 static void VisitLiveObject(JSArrayBuffer* array_buffer, | |
1694 MarkCompactCollector* collector, | |
1695 WeakObjectRetainer* retainer, | |
1696 bool record_slots) { | |
1697 Object* typed_array_obj = | |
1698 VisitWeakList<JSTypedArray>(array_buffer->weak_first_array(), | |
1699 collector, retainer, record_slots); | |
1700 array_buffer->set_weak_first_array(typed_array_obj); | |
1701 if (typed_array_obj != Smi::FromInt(0) && record_slots) { | |
1702 Object** slot = HeapObject::RawField( | |
1703 array_buffer, JSArrayBuffer::kWeakFirstArrayOffset); | |
1704 collector->RecordSlot(slot, slot, typed_array_obj); | |
1705 } | |
1706 } | |
1707 | |
1708 static const int kWeakNextOffset = JSArrayBuffer::kWeakNextOffset; | |
1709 }; | |
1710 | |
1711 | |
1712 void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, | |
1713 bool record_slots) { | |
1714 Object* array_buffer_obj = | |
1715 VisitWeakList<JSArrayBuffer>(array_buffers_list(), | |
1716 mark_compact_collector(), | |
1717 retainer, record_slots); | |
1718 set_array_buffers_list(array_buffer_obj); | |
1719 } | |
1720 | |
1721 | |
1621 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { | 1722 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { |
1622 DisallowHeapAllocation no_allocation; | 1723 DisallowHeapAllocation no_allocation; |
1623 | 1724 |
1624 // Both the external string table and the string table may contain | 1725 // Both the external string table and the string table may contain |
1625 // external strings, but neither lists them exhaustively, nor is the | 1726 // external strings, but neither lists them exhaustively, nor is the |
1626 // intersection set empty. Therefore we iterate over the external string | 1727 // intersection set empty. Therefore we iterate over the external string |
1627 // table first, ignoring internalized strings, and then over the | 1728 // table first, ignoring internalized strings, and then over the |
1628 // internalized string table. | 1729 // internalized string table. |
1629 | 1730 |
1630 class ExternalStringTableVisitorAdapter : public ObjectVisitor { | 1731 class ExternalStringTableVisitorAdapter : public ObjectVisitor { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1786 template VisitSpecialized<Symbol::kSize>); | 1887 template VisitSpecialized<Symbol::kSize>); |
1787 | 1888 |
1788 table_.Register(kVisitSharedFunctionInfo, | 1889 table_.Register(kVisitSharedFunctionInfo, |
1789 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1890 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
1790 template VisitSpecialized<SharedFunctionInfo::kSize>); | 1891 template VisitSpecialized<SharedFunctionInfo::kSize>); |
1791 | 1892 |
1792 table_.Register(kVisitJSWeakMap, | 1893 table_.Register(kVisitJSWeakMap, |
1793 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1894 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
1794 Visit); | 1895 Visit); |
1795 | 1896 |
1897 table_.Register(kVisitJSArrayBuffer, | |
1898 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | |
1899 Visit); | |
1900 | |
1901 table_.Register(kVisitJSTypedArray, | |
1902 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | |
1903 Visit); | |
1904 | |
1796 table_.Register(kVisitJSRegExp, | 1905 table_.Register(kVisitJSRegExp, |
1797 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1906 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
1798 Visit); | 1907 Visit); |
1799 | 1908 |
1800 if (marks_handling == IGNORE_MARKS) { | 1909 if (marks_handling == IGNORE_MARKS) { |
1801 table_.Register(kVisitJSFunction, | 1910 table_.Register(kVisitJSFunction, |
1802 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1911 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
1803 template VisitSpecialized<JSFunction::kSize>); | 1912 template VisitSpecialized<JSFunction::kSize>); |
1804 } else { | 1913 } else { |
1805 table_.Register(kVisitJSFunction, &EvacuateJSFunction); | 1914 table_.Register(kVisitJSFunction, &EvacuateJSFunction); |
(...skipping 6137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7943 if (FLAG_parallel_recompilation) { | 8052 if (FLAG_parallel_recompilation) { |
7944 heap_->relocation_mutex_->Lock(); | 8053 heap_->relocation_mutex_->Lock(); |
7945 #ifdef DEBUG | 8054 #ifdef DEBUG |
7946 heap_->relocation_mutex_locked_by_optimizer_thread_ = | 8055 heap_->relocation_mutex_locked_by_optimizer_thread_ = |
7947 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); | 8056 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); |
7948 #endif // DEBUG | 8057 #endif // DEBUG |
7949 } | 8058 } |
7950 } | 8059 } |
7951 | 8060 |
7952 } } // namespace v8::internal | 8061 } } // namespace v8::internal |
OLD | NEW |