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 |