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 |