| 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 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 #ifndef HeapPage_h | 31 #ifndef HeapPage_h |
| 32 #define HeapPage_h | 32 #define HeapPage_h |
| 33 | 33 |
| 34 #include "platform/PlatformExport.h" | 34 #include "platform/PlatformExport.h" |
| 35 #include "platform/heap/BlinkGC.h" | 35 #include "platform/heap/BlinkGC.h" |
| 36 #include "platform/heap/GCInfo.h" | 36 #include "platform/heap/GCInfo.h" |
| 37 #include "platform/heap/ThreadState.h" | 37 #include "platform/heap/ThreadState.h" |
| 38 #include "platform/heap/Visitor.h" | 38 #include "platform/heap/Visitor.h" |
| 39 #include "wtf/AddressSanitizer.h" | 39 #include "wtf/AddressSanitizer.h" |
| 40 #include "wtf/Allocator.h" |
| 40 #include "wtf/Assertions.h" | 41 #include "wtf/Assertions.h" |
| 41 #include "wtf/Atomics.h" | 42 #include "wtf/Atomics.h" |
| 42 #include "wtf/ContainerAnnotations.h" | 43 #include "wtf/ContainerAnnotations.h" |
| 43 #include "wtf/Forward.h" | 44 #include "wtf/Forward.h" |
| 44 #include "wtf/PageAllocator.h" | 45 #include "wtf/PageAllocator.h" |
| 45 #include <stdint.h> | 46 #include <stdint.h> |
| 46 | 47 |
| 47 namespace blink { | 48 namespace blink { |
| 48 | 49 |
| 49 const size_t blinkPageSizeLog2 = 17; | 50 const size_t blinkPageSizeLog2 = 17; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 // On free-list entries we reuse the dead bit to distinguish a normal free-list | 159 // On free-list entries we reuse the dead bit to distinguish a normal free-list |
| 159 // entry from one that has been promptly freed. | 160 // entry from one that has been promptly freed. |
| 160 const size_t headerPromptlyFreedBitMask = headerFreedBitMask | headerDeadBitMask
; | 161 const size_t headerPromptlyFreedBitMask = headerFreedBitMask | headerDeadBitMask
; |
| 161 const size_t largeObjectSizeInHeader = 0; | 162 const size_t largeObjectSizeInHeader = 0; |
| 162 const size_t gcInfoIndexForFreeListHeader = 0; | 163 const size_t gcInfoIndexForFreeListHeader = 0; |
| 163 const size_t nonLargeObjectPageSizeMax = 1 << 17; | 164 const size_t nonLargeObjectPageSizeMax = 1 << 17; |
| 164 | 165 |
| 165 static_assert(nonLargeObjectPageSizeMax >= blinkPageSize, "max size supported by
HeapObjectHeader must at least be blinkPageSize"); | 166 static_assert(nonLargeObjectPageSizeMax >= blinkPageSize, "max size supported by
HeapObjectHeader must at least be blinkPageSize"); |
| 166 | 167 |
| 167 class PLATFORM_EXPORT HeapObjectHeader { | 168 class PLATFORM_EXPORT HeapObjectHeader { |
| 169 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
| 168 public: | 170 public: |
| 169 // If gcInfoIndex is 0, this header is interpreted as a free list header. | 171 // If gcInfoIndex is 0, this header is interpreted as a free list header. |
| 170 NO_SANITIZE_ADDRESS | 172 NO_SANITIZE_ADDRESS |
| 171 HeapObjectHeader(size_t size, size_t gcInfoIndex) | 173 HeapObjectHeader(size_t size, size_t gcInfoIndex) |
| 172 { | 174 { |
| 173 #if ENABLE(ASSERT) | 175 #if ENABLE(ASSERT) |
| 174 m_magic = magic; | 176 m_magic = magic; |
| 175 #endif | 177 #endif |
| 176 // sizeof(HeapObjectHeader) must be equal to or smaller than | 178 // sizeof(HeapObjectHeader) must be equal to or smaller than |
| 177 // allocationGranurarity, because HeapObjectHeader is used as a header | 179 // allocationGranurarity, because HeapObjectHeader is used as a header |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 // multiple objects in the page. An object whose size is smaller than | 343 // multiple objects in the page. An object whose size is smaller than |
| 342 // |largeObjectSizeThreshold| is stored in NormalPage. | 344 // |largeObjectSizeThreshold| is stored in NormalPage. |
| 343 // | 345 // |
| 344 // - LargeObjectPage is a page that contains only one object. The object size | 346 // - LargeObjectPage is a page that contains only one object. The object size |
| 345 // is arbitrary. An object whose size is larger than |blinkPageSize| is stored | 347 // is arbitrary. An object whose size is larger than |blinkPageSize| is stored |
| 346 // as a single project in LargeObjectPage. | 348 // as a single project in LargeObjectPage. |
| 347 // | 349 // |
| 348 // Note: An object whose size is between |largeObjectSizeThreshold| and | 350 // Note: An object whose size is between |largeObjectSizeThreshold| and |
| 349 // |blinkPageSize| can go to either of NormalPage or LargeObjectPage. | 351 // |blinkPageSize| can go to either of NormalPage or LargeObjectPage. |
| 350 class BasePage { | 352 class BasePage { |
| 353 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
| 351 public: | 354 public: |
| 352 BasePage(PageMemory*, BaseHeap*); | 355 BasePage(PageMemory*, BaseHeap*); |
| 353 virtual ~BasePage() { } | 356 virtual ~BasePage() { } |
| 354 | 357 |
| 355 void link(BasePage** previousNext) | 358 void link(BasePage** previousNext) |
| 356 { | 359 { |
| 357 m_next = *previousNext; | 360 m_next = *previousNext; |
| 358 *previousNext = this; | 361 *previousNext = this; |
| 359 } | 362 } |
| 360 void unlink(BasePage** previousNext) | 363 void unlink(BasePage** previousNext) |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 // is a cache of 'pages' that have previously been determined to be wholly | 570 // is a cache of 'pages' that have previously been determined to be wholly |
| 568 // outside of the heap. The size of these pages must be smaller than the | 571 // outside of the heap. The size of these pages must be smaller than the |
| 569 // allocation alignment of the heap pages. We determine off-heap-ness by | 572 // allocation alignment of the heap pages. We determine off-heap-ness by |
| 570 // rounding down the pointer to the nearest page and looking up the page in the | 573 // rounding down the pointer to the nearest page and looking up the page in the |
| 571 // cache. If there is a miss in the cache we can determine the status of the | 574 // cache. If there is a miss in the cache we can determine the status of the |
| 572 // pointer precisely using the heap RegionTree. | 575 // pointer precisely using the heap RegionTree. |
| 573 // | 576 // |
| 574 // The HeapDoesNotContainCache is a negative cache, so it must be flushed when | 577 // The HeapDoesNotContainCache is a negative cache, so it must be flushed when |
| 575 // memory is added to the heap. | 578 // memory is added to the heap. |
| 576 class HeapDoesNotContainCache { | 579 class HeapDoesNotContainCache { |
| 580 USING_FAST_MALLOC(HeapDoesNotContainCache); |
| 577 public: | 581 public: |
| 578 HeapDoesNotContainCache() | 582 HeapDoesNotContainCache() |
| 579 : m_entries(adoptArrayPtr(new Address[HeapDoesNotContainCache::numberOfE
ntries])) | 583 : m_hasEntries(false) |
| 580 , m_hasEntries(false) | |
| 581 { | 584 { |
| 582 // Start by flushing the cache in a non-empty state to initialize all th
e cache entries. | 585 // Start by flushing the cache in a non-empty state to initialize all th
e cache entries. |
| 583 for (int i = 0; i < numberOfEntries; ++i) | 586 for (int i = 0; i < numberOfEntries; ++i) |
| 584 m_entries[i] = nullptr; | 587 m_entries[i] = nullptr; |
| 585 } | 588 } |
| 586 | 589 |
| 587 void flush(); | 590 void flush(); |
| 588 bool isEmpty() { return !m_hasEntries; } | 591 bool isEmpty() { return !m_hasEntries; } |
| 589 | 592 |
| 590 // Perform a lookup in the cache. | 593 // Perform a lookup in the cache. |
| 591 // | 594 // |
| 592 // If lookup returns false, the argument address was not found in | 595 // If lookup returns false, the argument address was not found in |
| 593 // the cache and it is unknown if the address is in the Blink | 596 // the cache and it is unknown if the address is in the Blink |
| 594 // heap. | 597 // heap. |
| 595 // | 598 // |
| 596 // If lookup returns true, the argument address was found in the | 599 // If lookup returns true, the argument address was found in the |
| 597 // cache which means the address is not in the heap. | 600 // cache which means the address is not in the heap. |
| 598 PLATFORM_EXPORT bool lookup(Address); | 601 PLATFORM_EXPORT bool lookup(Address); |
| 599 | 602 |
| 600 // Add an entry to the cache. | 603 // Add an entry to the cache. |
| 601 PLATFORM_EXPORT void addEntry(Address); | 604 PLATFORM_EXPORT void addEntry(Address); |
| 602 | 605 |
| 603 private: | 606 private: |
| 604 static const int numberOfEntriesLog2 = 12; | 607 static const int numberOfEntriesLog2 = 12; |
| 605 static const int numberOfEntries = 1 << numberOfEntriesLog2; | 608 static const int numberOfEntries = 1 << numberOfEntriesLog2; |
| 606 | 609 |
| 607 static size_t hash(Address); | 610 static size_t hash(Address); |
| 608 | 611 |
| 609 WTF::OwnPtr<Address[]> m_entries; | 612 Address m_entries[numberOfEntries]; |
| 610 bool m_hasEntries; | 613 bool m_hasEntries; |
| 611 }; | 614 }; |
| 612 | 615 |
| 613 class FreeList { | 616 class FreeList { |
| 617 DISALLOW_NEW(); |
| 614 public: | 618 public: |
| 615 FreeList(); | 619 FreeList(); |
| 616 | 620 |
| 617 void addToFreeList(Address, size_t); | 621 void addToFreeList(Address, size_t); |
| 618 void clear(); | 622 void clear(); |
| 619 | 623 |
| 620 // Returns a bucket number for inserting a FreeListEntry of a given size. | 624 // Returns a bucket number for inserting a FreeListEntry of a given size. |
| 621 // All FreeListEntries in the given bucket, n, have size >= 2^n. | 625 // All FreeListEntries in the given bucket, n, have size >= 2^n. |
| 622 static int bucketIndexForSize(size_t); | 626 static int bucketIndexForSize(size_t); |
| 623 | 627 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 639 }; | 643 }; |
| 640 | 644 |
| 641 // Each thread has a number of thread heaps (e.g., Generic heaps, | 645 // Each thread has a number of thread heaps (e.g., Generic heaps, |
| 642 // typed heaps for Node, heaps for collection backings etc) | 646 // typed heaps for Node, heaps for collection backings etc) |
| 643 // and BaseHeap represents each thread heap. | 647 // and BaseHeap represents each thread heap. |
| 644 // | 648 // |
| 645 // BaseHeap is a parent class of NormalPageHeap and LargeObjectHeap. | 649 // BaseHeap is a parent class of NormalPageHeap and LargeObjectHeap. |
| 646 // NormalPageHeap represents a heap that contains NormalPages | 650 // NormalPageHeap represents a heap that contains NormalPages |
| 647 // and LargeObjectHeap represents a heap that contains LargeObjectPages. | 651 // and LargeObjectHeap represents a heap that contains LargeObjectPages. |
| 648 class PLATFORM_EXPORT BaseHeap { | 652 class PLATFORM_EXPORT BaseHeap { |
| 653 USING_FAST_MALLOC(BaseHeap); |
| 649 public: | 654 public: |
| 650 BaseHeap(ThreadState*, int); | 655 BaseHeap(ThreadState*, int); |
| 651 virtual ~BaseHeap(); | 656 virtual ~BaseHeap(); |
| 652 void cleanupPages(); | 657 void cleanupPages(); |
| 653 | 658 |
| 654 void takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotInfo&); | 659 void takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotInfo&); |
| 655 #if ENABLE(ASSERT) | 660 #if ENABLE(ASSERT) |
| 656 BasePage* findPageFromAddress(Address); | 661 BasePage* findPageFromAddress(Address); |
| 657 #endif | 662 #endif |
| 658 virtual void takeFreelistSnapshot(const String& dumpBaseName) { } | 663 virtual void takeFreelistSnapshot(const String& dumpBaseName) { } |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader))
; | 879 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader))
; |
| 875 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); | 880 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); |
| 876 return result; | 881 return result; |
| 877 } | 882 } |
| 878 return outOfLineAllocate(allocationSize, gcInfoIndex); | 883 return outOfLineAllocate(allocationSize, gcInfoIndex); |
| 879 } | 884 } |
| 880 | 885 |
| 881 } // namespace blink | 886 } // namespace blink |
| 882 | 887 |
| 883 #endif // HeapPage_h | 888 #endif // HeapPage_h |
| OLD | NEW |