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 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 static HeapDoesNotContainCache* create() |
| 579 : m_entries(adoptArrayPtr(new Address[HeapDoesNotContainCache::numberOfE ntries])) | |
| 580 , m_hasEntries(false) | |
| 581 { | 583 { |
| 582 // Start by flushing the cache in a non-empty state to initialize all th e cache entries. | 584 size_t size = sizeof(HeapDoesNotContainCache) + sizeof(Address) * HeapDo esNotContainCache::numberOfEntries; |
|
haraken
2016/01/20 10:52:27
Can we use a Vector?
tasak
2016/01/21 04:37:46
Yes... but I think, it's too much, because m_entri
haraken
2016/01/21 04:52:57
Then can we write something like:
class HeapDoesN
tasak
2016/01/26 02:54:45
I see. Sure. Done.
| |
| 583 for (int i = 0; i < numberOfEntries; ++i) | 585 HeapDoesNotContainCache* cache = static_cast<HeapDoesNotContainCache*>(W TF::Partitions::fastMalloc(size, "HeapDoesNotContainCache")); |
| 584 m_entries[i] = nullptr; | 586 return new (cache) HeapDoesNotContainCache(reinterpret_cast<Address*>(ca che + 1)); |
| 585 } | 587 } |
| 586 | 588 |
| 587 void flush(); | 589 void flush(); |
| 588 bool isEmpty() { return !m_hasEntries; } | 590 bool isEmpty() { return !m_hasEntries; } |
| 589 | 591 |
| 590 // Perform a lookup in the cache. | 592 // Perform a lookup in the cache. |
| 591 // | 593 // |
| 592 // If lookup returns false, the argument address was not found in | 594 // 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 | 595 // the cache and it is unknown if the address is in the Blink |
| 594 // heap. | 596 // heap. |
| 595 // | 597 // |
| 596 // If lookup returns true, the argument address was found in the | 598 // If lookup returns true, the argument address was found in the |
| 597 // cache which means the address is not in the heap. | 599 // cache which means the address is not in the heap. |
| 598 PLATFORM_EXPORT bool lookup(Address); | 600 PLATFORM_EXPORT bool lookup(Address); |
| 599 | 601 |
| 600 // Add an entry to the cache. | 602 // Add an entry to the cache. |
| 601 PLATFORM_EXPORT void addEntry(Address); | 603 PLATFORM_EXPORT void addEntry(Address); |
| 602 | 604 |
| 603 private: | 605 private: |
| 606 HeapDoesNotContainCache() = delete; | |
| 607 HeapDoesNotContainCache(Address* entries) | |
| 608 : m_entries(entries) | |
| 609 , m_hasEntries(false) | |
| 610 { | |
| 611 // Start by flushing the cache in a non-empty state to initialize all th e cache entries. | |
| 612 for (int i = 0; i < numberOfEntries; ++i) | |
| 613 m_entries[i] = nullptr; | |
| 614 } | |
| 615 | |
| 604 static const int numberOfEntriesLog2 = 12; | 616 static const int numberOfEntriesLog2 = 12; |
| 605 static const int numberOfEntries = 1 << numberOfEntriesLog2; | 617 static const int numberOfEntries = 1 << numberOfEntriesLog2; |
| 606 | 618 |
| 607 static size_t hash(Address); | 619 static size_t hash(Address); |
| 608 | 620 |
| 609 WTF::OwnPtr<Address[]> m_entries; | 621 Address* m_entries; |
| 610 bool m_hasEntries; | 622 bool m_hasEntries; |
| 611 }; | 623 }; |
| 612 | 624 |
| 613 class FreeList { | 625 class FreeList { |
| 626 DISALLOW_NEW(); | |
| 614 public: | 627 public: |
| 615 FreeList(); | 628 FreeList(); |
| 616 | 629 |
| 617 void addToFreeList(Address, size_t); | 630 void addToFreeList(Address, size_t); |
| 618 void clear(); | 631 void clear(); |
| 619 | 632 |
| 620 // Returns a bucket number for inserting a FreeListEntry of a given size. | 633 // Returns a bucket number for inserting a FreeListEntry of a given size. |
| 621 // All FreeListEntries in the given bucket, n, have size >= 2^n. | 634 // All FreeListEntries in the given bucket, n, have size >= 2^n. |
| 622 static int bucketIndexForSize(size_t); | 635 static int bucketIndexForSize(size_t); |
| 623 | 636 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 639 }; | 652 }; |
| 640 | 653 |
| 641 // Each thread has a number of thread heaps (e.g., Generic heaps, | 654 // Each thread has a number of thread heaps (e.g., Generic heaps, |
| 642 // typed heaps for Node, heaps for collection backings etc) | 655 // typed heaps for Node, heaps for collection backings etc) |
| 643 // and BaseHeap represents each thread heap. | 656 // and BaseHeap represents each thread heap. |
| 644 // | 657 // |
| 645 // BaseHeap is a parent class of NormalPageHeap and LargeObjectHeap. | 658 // BaseHeap is a parent class of NormalPageHeap and LargeObjectHeap. |
| 646 // NormalPageHeap represents a heap that contains NormalPages | 659 // NormalPageHeap represents a heap that contains NormalPages |
| 647 // and LargeObjectHeap represents a heap that contains LargeObjectPages. | 660 // and LargeObjectHeap represents a heap that contains LargeObjectPages. |
| 648 class PLATFORM_EXPORT BaseHeap { | 661 class PLATFORM_EXPORT BaseHeap { |
| 662 USING_FAST_MALLOC(BaseHeap); | |
| 649 public: | 663 public: |
| 650 BaseHeap(ThreadState*, int); | 664 BaseHeap(ThreadState*, int); |
| 651 virtual ~BaseHeap(); | 665 virtual ~BaseHeap(); |
| 652 void cleanupPages(); | 666 void cleanupPages(); |
| 653 | 667 |
| 654 void takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotInfo&); | 668 void takeSnapshot(const String& dumpBaseName, ThreadState::GCSnapshotInfo&); |
| 655 #if ENABLE(ASSERT) | 669 #if ENABLE(ASSERT) |
| 656 BasePage* findPageFromAddress(Address); | 670 BasePage* findPageFromAddress(Address); |
| 657 #endif | 671 #endif |
| 658 virtual void takeFreelistSnapshot(const String& dumpBaseName) { } | 672 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)) ; | 888 SET_MEMORY_ACCESSIBLE(result, allocationSize - sizeof(HeapObjectHeader)) ; |
| 875 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); | 889 ASSERT(findPageFromAddress(headerAddress + allocationSize - 1)); |
| 876 return result; | 890 return result; |
| 877 } | 891 } |
| 878 return outOfLineAllocate(allocationSize, gcInfoIndex); | 892 return outOfLineAllocate(allocationSize, gcInfoIndex); |
| 879 } | 893 } |
| 880 | 894 |
| 881 } // namespace blink | 895 } // namespace blink |
| 882 | 896 |
| 883 #endif // HeapPage_h | 897 #endif // HeapPage_h |
| OLD | NEW |