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 Heap_h | 31 #ifndef Heap_h |
| 32 #define Heap_h | 32 #define Heap_h |
| 33 | 33 |
| 34 #include "platform/PlatformExport.h" | 34 #include "platform/PlatformExport.h" |
| 35 #include "platform/heap/AddressSanitizer.h" | 35 #include "platform/heap/AddressSanitizer.h" |
| 36 #include "platform/heap/ThreadState.h" | 36 #include "platform/heap/ThreadState.h" |
| 37 #include "platform/heap/Visitor.h" | 37 #include "platform/heap/Visitor.h" |
| 38 #include "public/platform/WebThread.h" | 38 #include "public/platform/WebThread.h" |
| 39 #include "wtf/Assertions.h" | 39 #include "wtf/Assertions.h" |
| 40 #include "wtf/Atomics.h" | |
| 40 #include "wtf/HashCountedSet.h" | 41 #include "wtf/HashCountedSet.h" |
| 41 #include "wtf/LinkedHashSet.h" | 42 #include "wtf/LinkedHashSet.h" |
| 42 #include "wtf/ListHashSet.h" | 43 #include "wtf/ListHashSet.h" |
| 43 #include "wtf/OwnPtr.h" | 44 #include "wtf/OwnPtr.h" |
| 44 #include "wtf/PassRefPtr.h" | 45 #include "wtf/PassRefPtr.h" |
| 45 #include "wtf/ThreadSafeRefCounted.h" | 46 #include "wtf/ThreadSafeRefCounted.h" |
| 46 | 47 |
| 47 #include <stdint.h> | 48 #include <stdint.h> |
| 48 | 49 |
| 49 // FIXME: We temporarily disable parallel marking because the current | 50 // FIXME: We temporarily disable parallel marking because the current |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 #endif | 110 #endif |
| 110 | 111 |
| 111 const int numberOfPagesToConsiderForCoalescing = 100; | 112 const int numberOfPagesToConsiderForCoalescing = 100; |
| 112 | 113 |
| 113 enum CallbackInvocationMode { | 114 enum CallbackInvocationMode { |
| 114 GlobalMarking, | 115 GlobalMarking, |
| 115 ThreadLocalMarking, | 116 ThreadLocalMarking, |
| 116 }; | 117 }; |
| 117 | 118 |
| 118 class CallbackStack; | 119 class CallbackStack; |
| 119 class HeapStats; | |
| 120 class PageMemory; | 120 class PageMemory; |
| 121 template<ThreadAffinity affinity> class ThreadLocalPersistents; | 121 template<ThreadAffinity affinity> class ThreadLocalPersistents; |
| 122 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr ait<T>::Affinity > > class Persistent; | 122 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTr ait<T>::Affinity > > class Persistent; |
| 123 | 123 |
| 124 #if ENABLE(GC_PROFILE_HEAP) | 124 #if ENABLE(GC_PROFILE_HEAP) |
| 125 class TracedValue; | 125 class TracedValue; |
| 126 #endif | 126 #endif |
| 127 | 127 |
| 128 PLATFORM_EXPORT size_t osPageSize(); | 128 PLATFORM_EXPORT size_t osPageSize(); |
| 129 | 129 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 size_t payloadSize() { return heapObjectHeader()->payloadSize(); } | 256 size_t payloadSize() { return heapObjectHeader()->payloadSize(); } |
| 257 | 257 |
| 258 Header* heapObjectHeader() | 258 Header* heapObjectHeader() |
| 259 { | 259 { |
| 260 Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + he aderPadding<Header>(); | 260 Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + he aderPadding<Header>(); |
| 261 return reinterpret_cast<Header*>(headerAddress); | 261 return reinterpret_cast<Header*>(headerAddress); |
| 262 } | 262 } |
| 263 | 263 |
| 264 bool isMarked(); | 264 bool isMarked(); |
| 265 void unmark(); | 265 void unmark(); |
| 266 void getStatsForTesting(HeapStats&); | 266 size_t objectPayloadSizeForTesting(); |
| 267 void mark(Visitor*); | 267 void mark(Visitor*); |
| 268 void finalize(); | 268 void finalize(); |
| 269 void setDeadMark(); | 269 void setDeadMark(); |
| 270 virtual void markOrphaned() | 270 virtual void markOrphaned() |
| 271 { | 271 { |
| 272 // Zap the payload with a recognizable value to detect any incorrect | 272 // Zap the payload with a recognizable value to detect any incorrect |
| 273 // cross thread pointer usage. | 273 // cross thread pointer usage. |
| 274 memset(payload(), orphanedZapValue, payloadSize()); | 274 memset(payload(), orphanedZapValue, payloadSize()); |
| 275 BaseHeapPage::markOrphaned(); | 275 BaseHeapPage::markOrphaned(); |
| 276 } | 276 } |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 527 return address() + sizeof(*this) + headerPadding<Header>(); | 527 return address() + sizeof(*this) + headerPadding<Header>(); |
| 528 } | 528 } |
| 529 | 529 |
| 530 static size_t payloadSize() | 530 static size_t payloadSize() |
| 531 { | 531 { |
| 532 return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header >()) & ~allocationMask; | 532 return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header >()) & ~allocationMask; |
| 533 } | 533 } |
| 534 | 534 |
| 535 Address end() { return payload() + payloadSize(); } | 535 Address end() { return payload() + payloadSize(); } |
| 536 | 536 |
| 537 void getStatsForTesting(HeapStats&); | 537 size_t objectPayloadSizeForTesting(); |
| 538 void clearLiveAndMarkDead(); | 538 void clearLiveAndMarkDead(); |
| 539 void sweep(HeapStats*, ThreadHeap<Header>*); | 539 void sweep(ThreadHeap<Header>*); |
| 540 void clearObjectStartBitMap(); | 540 void clearObjectStartBitMap(); |
| 541 void finalize(Header*); | 541 void finalize(Header*); |
| 542 virtual void checkAndMarkPointer(Visitor*, Address) override; | 542 virtual void checkAndMarkPointer(Visitor*, Address) override; |
| 543 #if ENABLE(GC_PROFILE_MARKING) | 543 #if ENABLE(GC_PROFILE_MARKING) |
| 544 const GCInfo* findGCInfo(Address) override; | 544 const GCInfo* findGCInfo(Address) override; |
| 545 #endif | 545 #endif |
| 546 #if ENABLE(GC_PROFILE_HEAP) | 546 #if ENABLE(GC_PROFILE_HEAP) |
| 547 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); | 547 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*); |
| 548 #endif | 548 #endif |
| 549 | 549 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 #if ENABLE(GC_PROFILE_MARKING) | 696 #if ENABLE(GC_PROFILE_MARKING) |
| 697 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0; | 697 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0; |
| 698 #endif | 698 #endif |
| 699 | 699 |
| 700 #if ENABLE(GC_PROFILE_HEAP) | 700 #if ENABLE(GC_PROFILE_HEAP) |
| 701 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; | 701 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0; |
| 702 #endif | 702 #endif |
| 703 | 703 |
| 704 // Sweep this part of the Blink heap. This finalizes dead objects | 704 // Sweep this part of the Blink heap. This finalizes dead objects |
| 705 // and builds freelists for all the unused memory. | 705 // and builds freelists for all the unused memory. |
| 706 virtual void sweep(HeapStats*) = 0; | 706 virtual void sweep() = 0; |
| 707 virtual void postSweepProcessing() = 0; | 707 virtual void postSweepProcessing() = 0; |
| 708 | 708 |
| 709 virtual void clearFreeLists() = 0; | 709 virtual void clearFreeLists() = 0; |
| 710 virtual void clearLiveAndMarkDead() = 0; | 710 virtual void clearLiveAndMarkDead() = 0; |
| 711 | 711 |
| 712 virtual void makeConsistentForSweeping() = 0; | 712 virtual void makeConsistentForSweeping() = 0; |
| 713 #if ENABLE(ASSERT) | 713 #if ENABLE(ASSERT) |
| 714 virtual bool isConsistentForSweeping() = 0; | 714 virtual bool isConsistentForSweeping() = 0; |
| 715 #endif | 715 #endif |
| 716 virtual void getStatsForTesting(HeapStats&) = 0; | 716 virtual size_t objectPayloadSizeForTesting() = 0; |
| 717 | 717 |
| 718 virtual void updateRemainingAllocationSize() = 0; | 718 virtual void updateRemainingAllocationSize() = 0; |
| 719 | 719 |
| 720 virtual void prepareHeapForTermination() = 0; | 720 virtual void prepareHeapForTermination() = 0; |
| 721 | 721 |
| 722 virtual int normalPageCount() = 0; | 722 virtual int normalPageCount() = 0; |
| 723 | 723 |
| 724 virtual PassOwnPtr<BaseHeap> split(int normalPages) = 0; | 724 virtual PassOwnPtr<BaseHeap> split(int normalPages) = 0; |
| 725 virtual void merge(PassOwnPtr<BaseHeap> other) = 0; | 725 virtual void merge(PassOwnPtr<BaseHeap> other) = 0; |
| 726 }; | 726 }; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 766 virtual void cleanupPages() override; | 766 virtual void cleanupPages() override; |
| 767 | 767 |
| 768 virtual BaseHeapPage* heapPageFromAddress(Address) override; | 768 virtual BaseHeapPage* heapPageFromAddress(Address) override; |
| 769 #if ENABLE(GC_PROFILE_MARKING) | 769 #if ENABLE(GC_PROFILE_MARKING) |
| 770 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) override; | 770 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) override; |
| 771 #endif | 771 #endif |
| 772 #if ENABLE(GC_PROFILE_HEAP) | 772 #if ENABLE(GC_PROFILE_HEAP) |
| 773 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; | 773 virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) override; |
| 774 #endif | 774 #endif |
| 775 | 775 |
| 776 virtual void sweep(HeapStats*) override; | 776 virtual void sweep() override; |
| 777 virtual void postSweepProcessing() override; | 777 virtual void postSweepProcessing() override; |
| 778 | 778 |
| 779 virtual void clearFreeLists() override; | 779 virtual void clearFreeLists() override; |
| 780 virtual void clearLiveAndMarkDead() override; | 780 virtual void clearLiveAndMarkDead() override; |
| 781 | 781 |
| 782 virtual void makeConsistentForSweeping() override; | 782 virtual void makeConsistentForSweeping() override; |
| 783 #if ENABLE(ASSERT) | 783 #if ENABLE(ASSERT) |
| 784 virtual bool isConsistentForSweeping() override; | 784 virtual bool isConsistentForSweeping() override; |
| 785 #endif | 785 #endif |
| 786 virtual void getStatsForTesting(HeapStats&) override; | 786 virtual size_t objectPayloadSizeForTesting() override; |
| 787 | 787 |
| 788 virtual void updateRemainingAllocationSize() override; | 788 virtual void updateRemainingAllocationSize() override; |
| 789 | 789 |
| 790 ThreadState* threadState() { return m_threadState; } | 790 ThreadState* threadState() { return m_threadState; } |
| 791 HeapStats& stats() { return m_threadState->stats(); } | |
| 792 | 791 |
| 793 void addToFreeList(Address address, size_t size) | 792 void addToFreeList(Address address, size_t size) |
| 794 { | 793 { |
| 795 ASSERT(heapPageFromAddress(address)); | 794 ASSERT(heapPageFromAddress(address)); |
| 796 ASSERT(heapPageFromAddress(address + size - 1)); | 795 ASSERT(heapPageFromAddress(address + size - 1)); |
| 797 m_freeList.addToFreeList(address, size); | 796 m_freeList.addToFreeList(address, size); |
| 798 } | 797 } |
| 799 | 798 |
| 800 inline Address allocate(size_t, const GCInfo*); | 799 inline Address allocate(size_t, const GCInfo*); |
| 801 inline static size_t roundedAllocationSize(size_t size) | 800 inline static size_t roundedAllocationSize(size_t size) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 834 bool allocateFromFreeList(size_t); | 833 bool allocateFromFreeList(size_t); |
| 835 | 834 |
| 836 void freeLargeObject(LargeHeapObject<Header>*, LargeHeapObject<Header>**); | 835 void freeLargeObject(LargeHeapObject<Header>*, LargeHeapObject<Header>**); |
| 837 void allocatePage(const GCInfo*); | 836 void allocatePage(const GCInfo*); |
| 838 | 837 |
| 839 #if ENABLE(ASSERT) | 838 #if ENABLE(ASSERT) |
| 840 bool pagesToBeSweptContains(Address); | 839 bool pagesToBeSweptContains(Address); |
| 841 bool pagesAllocatedDuringSweepingContains(Address); | 840 bool pagesAllocatedDuringSweepingContains(Address); |
| 842 #endif | 841 #endif |
| 843 | 842 |
| 844 void sweepNormalPages(HeapStats*); | 843 void sweepNormalPages(); |
| 845 void sweepLargePages(HeapStats*); | 844 void sweepLargePages(); |
| 846 bool coalesce(size_t); | 845 bool coalesce(size_t); |
| 847 | 846 |
| 848 Address m_currentAllocationPoint; | 847 Address m_currentAllocationPoint; |
| 849 size_t m_remainingAllocationSize; | 848 size_t m_remainingAllocationSize; |
| 850 size_t m_lastRemainingAllocationSize; | 849 size_t m_lastRemainingAllocationSize; |
| 851 | 850 |
| 852 HeapPage<Header>* m_firstPage; | 851 HeapPage<Header>* m_firstPage; |
| 853 LargeHeapObject<Header>* m_firstLargeHeapObject; | 852 LargeHeapObject<Header>* m_firstLargeHeapObject; |
| 854 | 853 |
| 855 HeapPage<Header>* m_firstPageAllocatedDuringSweeping; | 854 HeapPage<Header>* m_firstPageAllocatedDuringSweeping; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 956 static void dumpPathToObjectOnNextGC(void* p); | 955 static void dumpPathToObjectOnNextGC(void* p); |
| 957 | 956 |
| 958 // Forcibly find GCInfo of the object at Address. | 957 // Forcibly find GCInfo of the object at Address. |
| 959 // This is slow and should only be used for debug purposes. | 958 // This is slow and should only be used for debug purposes. |
| 960 // It involves finding the heap page and scanning the heap page for an objec t header. | 959 // It involves finding the heap page and scanning the heap page for an objec t header. |
| 961 static const GCInfo* findGCInfo(Address); | 960 static const GCInfo* findGCInfo(Address); |
| 962 | 961 |
| 963 static String createBacktraceString(); | 962 static String createBacktraceString(); |
| 964 #endif | 963 #endif |
| 965 | 964 |
| 966 // Collect heap stats for all threads attached to the Blink | 965 static size_t objectPayloadSizeForTesting(); |
| 967 // garbage collector. Should only be called during garbage | |
| 968 // collection where threads are known to be at safe points. | |
| 969 static void getStats(HeapStats*); | |
| 970 | |
| 971 static void getStatsForTesting(HeapStats*); | |
| 972 | 966 |
| 973 static void getHeapSpaceSize(uint64_t*, uint64_t*); | 967 static void getHeapSpaceSize(uint64_t*, uint64_t*); |
| 974 | 968 |
| 975 static void makeConsistentForSweeping(); | 969 static void makeConsistentForSweeping(); |
| 976 | 970 |
| 977 #if ENABLE(ASSERT) | 971 #if ENABLE(ASSERT) |
| 978 static bool isConsistentForSweeping(); | 972 static bool isConsistentForSweeping(); |
| 979 #endif | 973 #endif |
| 980 | 974 |
| 981 static void flushHeapDoesNotContainCache(); | 975 static void flushHeapDoesNotContainCache(); |
| 982 | 976 |
| 983 // Return true if the last GC found a pointer into a heap page | 977 // Return true if the last GC found a pointer into a heap page |
| 984 // during conservative scanning. | 978 // during conservative scanning. |
| 985 static bool lastGCWasConservative() { return s_lastGCWasConservative; } | 979 static bool lastGCWasConservative() { return s_lastGCWasConservative; } |
| 986 | 980 |
| 987 static FreePagePool* freePagePool() { return s_freePagePool; } | 981 static FreePagePool* freePagePool() { return s_freePagePool; } |
| 988 static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; } | 982 static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; } |
| 989 | 983 |
| 990 // This look-up uses the region search tree and a negative contains cache to | 984 // This look-up uses the region search tree and a negative contains cache to |
| 991 // provide an efficient mapping from arbitrary addresses to the containing | 985 // provide an efficient mapping from arbitrary addresses to the containing |
| 992 // heap-page if one exists. | 986 // heap-page if one exists. |
| 993 static BaseHeapPage* lookup(Address); | 987 static BaseHeapPage* lookup(Address); |
| 994 static void addPageMemoryRegion(PageMemoryRegion*); | 988 static void addPageMemoryRegion(PageMemoryRegion*); |
| 995 static void removePageMemoryRegion(PageMemoryRegion*); | 989 static void removePageMemoryRegion(PageMemoryRegion*); |
| 996 | 990 |
| 991 static void resetAllocatedObjectSize() { s_allocatedObjectSize = 0; } | |
|
sof
2014/11/14 12:44:20
Add a comment to make it clearer why this doesn't
haraken
2014/11/14 15:15:00
Added ASSERT(ThreadState::isAnyThreadInGC()).
sof
2014/11/14 16:37:21
An assert is even better. I suppose there isn't a
haraken
2014/11/17 01:05:02
Done.
| |
| 992 static void increaseAllocatedObjectSize(size_t delta) { atomicAdd(&s_allocat edObjectSize, delta); } | |
| 993 static void decreaseAllocatedObjectSize(size_t delta) { atomicSubtract(&s_al locatedObjectSize, delta); } | |
| 994 static size_t allocatedObjectSize() { return s_allocatedObjectSize; } | |
| 995 static void resetLiveObjectSize() { s_liveObjectSize = 0; } | |
| 996 static void increaseLiveObjectSize(size_t delta) { atomicAdd(&s_liveObjectSi ze, delta); } | |
| 997 static size_t liveObjectSize() { return s_liveObjectSize; } | |
| 998 static void increaseAllocatedSpace(size_t delta) { atomicAdd(&s_allocatedSpa ce, delta); } | |
| 999 static void decreaseAllocatedSpace(size_t delta) { atomicSubtract(&s_allocat edSpace, delta); } | |
| 1000 static size_t allocatedSpace() { return s_allocatedSpace; } | |
| 1001 | |
| 997 private: | 1002 private: |
| 998 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted | 1003 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted |
| 999 // by base addresses. | 1004 // by base addresses. |
| 1000 class RegionTree { | 1005 class RegionTree { |
| 1001 public: | 1006 public: |
| 1002 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (0), m_right(0) { } | 1007 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (0), m_right(0) { } |
| 1003 ~RegionTree() | 1008 ~RegionTree() |
| 1004 { | 1009 { |
| 1005 delete m_left; | 1010 delete m_left; |
| 1006 delete m_right; | 1011 delete m_right; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1019 static CallbackStack* s_markingStack; | 1024 static CallbackStack* s_markingStack; |
| 1020 static CallbackStack* s_postMarkingCallbackStack; | 1025 static CallbackStack* s_postMarkingCallbackStack; |
| 1021 static CallbackStack* s_weakCallbackStack; | 1026 static CallbackStack* s_weakCallbackStack; |
| 1022 static CallbackStack* s_ephemeronStack; | 1027 static CallbackStack* s_ephemeronStack; |
| 1023 static HeapDoesNotContainCache* s_heapDoesNotContainCache; | 1028 static HeapDoesNotContainCache* s_heapDoesNotContainCache; |
| 1024 static bool s_shutdownCalled; | 1029 static bool s_shutdownCalled; |
| 1025 static bool s_lastGCWasConservative; | 1030 static bool s_lastGCWasConservative; |
| 1026 static FreePagePool* s_freePagePool; | 1031 static FreePagePool* s_freePagePool; |
| 1027 static OrphanedPagePool* s_orphanedPagePool; | 1032 static OrphanedPagePool* s_orphanedPagePool; |
| 1028 static RegionTree* s_regionTree; | 1033 static RegionTree* s_regionTree; |
| 1034 static size_t s_allocatedSpace; | |
| 1035 static size_t s_allocatedObjectSize; | |
| 1036 static size_t s_liveObjectSize; | |
| 1029 friend class ThreadState; | 1037 friend class ThreadState; |
| 1030 }; | 1038 }; |
| 1031 | 1039 |
| 1032 // The NoAllocationScope class is used in debug mode to catch unwanted | 1040 // The NoAllocationScope class is used in debug mode to catch unwanted |
| 1033 // allocations. E.g. allocations during GC. | 1041 // allocations. E.g. allocations during GC. |
| 1034 template<ThreadAffinity Affinity> | 1042 template<ThreadAffinity Affinity> |
| 1035 class NoAllocationScope { | 1043 class NoAllocationScope { |
| 1036 public: | 1044 public: |
| 1037 NoAllocationScope() : m_active(true) { enter(); } | 1045 NoAllocationScope() : m_active(true) { enter(); } |
| 1038 | 1046 |
| (...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2418 }; | 2426 }; |
| 2419 | 2427 |
| 2420 template<typename T> | 2428 template<typename T> |
| 2421 struct IfWeakMember<WeakMember<T> > { | 2429 struct IfWeakMember<WeakMember<T> > { |
| 2422 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } | 2430 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit or->isAlive(t.get()); } |
| 2423 }; | 2431 }; |
| 2424 | 2432 |
| 2425 } // namespace blink | 2433 } // namespace blink |
| 2426 | 2434 |
| 2427 #endif // Heap_h | 2435 #endif // Heap_h |
| OLD | NEW |