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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 // The dead bit is used for objects that have gone through a GC marking, but did | 74 // The dead bit is used for objects that have gone through a GC marking, but did |
75 // not get swept before a new GC started. In that case we set the dead bit on | 75 // not get swept before a new GC started. In that case we set the dead bit on |
76 // objects that were not marked in the previous GC to ensure we are not tracing | 76 // objects that were not marked in the previous GC to ensure we are not tracing |
77 // them via a conservatively found pointer. Tracing dead objects could lead to | 77 // them via a conservatively found pointer. Tracing dead objects could lead to |
78 // tracing of already finalized objects in another thread's heap which is a | 78 // tracing of already finalized objects in another thread's heap which is a |
79 // use-after-free situation. | 79 // use-after-free situation. |
80 const size_t deadBitMask = 4; | 80 const size_t deadBitMask = 4; |
81 // On free-list entries we reuse the dead bit to distinguish a normal free-list | 81 // On free-list entries we reuse the dead bit to distinguish a normal free-list |
82 // entry from one that has been promptly freed. | 82 // entry from one that has been promptly freed. |
83 const size_t promptlyFreedMask = freeListMask | deadBitMask; | 83 const size_t promptlyFreedMask = freeListMask | deadBitMask; |
84 #if ENABLE(GC_PROFILE_HEAP) | 84 //#if ENABLE(GC_PROFILE_HEAP) |
85 const size_t heapObjectGenerations = 8; | 85 const size_t heapObjectGenerations = 8; |
86 const size_t maxHeapObjectAge = heapObjectGenerations - 1; | 86 const size_t maxHeapObjectAge = heapObjectGenerations - 1; |
87 const size_t heapObjectAgeMask = ~(maxHeapObjectSize - 1); | 87 const size_t heapObjectAgeMask = ~(maxHeapObjectSize - 1); |
88 const size_t sizeMask = ~heapObjectAgeMask & ~static_cast<size_t>(7); | 88 const size_t sizeMask = ~heapObjectAgeMask & ~static_cast<size_t>(7); |
89 #else | 89 //#else |
90 const size_t sizeMask = ~static_cast<size_t>(7); | 90 //const size_t sizeMask = ~static_cast<size_t>(7); |
91 #endif | 91 //#endif |
92 const uint8_t freelistZapValue = 42; | 92 const uint8_t freelistZapValue = 42; |
93 const uint8_t finalizedZapValue = 24; | 93 const uint8_t finalizedZapValue = 24; |
94 // The orphaned zap value must be zero in the lowest bits to allow for using | 94 // The orphaned zap value must be zero in the lowest bits to allow for using |
95 // the mark bit when tracing. | 95 // the mark bit when tracing. |
96 const uint8_t orphanedZapValue = 240; | 96 const uint8_t orphanedZapValue = 240; |
97 const int numberOfPagesToConsiderForCoalescing = 100; | 97 const int numberOfPagesToConsiderForCoalescing = 100; |
98 | 98 |
99 enum CallbackInvocationMode { | 99 enum CallbackInvocationMode { |
100 GlobalMarking, | 100 GlobalMarking, |
101 ThreadLocalMarking, | 101 ThreadLocalMarking, |
102 }; | 102 }; |
103 | 103 |
104 class CallbackStack; | 104 class CallbackStack; |
105 class PageMemory; | 105 class PageMemory; |
106 template<ThreadAffinity affinity> class ThreadLocalPersistents; | 106 template<ThreadAffinity affinity> class ThreadLocalPersistents; |
107 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr
ait<T>::Affinity > > class Persistent; | 107 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr
ait<T>::Affinity > > class Persistent; |
108 | 108 |
109 #if ENABLE(GC_PROFILE_HEAP) | 109 #if ENABLE(GC_PROFILE_HEAP) || ENABLE(GC_PROFILE_FREE_LIST) |
110 class TracedValue; | 110 class TracedValue; |
111 #endif | 111 #endif |
112 | 112 |
113 PLATFORM_EXPORT size_t osPageSize(); | 113 PLATFORM_EXPORT size_t osPageSize(); |
114 | 114 |
115 // Blink heap pages are set up with a guard page before and after the | 115 // Blink heap pages are set up with a guard page before and after the |
116 // payload. | 116 // payload. |
117 inline size_t blinkPagePayloadSize() | 117 inline size_t blinkPagePayloadSize() |
118 { | 118 { |
119 return blinkPageSize - 2 * osPageSize(); | 119 return blinkPageSize - 2 * osPageSize(); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 285 |
286 NO_SANITIZE_ADDRESS | 286 NO_SANITIZE_ADDRESS |
287 void markPromptlyFreed() { m_size |= promptlyFreedMask; } | 287 void markPromptlyFreed() { m_size |= promptlyFreedMask; } |
288 | 288 |
289 NO_SANITIZE_ADDRESS | 289 NO_SANITIZE_ADDRESS |
290 size_t size() const { return m_size & sizeMask; } | 290 size_t size() const { return m_size & sizeMask; } |
291 | 291 |
292 NO_SANITIZE_ADDRESS | 292 NO_SANITIZE_ADDRESS |
293 void setSize(size_t size) { m_size = (size | (m_size & ~sizeMask)); } | 293 void setSize(size_t size) { m_size = (size | (m_size & ~sizeMask)); } |
294 | 294 |
295 #if ENABLE(GC_PROFILE_HEAP) | 295 //#if ENABLE(GC_PROFILE_HEAP) |
296 NO_SANITIZE_ADDRESS | 296 NO_SANITIZE_ADDRESS |
297 size_t encodedSize() const { return m_size; } | 297 size_t encodedSize() const { return m_size; } |
298 | 298 |
299 NO_SANITIZE_ADDRESS | 299 NO_SANITIZE_ADDRESS |
300 size_t age() const { return m_size >> maxHeapObjectSizeLog2; } | 300 size_t age() const { return m_size >> maxHeapObjectSizeLog2; } |
301 | 301 |
302 NO_SANITIZE_ADDRESS | 302 NO_SANITIZE_ADDRESS |
303 void incAge() | 303 void incAge() |
304 { | 304 { |
305 size_t current = age(); | 305 size_t current = age(); |
306 if (current < maxHeapObjectAge) | 306 if (current < maxHeapObjectAge) |
307 m_size = ((current + 1) << maxHeapObjectSizeLog2) | (m_size & ~heapO
bjectAgeMask); | 307 m_size = ((current + 1) << maxHeapObjectSizeLog2) | (m_size & ~heapO
bjectAgeMask); |
308 } | 308 } |
309 #endif | 309 //#endif |
310 | 310 |
311 protected: | 311 protected: |
312 volatile unsigned m_size; | 312 volatile unsigned m_size; |
313 }; | 313 }; |
314 | 314 |
315 // Our heap object layout is layered with the HeapObjectHeader closest | 315 // Our heap object layout is layered with the HeapObjectHeader closest |
316 // to the payload, this can be wrapped in a FinalizedObjectHeader if the | 316 // to the payload, this can be wrapped in a FinalizedObjectHeader if the |
317 // object is on the GeneralHeap and not on a specific TypedHeap. | 317 // object is on the GeneralHeap and not on a specific TypedHeap. |
318 // Finally if the object is a large object (> blinkPageSize/2) then it is | 318 // Finally if the object is a large object (> blinkPageSize/2) then it is |
319 // wrapped with a LargeObjectHeader. | 319 // wrapped with a LargeObjectHeader. |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 void clearObjectStartBitMap(); | 527 void clearObjectStartBitMap(); |
528 void finalize(Header*); | 528 void finalize(Header*); |
529 virtual void checkAndMarkPointer(Visitor*, Address) override; | 529 virtual void checkAndMarkPointer(Visitor*, Address) override; |
530 #if ENABLE(GC_PROFILE_MARKING) | 530 #if ENABLE(GC_PROFILE_MARKING) |
531 const GCInfo* findGCInfo(Address) override; | 531 const GCInfo* findGCInfo(Address) override; |
532 #endif | 532 #endif |
533 #if ENABLE(GC_PROFILE_HEAP) | 533 #if ENABLE(GC_PROFILE_HEAP) |
534 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); | 534 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); |
535 #endif | 535 #endif |
536 | 536 |
| 537 void countUnmarkedObjects(); |
| 538 |
537 #if defined(ADDRESS_SANITIZER) | 539 #if defined(ADDRESS_SANITIZER) |
538 void poisonUnmarkedObjects(); | 540 void poisonUnmarkedObjects(); |
539 #endif | 541 #endif |
540 NO_SANITIZE_ADDRESS | 542 NO_SANITIZE_ADDRESS |
541 virtual void markOrphaned() override | 543 virtual void markOrphaned() override |
542 { | 544 { |
543 // Zap the payload with a recognizable value to detect any incorrect | 545 // Zap the payload with a recognizable value to detect any incorrect |
544 // cross thread pointer usage. | 546 // cross thread pointer usage. |
545 #if defined(ADDRESS_SANITIZER) | 547 #if defined(ADDRESS_SANITIZER) |
546 // Don't use memset when running with ASan since this needs to zap | 548 // Don't use memset when running with ASan since this needs to zap |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 | 679 |
678 // Find the page in this thread heap containing the given | 680 // Find the page in this thread heap containing the given |
679 // address. Returns 0 if the address is not contained in any | 681 // address. Returns 0 if the address is not contained in any |
680 // page in this thread heap. | 682 // page in this thread heap. |
681 virtual BaseHeapPage* pageFromAddress(Address) = 0; | 683 virtual BaseHeapPage* pageFromAddress(Address) = 0; |
682 | 684 |
683 #if ENABLE(GC_PROFILE_MARKING) | 685 #if ENABLE(GC_PROFILE_MARKING) |
684 virtual const GCInfo* findGCInfoOfLargeObject(Address) = 0; | 686 virtual const GCInfo* findGCInfoOfLargeObject(Address) = 0; |
685 #endif | 687 #endif |
686 | 688 |
| 689 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 690 virtual void snapshotFreeList(TracedValue*) = 0; |
| 691 #endif |
| 692 |
687 #if ENABLE(GC_PROFILE_HEAP) | 693 #if ENABLE(GC_PROFILE_HEAP) |
688 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; | 694 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; |
689 #endif | 695 #endif |
690 | 696 |
691 // Sweep this part of the Blink heap. This finalizes dead objects | 697 // Sweep this part of the Blink heap. This finalizes dead objects |
692 // and builds freelists for all the unused memory. | 698 // and builds freelists for all the unused memory. |
693 virtual void sweep() = 0; | 699 virtual void sweep() = 0; |
694 virtual void postSweepProcessing() = 0; | 700 virtual void postSweepProcessing() = 0; |
695 | 701 |
696 virtual void clearFreeLists() = 0; | 702 virtual void clearFreeLists() = 0; |
(...skipping 13 matching lines...) Expand all Loading... |
710 }; | 716 }; |
711 | 717 |
712 template<typename Header> | 718 template<typename Header> |
713 class FreeList { | 719 class FreeList { |
714 public: | 720 public: |
715 FreeList(); | 721 FreeList(); |
716 | 722 |
717 void addToFreeList(Address, size_t); | 723 void addToFreeList(Address, size_t); |
718 void clear(); | 724 void clear(); |
719 | 725 |
| 726 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 727 void countBucketSizes(size_t[], size_t[], size_t* freeSize) const; |
| 728 #endif |
| 729 |
720 private: | 730 private: |
721 // Returns a bucket number for inserting a FreeListEntry of a | 731 // Returns a bucket number for inserting a FreeListEntry of a |
722 // given size. All FreeListEntries in the given bucket, n, have | 732 // given size. All FreeListEntries in the given bucket, n, have |
723 // size >= 2^n. | 733 // size >= 2^n. |
724 static int bucketIndexForSize(size_t); | 734 static int bucketIndexForSize(size_t); |
725 | 735 |
726 int m_biggestFreeListIndex; | 736 int m_biggestFreeListIndex; |
727 | 737 |
728 // All FreeListEntries in the nth list have size >= 2^n. | 738 // All FreeListEntries in the nth list have size >= 2^n. |
729 FreeListEntry* m_freeLists[blinkPageSizeLog2]; | 739 FreeListEntry* m_freeLists[blinkPageSizeLog2]; |
(...skipping 16 matching lines...) Expand all Loading... |
746 class ThreadHeap : public BaseHeap { | 756 class ThreadHeap : public BaseHeap { |
747 public: | 757 public: |
748 ThreadHeap(ThreadState*, int); | 758 ThreadHeap(ThreadState*, int); |
749 virtual ~ThreadHeap(); | 759 virtual ~ThreadHeap(); |
750 virtual void cleanupPages() override; | 760 virtual void cleanupPages() override; |
751 | 761 |
752 virtual BaseHeapPage* pageFromAddress(Address) override; | 762 virtual BaseHeapPage* pageFromAddress(Address) override; |
753 #if ENABLE(GC_PROFILE_MARKING) | 763 #if ENABLE(GC_PROFILE_MARKING) |
754 virtual const GCInfo* findGCInfoOfLargeObject(Address) override; | 764 virtual const GCInfo* findGCInfoOfLargeObject(Address) override; |
755 #endif | 765 #endif |
| 766 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 767 virtual void snapshotFreeList(TracedValue*) override; |
| 768 #endif |
756 #if ENABLE(GC_PROFILE_HEAP) | 769 #if ENABLE(GC_PROFILE_HEAP) |
757 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; | 770 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; |
758 #endif | 771 #endif |
759 | 772 |
760 virtual void sweep() override; | 773 virtual void sweep() override; |
761 virtual void postSweepProcessing() override; | 774 virtual void postSweepProcessing() override; |
762 | 775 |
763 virtual void clearFreeLists() override; | 776 virtual void clearFreeLists() override; |
764 virtual void markUnmarkedObjectsDead() override; | 777 virtual void markUnmarkedObjectsDead() override; |
765 | 778 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 private: | 811 private: |
799 void addPageToHeap(const GCInfo*); | 812 void addPageToHeap(const GCInfo*); |
800 PLATFORM_EXPORT Address outOfLineAllocate(size_t payloadSize, size_t allocat
ionSize, const GCInfo*); | 813 PLATFORM_EXPORT Address outOfLineAllocate(size_t payloadSize, size_t allocat
ionSize, const GCInfo*); |
801 static size_t allocationSizeFromSize(size_t); | 814 static size_t allocationSizeFromSize(size_t); |
802 PLATFORM_EXPORT Address allocateLargeObject(size_t, const GCInfo*); | 815 PLATFORM_EXPORT Address allocateLargeObject(size_t, const GCInfo*); |
803 Address currentAllocationPoint() const { return m_currentAllocationPoint; } | 816 Address currentAllocationPoint() const { return m_currentAllocationPoint; } |
804 size_t remainingAllocationSize() const { return m_remainingAllocationSize; } | 817 size_t remainingAllocationSize() const { return m_remainingAllocationSize; } |
805 bool ownsNonEmptyAllocationArea() const { return currentAllocationPoint() &&
remainingAllocationSize(); } | 818 bool ownsNonEmptyAllocationArea() const { return currentAllocationPoint() &&
remainingAllocationSize(); } |
806 void setAllocationPoint(Address point, size_t size) | 819 void setAllocationPoint(Address point, size_t size) |
807 { | 820 { |
| 821 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 822 m_allocationPointSizeSum += size; |
| 823 ++m_setAllocationPointCount; |
| 824 #endif |
808 ASSERT(!point || pageFromAddress(point)); | 825 ASSERT(!point || pageFromAddress(point)); |
809 ASSERT(size <= HeapPage<Header>::payloadSize()); | 826 ASSERT(size <= HeapPage<Header>::payloadSize()); |
810 updateRemainingAllocationSize(); | 827 updateRemainingAllocationSize(); |
811 m_currentAllocationPoint = point; | 828 m_currentAllocationPoint = point; |
812 m_lastRemainingAllocationSize = m_remainingAllocationSize = size; | 829 m_lastRemainingAllocationSize = m_remainingAllocationSize = size; |
813 } | 830 } |
814 void ensureCurrentAllocation(size_t, const GCInfo*); | 831 void ensureCurrentAllocation(size_t, const GCInfo*); |
815 bool allocateFromFreeList(size_t); | 832 bool allocateFromFreeList(size_t); |
816 | 833 |
817 void freeLargeObject(LargeObject<Header>*, LargeObject<Header>**); | 834 void freeLargeObject(LargeObject<Header>*, LargeObject<Header>**); |
818 void allocatePage(const GCInfo*); | 835 void allocatePage(const GCInfo*); |
819 | 836 |
820 #if ENABLE(ASSERT) | 837 #if ENABLE(ASSERT) |
821 bool pagesToBeSweptContains(Address); | 838 bool pagesToBeSweptContains(Address); |
822 bool pagesAllocatedDuringSweepingContains(Address); | 839 bool pagesAllocatedDuringSweepingContains(Address); |
823 #endif | 840 #endif |
824 | 841 |
825 void sweepNormalPages(); | 842 void sweepNormalPages(); |
826 void sweepLargePages(); | 843 void sweepLargePages(); |
827 bool coalesce(size_t); | 844 bool coalesce(size_t); |
828 | 845 |
829 Address m_currentAllocationPoint; | 846 Address m_currentAllocationPoint; |
830 size_t m_remainingAllocationSize; | 847 size_t m_remainingAllocationSize; |
831 size_t m_lastRemainingAllocationSize; | 848 size_t m_lastRemainingAllocationSize; |
832 | 849 |
| 850 double m_totalAllocationSize; |
| 851 size_t m_allocationCount; |
| 852 size_t m_inlineAllocationCount; |
| 853 |
833 HeapPage<Header>* m_firstPage; | 854 HeapPage<Header>* m_firstPage; |
834 LargeObject<Header>* m_firstLargeObject; | 855 LargeObject<Header>* m_firstLargeObject; |
835 | 856 |
836 HeapPage<Header>* m_firstPageAllocatedDuringSweeping; | 857 HeapPage<Header>* m_firstPageAllocatedDuringSweeping; |
837 HeapPage<Header>* m_lastPageAllocatedDuringSweeping; | 858 HeapPage<Header>* m_lastPageAllocatedDuringSweeping; |
838 | 859 |
839 LargeObject<Header>* m_firstLargeObjectAllocatedDuringSweeping; | 860 LargeObject<Header>* m_firstLargeObjectAllocatedDuringSweeping; |
840 LargeObject<Header>* m_lastLargeObjectAllocatedDuringSweeping; | 861 LargeObject<Header>* m_lastLargeObjectAllocatedDuringSweeping; |
841 | 862 |
842 ThreadState* m_threadState; | 863 ThreadState* m_threadState; |
843 | 864 |
844 FreeList<Header> m_freeList; | 865 FreeList<Header> m_freeList; |
845 | 866 |
846 // Index into the page pools. This is used to ensure that the pages of the | 867 // Index into the page pools. This is used to ensure that the pages of the |
847 // same type go into the correct page pool and thus avoid type confusion. | 868 // same type go into the correct page pool and thus avoid type confusion. |
848 int m_index; | 869 int m_index; |
849 | 870 |
850 int m_numberOfNormalPages; | 871 int m_numberOfNormalPages; |
851 | 872 |
852 // The promptly freed count contains the number of promptly freed objects | 873 // The promptly freed count contains the number of promptly freed objects |
853 // since the last sweep or since it was manually reset to delay coalescing. | 874 // since the last sweep or since it was manually reset to delay coalescing. |
854 size_t m_promptlyFreedCount; | 875 size_t m_promptlyFreedCount; |
| 876 |
| 877 #if ENABLE(GC_PROFILE_FREE_LIST) |
| 878 size_t m_allocationPointSizeSum = 0; |
| 879 size_t m_setAllocationPointCount = 0; |
| 880 #endif |
855 }; | 881 }; |
856 | 882 |
857 class PLATFORM_EXPORT Heap { | 883 class PLATFORM_EXPORT Heap { |
858 public: | 884 public: |
859 static void init(); | 885 static void init(); |
860 static void shutdown(); | 886 static void shutdown(); |
861 static void doShutdown(); | 887 static void doShutdown(); |
862 | 888 |
863 static BaseHeapPage* contains(Address); | 889 static BaseHeapPage* contains(Address); |
864 static BaseHeapPage* contains(void* pointer) { return contains(reinterpret_c
ast<Address>(pointer)); } | 890 static BaseHeapPage* contains(void* pointer) { return contains(reinterpret_c
ast<Address>(pointer)); } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 static void collectGarbage(ThreadState::StackState, ThreadState::CauseOfGC =
ThreadState::NormalGC); | 944 static void collectGarbage(ThreadState::StackState, ThreadState::CauseOfGC =
ThreadState::NormalGC); |
919 static void collectGarbageForTerminatingThread(ThreadState*); | 945 static void collectGarbageForTerminatingThread(ThreadState*); |
920 static void collectAllGarbage(); | 946 static void collectAllGarbage(); |
921 template<CallbackInvocationMode Mode> static void processMarkingStack(); | 947 template<CallbackInvocationMode Mode> static void processMarkingStack(); |
922 static void postMarkingProcessing(); | 948 static void postMarkingProcessing(); |
923 static void globalWeakProcessing(); | 949 static void globalWeakProcessing(); |
924 static void setForcePreciseGCForTesting(); | 950 static void setForcePreciseGCForTesting(); |
925 | 951 |
926 static void prepareForGC(); | 952 static void prepareForGC(); |
927 | 953 |
| 954 static void reportSweepingStats(); |
| 955 |
928 // Conservatively checks whether an address is a pointer in any of the threa
d | 956 // Conservatively checks whether an address is a pointer in any of the threa
d |
929 // heaps. If so marks the object pointed to as live. | 957 // heaps. If so marks the object pointed to as live. |
930 static Address checkAndMarkPointer(Visitor*, Address); | 958 static Address checkAndMarkPointer(Visitor*, Address); |
931 | 959 |
932 #if ENABLE(GC_PROFILE_MARKING) | 960 #if ENABLE(GC_PROFILE_MARKING) |
933 // Dump the path to specified object on the next GC. This method is to be in
voked from GDB. | 961 // Dump the path to specified object on the next GC. This method is to be in
voked from GDB. |
934 static void dumpPathToObjectOnNextGC(void* p); | 962 static void dumpPathToObjectOnNextGC(void* p); |
935 | 963 |
936 // Forcibly find GCInfo of the object at Address. | 964 // Forcibly find GCInfo of the object at Address. |
937 // This is slow and should only be used for debug purposes. | 965 // This is slow and should only be used for debug purposes. |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 // Add space for header. | 1361 // Add space for header. |
1334 size_t allocationSize = size + sizeof(Header); | 1362 size_t allocationSize = size + sizeof(Header); |
1335 // Align size with allocation granularity. | 1363 // Align size with allocation granularity. |
1336 allocationSize = (allocationSize + allocationMask) & ~allocationMask; | 1364 allocationSize = (allocationSize + allocationMask) & ~allocationMask; |
1337 return allocationSize; | 1365 return allocationSize; |
1338 } | 1366 } |
1339 | 1367 |
1340 template<typename Header> | 1368 template<typename Header> |
1341 Address ThreadHeap<Header>::allocate(size_t size, const GCInfo* gcInfo) | 1369 Address ThreadHeap<Header>::allocate(size_t size, const GCInfo* gcInfo) |
1342 { | 1370 { |
| 1371 m_totalAllocationSize += size; |
| 1372 m_allocationCount++; |
1343 size_t allocationSize = allocationSizeFromSize(size); | 1373 size_t allocationSize = allocationSizeFromSize(size); |
1344 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { | 1374 if (LIKELY(allocationSize <= m_remainingAllocationSize)) { |
| 1375 m_inlineAllocationCount++; |
1345 Address headerAddress = m_currentAllocationPoint; | 1376 Address headerAddress = m_currentAllocationPoint; |
1346 m_currentAllocationPoint += allocationSize; | 1377 m_currentAllocationPoint += allocationSize; |
1347 m_remainingAllocationSize -= allocationSize; | 1378 m_remainingAllocationSize -= allocationSize; |
1348 new (NotNull, headerAddress) Header(allocationSize, gcInfo); | 1379 new (NotNull, headerAddress) Header(allocationSize, gcInfo); |
1349 Address result = headerAddress + sizeof(Header); | 1380 Address result = headerAddress + sizeof(Header); |
1350 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); | 1381 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); |
1351 | 1382 |
1352 // Unpoison the memory used for the object (payload). | 1383 // Unpoison the memory used for the object (payload). |
1353 ASAN_UNPOISON_MEMORY_REGION(result, allocationSize - sizeof(Header)); | 1384 ASAN_UNPOISON_MEMORY_REGION(result, allocationSize - sizeof(Header)); |
1354 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | 1385 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2352 template<typename T, size_t inlineCapacity> | 2383 template<typename T, size_t inlineCapacity> |
2353 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; | 2384 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T
, inlineCapacity, HeapAllocator> > { }; |
2354 template<typename T, size_t inlineCapacity> | 2385 template<typename T, size_t inlineCapacity> |
2355 struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T,
inlineCapacity, HeapAllocator> > { }; | 2386 struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T,
inlineCapacity, HeapAllocator> > { }; |
2356 template<typename T, typename U, typename V> | 2387 template<typename T, typename U, typename V> |
2357 struct GCInfoTrait<HeapHashCountedSet<T, U, V> > : public GCInfoTrait<HashCounte
dSet<T, U, V, HeapAllocator> > { }; | 2388 struct GCInfoTrait<HeapHashCountedSet<T, U, V> > : public GCInfoTrait<HashCounte
dSet<T, U, V, HeapAllocator> > { }; |
2358 | 2389 |
2359 } // namespace blink | 2390 } // namespace blink |
2360 | 2391 |
2361 #endif // Heap_h | 2392 #endif // Heap_h |
OLD | NEW |