Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 { | 536 { |
| 537 HeapObjectHeader* header = heapObjectHeader(); | 537 HeapObjectHeader* header = heapObjectHeader(); |
| 538 if (header->isMarked()) | 538 if (header->isMarked()) |
| 539 header->unmark(); | 539 header->unmark(); |
| 540 else | 540 else |
| 541 header->markDead(); | 541 header->markDead(); |
| 542 } | 542 } |
| 543 | 543 |
| 544 void LargeObject::removeFromHeap(ThreadHeap* heap) | 544 void LargeObject::removeFromHeap(ThreadHeap* heap) |
| 545 { | 545 { |
| 546 m_sweepStatus = 0; | |
| 546 heap->freeLargeObject(this); | 547 heap->freeLargeObject(this); |
| 547 } | 548 } |
| 548 | 549 |
| 549 ThreadHeap::ThreadHeap(ThreadState* state, int index) | 550 ThreadHeap::ThreadHeap(ThreadState* state, int index) |
| 550 : m_currentAllocationPoint(nullptr) | 551 : m_currentAllocationPoint(nullptr) |
| 551 , m_remainingAllocationSize(0) | 552 , m_remainingAllocationSize(0) |
| 552 , m_lastRemainingAllocationSize(0) | 553 , m_lastRemainingAllocationSize(0) |
| 553 , m_firstPage(nullptr) | 554 , m_firstPage(nullptr) |
| 554 , m_firstLargeObject(nullptr) | 555 , m_firstLargeObject(nullptr) |
| 555 , m_firstUnsweptPage(nullptr) | 556 , m_firstUnsweptPage(nullptr) |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 HeapPage* page = m_firstUnsweptPage; | 741 HeapPage* page = m_firstUnsweptPage; |
| 741 if (page->isEmpty()) { | 742 if (page->isEmpty()) { |
| 742 page->unlink(&m_firstUnsweptPage); | 743 page->unlink(&m_firstUnsweptPage); |
| 743 page->removeFromHeap(this); | 744 page->removeFromHeap(this); |
| 744 } else { | 745 } else { |
| 745 // Sweep a page and move the page from m_firstUnsweptPages to | 746 // Sweep a page and move the page from m_firstUnsweptPages to |
| 746 // m_firstPages. | 747 // m_firstPages. |
| 747 page->sweep(this); | 748 page->sweep(this); |
| 748 page->unlink(&m_firstUnsweptPage); | 749 page->unlink(&m_firstUnsweptPage); |
| 749 page->link(&m_firstPage); | 750 page->link(&m_firstPage); |
| 751 page->markAsLazilySwept(); | |
| 750 | 752 |
| 751 result = allocateFromFreeList(allocationSize, gcInfoIndex); | 753 result = allocateFromFreeList(allocationSize, gcInfoIndex); |
| 752 if (result) { | 754 if (result) |
| 753 break; | 755 break; |
| 754 } | |
| 755 } | 756 } |
| 756 } | 757 } |
| 757 | 758 |
| 758 if (threadState()->isMainThread()) | 759 if (threadState()->isMainThread()) |
| 759 ScriptForbiddenScope::exit(); | 760 ScriptForbiddenScope::exit(); |
| 760 return result; | 761 return result; |
| 761 } | 762 } |
| 762 | 763 |
| 763 bool ThreadHeap::lazySweepLargeObjects(size_t allocationSize) | 764 bool ThreadHeap::lazySweepLargeObjects(size_t allocationSize) |
| 764 { | 765 { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 797 if (sweptSize >= allocationSize) { | 798 if (sweptSize >= allocationSize) { |
| 798 result = true; | 799 result = true; |
| 799 break; | 800 break; |
| 800 } | 801 } |
| 801 } else { | 802 } else { |
| 802 // Sweep a large object and move the large object from | 803 // Sweep a large object and move the large object from |
| 803 // m_firstUnsweptLargeObjects to m_firstLargeObjects. | 804 // m_firstUnsweptLargeObjects to m_firstLargeObjects. |
| 804 largeObject->sweep(this); | 805 largeObject->sweep(this); |
| 805 largeObject->unlink(&m_firstUnsweptLargeObject); | 806 largeObject->unlink(&m_firstUnsweptLargeObject); |
| 806 largeObject->link(&m_firstLargeObject); | 807 largeObject->link(&m_firstLargeObject); |
| 808 largeObject->markAsLazilySwept(); | |
| 807 } | 809 } |
| 808 } | 810 } |
| 809 | 811 |
| 810 if (threadState()->isMainThread()) | 812 if (threadState()->isMainThread()) |
| 811 ScriptForbiddenScope::exit(); | 813 ScriptForbiddenScope::exit(); |
| 812 return result; | 814 return result; |
| 813 } | 815 } |
| 814 | 816 |
| 815 void ThreadHeap::completeSweep() | 817 void ThreadHeap::completeSweep() |
| 816 { | 818 { |
| 817 RELEASE_ASSERT(threadState()->isSweepingInProgress()); | 819 RELEASE_ASSERT(threadState()->isSweepingInProgress()); |
| 818 ASSERT(threadState()->sweepForbidden()); | 820 ASSERT(threadState()->sweepForbidden()); |
| 819 | 821 |
| 820 if (threadState()->isMainThread()) | 822 if (threadState()->isMainThread()) |
| 821 ScriptForbiddenScope::enter(); | 823 ScriptForbiddenScope::enter(); |
| 822 | 824 |
| 823 // Sweep normal pages. | 825 // Sweep normal pages. |
| 824 while (m_firstUnsweptPage) { | 826 while (m_firstUnsweptPage) { |
| 825 HeapPage* page = m_firstUnsweptPage; | 827 HeapPage* page = m_firstUnsweptPage; |
| 826 if (page->isEmpty()) { | 828 if (page->isEmpty()) { |
| 827 page->unlink(&m_firstUnsweptPage); | 829 page->unlink(&m_firstUnsweptPage); |
| 828 page->removeFromHeap(this); | 830 page->removeFromHeap(this); |
| 829 } else { | 831 } else { |
| 830 // Sweep a page and move the page from m_firstUnsweptPages to | 832 // Sweep a page and move the page from m_firstUnsweptPages to |
| 831 // m_firstPages. | 833 // m_firstPages. |
| 832 page->sweep(this); | 834 page->sweep(this); |
| 833 page->unlink(&m_firstUnsweptPage); | 835 page->unlink(&m_firstUnsweptPage); |
| 834 page->link(&m_firstPage); | 836 page->link(&m_firstPage); |
| 837 page->markAsLazilySwept(); | |
| 835 } | 838 } |
| 836 } | 839 } |
| 837 | 840 |
| 838 // Sweep large objects. | 841 // Sweep large objects. |
| 839 while (m_firstUnsweptLargeObject) { | 842 while (m_firstUnsweptLargeObject) { |
| 840 LargeObject* largeObject = m_firstUnsweptLargeObject; | 843 LargeObject* largeObject = m_firstUnsweptLargeObject; |
| 841 if (largeObject->isEmpty()) { | 844 if (largeObject->isEmpty()) { |
| 842 largeObject->unlink(&m_firstUnsweptLargeObject); | 845 largeObject->unlink(&m_firstUnsweptLargeObject); |
| 843 largeObject->removeFromHeap(this); | 846 largeObject->removeFromHeap(this); |
| 844 } else { | 847 } else { |
| 845 // Sweep a large object and move the large object from | 848 // Sweep a large object and move the large object from |
| 846 // m_firstUnsweptLargeObjects to m_firstLargeObjects. | 849 // m_firstUnsweptLargeObjects to m_firstLargeObjects. |
| 847 largeObject->sweep(this); | 850 largeObject->sweep(this); |
| 848 largeObject->unlink(&m_firstUnsweptLargeObject); | 851 largeObject->unlink(&m_firstUnsweptLargeObject); |
| 849 largeObject->link(&m_firstLargeObject); | 852 largeObject->link(&m_firstLargeObject); |
| 853 largeObject->markAsLazilySwept(); | |
| 850 } | 854 } |
| 851 } | 855 } |
| 852 | 856 |
| 853 if (threadState()->isMainThread()) | 857 if (threadState()->isMainThread()) |
| 854 ScriptForbiddenScope::exit(); | 858 ScriptForbiddenScope::exit(); |
| 855 } | 859 } |
| 856 | 860 |
| 857 #if ENABLE(ASSERT) | 861 #if ENABLE(ASSERT) |
| 858 static bool isLargeObjectAligned(LargeObject* largeObject, Address address) | 862 static bool isLargeObjectAligned(LargeObject* largeObject, Address address) |
| 859 { | 863 { |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1231 } | 1235 } |
| 1232 | 1236 |
| 1233 BaseHeapPage::BaseHeapPage(PageMemory* storage, ThreadState* state) | 1237 BaseHeapPage::BaseHeapPage(PageMemory* storage, ThreadState* state) |
| 1234 : m_storage(storage) | 1238 : m_storage(storage) |
| 1235 , m_threadState(state) | 1239 , m_threadState(state) |
| 1236 , m_terminating(false) | 1240 , m_terminating(false) |
| 1237 { | 1241 { |
| 1238 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); | 1242 ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this))); |
| 1239 } | 1243 } |
| 1240 | 1244 |
| 1245 void BaseHeapPage::markAsLazilySwept() | |
| 1246 { | |
| 1247 // To signal completion of a lazy sweep, update the | |
| 1248 // page's sweep status to match that of the ThreadState's | |
| 1249 // flip-flop sweep token. | |
| 1250 bool currentToken = threadState()->lazySweepToken(); | |
| 1251 m_sweepStatus = currentToken ? 2 : 1; | |
| 1252 } | |
| 1253 | |
| 1254 bool BaseHeapPage::hasBeenLazilySwept() const | |
| 1255 { | |
| 1256 // Returns true if this page has been swept | |
| 1257 // by the ongoing lazy sweep operation. | |
| 1258 ASSERT(threadState()->isSweepingInProgress()); | |
| 1259 ASSERT(m_sweepStatus <= 2); | |
| 1260 if (!m_sweepStatus) | |
| 1261 return false; | |
| 1262 | |
| 1263 bool currentToken = threadState()->lazySweepToken(); | |
| 1264 return currentToken == (m_sweepStatus == 2); | |
| 1265 } | |
| 1266 | |
| 1241 void BaseHeapPage::markOrphaned() | 1267 void BaseHeapPage::markOrphaned() |
| 1242 { | 1268 { |
| 1243 m_threadState = nullptr; | 1269 m_threadState = nullptr; |
| 1244 m_terminating = false; | 1270 m_terminating = false; |
| 1245 // Since we zap the page payload for orphaned pages we need to mark it as | 1271 // Since we zap the page payload for orphaned pages we need to mark it as |
| 1246 // unused so a conservative pointer won't interpret the object headers. | 1272 // unused so a conservative pointer won't interpret the object headers. |
| 1247 storage()->markUnused(); | 1273 storage()->markUnused(); |
| 1248 } | 1274 } |
| 1249 | 1275 |
| 1250 OrphanedPagePool::~OrphanedPagePool() | 1276 OrphanedPagePool::~OrphanedPagePool() |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1611 if (header->isMarked()) | 1637 if (header->isMarked()) |
| 1612 header->unmark(); | 1638 header->unmark(); |
| 1613 else | 1639 else |
| 1614 header->markDead(); | 1640 header->markDead(); |
| 1615 headerAddress += header->size(); | 1641 headerAddress += header->size(); |
| 1616 } | 1642 } |
| 1617 } | 1643 } |
| 1618 | 1644 |
| 1619 void HeapPage::removeFromHeap(ThreadHeap* heap) | 1645 void HeapPage::removeFromHeap(ThreadHeap* heap) |
| 1620 { | 1646 { |
| 1647 m_sweepStatus = 0; | |
| 1621 heap->freePage(this); | 1648 heap->freePage(this); |
| 1622 } | 1649 } |
| 1623 | 1650 |
| 1624 void HeapPage::populateObjectStartBitMap() | 1651 void HeapPage::populateObjectStartBitMap() |
| 1625 { | 1652 { |
| 1626 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); | 1653 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); |
| 1627 Address start = payload(); | 1654 Address start = payload(); |
| 1628 for (Address headerAddress = start; headerAddress < payloadEnd();) { | 1655 for (Address headerAddress = start; headerAddress < payloadEnd();) { |
| 1629 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); | 1656 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); |
| 1630 size_t objectOffset = headerAddress - start; | 1657 size_t objectOffset = headerAddress - start; |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2119 | 2146 |
| 2120 #if !ENABLE(ASSERT) | 2147 #if !ENABLE(ASSERT) |
| 2121 s_heapDoesNotContainCache->addEntry(address); | 2148 s_heapDoesNotContainCache->addEntry(address); |
| 2122 #else | 2149 #else |
| 2123 if (!s_heapDoesNotContainCache->lookup(address)) | 2150 if (!s_heapDoesNotContainCache->lookup(address)) |
| 2124 s_heapDoesNotContainCache->addEntry(address); | 2151 s_heapDoesNotContainCache->addEntry(address); |
| 2125 #endif | 2152 #endif |
| 2126 return nullptr; | 2153 return nullptr; |
| 2127 } | 2154 } |
| 2128 | 2155 |
| 2156 bool Heap::isFinalizedObjectAlive(const void* objectPointer) | |
|
haraken
2015/01/16 00:57:10
I like having this method in our heap infrastructu
| |
| 2157 { | |
| 2158 #if ENABLE(OILPAN) | |
| 2159 if (!ThreadState::current()->isSweepingInProgress()) | |
| 2160 return true; | |
| 2161 | |
| 2162 BaseHeapPage* page = pageFromObject(objectPointer); | |
| 2163 if (page->hasBeenLazilySwept()) | |
| 2164 return true; | |
| 2165 | |
| 2166 return s_markingVisitor->isMarked(objectPointer); | |
| 2167 #else | |
| 2168 // FIXME: remove when incremental sweeping is always on | |
| 2169 // (cf. ThreadState::postGCProcessing()). | |
| 2170 return true; | |
| 2171 #endif | |
| 2172 } | |
| 2173 | |
| 2129 #if ENABLE(GC_PROFILE_MARKING) | 2174 #if ENABLE(GC_PROFILE_MARKING) |
| 2130 const GCInfo* Heap::findGCInfo(Address address) | 2175 const GCInfo* Heap::findGCInfo(Address address) |
| 2131 { | 2176 { |
| 2132 return ThreadState::findGCInfoFromAllThreads(address); | 2177 return ThreadState::findGCInfoFromAllThreads(address); |
| 2133 } | 2178 } |
| 2134 #endif | 2179 #endif |
| 2135 | 2180 |
| 2136 #if ENABLE(GC_PROFILE_MARKING) | 2181 #if ENABLE(GC_PROFILE_MARKING) |
| 2137 void Heap::dumpPathToObjectOnNextGC(void* p) | 2182 void Heap::dumpPathToObjectOnNextGC(void* p) |
| 2138 { | 2183 { |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2687 bool Heap::s_shutdownCalled = false; | 2732 bool Heap::s_shutdownCalled = false; |
| 2688 bool Heap::s_lastGCWasConservative = false; | 2733 bool Heap::s_lastGCWasConservative = false; |
| 2689 FreePagePool* Heap::s_freePagePool; | 2734 FreePagePool* Heap::s_freePagePool; |
| 2690 OrphanedPagePool* Heap::s_orphanedPagePool; | 2735 OrphanedPagePool* Heap::s_orphanedPagePool; |
| 2691 Heap::RegionTree* Heap::s_regionTree = nullptr; | 2736 Heap::RegionTree* Heap::s_regionTree = nullptr; |
| 2692 size_t Heap::s_allocatedObjectSize = 0; | 2737 size_t Heap::s_allocatedObjectSize = 0; |
| 2693 size_t Heap::s_allocatedSpace = 0; | 2738 size_t Heap::s_allocatedSpace = 0; |
| 2694 size_t Heap::s_markedObjectSize = 0; | 2739 size_t Heap::s_markedObjectSize = 0; |
| 2695 | 2740 |
| 2696 } // namespace blink | 2741 } // namespace blink |
| OLD | NEW |