| 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 #endif | 118 #endif |
| 119 | 119 |
| 120 #if !ENABLE(ASSERT) && CPU(64BIT) | 120 #if !ENABLE(ASSERT) && CPU(64BIT) |
| 121 #define USE_4BYTE_HEADER_PADDING 1 | 121 #define USE_4BYTE_HEADER_PADDING 1 |
| 122 #else | 122 #else |
| 123 #define USE_4BYTE_HEADER_PADDING 0 | 123 #define USE_4BYTE_HEADER_PADDING 0 |
| 124 #endif | 124 #endif |
| 125 | 125 |
| 126 class CallbackStack; | 126 class CallbackStack; |
| 127 class FreePagePool; | 127 class FreePagePool; |
| 128 class NormalPageHeap; | 128 class NormalPageArena; |
| 129 class OrphanedPagePool; | 129 class OrphanedPagePool; |
| 130 class PageMemory; | 130 class PageMemory; |
| 131 class PageMemoryRegion; | 131 class PageMemoryRegion; |
| 132 class WebMemoryAllocatorDump; | 132 class WebMemoryAllocatorDump; |
| 133 | 133 |
| 134 // HeapObjectHeader is 4 byte (32 bit) that has the following layout: | 134 // HeapObjectHeader is 4 byte (32 bit) that has the following layout: |
| 135 // | 135 // |
| 136 // | gcInfoIndex (14 bit) | DOM mark bit (1 bit) | size (14 bit) | dead bit (1 b
it) | freed bit (1 bit) | mark bit (1 bit) | | 136 // | gcInfoIndex (14 bit) | DOM mark bit (1 bit) | size (14 bit) | dead bit (1 b
it) | freed bit (1 bit) | mark bit (1 bit) | |
| 137 // | 137 // |
| 138 // - For non-large objects, 14 bit is enough for |size| because the blink | 138 // - For non-large objects, 14 bit is enough for |size| because the blink |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 size_t size() override { return blinkPageSize; } | 485 size_t size() override { return blinkPageSize; } |
| 486 static size_t pageHeaderSize() | 486 static size_t pageHeaderSize() |
| 487 { | 487 { |
| 488 // Compute the amount of padding we have to add to a header to make | 488 // Compute the amount of padding we have to add to a header to make |
| 489 // the size of the header plus the padding a multiple of 8 bytes. | 489 // the size of the header plus the padding a multiple of 8 bytes. |
| 490 size_t paddingSize = (sizeof(NormalPage) + allocationGranularity - (size
of(HeapObjectHeader) % allocationGranularity)) % allocationGranularity; | 490 size_t paddingSize = (sizeof(NormalPage) + allocationGranularity - (size
of(HeapObjectHeader) % allocationGranularity)) % allocationGranularity; |
| 491 return sizeof(NormalPage) + paddingSize; | 491 return sizeof(NormalPage) + paddingSize; |
| 492 } | 492 } |
| 493 | 493 |
| 494 | 494 |
| 495 NormalPageHeap* arenaForNormalPage(); | 495 NormalPageArena* arenaForNormalPage(); |
| 496 | 496 |
| 497 private: | 497 private: |
| 498 HeapObjectHeader* findHeaderFromAddress(Address); | 498 HeapObjectHeader* findHeaderFromAddress(Address); |
| 499 void populateObjectStartBitMap(); | 499 void populateObjectStartBitMap(); |
| 500 | 500 |
| 501 bool m_objectStartBitMapComputed; | 501 bool m_objectStartBitMapComputed; |
| 502 uint8_t m_objectStartBitMap[reservedForObjectBitMap]; | 502 uint8_t m_objectStartBitMap[reservedForObjectBitMap]; |
| 503 }; | 503 }; |
| 504 | 504 |
| 505 // Large allocations are allocated as separate objects and linked in a list. | 505 // Large allocations are allocated as separate objects and linked in a list. |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 static void zapFreedMemory(Address, size_t); | 639 static void zapFreedMemory(Address, size_t); |
| 640 static void checkFreedMemoryIsZapped(Address, size_t); | 640 static void checkFreedMemoryIsZapped(Address, size_t); |
| 641 #endif | 641 #endif |
| 642 | 642 |
| 643 private: | 643 private: |
| 644 int m_biggestFreeListIndex; | 644 int m_biggestFreeListIndex; |
| 645 | 645 |
| 646 // All FreeListEntries in the nth list have size >= 2^n. | 646 // All FreeListEntries in the nth list have size >= 2^n. |
| 647 FreeListEntry* m_freeLists[blinkPageSizeLog2]; | 647 FreeListEntry* m_freeLists[blinkPageSizeLog2]; |
| 648 | 648 |
| 649 friend class NormalPageHeap; | 649 friend class NormalPageArena; |
| 650 }; | 650 }; |
| 651 | 651 |
| 652 // Each thread has a number of thread arenas (e.g., Generic arenas, | 652 // Each thread has a number of thread arenas (e.g., Generic arenas, |
| 653 // typed arenas for Node, arenas for collection backings etc) | 653 // typed arenas for Node, arenas for collection backings etc) |
| 654 // and BaseArena represents each thread heap. | 654 // and BaseArena represents each thread arena. |
| 655 // | 655 // |
| 656 // BaseArena is a parent class of NormalPageHeap and LargeObjectHeap. | 656 // BaseArena is a parent class of NormalPageArena and LargeObjectArena. |
| 657 // NormalPageHeap represents a heap that contains NormalPages | 657 // NormalPageArena represents a part of a heap that contains NormalPages |
| 658 // and LargeObjectHeap represents a heap that contains LargeObjectPages. | 658 // and LargeObjectArena represents a part of a heap that contains |
| 659 // LargeObjectPages. |
| 659 class PLATFORM_EXPORT BaseArena { | 660 class PLATFORM_EXPORT BaseArena { |
| 660 USING_FAST_MALLOC(BaseArena); | 661 USING_FAST_MALLOC(BaseArena); |
| 661 public: | 662 public: |
| 662 BaseArena(ThreadState*, int); | 663 BaseArena(ThreadState*, int); |
| 663 virtual ~BaseArena(); | 664 virtual ~BaseArena(); |
| 664 void cleanupPages(); | 665 void cleanupPages(); |
| 665 | 666 |
| 666 void takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotInfo&); | 667 void takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotInfo&); |
| 667 #if ENABLE(ASSERT) | 668 #if ENABLE(ASSERT) |
| 668 BasePage* findPageFromAddress(Address); | 669 BasePage* findPageFromAddress(Address); |
| 669 #endif | 670 #endif |
| 670 virtual void takeFreelistSnapshot(const String& dumpBaseName) { } | 671 virtual void takeFreelistSnapshot(const String& dumpBaseName) { } |
| 671 virtual void clearFreeLists() { } | 672 virtual void clearFreeLists() { } |
| 672 void makeConsistentForGC(); | 673 void makeConsistentForGC(); |
| 673 void makeConsistentForMutator(); | 674 void makeConsistentForMutator(); |
| 674 #if ENABLE(ASSERT) | 675 #if ENABLE(ASSERT) |
| 675 virtual bool isConsistentForGC() = 0; | 676 virtual bool isConsistentForGC() = 0; |
| 676 #endif | 677 #endif |
| 677 size_t objectPayloadSizeForTesting(); | 678 size_t objectPayloadSizeForTesting(); |
| 678 void prepareHeapForTermination(); | 679 void prepareHeapForTermination(); |
| 679 void prepareForSweep(); | 680 void prepareForSweep(); |
| 680 #if defined(ADDRESS_SANITIZER) | 681 #if defined(ADDRESS_SANITIZER) |
| 681 void poisonHeap(BlinkGC::ObjectsToPoison, BlinkGC::Poisoning); | 682 void poisonArena(BlinkGC::ObjectsToPoison, BlinkGC::Poisoning); |
| 682 #endif | 683 #endif |
| 683 Address lazySweep(size_t, size_t gcInfoIndex); | 684 Address lazySweep(size_t, size_t gcInfoIndex); |
| 684 void sweepUnsweptPage(); | 685 void sweepUnsweptPage(); |
| 685 // Returns true if we have swept all pages within the deadline. | 686 // Returns true if we have swept all pages within the deadline. |
| 686 // Returns false otherwise. | 687 // Returns false otherwise. |
| 687 bool lazySweepWithDeadline(double deadlineSeconds); | 688 bool lazySweepWithDeadline(double deadlineSeconds); |
| 688 void completeSweep(); | 689 void completeSweep(); |
| 689 | 690 |
| 690 ThreadState* threadState() { return m_threadState; } | 691 ThreadState* threadState() { return m_threadState; } |
| 691 int arenaIndex() const { return m_index; } | 692 int arenaIndex() const { return m_index; } |
| 692 | 693 |
| 693 protected: | 694 protected: |
| 694 BasePage* m_firstPage; | 695 BasePage* m_firstPage; |
| 695 BasePage* m_firstUnsweptPage; | 696 BasePage* m_firstUnsweptPage; |
| 696 | 697 |
| 697 private: | 698 private: |
| 698 virtual Address lazySweepPages(size_t, size_t gcInfoIndex) = 0; | 699 virtual Address lazySweepPages(size_t, size_t gcInfoIndex) = 0; |
| 699 | 700 |
| 700 ThreadState* m_threadState; | 701 ThreadState* m_threadState; |
| 701 | 702 |
| 702 // Index into the page pools. This is used to ensure that the pages of the | 703 // Index into the page pools. This is used to ensure that the pages of the |
| 703 // same type go into the correct page pool and thus avoid type confusion. | 704 // same type go into the correct page pool and thus avoid type confusion. |
| 704 int m_index; | 705 int m_index; |
| 705 }; | 706 }; |
| 706 | 707 |
| 707 class PLATFORM_EXPORT NormalPageHeap final : public BaseArena { | 708 class PLATFORM_EXPORT NormalPageArena final : public BaseArena { |
| 708 public: | 709 public: |
| 709 NormalPageHeap(ThreadState*, int); | 710 NormalPageArena(ThreadState*, int); |
| 710 void addToFreeList(Address address, size_t size) | 711 void addToFreeList(Address address, size_t size) |
| 711 { | 712 { |
| 712 ASSERT(findPageFromAddress(address)); | 713 ASSERT(findPageFromAddress(address)); |
| 713 ASSERT(findPageFromAddress(address + size - 1)); | 714 ASSERT(findPageFromAddress(address + size - 1)); |
| 714 m_freeList.addToFreeList(address, size); | 715 m_freeList.addToFreeList(address, size); |
| 715 } | 716 } |
| 716 void clearFreeLists() override; | 717 void clearFreeLists() override; |
| 717 #if ENABLE(ASSERT) | 718 #if ENABLE(ASSERT) |
| 718 bool isConsistentForGC() override; | 719 bool isConsistentForGC() override; |
| 719 bool pagesToBeSweptContains(Address); | 720 bool pagesToBeSweptContains(Address); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 752 | 753 |
| 753 FreeList m_freeList; | 754 FreeList m_freeList; |
| 754 Address m_currentAllocationPoint; | 755 Address m_currentAllocationPoint; |
| 755 size_t m_remainingAllocationSize; | 756 size_t m_remainingAllocationSize; |
| 756 size_t m_lastRemainingAllocationSize; | 757 size_t m_lastRemainingAllocationSize; |
| 757 | 758 |
| 758 // The size of promptly freed objects in the heap. | 759 // The size of promptly freed objects in the heap. |
| 759 size_t m_promptlyFreedSize; | 760 size_t m_promptlyFreedSize; |
| 760 }; | 761 }; |
| 761 | 762 |
| 762 class LargeObjectHeap final : public BaseArena { | 763 class LargeObjectArena final : public BaseArena { |
| 763 public: | 764 public: |
| 764 LargeObjectHeap(ThreadState*, int); | 765 LargeObjectArena(ThreadState*, int); |
| 765 Address allocateLargeObjectPage(size_t, size_t gcInfoIndex); | 766 Address allocateLargeObjectPage(size_t, size_t gcInfoIndex); |
| 766 void freeLargeObjectPage(LargeObjectPage*); | 767 void freeLargeObjectPage(LargeObjectPage*); |
| 767 #if ENABLE(ASSERT) | 768 #if ENABLE(ASSERT) |
| 768 bool isConsistentForGC() override { return true; } | 769 bool isConsistentForGC() override { return true; } |
| 769 #endif | 770 #endif |
| 770 private: | 771 private: |
| 771 Address doAllocateLargeObjectPage(size_t, size_t gcInfoIndex); | 772 Address doAllocateLargeObjectPage(size_t, size_t gcInfoIndex); |
| 772 Address lazySweepPages(size_t, size_t gcInfoIndex) override; | 773 Address lazySweepPages(size_t, size_t gcInfoIndex) override; |
| 773 }; | 774 }; |
| 774 | 775 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 } | 866 } |
| 866 | 867 |
| 867 NO_SANITIZE_ADDRESS inline | 868 NO_SANITIZE_ADDRESS inline |
| 868 void HeapObjectHeader::markDead() | 869 void HeapObjectHeader::markDead() |
| 869 { | 870 { |
| 870 ASSERT(checkHeader()); | 871 ASSERT(checkHeader()); |
| 871 ASSERT(!isMarked()); | 872 ASSERT(!isMarked()); |
| 872 m_encoded |= headerDeadBitMask; | 873 m_encoded |= headerDeadBitMask; |
| 873 } | 874 } |
| 874 | 875 |
| 875 inline Address NormalPageHeap::allocateObject(size_t allocationSize, size_t gcIn
foIndex) | 876 inline Address NormalPageArena::allocateObject(size_t allocationSize, size_t gcI
nfoIndex) |
| 876 { | 877 { |
| 877 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { | 878 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { |
| 878 Address headerAddress = m_currentAllocationPoint; | 879 Address headerAddress = m_currentAllocationPoint; |
| 879 m_currentAllocationPoint += allocationSize; | 880 m_currentAllocationPoint += allocationSize; |
| 880 m_remainingAllocationSize -= allocationSize; | 881 m_remainingAllocationSize -= allocationSize; |
| 881 ASSERT(gcInfoIndex > 0); | 882 ASSERT(gcInfoIndex > 0); |
| 882 new (NotNull, headerAddress) HeapObjectHeader(allocationSize, gcInfoInde
x); | 883 new (NotNull, headerAddress) HeapObjectHeader(allocationSize, gcInfoInde
x); |
| 883 Address result = headerAddress + sizeof(HeapObjectHeader); | 884 Address result = headerAddress + sizeof(HeapObjectHeader); |
| 884 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); | 885 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); |
| 885 | 886 |
| 886 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader))
; | 887 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader))
; |
| 887 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); | 888 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); |
| 888 return result; | 889 return result; |
| 889 } | 890 } |
| 890 return outOfLineAllocate(allocationSize, gcInfoIndex); | 891 return outOfLineAllocate(allocationSize, gcInfoIndex); |
| 891 } | 892 } |
| 892 | 893 |
| 893 } // namespace blink | 894 } // namespace blink |
| 894 | 895 |
| 895 #endif // HeapPage_h | 896 #endif // HeapPage_h |
| OLD | NEW |