| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 #else | 85 #else |
| 86 #define FILL_ZERO_IF_PRODUCTION(address, size) memset((address), 0, (size)) | 86 #define FILL_ZERO_IF_PRODUCTION(address, size) memset((address), 0, (size)) |
| 87 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) do { } while (false) | 87 #define FILL_ZERO_IF_NOT_PRODUCTION(address, size) do { } while (false) |
| 88 #endif | 88 #endif |
| 89 | 89 |
| 90 class CallbackStack; | 90 class CallbackStack; |
| 91 class PageMemory; | 91 class PageMemory; |
| 92 template<ThreadAffinity affinity> class ThreadLocalPersistents; | 92 template<ThreadAffinity affinity> class ThreadLocalPersistents; |
| 93 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr
ait<T>::Affinity>> class Persistent; | 93 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr
ait<T>::Affinity>> class Persistent; |
| 94 | 94 |
| 95 #if ENABLE(GC_PROFILE_HEAP) | 95 #if ENABLE(GC_PROFILE_HEAP) || ENABLE(GC_PROFILE_FREE_LIST) |
| 96 class TracedValue; | 96 class TracedValue; |
| 97 #endif | 97 #endif |
| 98 | 98 |
| 99 // HeapObjectHeader is 4 byte (32 bit) that has the following layout: | 99 // HeapObjectHeader is 4 byte (32 bit) that has the following layout: |
| 100 // | 100 // |
| 101 // | gcInfoIndex (15 bit) | size (14 bit) | dead bit (1 bit) | freed bit (1 bit)
| mark bit (1 bit) | | 101 // | gcInfoIndex (15 bit) | size (14 bit) | dead bit (1 bit) | freed bit (1 bit)
| mark bit (1 bit) | |
| 102 // | 102 // |
| 103 // - For non-large objects, 14 bit is enough for |size| because the blink | 103 // - For non-large objects, 14 bit is enough for |size| because the blink |
| 104 // page size is 2^17 byte and each object is guaranteed to be aligned with | 104 // page size is 2^17 byte and each object is guaranteed to be aligned with |
| 105 // 2^3 byte. | 105 // 2^3 byte. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 118 // them via a conservatively found pointer. Tracing dead objects could lead to | 118 // them via a conservatively found pointer. Tracing dead objects could lead to |
| 119 // tracing of already finalized objects in another thread's heap which is a | 119 // tracing of already finalized objects in another thread's heap which is a |
| 120 // use-after-free situation. | 120 // use-after-free situation. |
| 121 const size_t headerDeadBitMask = 4; | 121 const size_t headerDeadBitMask = 4; |
| 122 // On free-list entries we reuse the dead bit to distinguish a normal free-list | 122 // On free-list entries we reuse the dead bit to distinguish a normal free-list |
| 123 // entry from one that has been promptly freed. | 123 // entry from one that has been promptly freed. |
| 124 const size_t headerPromptlyFreedBitMask = headerFreedBitMask | headerDeadBitMask
; | 124 const size_t headerPromptlyFreedBitMask = headerFreedBitMask | headerDeadBitMask
; |
| 125 const size_t largeObjectSizeInHeader = 0; | 125 const size_t largeObjectSizeInHeader = 0; |
| 126 const size_t gcInfoIndexForFreeListHeader = 0; | 126 const size_t gcInfoIndexForFreeListHeader = 0; |
| 127 const size_t nonLargeObjectSizeMax = 1 << 17; | 127 const size_t nonLargeObjectSizeMax = 1 << 17; |
| 128 #if ENABLE(GC_PROFILE_HEAP) | 128 //#if ENABLE(GC_PROFILE_HEAP) |
| 129 const size_t maxHeapObjectAge = 7; | 129 const size_t maxHeapObjectAge = 7; |
| 130 #endif | 130 //#endif |
| 131 | 131 |
| 132 static_assert(nonLargeObjectSizeMax >= blinkPageSize, "max size supported by Hea
pObjectHeader must at least be blinkPageSize"); | 132 static_assert(nonLargeObjectSizeMax >= blinkPageSize, "max size supported by Hea
pObjectHeader must at least be blinkPageSize"); |
| 133 | 133 |
| 134 class PLATFORM_EXPORT HeapObjectHeader { | 134 class PLATFORM_EXPORT HeapObjectHeader { |
| 135 public: | 135 public: |
| 136 // If gcInfoIndex is 0, this header is interpreted as a free list header. | 136 // If gcInfoIndex is 0, this header is interpreted as a free list header. |
| 137 NO_SANITIZE_ADDRESS | 137 NO_SANITIZE_ADDRESS |
| 138 HeapObjectHeader(size_t size, size_t gcInfoIndex) | 138 HeapObjectHeader(size_t size, size_t gcInfoIndex) |
| 139 { | 139 { |
| 140 #if ENABLE(ASSERT) | 140 #if ENABLE(ASSERT) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 // GC. | 187 // GC. |
| 188 void zapMagic(); | 188 void zapMagic(); |
| 189 #endif | 189 #endif |
| 190 | 190 |
| 191 void finalize(Address, size_t); | 191 void finalize(Address, size_t); |
| 192 static HeapObjectHeader* fromPayload(const void*); | 192 static HeapObjectHeader* fromPayload(const void*); |
| 193 | 193 |
| 194 static const uint16_t magic = 0xfff1; | 194 static const uint16_t magic = 0xfff1; |
| 195 static const uint16_t zappedMagic = 0x4321; | 195 static const uint16_t zappedMagic = 0x4321; |
| 196 | 196 |
| 197 #if ENABLE(GC_PROFILE_HEAP) | 197 //#if ENABLE(GC_PROFILE_HEAP) |
| 198 NO_SANITIZE_ADDRESS | 198 NO_SANITIZE_ADDRESS |
| 199 size_t encodedSize() const { return m_encoded; } | 199 size_t encodedSize() const { return m_encoded; } |
| 200 | 200 |
| 201 NO_SANITIZE_ADDRESS | 201 NO_SANITIZE_ADDRESS |
| 202 size_t age() const { return m_age; } | 202 size_t age() const { return m_age; } |
| 203 | 203 |
| 204 NO_SANITIZE_ADDRESS | 204 NO_SANITIZE_ADDRESS |
| 205 void incAge() | 205 void incAge() |
| 206 { | 206 { |
| 207 if (m_age < maxHeapObjectAge) | 207 if (m_age < maxHeapObjectAge) |
| 208 m_age++; | 208 m_age++; |
| 209 } | 209 } |
| 210 #endif | 210 //#endif |
| 211 | 211 |
| 212 #if !ENABLE(ASSERT) && !ENABLE(GC_PROFILE_HEAP) && CPU(64BIT) | 212 #if !ENABLE(ASSERT) && !ENABLE(GC_PROFILE_HEAP) && CPU(64BIT) |
| 213 // This method is needed just to avoid compilers from removing m_padding. | 213 // This method is needed just to avoid compilers from removing m_padding. |
| 214 uint64_t unusedMethod() const { return m_padding; } | 214 uint64_t unusedMethod() const { return m_padding; } |
| 215 #endif | 215 #endif |
| 216 | 216 |
| 217 private: | 217 private: |
| 218 uint32_t m_encoded; | 218 uint32_t m_encoded; |
| 219 #if ENABLE(ASSERT) | 219 #if ENABLE(ASSERT) |
| 220 uint16_t m_magic; | 220 uint16_t m_magic; |
| 221 #endif | 221 #endif |
| 222 #if ENABLE(GC_PROFILE_HEAP) | 222 //#if ENABLE(GC_PROFILE_HEAP) |
| 223 uint8_t m_age; | 223 uint8_t m_age; |
| 224 #endif | 224 //#endif |
| 225 | 225 |
| 226 // In 64 bit architectures, we intentionally add 4 byte padding immediately | 226 // In 64 bit architectures, we intentionally add 4 byte padding immediately |
| 227 // after the HeapHeaderObject. This is because: | 227 // after the HeapHeaderObject. This is because: |
| 228 // | 228 // |
| 229 // | HeapHeaderObject (4 byte) | padding (4 byte) | object payload (8 * n by
te) | | 229 // | HeapHeaderObject (4 byte) | padding (4 byte) | object payload (8 * n by
te) | |
| 230 // ^8 byte aligned ^8 byte aligned | 230 // ^8 byte aligned ^8 byte aligned |
| 231 // | 231 // |
| 232 // is better than: | 232 // is better than: |
| 233 // | 233 // |
| 234 // | HeapHeaderObject (4 byte) | object payload (8 * n byte) | padding (4 by
te) | | 234 // | HeapHeaderObject (4 byte) | object payload (8 * n byte) | padding (4 by
te) | |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 // Check if the given address points to an object in this | 375 // Check if the given address points to an object in this |
| 376 // heap page. If so, find the start of that object and mark it | 376 // heap page. If so, find the start of that object and mark it |
| 377 // using the given Visitor. Otherwise do nothing. The pointer must | 377 // using the given Visitor. Otherwise do nothing. The pointer must |
| 378 // be within the same aligned blinkPageSize as the this-pointer. | 378 // be within the same aligned blinkPageSize as the this-pointer. |
| 379 // | 379 // |
| 380 // This is used during conservative stack scanning to | 380 // This is used during conservative stack scanning to |
| 381 // conservatively mark all objects that could be referenced from | 381 // conservatively mark all objects that could be referenced from |
| 382 // the stack. | 382 // the stack. |
| 383 virtual void checkAndMarkPointer(Visitor*, Address) = 0; | 383 virtual void checkAndMarkPointer(Visitor*, Address) = 0; |
| 384 virtual void markOrphaned(); | 384 virtual void markOrphaned(); |
| 385 |
| 385 #if ENABLE(GC_PROFILE_MARKING) | 386 #if ENABLE(GC_PROFILE_MARKING) |
| 386 virtual const GCInfo* findGCInfo(Address) = 0; | 387 virtual const GCInfo* findGCInfo(Address) = 0; |
| 387 #endif | 388 #endif |
| 388 #if ENABLE(GC_PROFILE_HEAP) | 389 #if ENABLE(GC_PROFILE_HEAP) |
| 389 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; | 390 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; |
| 390 #endif | 391 #endif |
| 391 #if ENABLE(ASSERT) | 392 #if ENABLE(ASSERT) || ENABLE(GC_PROFILE_MARKING) |
| 392 virtual bool contains(Address) = 0; | 393 virtual bool contains(Address) = 0; |
| 393 #endif | 394 #endif |
| 394 virtual size_t size() = 0; | 395 virtual size_t size() = 0; |
| 395 virtual bool isLargeObject() { return false; } | 396 virtual bool isLargeObject() { return false; } |
| 396 | 397 |
| 397 Address address() { return reinterpret_cast<Address>(this); } | 398 Address address() { return reinterpret_cast<Address>(this); } |
| 398 PageMemory* storage() const { return m_storage; } | 399 PageMemory* storage() const { return m_storage; } |
| 399 ThreadHeap* heap() const { return m_heap; } | 400 ThreadHeap* heap() const { return m_heap; } |
| 400 bool orphaned() { return !m_heap; } | 401 bool orphaned() { return !m_heap; } |
| 401 bool terminating() { return m_terminating; } | 402 bool terminating() { return m_terminating; } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 #endif | 475 #endif |
| 475 memset(payload(), orphanedZapValue, payloadSize()); | 476 memset(payload(), orphanedZapValue, payloadSize()); |
| 476 BaseHeapPage::markOrphaned(); | 477 BaseHeapPage::markOrphaned(); |
| 477 } | 478 } |
| 478 #if ENABLE(GC_PROFILE_MARKING) | 479 #if ENABLE(GC_PROFILE_MARKING) |
| 479 const GCInfo* findGCInfo(Address) override; | 480 const GCInfo* findGCInfo(Address) override; |
| 480 #endif | 481 #endif |
| 481 #if ENABLE(GC_PROFILE_HEAP) | 482 #if ENABLE(GC_PROFILE_HEAP) |
| 482 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); | 483 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); |
| 483 #endif | 484 #endif |
| 484 #if ENABLE(ASSERT) | 485 #if ENABLE(ASSERT) || ENABLE(GC_PROFILE_MARKING) |
| 485 // Returns true for the whole blinkPageSize page that the page is on, even | 486 // Returns true for the whole blinkPageSize page that the page is on, even |
| 486 // for the header, and the unmapped guard page at the start. That ensures | 487 // for the header, and the unmapped guard page at the start. That ensures |
| 487 // the result can be used to populate the negative page cache. | 488 // the result can be used to populate the negative page cache. |
| 488 virtual bool contains(Address addr) override | 489 virtual bool contains(Address addr) override |
| 489 { | 490 { |
| 490 Address blinkPageStart = roundToBlinkPageStart(address()); | 491 Address blinkPageStart = roundToBlinkPageStart(address()); |
| 491 ASSERT(blinkPageStart == address() - WTF::kSystemPageSize); // Page is a
t aligned address plus guard page size. | 492 ASSERT(blinkPageStart == address() - WTF::kSystemPageSize); // Page is a
t aligned address plus guard page size. |
| 492 return blinkPageStart <= addr && addr < blinkPageStart + blinkPageSize; | 493 return blinkPageStart <= addr && addr < blinkPageStart + blinkPageSize; |
| 493 } | 494 } |
| 494 #endif | 495 #endif |
| 495 virtual size_t size() override { return blinkPageSize; } | 496 virtual size_t size() override { return blinkPageSize; } |
| 496 | 497 |
| 497 HeapPage* next() { return m_next; } | 498 HeapPage* next() { return m_next; } |
| 498 | 499 |
| 499 void clearObjectStartBitMap(); | 500 void clearObjectStartBitMap(); |
| 500 | 501 |
| 502 void countUnmarkedObjects(); |
| 503 |
| 501 #if defined(ADDRESS_SANITIZER) | 504 #if defined(ADDRESS_SANITIZER) |
| 502 void poisonUnmarkedObjects(); | 505 void poisonUnmarkedObjects(); |
| 503 #endif | 506 #endif |
| 504 | 507 |
| 505 // This method is needed just to avoid compilers from removing m_padding. | 508 // This method is needed just to avoid compilers from removing m_padding. |
| 506 uint64_t unusedMethod() const { return m_padding; } | 509 uint64_t unusedMethod() const { return m_padding; } |
| 507 | 510 |
| 508 private: | 511 private: |
| 509 HeapObjectHeader* findHeaderFromAddress(Address); | 512 HeapObjectHeader* findHeaderFromAddress(Address); |
| 510 void populateObjectStartBitMap(); | 513 void populateObjectStartBitMap(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 virtual void markUnmarkedObjectsDead() override; | 546 virtual void markUnmarkedObjectsDead() override; |
| 544 virtual void checkAndMarkPointer(Visitor*, Address) override; | 547 virtual void checkAndMarkPointer(Visitor*, Address) override; |
| 545 virtual void markOrphaned() override | 548 virtual void markOrphaned() override |
| 546 { | 549 { |
| 547 // Zap the payload with a recognizable value to detect any incorrect | 550 // Zap the payload with a recognizable value to detect any incorrect |
| 548 // cross thread pointer usage. | 551 // cross thread pointer usage. |
| 549 memset(payload(), orphanedZapValue, payloadSize()); | 552 memset(payload(), orphanedZapValue, payloadSize()); |
| 550 BaseHeapPage::markOrphaned(); | 553 BaseHeapPage::markOrphaned(); |
| 551 } | 554 } |
| 552 #if ENABLE(GC_PROFILE_MARKING) | 555 #if ENABLE(GC_PROFILE_MARKING) |
| 553 virtual const GCInfo* findGCInfo(Address address) override | 556 virtual const GCInfo* findGCInfo(Address); |
| 554 { | |
| 555 if (!objectContains(address)) | |
| 556 return nullptr; | |
| 557 return gcInfo(); | |
| 558 } | |
| 559 #endif | 557 #endif |
| 560 #if ENABLE(GC_PROFILE_HEAP) | 558 #if ENABLE(GC_PROFILE_HEAP) |
| 561 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; | 559 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; |
| 562 #endif | 560 #endif |
| 563 #if ENABLE(ASSERT) | 561 #if ENABLE(ASSERT) || ENABLE(GC_PROFILE_MARKING) |
| 564 // Returns true for any address that is on one of the pages that this | 562 // Returns true for any address that is on one of the pages that this |
| 565 // large object uses. That ensures that we can use a negative result to | 563 // large object uses. That ensures that we can use a negative result to |
| 566 // populate the negative page cache. | 564 // populate the negative page cache. |
| 567 virtual bool contains(Address object) override | 565 virtual bool contains(Address object) override |
| 568 { | 566 { |
| 569 return roundToBlinkPageStart(address()) <= object && object < roundToBli
nkPageEnd(address() + size()); | 567 return roundToBlinkPageStart(address()) <= object && object < roundToBli
nkPageEnd(address() + size()); |
| 570 } | 568 } |
| 571 #endif | 569 #endif |
| 572 virtual size_t size() | 570 virtual size_t size() |
| 573 { | 571 { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 private: | 703 private: |
| 706 void clearMemory(PageMemory*); | 704 void clearMemory(PageMemory*); |
| 707 }; | 705 }; |
| 708 | 706 |
| 709 class FreeList { | 707 class FreeList { |
| 710 public: | 708 public: |
| 711 FreeList(); | 709 FreeList(); |
| 712 | 710 |
| 713 void addToFreeList(Address, size_t); | 711 void addToFreeList(Address, size_t); |
| 714 void clear(); | 712 void clear(); |
| 713 FreeListEntry* takeEntry(size_t allocationSize); |
| 714 |
| 715 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 716 void countBucketSizes(size_t[], size_t[], size_t* freeSize) const; |
| 717 #endif |
| 715 | 718 |
| 716 // Returns a bucket number for inserting a FreeListEntry of a given size. | 719 // Returns a bucket number for inserting a FreeListEntry of a given size. |
| 717 // All FreeListEntries in the given bucket, n, have size >= 2^n. | 720 // All FreeListEntries in the given bucket, n, have size >= 2^n. |
| 718 static int bucketIndexForSize(size_t); | 721 static int bucketIndexForSize(size_t); |
| 719 | 722 |
| 720 private: | 723 private: |
| 721 int m_biggestFreeListIndex; | 724 int m_biggestFreeListIndex; |
| 722 | 725 |
| 723 // All FreeListEntries in the nth list have size >= 2^n. | 726 // All FreeListEntries in the nth list have size >= 2^n. |
| 724 FreeListEntry* m_freeLists[blinkPageSizeLog2]; | 727 FreeListEntry* m_freeLists[blinkPageSizeLog2]; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 735 // Each thread heap contains the functionality to allocate new objects | 738 // Each thread heap contains the functionality to allocate new objects |
| 736 // (potentially adding new pages to the heap), to find and mark | 739 // (potentially adding new pages to the heap), to find and mark |
| 737 // objects during conservative stack scanning and to sweep the set of | 740 // objects during conservative stack scanning and to sweep the set of |
| 738 // pages after a GC. | 741 // pages after a GC. |
| 739 class PLATFORM_EXPORT ThreadHeap final { | 742 class PLATFORM_EXPORT ThreadHeap final { |
| 740 public: | 743 public: |
| 741 ThreadHeap(ThreadState*, int); | 744 ThreadHeap(ThreadState*, int); |
| 742 ~ThreadHeap(); | 745 ~ThreadHeap(); |
| 743 void cleanupPages(); | 746 void cleanupPages(); |
| 744 | 747 |
| 745 #if ENABLE(ASSERT) | 748 #if ENABLE(ASSERT) || ENABLE(GC_PROFILE_MARKING) |
| 746 BaseHeapPage* findPageFromAddress(Address); | 749 BaseHeapPage* findPageFromAddress(Address); |
| 747 #endif | 750 #endif |
| 751 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 752 virtual void snapshotFreeList(TracedValue*); |
| 753 #endif |
| 748 #if ENABLE(GC_PROFILE_HEAP) | 754 #if ENABLE(GC_PROFILE_HEAP) |
| 749 void snapshot(TracedValue*, ThreadState::SnapshotInfo*); | 755 void snapshot(TracedValue*, ThreadState::SnapshotInfo*); |
| 750 #endif | 756 #endif |
| 751 | 757 |
| 752 void clearFreeLists(); | 758 void clearFreeLists(); |
| 753 void makeConsistentForSweeping(); | 759 void makeConsistentForSweeping(); |
| 754 #if ENABLE(ASSERT) | 760 #if ENABLE(ASSERT) |
| 755 bool isConsistentForSweeping(); | 761 bool isConsistentForSweeping(); |
| 756 #endif | 762 #endif |
| 757 size_t objectPayloadSizeForTesting(); | 763 size_t objectPayloadSizeForTesting(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 bool pagesToBeSweptContains(Address); | 810 bool pagesToBeSweptContains(Address); |
| 805 #endif | 811 #endif |
| 806 | 812 |
| 807 bool coalesce(); | 813 bool coalesce(); |
| 808 void preparePagesForSweeping(); | 814 void preparePagesForSweeping(); |
| 809 | 815 |
| 810 Address m_currentAllocationPoint; | 816 Address m_currentAllocationPoint; |
| 811 size_t m_remainingAllocationSize; | 817 size_t m_remainingAllocationSize; |
| 812 size_t m_lastRemainingAllocationSize; | 818 size_t m_lastRemainingAllocationSize; |
| 813 | 819 |
| 820 double m_totalAllocationSize; |
| 821 size_t m_allocationCount; |
| 822 size_t m_inlineAllocationCount; |
| 823 |
| 814 HeapPage* m_firstPage; | 824 HeapPage* m_firstPage; |
| 815 LargeObject* m_firstLargeObject; | 825 LargeObject* m_firstLargeObject; |
| 816 HeapPage* m_firstUnsweptPage; | 826 HeapPage* m_firstUnsweptPage; |
| 817 LargeObject* m_firstUnsweptLargeObject; | 827 LargeObject* m_firstUnsweptLargeObject; |
| 818 | 828 |
| 819 ThreadState* m_threadState; | 829 ThreadState* m_threadState; |
| 820 | 830 |
| 821 FreeList m_freeList; | 831 FreeList m_freeList; |
| 822 | 832 |
| 823 // Index into the page pools. This is used to ensure that the pages of the | 833 // Index into the page pools. This is used to ensure that the pages of the |
| 824 // same type go into the correct page pool and thus avoid type confusion. | 834 // same type go into the correct page pool and thus avoid type confusion. |
| 825 int m_index; | 835 int m_index; |
| 826 | 836 |
| 827 // The size of promptly freed objects in the heap. | 837 // The size of promptly freed objects in the heap. |
| 828 size_t m_promptlyFreedSize; | 838 size_t m_promptlyFreedSize; |
| 839 |
| 840 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 841 size_t m_allocationPointSizeSum = 0; |
| 842 size_t m_setAllocationPointCount = 0; |
| 843 #endif |
| 829 }; | 844 }; |
| 830 | 845 |
| 831 // Mask an address down to the enclosing oilpan heap base page. All oilpan heap | 846 // Mask an address down to the enclosing oilpan heap base page. All oilpan heap |
| 832 // pages are aligned at blinkPageBase plus an OS page size. | 847 // pages are aligned at blinkPageBase plus an OS page size. |
| 833 // FIXME: Remove PLATFORM_EXPORT once we get a proper public interface to our | 848 // FIXME: Remove PLATFORM_EXPORT once we get a proper public interface to our |
| 834 // typed heaps. This is only exported to enable tests in HeapTest.cpp. | 849 // typed heaps. This is only exported to enable tests in HeapTest.cpp. |
| 835 PLATFORM_EXPORT inline BaseHeapPage* pageFromObject(const void* object) | 850 PLATFORM_EXPORT inline BaseHeapPage* pageFromObject(const void* object) |
| 836 { | 851 { |
| 837 Address address = reinterpret_cast<Address>(const_cast<void*>(object)); | 852 Address address = reinterpret_cast<Address>(const_cast<void*>(object)); |
| 838 BaseHeapPage* page = reinterpret_cast<BaseHeapPage*>(blinkPageAddress(addres
s) + WTF::kSystemPageSize); | 853 BaseHeapPage* page = reinterpret_cast<BaseHeapPage*>(blinkPageAddress(addres
s) + WTF::kSystemPageSize); |
| 839 ASSERT(page->contains(address)); | 854 ASSERT(page->contains(address)); |
| 840 return page; | 855 return page; |
| 841 } | 856 } |
| 842 | 857 |
| 843 class PLATFORM_EXPORT Heap { | 858 class PLATFORM_EXPORT Heap { |
| 844 public: | 859 public: |
| 845 static void init(); | 860 static void init(); |
| 846 static void shutdown(); | 861 static void shutdown(); |
| 847 static void doShutdown(); | 862 static void doShutdown(); |
| 848 | 863 |
| 849 #if ENABLE(ASSERT) | 864 #if ENABLE(ASSERT) || ENABLE(GC_PROFILE_MARKING) |
| 850 static BaseHeapPage* findPageFromAddress(Address); | 865 static BaseHeapPage* findPageFromAddress(Address); |
| 851 static BaseHeapPage* findPageFromAddress(void* pointer) { return findPageFro
mAddress(reinterpret_cast<Address>(pointer)); } | 866 static BaseHeapPage* findPageFromAddress(void* pointer) { return findPageFro
mAddress(reinterpret_cast<Address>(pointer)); } |
| 852 static bool containedInHeapOrOrphanedPage(void*); | 867 static bool containedInHeapOrOrphanedPage(void*); |
| 853 #endif | 868 #endif |
| 854 | 869 |
| 855 // Is the finalizable GC object still alive, but slated for lazy sweeping? | 870 // Is the finalizable GC object still alive, but slated for lazy sweeping? |
| 856 // If a lazy sweep is in progress, returns true if the object was found | 871 // If a lazy sweep is in progress, returns true if the object was found |
| 857 // to be not reachable during the marking phase, but it has yet to be swept | 872 // to be not reachable during the marking phase, but it has yet to be swept |
| 858 // and finalized. The predicate returns false in all other cases. | 873 // and finalized. The predicate returns false in all other cases. |
| 859 // | 874 // |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 static void collectAllGarbage(); | 945 static void collectAllGarbage(); |
| 931 | 946 |
| 932 static void processMarkingStack(Visitor*); | 947 static void processMarkingStack(Visitor*); |
| 933 static void postMarkingProcessing(Visitor*); | 948 static void postMarkingProcessing(Visitor*); |
| 934 static void globalWeakProcessing(Visitor*); | 949 static void globalWeakProcessing(Visitor*); |
| 935 static void setForcePreciseGCForTesting(); | 950 static void setForcePreciseGCForTesting(); |
| 936 | 951 |
| 937 static void preGC(); | 952 static void preGC(); |
| 938 static void postGC(ThreadState::GCType); | 953 static void postGC(ThreadState::GCType); |
| 939 | 954 |
| 955 static void reportSweepingStats(); |
| 956 |
| 940 // Conservatively checks whether an address is a pointer in any of the | 957 // Conservatively checks whether an address is a pointer in any of the |
| 941 // thread heaps. If so marks the object pointed to as live. | 958 // thread heaps. If so marks the object pointed to as live. |
| 942 static Address checkAndMarkPointer(Visitor*, Address); | 959 static Address checkAndMarkPointer(Visitor*, Address); |
| 943 | 960 |
| 944 #if ENABLE(GC_PROFILE_MARKING) | 961 #if ENABLE(GC_PROFILE_MARKING) |
| 945 // Dump the path to specified object on the next GC. This method is to be | 962 // Dump the path to specified object on the next GC. This method is to be |
| 946 // invoked from GDB. | 963 // invoked from GDB. |
| 947 static void dumpPathToObjectOnNextGC(void* p); | 964 static void dumpPathToObjectOnNextGC(void* p); |
| 948 | 965 |
| 949 // Forcibly find GCInfo of the object at Address. This is slow and should | 966 // Forcibly find GCInfo of the object at Address. This is slow and should |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1337 | 1354 |
| 1338 // Add space for header. | 1355 // Add space for header. |
| 1339 size_t allocationSize = size + sizeof(HeapObjectHeader); | 1356 size_t allocationSize = size + sizeof(HeapObjectHeader); |
| 1340 // Align size with allocation granularity. | 1357 // Align size with allocation granularity. |
| 1341 allocationSize = (allocationSize + allocationMask) & ~allocationMask; | 1358 allocationSize = (allocationSize + allocationMask) & ~allocationMask; |
| 1342 return allocationSize; | 1359 return allocationSize; |
| 1343 } | 1360 } |
| 1344 | 1361 |
| 1345 Address ThreadHeap::allocateObject(size_t allocationSize, size_t gcInfoIndex) | 1362 Address ThreadHeap::allocateObject(size_t allocationSize, size_t gcInfoIndex) |
| 1346 { | 1363 { |
| 1364 m_totalAllocationSize += allocationSize; |
| 1365 m_allocationCount++; |
| 1347 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { | 1366 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { |
| 1367 m_inlineAllocationCount++; |
| 1348 Address headerAddress = m_currentAllocationPoint; | 1368 Address headerAddress = m_currentAllocationPoint; |
| 1349 m_currentAllocationPoint += allocationSize; | 1369 m_currentAllocationPoint += allocationSize; |
| 1350 m_remainingAllocationSize -= allocationSize; | 1370 m_remainingAllocationSize -= allocationSize; |
| 1351 ASSERT(gcInfoIndex > 0); | 1371 ASSERT(gcInfoIndex > 0); |
| 1352 new (NotNull, headerAddress) HeapObjectHeader(allocationSize, gcInfoInde
x); | 1372 new (NotNull, headerAddress) HeapObjectHeader(allocationSize, gcInfoInde
x); |
| 1353 Address result = headerAddress + sizeof(HeapObjectHeader); | 1373 Address result = headerAddress + sizeof(HeapObjectHeader); |
| 1354 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); | 1374 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); |
| 1355 | 1375 |
| 1356 // Unpoison the memory used for the object (payload). | 1376 // Unpoison the memory used for the object (payload). |
| 1357 ASAN_UNPOISON_MEMORY_REGION(result, allocationSize - sizeof(HeapObjectHe
ader)); | 1377 ASAN_UNPOISON_MEMORY_REGION(result, allocationSize - sizeof(HeapObjectHe
ader)); |
| (...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2434 template<typename T, size_t inlineCapacity> | 2454 template<typename T, size_t inlineCapacity> |
| 2435 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2455 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
| 2436 template<typename T, size_t inlineCapacity> | 2456 template<typename T, size_t inlineCapacity> |
| 2437 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2457 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
| 2438 template<typename T, typename U, typename V> | 2458 template<typename T, typename U, typename V> |
| 2439 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2459 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
| 2440 | 2460 |
| 2441 } // namespace blink | 2461 } // namespace blink |
| 2442 | 2462 |
| 2443 #endif // Heap_h | 2463 #endif // Heap_h |
| OLD | NEW |