| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 { | 109 { |
| 110 return (allocationGranularity - (sizeof(Header) % allocationGranularity)) %
allocationGranularity; | 110 return (allocationGranularity - (sizeof(Header) % allocationGranularity)) %
allocationGranularity; |
| 111 } | 111 } |
| 112 | 112 |
| 113 // Masks an address down to the enclosing blink page base address. | 113 // Masks an address down to the enclosing blink page base address. |
| 114 inline Address blinkPageAddress(Address address) | 114 inline Address blinkPageAddress(Address address) |
| 115 { | 115 { |
| 116 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blin
kPageBaseMask); | 116 return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blin
kPageBaseMask); |
| 117 } | 117 } |
| 118 | 118 |
| 119 #ifndef NDEBUG | 119 #if ENABLE(ASSERT) |
| 120 | 120 |
| 121 // Sanity check for a page header address: the address of the page | 121 // Sanity check for a page header address: the address of the page |
| 122 // header should be OS page size away from being Blink page size | 122 // header should be OS page size away from being Blink page size |
| 123 // aligned. | 123 // aligned. |
| 124 inline bool isPageHeaderAddress(Address address) | 124 inline bool isPageHeaderAddress(Address address) |
| 125 { | 125 { |
| 126 return !((reinterpret_cast<uintptr_t>(address) & blinkPageOffsetMask) - osPa
geSize()); | 126 return !((reinterpret_cast<uintptr_t>(address) & blinkPageOffsetMask) - osPa
geSize()); |
| 127 } | 127 } |
| 128 #endif | 128 #endif |
| 129 | 129 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 // | 297 // |
| 298 // Object memory layout: | 298 // Object memory layout: |
| 299 // [ LargeObjectHeader | ] [ FinalizedObjectHeader | ] HeapObjectHeader | payloa
d | 299 // [ LargeObjectHeader | ] [ FinalizedObjectHeader | ] HeapObjectHeader | payloa
d |
| 300 // The [ ] notation denotes that the LargeObjectHeader and the FinalizedObjectHe
ader | 300 // The [ ] notation denotes that the LargeObjectHeader and the FinalizedObjectHe
ader |
| 301 // are independently optional. | 301 // are independently optional. |
| 302 class PLATFORM_EXPORT HeapObjectHeader : public BasicObjectHeader { | 302 class PLATFORM_EXPORT HeapObjectHeader : public BasicObjectHeader { |
| 303 public: | 303 public: |
| 304 NO_SANITIZE_ADDRESS | 304 NO_SANITIZE_ADDRESS |
| 305 explicit HeapObjectHeader(size_t encodedSize) | 305 explicit HeapObjectHeader(size_t encodedSize) |
| 306 : BasicObjectHeader(encodedSize) | 306 : BasicObjectHeader(encodedSize) |
| 307 #ifndef NDEBUG | 307 #if ENABLE(ASSERT) |
| 308 , m_magic(magic) | 308 , m_magic(magic) |
| 309 #endif | 309 #endif |
| 310 { } | 310 { } |
| 311 | 311 |
| 312 NO_SANITIZE_ADDRESS | 312 NO_SANITIZE_ADDRESS |
| 313 HeapObjectHeader(size_t encodedSize, const GCInfo*) | 313 HeapObjectHeader(size_t encodedSize, const GCInfo*) |
| 314 : BasicObjectHeader(encodedSize) | 314 : BasicObjectHeader(encodedSize) |
| 315 #ifndef NDEBUG | 315 #if ENABLE(ASSERT) |
| 316 , m_magic(magic) | 316 , m_magic(magic) |
| 317 #endif | 317 #endif |
| 318 { } | 318 { } |
| 319 | 319 |
| 320 inline void checkHeader() const; | 320 inline void checkHeader() const; |
| 321 inline bool isMarked() const; | 321 inline bool isMarked() const; |
| 322 | 322 |
| 323 inline void mark(); | 323 inline void mark(); |
| 324 inline void unmark(); | 324 inline void unmark(); |
| 325 | 325 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 341 static void finalize(const GCInfo*, Address, size_t); | 341 static void finalize(const GCInfo*, Address, size_t); |
| 342 static HeapObjectHeader* fromPayload(const void*); | 342 static HeapObjectHeader* fromPayload(const void*); |
| 343 | 343 |
| 344 static const intptr_t magic = 0xc0de247; | 344 static const intptr_t magic = 0xc0de247; |
| 345 static const intptr_t zappedMagic = 0xC0DEdead; | 345 static const intptr_t zappedMagic = 0xC0DEdead; |
| 346 // The zap value for vtables should be < 4K to ensure it cannot be | 346 // The zap value for vtables should be < 4K to ensure it cannot be |
| 347 // used for dispatch. | 347 // used for dispatch. |
| 348 static const intptr_t zappedVTable = 0xd0d; | 348 static const intptr_t zappedVTable = 0xd0d; |
| 349 | 349 |
| 350 private: | 350 private: |
| 351 #ifndef NDEBUG | 351 #if ENABLE(ASSERT) |
| 352 intptr_t m_magic; | 352 intptr_t m_magic; |
| 353 #endif | 353 #endif |
| 354 }; | 354 }; |
| 355 | 355 |
| 356 const size_t objectHeaderSize = sizeof(HeapObjectHeader); | 356 const size_t objectHeaderSize = sizeof(HeapObjectHeader); |
| 357 | 357 |
| 358 // Each object on the GeneralHeap needs to carry a pointer to its | 358 // Each object on the GeneralHeap needs to carry a pointer to its |
| 359 // own GCInfo structure for tracing and potential finalization. | 359 // own GCInfo structure for tracing and potential finalization. |
| 360 class PLATFORM_EXPORT FinalizedHeapObjectHeader : public HeapObjectHeader { | 360 class PLATFORM_EXPORT FinalizedHeapObjectHeader : public HeapObjectHeader { |
| 361 public: | 361 public: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 391 | 391 |
| 392 const size_t finalizedHeaderSize = sizeof(FinalizedHeapObjectHeader); | 392 const size_t finalizedHeaderSize = sizeof(FinalizedHeapObjectHeader); |
| 393 | 393 |
| 394 class FreeListEntry : public HeapObjectHeader { | 394 class FreeListEntry : public HeapObjectHeader { |
| 395 public: | 395 public: |
| 396 NO_SANITIZE_ADDRESS | 396 NO_SANITIZE_ADDRESS |
| 397 explicit FreeListEntry(size_t size) | 397 explicit FreeListEntry(size_t size) |
| 398 : HeapObjectHeader(freeListEncodedSize(size)) | 398 : HeapObjectHeader(freeListEncodedSize(size)) |
| 399 , m_next(0) | 399 , m_next(0) |
| 400 { | 400 { |
| 401 #if !defined(NDEBUG) && !defined(ADDRESS_SANITIZER) | 401 #if ENABLE(ASSERT) && !defined(ADDRESS_SANITIZER) |
| 402 // Zap free area with asterisks, aka 0x2a2a2a2a. | 402 // Zap free area with asterisks, aka 0x2a2a2a2a. |
| 403 // For ASan don't zap since we keep accounting in the freelist entry. | 403 // For ASan don't zap since we keep accounting in the freelist entry. |
| 404 for (size_t i = sizeof(*this); i < size; i++) | 404 for (size_t i = sizeof(*this); i < size; i++) |
| 405 reinterpret_cast<Address>(this)[i] = freelistZapValue; | 405 reinterpret_cast<Address>(this)[i] = freelistZapValue; |
| 406 ASSERT(size >= objectHeaderSize); | 406 ASSERT(size >= objectHeaderSize); |
| 407 zapMagic(); | 407 zapMagic(); |
| 408 #endif | 408 #endif |
| 409 } | 409 } |
| 410 | 410 |
| 411 Address address() { return reinterpret_cast<Address>(this); } | 411 Address address() { return reinterpret_cast<Address>(this); } |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 // multiple chained CallbackStack object instances. | 684 // multiple chained CallbackStack object instances. |
| 685 // There are two logical callback stacks. One containing all the marking callbac
ks and | 685 // There are two logical callback stacks. One containing all the marking callbac
ks and |
| 686 // one containing the weak pointer callbacks. | 686 // one containing the weak pointer callbacks. |
| 687 class CallbackStack { | 687 class CallbackStack { |
| 688 public: | 688 public: |
| 689 CallbackStack(CallbackStack** first) | 689 CallbackStack(CallbackStack** first) |
| 690 : m_limit(&(m_buffer[bufferSize])) | 690 : m_limit(&(m_buffer[bufferSize])) |
| 691 , m_current(&(m_buffer[0])) | 691 , m_current(&(m_buffer[0])) |
| 692 , m_next(*first) | 692 , m_next(*first) |
| 693 { | 693 { |
| 694 #ifndef NDEBUG | 694 #if ENABLE(ASSERT) |
| 695 clearUnused(); | 695 clearUnused(); |
| 696 #endif | 696 #endif |
| 697 *first = this; | 697 *first = this; |
| 698 } | 698 } |
| 699 | 699 |
| 700 ~CallbackStack(); | 700 ~CallbackStack(); |
| 701 void clearUnused(); | 701 void clearUnused(); |
| 702 | 702 |
| 703 bool isEmpty(); | 703 bool isEmpty(); |
| 704 | 704 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 730 bool popAndInvokeCallback(CallbackStack** first, Visitor*); | 730 bool popAndInvokeCallback(CallbackStack** first, Visitor*); |
| 731 static void invokeCallbacks(CallbackStack** first, Visitor*); | 731 static void invokeCallbacks(CallbackStack** first, Visitor*); |
| 732 | 732 |
| 733 Item* allocateEntry(CallbackStack** first) | 733 Item* allocateEntry(CallbackStack** first) |
| 734 { | 734 { |
| 735 if (m_current < m_limit) | 735 if (m_current < m_limit) |
| 736 return m_current++; | 736 return m_current++; |
| 737 return (new CallbackStack(first))->allocateEntry(first); | 737 return (new CallbackStack(first))->allocateEntry(first); |
| 738 } | 738 } |
| 739 | 739 |
| 740 #ifndef NDEBUG | 740 #if ENABLE(ASSERT) |
| 741 bool hasCallbackForObject(const void*); | 741 bool hasCallbackForObject(const void*); |
| 742 #endif | 742 #endif |
| 743 | 743 |
| 744 private: | 744 private: |
| 745 void invokeOldestCallbacks(Visitor*); | 745 void invokeOldestCallbacks(Visitor*); |
| 746 | 746 |
| 747 static const size_t bufferSize = 8000; | 747 static const size_t bufferSize = 8000; |
| 748 Item m_buffer[bufferSize]; | 748 Item m_buffer[bufferSize]; |
| 749 Item* m_limit; | 749 Item* m_limit; |
| 750 Item* m_current; | 750 Item* m_current; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 770 virtual void sweep() = 0; | 770 virtual void sweep() = 0; |
| 771 | 771 |
| 772 // Forcefully finalize all objects in this part of the Blink heap | 772 // Forcefully finalize all objects in this part of the Blink heap |
| 773 // (potentially with the exception of one object). This is used | 773 // (potentially with the exception of one object). This is used |
| 774 // during thread termination to make sure that all objects for the | 774 // during thread termination to make sure that all objects for the |
| 775 // dying thread are finalized. | 775 // dying thread are finalized. |
| 776 virtual void assertEmpty() = 0; | 776 virtual void assertEmpty() = 0; |
| 777 | 777 |
| 778 virtual void clearFreeLists() = 0; | 778 virtual void clearFreeLists() = 0; |
| 779 virtual void clearMarks() = 0; | 779 virtual void clearMarks() = 0; |
| 780 #ifndef NDEBUG | 780 #if ENABLE(ASSERT) |
| 781 virtual void getScannedStats(HeapStats&) = 0; | 781 virtual void getScannedStats(HeapStats&) = 0; |
| 782 #endif | 782 #endif |
| 783 | 783 |
| 784 virtual void makeConsistentForGC() = 0; | 784 virtual void makeConsistentForGC() = 0; |
| 785 virtual bool isConsistentForGC() = 0; | 785 virtual bool isConsistentForGC() = 0; |
| 786 | 786 |
| 787 // Returns a bucket number for inserting a FreeListEntry of a | 787 // Returns a bucket number for inserting a FreeListEntry of a |
| 788 // given size. All FreeListEntries in the given bucket, n, have | 788 // given size. All FreeListEntries in the given bucket, n, have |
| 789 // size >= 2^n. | 789 // size >= 2^n. |
| 790 static int bucketIndexForSize(size_t); | 790 static int bucketIndexForSize(size_t); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 807 virtual ~ThreadHeap(); | 807 virtual ~ThreadHeap(); |
| 808 | 808 |
| 809 virtual BaseHeapPage* heapPageFromAddress(Address); | 809 virtual BaseHeapPage* heapPageFromAddress(Address); |
| 810 #if ENABLE(GC_TRACING) | 810 #if ENABLE(GC_TRACING) |
| 811 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address); | 811 virtual const GCInfo* findGCInfoOfLargeHeapObject(Address); |
| 812 #endif | 812 #endif |
| 813 virtual void sweep(); | 813 virtual void sweep(); |
| 814 virtual void assertEmpty(); | 814 virtual void assertEmpty(); |
| 815 virtual void clearFreeLists(); | 815 virtual void clearFreeLists(); |
| 816 virtual void clearMarks(); | 816 virtual void clearMarks(); |
| 817 #ifndef NDEBUG | 817 #if ENABLE(ASSERT) |
| 818 virtual void getScannedStats(HeapStats&); | 818 virtual void getScannedStats(HeapStats&); |
| 819 #endif | 819 #endif |
| 820 | 820 |
| 821 virtual void makeConsistentForGC(); | 821 virtual void makeConsistentForGC(); |
| 822 virtual bool isConsistentForGC(); | 822 virtual bool isConsistentForGC(); |
| 823 | 823 |
| 824 ThreadState* threadState() { return m_threadState; } | 824 ThreadState* threadState() { return m_threadState; } |
| 825 HeapStats& stats() { return m_threadState->stats(); } | 825 HeapStats& stats() { return m_threadState->stats(); } |
| 826 void flushHeapContainsCache() | 826 void flushHeapContainsCache() |
| 827 { | 827 { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 // and the object. Returns false when there is nothing more to do. | 935 // and the object. Returns false when there is nothing more to do. |
| 936 static bool popAndInvokeTraceCallback(Visitor*); | 936 static bool popAndInvokeTraceCallback(Visitor*); |
| 937 | 937 |
| 938 // Remove an item from the weak callback work list and call the callback | 938 // Remove an item from the weak callback work list and call the callback |
| 939 // with the visitor and the closure pointer. Returns false when there is | 939 // with the visitor and the closure pointer. Returns false when there is |
| 940 // nothing more to do. | 940 // nothing more to do. |
| 941 static bool popAndInvokeWeakPointerCallback(Visitor*); | 941 static bool popAndInvokeWeakPointerCallback(Visitor*); |
| 942 | 942 |
| 943 // Register an ephemeron table for fixed-point iteration. | 943 // Register an ephemeron table for fixed-point iteration. |
| 944 static void registerWeakTable(void* containerObject, EphemeronCallback, Ephe
meronCallback); | 944 static void registerWeakTable(void* containerObject, EphemeronCallback, Ephe
meronCallback); |
| 945 #ifndef NDEBUG | 945 #if ENABLE(ASSERT) |
| 946 static bool weakTableRegistered(const void*); | 946 static bool weakTableRegistered(const void*); |
| 947 #endif | 947 #endif |
| 948 | 948 |
| 949 template<typename T> static Address allocate(size_t); | 949 template<typename T> static Address allocate(size_t); |
| 950 template<typename T> static Address reallocate(void* previous, size_t); | 950 template<typename T> static Address reallocate(void* previous, size_t); |
| 951 | 951 |
| 952 static void collectGarbage(ThreadState::StackState); | 952 static void collectGarbage(ThreadState::StackState); |
| 953 static void collectAllGarbage(); | 953 static void collectAllGarbage(); |
| 954 static void setForcePreciseGCForTesting(); | 954 static void setForcePreciseGCForTesting(); |
| 955 | 955 |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 Address headerAddress = m_currentAllocationPoint; | 1366 Address headerAddress = m_currentAllocationPoint; |
| 1367 m_currentAllocationPoint += allocationSize; | 1367 m_currentAllocationPoint += allocationSize; |
| 1368 m_remainingAllocationSize -= allocationSize; | 1368 m_remainingAllocationSize -= allocationSize; |
| 1369 Header* header = new (NotNull, headerAddress) Header(allocationSize, gcInfo)
; | 1369 Header* header = new (NotNull, headerAddress) Header(allocationSize, gcInfo)
; |
| 1370 size_t payloadSize = allocationSize - sizeof(Header); | 1370 size_t payloadSize = allocationSize - sizeof(Header); |
| 1371 stats().increaseObjectSpace(payloadSize); | 1371 stats().increaseObjectSpace(payloadSize); |
| 1372 Address result = headerAddress + sizeof(*header); | 1372 Address result = headerAddress + sizeof(*header); |
| 1373 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); | 1373 ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask)); |
| 1374 // Unpoison the memory used for the object (payload). | 1374 // Unpoison the memory used for the object (payload). |
| 1375 ASAN_UNPOISON_MEMORY_REGION(result, payloadSize); | 1375 ASAN_UNPOISON_MEMORY_REGION(result, payloadSize); |
| 1376 #if !defined(NDEBUG) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) | 1376 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) |
| 1377 memset(result, 0, payloadSize); | 1377 memset(result, 0, payloadSize); |
| 1378 #endif | 1378 #endif |
| 1379 ASSERT(heapPageFromAddress(headerAddress + allocationSize - 1)); | 1379 ASSERT(heapPageFromAddress(headerAddress + allocationSize - 1)); |
| 1380 return result; | 1380 return result; |
| 1381 } | 1381 } |
| 1382 | 1382 |
| 1383 // FIXME: Allocate objects that do not need finalization separately | 1383 // FIXME: Allocate objects that do not need finalization separately |
| 1384 // and use separate sweeping to not have to check for finalizers. | 1384 // and use separate sweeping to not have to check for finalizers. |
| 1385 template<typename T> | 1385 template<typename T> |
| 1386 Address Heap::allocate(size_t size) | 1386 Address Heap::allocate(size_t size) |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1490 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) |
| 1491 { | 1491 { |
| 1492 visitor->registerWeakMembers(closure, object, callback); | 1492 visitor->registerWeakMembers(closure, object, callback); |
| 1493 } | 1493 } |
| 1494 | 1494 |
| 1495 static void registerWeakTable(Visitor* visitor, const void* closure, Ephemer
onCallback iterationCallback, EphemeronCallback iterationDoneCallback) | 1495 static void registerWeakTable(Visitor* visitor, const void* closure, Ephemer
onCallback iterationCallback, EphemeronCallback iterationDoneCallback) |
| 1496 { | 1496 { |
| 1497 visitor->registerWeakTable(closure, iterationCallback, iterationDoneCall
back); | 1497 visitor->registerWeakTable(closure, iterationCallback, iterationDoneCall
back); |
| 1498 } | 1498 } |
| 1499 | 1499 |
| 1500 #ifndef NDEBUG | 1500 #if ENABLE(ASSERT) |
| 1501 static bool weakTableRegistered(Visitor* visitor, const void* closure) | 1501 static bool weakTableRegistered(Visitor* visitor, const void* closure) |
| 1502 { | 1502 { |
| 1503 return visitor->weakTableRegistered(closure); | 1503 return visitor->weakTableRegistered(closure); |
| 1504 } | 1504 } |
| 1505 #endif | 1505 #endif |
| 1506 | 1506 |
| 1507 template<typename T> | 1507 template<typename T> |
| 1508 struct ResultType { | 1508 struct ResultType { |
| 1509 typedef T* Type; | 1509 typedef T* Type; |
| 1510 }; | 1510 }; |
| (...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2263 COMPILE_ASSERT(!WTF::IsWeak<T>::value, WeDontSupportWeaknessInHeapVector
sOrDeques); | 2263 COMPILE_ASSERT(!WTF::IsWeak<T>::value, WeDontSupportWeaknessInHeapVector
sOrDeques); |
| 2264 if (WTF::ShouldBeTraced<Traits>::value) | 2264 if (WTF::ShouldBeTraced<Traits>::value) |
| 2265 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); | 2265 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); |
| 2266 } | 2266 } |
| 2267 static void mark(Visitor* visitor, const Backing* backing) | 2267 static void mark(Visitor* visitor, const Backing* backing) |
| 2268 { | 2268 { |
| 2269 visitor->mark(backing, &trace); | 2269 visitor->mark(backing, &trace); |
| 2270 } | 2270 } |
| 2271 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2271 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
| 2272 { | 2272 { |
| 2273 #ifndef NDEBUG | 2273 #if ENABLE(ASSERT) |
| 2274 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | 2274 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); |
| 2275 #endif | 2275 #endif |
| 2276 } | 2276 } |
| 2277 }; | 2277 }; |
| 2278 | 2278 |
| 2279 // The trace trait for the heap hashtable backing is used when we find a | 2279 // The trace trait for the heap hashtable backing is used when we find a |
| 2280 // direct pointer to the backing from the conservative stack scanner. This | 2280 // direct pointer to the backing from the conservative stack scanner. This |
| 2281 // normally indicates that there is an ongoing iteration over the table, and so | 2281 // normally indicates that there is an ongoing iteration over the table, and so |
| 2282 // we disable weak processing of table entries. When the backing is found | 2282 // we disable weak processing of table entries. When the backing is found |
| 2283 // through the owning hash table we mark differently, in order to do weak | 2283 // through the owning hash table we mark differently, in order to do weak |
| 2284 // processing. | 2284 // processing. |
| 2285 template<typename Table> | 2285 template<typename Table> |
| 2286 struct TraceTrait<HeapHashTableBacking<Table> > { | 2286 struct TraceTrait<HeapHashTableBacking<Table> > { |
| 2287 typedef HeapHashTableBacking<Table> Backing; | 2287 typedef HeapHashTableBacking<Table> Backing; |
| 2288 typedef typename Table::ValueTraits Traits; | 2288 typedef typename Table::ValueTraits Traits; |
| 2289 static void trace(Visitor* visitor, void* self) | 2289 static void trace(Visitor* visitor, void* self) |
| 2290 { | 2290 { |
| 2291 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 2291 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
| 2292 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); | 2292 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActStrong, Backing, void>::trace(visitor, self); |
| 2293 } | 2293 } |
| 2294 static void mark(Visitor* visitor, const Backing* backing) | 2294 static void mark(Visitor* visitor, const Backing* backing) |
| 2295 { | 2295 { |
| 2296 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) | 2296 if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WT
F::WeakHandlingInCollections) |
| 2297 visitor->mark(backing, &trace); | 2297 visitor->mark(backing, &trace); |
| 2298 else | 2298 else |
| 2299 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. | 2299 visitor->markNoTracing(backing); // If we know the trace function wi
ll do nothing there is no need to call it. |
| 2300 } | 2300 } |
| 2301 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2301 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
| 2302 { | 2302 { |
| 2303 #ifndef NDEBUG | 2303 #if ENABLE(ASSERT) |
| 2304 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); | 2304 visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>
::get()); |
| 2305 #endif | 2305 #endif |
| 2306 } | 2306 } |
| 2307 }; | 2307 }; |
| 2308 | 2308 |
| 2309 template<typename Table> | 2309 template<typename Table> |
| 2310 void HeapHashTableBacking<Table>::finalize(void* pointer) | 2310 void HeapHashTableBacking<Table>::finalize(void* pointer) |
| 2311 { | 2311 { |
| 2312 typedef typename Table::ValueType Value; | 2312 typedef typename Table::ValueType Value; |
| 2313 ASSERT(Table::ValueTraits::needsDestruction); | 2313 ASSERT(Table::ValueTraits::needsDestruction); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2347 }; | 2347 }; |
| 2348 | 2348 |
| 2349 template<typename T> | 2349 template<typename T> |
| 2350 struct IfWeakMember<WeakMember<T> > { | 2350 struct IfWeakMember<WeakMember<T> > { |
| 2351 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } | 2351 static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visit
or->isAlive(t.get()); } |
| 2352 }; | 2352 }; |
| 2353 | 2353 |
| 2354 } | 2354 } |
| 2355 | 2355 |
| 2356 #endif // Heap_h | 2356 #endif // Heap_h |
| OLD | NEW |