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(); | 748 page->sweep(); |
| 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(); | 805 largeObject->sweep(); |
| 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(); | 834 page->sweep(); |
| 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(); | 850 largeObject->sweep(); |
| 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, ThreadHeap* heap) | 1237 BaseHeapPage::BaseHeapPage(PageMemory* storage, ThreadHeap* heap) |
| 1234 : m_storage(storage) | 1238 : m_storage(storage) |
| 1235 , m_heap(heap) | 1239 , m_heap(heap) |
| 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 = heap()->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(heap()->threadState()->isSweepingInProgress()); | |
| 1259 ASSERT(m_sweepStatus <= 2); | |
| 1260 | |
| 1261 // Page has been swept, freed. | |
| 1262 if (!m_sweepStatus) | |
| 1263 return false; | |
| 1264 | |
| 1265 bool currentToken = heap()->threadState()->lazySweepToken(); | |
| 1266 return currentToken == (m_sweepStatus == 2); | |
|
haraken
2015/01/16 13:40:01
The token looks a bit tricky to me. Can we just de
sof
2015/01/16 13:43:10
I elected not to scan all pages (previously swept
haraken
2015/01/16 13:54:55
If you need to go with the flip bit, I guess you'l
| |
| 1267 } | |
| 1268 | |
| 1241 void BaseHeapPage::markOrphaned() | 1269 void BaseHeapPage::markOrphaned() |
| 1242 { | 1270 { |
| 1243 m_heap = nullptr; | 1271 m_heap = nullptr; |
| 1244 m_terminating = false; | 1272 m_terminating = false; |
| 1245 // Since we zap the page payload for orphaned pages we need to mark it as | 1273 // 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. | 1274 // unused so a conservative pointer won't interpret the object headers. |
| 1247 storage()->markUnused(); | 1275 storage()->markUnused(); |
| 1248 } | 1276 } |
| 1249 | 1277 |
| 1250 OrphanedPagePool::~OrphanedPagePool() | 1278 OrphanedPagePool::~OrphanedPagePool() |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1611 if (header->isMarked()) | 1639 if (header->isMarked()) |
| 1612 header->unmark(); | 1640 header->unmark(); |
| 1613 else | 1641 else |
| 1614 header->markDead(); | 1642 header->markDead(); |
| 1615 headerAddress += header->size(); | 1643 headerAddress += header->size(); |
| 1616 } | 1644 } |
| 1617 } | 1645 } |
| 1618 | 1646 |
| 1619 void HeapPage::removeFromHeap(ThreadHeap* heap) | 1647 void HeapPage::removeFromHeap(ThreadHeap* heap) |
| 1620 { | 1648 { |
| 1649 m_sweepStatus = 0; | |
| 1621 heap->freePage(this); | 1650 heap->freePage(this); |
| 1622 } | 1651 } |
| 1623 | 1652 |
| 1624 void HeapPage::populateObjectStartBitMap() | 1653 void HeapPage::populateObjectStartBitMap() |
| 1625 { | 1654 { |
| 1626 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); | 1655 memset(&m_objectStartBitMap, 0, objectStartBitMapSize); |
| 1627 Address start = payload(); | 1656 Address start = payload(); |
| 1628 for (Address headerAddress = start; headerAddress < payloadEnd();) { | 1657 for (Address headerAddress = start; headerAddress < payloadEnd();) { |
| 1629 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); | 1658 HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(headerAdd ress); |
| 1630 size_t objectOffset = headerAddress - start; | 1659 size_t objectOffset = headerAddress - start; |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2694 bool Heap::s_shutdownCalled = false; | 2723 bool Heap::s_shutdownCalled = false; |
| 2695 bool Heap::s_lastGCWasConservative = false; | 2724 bool Heap::s_lastGCWasConservative = false; |
| 2696 FreePagePool* Heap::s_freePagePool; | 2725 FreePagePool* Heap::s_freePagePool; |
| 2697 OrphanedPagePool* Heap::s_orphanedPagePool; | 2726 OrphanedPagePool* Heap::s_orphanedPagePool; |
| 2698 Heap::RegionTree* Heap::s_regionTree = nullptr; | 2727 Heap::RegionTree* Heap::s_regionTree = nullptr; |
| 2699 size_t Heap::s_allocatedObjectSize = 0; | 2728 size_t Heap::s_allocatedObjectSize = 0; |
| 2700 size_t Heap::s_allocatedSpace = 0; | 2729 size_t Heap::s_allocatedSpace = 0; |
| 2701 size_t Heap::s_markedObjectSize = 0; | 2730 size_t Heap::s_markedObjectSize = 0; |
| 2702 | 2731 |
| 2703 } // namespace blink | 2732 } // namespace blink |
| OLD | NEW |