Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / heap / Heap.h
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #ifndef Heap_h
32 #define Heap_h
33
34 #include "platform/PlatformExport.h"
35 #include "platform/heap/AddressSanitizer.h"
36 #include "platform/heap/ThreadState.h"
37 #include "platform/heap/Visitor.h"
38 #include "public/platform/WebThread.h"
39 #include "wtf/Assertions.h"
40 #include "wtf/HashCountedSet.h"
41 #include "wtf/LinkedHashSet.h"
42 #include "wtf/ListHashSet.h"
43 #include "wtf/OwnPtr.h"
44 #include "wtf/PassRefPtr.h"
45 #include "wtf/ThreadSafeRefCounted.h"
46
47 #include <stdint.h>
48
49 namespace blink {
50
51 const size_t blinkPageSizeLog2 = 17;
52 const size_t blinkPageSize = 1 << blinkPageSizeLog2;
53 const size_t blinkPageOffsetMask = blinkPageSize - 1;
54 const size_t blinkPageBaseMask = ~blinkPageOffsetMask;
55
56 // We allocate pages at random addresses but in groups of
57 // blinkPagesPerRegion at a given random address. We group pages to
58 // not spread out too much over the address space which would blow
59 // away the page tables and lead to bad performance.
60 const size_t blinkPagesPerRegion = 10;
61
62 // Double precision floats are more efficient when 8 byte aligned, so we 8 byte
63 // align all allocations even on 32 bit.
64 const size_t allocationGranularity = 8;
65 const size_t allocationMask = allocationGranularity - 1;
66 const size_t objectStartBitMapSize = (blinkPageSize + ((8 * allocationGranularity) - 1)) / (8 * allocationGranularity);
67 const size_t reservedForObjectBitMap = ((objectStartBitMapSize + allocationMask) & ~allocationMask);
68 const size_t maxHeapObjectSizeLog2 = 27;
69 const size_t maxHeapObjectSize = 1 << maxHeapObjectSizeLog2;
70
71 const size_t markBitMask = 1;
72 const size_t freeListMask = 2;
73 // The dead bit is used for objects that have gone through a GC marking, but did
74 // not get swept before a new GC started. In that case we set the dead bit on
75 // objects that were not marked in the previous GC to ensure we are not tracing
76 // them via a conservatively found pointer. Tracing dead objects could lead to
77 // tracing of already finalized objects in another thread's heap which is a
78 // use-after-free situation.
79 const size_t deadBitMask = 4;
80 // On free-list entries we reuse the dead bit to distinguish a normal free-list
81 // entry from one that has been promptly freed.
82 const size_t promptlyFreedMask = freeListMask | deadBitMask;
83 #if ENABLE(GC_PROFILE_HEAP)
84 const size_t heapObjectGenerations = 8;
85 const size_t maxHeapObjectAge = heapObjectGenerations - 1;
86 const size_t heapObjectAgeMask = ~(maxHeapObjectSize - 1);
87 const size_t sizeMask = ~heapObjectAgeMask & ~static_cast<size_t>(7);
88 #else
89 const size_t sizeMask = ~static_cast<size_t>(7);
90 #endif
91 const uint8_t freelistZapValue = 42;
92 const uint8_t finalizedZapValue = 24;
93 // The orphaned zap value must be zero in the lowest bits to allow for using
94 // the mark bit when tracing.
95 const uint8_t orphanedZapValue = 240;
96
97 const int numberOfMarkingThreads = 2;
98
99 const int numberOfPagesToConsiderForCoalescing = 100;
100
101 enum CallbackInvocationMode {
102     GlobalMarking,
103     ThreadLocalMarking,
104 };
105
106 class CallbackStack;
107 class HeapStats;
108 class PageMemory;
109 template<ThreadAffinity affinity> class ThreadLocalPersistents;
110 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > > class Persistent;
111 template<typename T> class CrossThreadPersistent;
112
113 #if ENABLE(GC_PROFILE_HEAP)
114 class TracedValue;
115 #endif
116
117 PLATFORM_EXPORT size_t osPageSize();
118
119 // Blink heap pages are set up with a guard page before and after the
120 // payload.
121 inline size_t blinkPagePayloadSize()
122 {
123     return blinkPageSize - 2 * osPageSize();
124 }
125
126 // Blink heap pages are aligned to the Blink heap page size.
127 // Therefore, the start of a Blink page can be obtained by
128 // rounding down to the Blink page size.
129 inline Address roundToBlinkPageStart(Address address)
130 {
131     return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blinkPageBaseMask);
132 }
133
134 inline Address roundToBlinkPageEnd(Address address)
135 {
136     return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address - 1) & blinkPageBaseMask) + blinkPageSize;
137 }
138
139 // Compute the amount of padding we have to add to a header to make
140 // the size of the header plus the padding a multiple of 8 bytes.
141 template<typename Header>
142 inline size_t headerPadding()
143 {
144     return (allocationGranularity - (sizeof(Header) % allocationGranularity)) % allocationGranularity;
145 }
146
147 // Masks an address down to the enclosing blink page base address.
148 inline Address blinkPageAddress(Address address)
149 {
150     return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blinkPageBaseMask);
151 }
152
153 #if ENABLE(ASSERT)
154
155 // Sanity check for a page header address: the address of the page
156 // header should be OS page size away from being Blink page size
157 // aligned.
158 inline bool isPageHeaderAddress(Address address)
159 {
160     return !((reinterpret_cast<uintptr_t>(address) & blinkPageOffsetMask) - osPageSize());
161 }
162 #endif
163
164 // Mask an address down to the enclosing oilpan heap base page.
165 // All oilpan heap pages are aligned at blinkPageBase plus an OS page size.
166 // FIXME: Remove PLATFORM_EXPORT once we get a proper public interface to our typed heaps.
167 // This is only exported to enable tests in HeapTest.cpp.
168 PLATFORM_EXPORT inline BaseHeapPage* pageHeaderFromObject(const void* object)
169 {
170     Address address = reinterpret_cast<Address>(const_cast<void*>(object));
171     return reinterpret_cast<BaseHeapPage*>(blinkPageAddress(address) + osPageSize());
172 }
173
174 // Large allocations are allocated as separate objects and linked in a
175 // list.
176 //
177 // In order to use the same memory allocation routines for everything
178 // allocated in the heap, large objects are considered heap pages
179 // containing only one object.
180 //
181 // The layout of a large heap object is as follows:
182 //
183 // | BaseHeapPage | next pointer | FinalizedHeapObjectHeader or HeapObjectHeader | payload |
184 template<typename Header>
185 class LargeHeapObject : public BaseHeapPage {
186 public:
187     LargeHeapObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state) : BaseHeapPage(storage, gcInfo, state)
188     {
189         COMPILE_ASSERT(!(sizeof(LargeHeapObject<Header>) & allocationMask), large_heap_object_header_misaligned);
190     }
191
192     virtual void checkAndMarkPointer(Visitor*, Address) OVERRIDE;
193     virtual bool isLargeObject() OVERRIDE { return true; }
194
195 #if ENABLE(GC_PROFILE_MARKING)
196     virtual const GCInfo* findGCInfo(Address address)
197     {
198         if (!objectContains(address))
199             return 0;
200         return gcInfo();
201     }
202 #endif
203
204 #if ENABLE(GC_PROFILE_HEAP)
205     void snapshot(TracedValue*, ThreadState::SnapshotInfo*);
206 #endif
207
208     void link(LargeHeapObject<Header>** previousNext)
209     {
210         m_next = *previousNext;
211         *previousNext = this;
212     }
213
214     void unlink(LargeHeapObject<Header>** previousNext)
215     {
216         *previousNext = m_next;
217     }
218
219     // The LargeHeapObject pseudo-page contains one actual object. Determine
220     // whether the pointer is within that object.
221     bool objectContains(Address object)
222     {
223         return (payload() <= object) && (object < address() + size());
224     }
225
226     // Returns true for any address that is on one of the pages that this
227     // large object uses. That ensures that we can use a negative result to
228     // populate the negative page cache.
229     virtual bool contains(Address object) OVERRIDE
230     {
231         return roundToBlinkPageStart(address()) <= object && object < roundToBlinkPageEnd(address() + size());
232     }
233
234     LargeHeapObject<Header>* next()
235     {
236         return m_next;
237     }
238
239     size_t size()
240     {
241         return heapObjectHeader()->size() + sizeof(LargeHeapObject<Header>) + headerPadding<Header>();
242     }
243
244     Address payload() { return heapObjectHeader()->payload(); }
245     size_t payloadSize() { return heapObjectHeader()->payloadSize(); }
246
247     Header* heapObjectHeader()
248     {
249         Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + headerPadding<Header>();
250         return reinterpret_cast<Header*>(headerAddress);
251     }
252
253     bool isMarked();
254     void unmark();
255     void getStats(HeapStats&);
256     void mark(Visitor*);
257     void finalize();
258     void setDeadMark();
259     virtual void markOrphaned()
260     {
261         // Zap the payload with a recognizable value to detect any incorrect
262         // cross thread pointer usage.
263         memset(payload(), orphanedZapValue, payloadSize());
264         BaseHeapPage::markOrphaned();
265     }
266
267 private:
268     friend class ThreadHeap<Header>;
269
270     LargeHeapObject<Header>* m_next;
271 };
272
273 // The BasicObjectHeader is the minimal object header. It is used when
274 // encountering heap space of size allocationGranularity to mark it as
275 // as freelist entry.
276 class PLATFORM_EXPORT BasicObjectHeader {
277 public:
278     NO_SANITIZE_ADDRESS
279     explicit BasicObjectHeader(size_t encodedSize)
280         : m_size(encodedSize) { }
281
282     static size_t freeListEncodedSize(size_t size) { return size | freeListMask; }
283
284     NO_SANITIZE_ADDRESS
285     bool isFree() { return m_size & freeListMask; }
286
287     NO_SANITIZE_ADDRESS
288     bool isPromptlyFreed() { return (m_size & promptlyFreedMask) == promptlyFreedMask; }
289
290     NO_SANITIZE_ADDRESS
291     void markPromptlyFreed() { m_size |= promptlyFreedMask; }
292
293     NO_SANITIZE_ADDRESS
294     size_t size() const { return m_size & sizeMask; }
295
296 #if ENABLE(GC_PROFILE_HEAP)
297     NO_SANITIZE_ADDRESS
298     size_t encodedSize() const { return m_size; }
299
300     NO_SANITIZE_ADDRESS
301     size_t age() const { return m_size >> maxHeapObjectSizeLog2; }
302
303     NO_SANITIZE_ADDRESS
304     void incAge()
305     {
306         size_t current = age();
307         if (current < maxHeapObjectAge)
308             m_size = ((current + 1) << maxHeapObjectSizeLog2) | (m_size & ~heapObjectAgeMask);
309     }
310 #endif
311
312 protected:
313     volatile unsigned m_size;
314 };
315
316 // Our heap object layout is layered with the HeapObjectHeader closest
317 // to the payload, this can be wrapped in a FinalizedObjectHeader if the
318 // object is on the GeneralHeap and not on a specific TypedHeap.
319 // Finally if the object is a large object (> blinkPageSize/2) then it is
320 // wrapped with a LargeObjectHeader.
321 //
322 // Object memory layout:
323 // [ LargeObjectHeader | ] [ FinalizedObjectHeader | ] HeapObjectHeader | payload
324 // The [ ] notation denotes that the LargeObjectHeader and the FinalizedObjectHeader
325 // are independently optional.
326 class PLATFORM_EXPORT HeapObjectHeader : public BasicObjectHeader {
327 public:
328     NO_SANITIZE_ADDRESS
329     explicit HeapObjectHeader(size_t encodedSize)
330         : BasicObjectHeader(encodedSize)
331 #if ENABLE(ASSERT)
332         , m_magic(magic)
333 #endif
334     { }
335
336     NO_SANITIZE_ADDRESS
337     HeapObjectHeader(size_t encodedSize, const GCInfo*)
338         : BasicObjectHeader(encodedSize)
339 #if ENABLE(ASSERT)
340         , m_magic(magic)
341 #endif
342     { }
343
344     inline void checkHeader() const;
345     inline bool isMarked() const;
346
347     inline void mark();
348     inline void unmark();
349
350     inline const GCInfo* gcInfo() { return 0; }
351
352     inline Address payload();
353     inline size_t payloadSize();
354     inline Address payloadEnd();
355
356     inline void setDeadMark();
357     inline void clearDeadMark();
358     inline bool hasDeadMark() const;
359
360     // Zap magic number with a new magic number that means there was once an
361     // object allocated here, but it was freed because nobody marked it during
362     // GC.
363     void zapMagic();
364
365     static void finalize(const GCInfo*, Address, size_t);
366     static HeapObjectHeader* fromPayload(const void*);
367
368     static const intptr_t magic = 0xc0de247;
369     static const intptr_t zappedMagic = 0xC0DEdead;
370     // The zap value for vtables should be < 4K to ensure it cannot be
371     // used for dispatch.
372     static const intptr_t zappedVTable = 0xd0d;
373
374 private:
375 #if ENABLE(ASSERT)
376     intptr_t m_magic;
377 #endif
378 };
379
380 const size_t objectHeaderSize = sizeof(HeapObjectHeader);
381
382 // Each object on the GeneralHeap needs to carry a pointer to its
383 // own GCInfo structure for tracing and potential finalization.
384 class PLATFORM_EXPORT FinalizedHeapObjectHeader : public HeapObjectHeader {
385 public:
386     NO_SANITIZE_ADDRESS
387     FinalizedHeapObjectHeader(size_t encodedSize, const GCInfo* gcInfo)
388         : HeapObjectHeader(encodedSize)
389         , m_gcInfo(gcInfo)
390     {
391     }
392
393     inline Address payload();
394     inline size_t payloadSize();
395
396     NO_SANITIZE_ADDRESS
397     const GCInfo* gcInfo() { return m_gcInfo; }
398
399     NO_SANITIZE_ADDRESS
400     TraceCallback traceCallback() { return m_gcInfo->m_trace; }
401
402     void finalize();
403
404     NO_SANITIZE_ADDRESS
405     inline bool hasFinalizer() { return m_gcInfo->hasFinalizer(); }
406
407     static FinalizedHeapObjectHeader* fromPayload(const void*);
408
409     NO_SANITIZE_ADDRESS
410     bool hasVTable() { return m_gcInfo->hasVTable(); }
411
412 private:
413     const GCInfo* m_gcInfo;
414 };
415
416 const size_t finalizedHeaderSize = sizeof(FinalizedHeapObjectHeader);
417
418 class FreeListEntry : public HeapObjectHeader {
419 public:
420     NO_SANITIZE_ADDRESS
421     explicit FreeListEntry(size_t size)
422         : HeapObjectHeader(freeListEncodedSize(size))
423         , m_next(0)
424     {
425 #if ENABLE(ASSERT) && !defined(ADDRESS_SANITIZER)
426         // Zap free area with asterisks, aka 0x2a2a2a2a.
427         // For ASan don't zap since we keep accounting in the freelist entry.
428         for (size_t i = sizeof(*this); i < size; i++)
429             reinterpret_cast<Address>(this)[i] = freelistZapValue;
430         ASSERT(size >= objectHeaderSize);
431         zapMagic();
432 #endif
433     }
434
435     Address address() { return reinterpret_cast<Address>(this); }
436
437     NO_SANITIZE_ADDRESS
438     void unlink(FreeListEntry** prevNext)
439     {
440         *prevNext = m_next;
441         m_next = 0;
442     }
443
444     NO_SANITIZE_ADDRESS
445     void link(FreeListEntry** prevNext)
446     {
447         m_next = *prevNext;
448         *prevNext = this;
449     }
450
451     NO_SANITIZE_ADDRESS
452     FreeListEntry* next() const { return m_next; }
453
454     NO_SANITIZE_ADDRESS
455     void append(FreeListEntry* next)
456     {
457         ASSERT(!m_next);
458         m_next = next;
459     }
460
461 #if defined(ADDRESS_SANITIZER)
462     NO_SANITIZE_ADDRESS
463     bool shouldAddToFreeList()
464     {
465         // Init if not already magic.
466         if ((m_asanMagic & ~asanDeferMemoryReuseMask) != asanMagic) {
467             m_asanMagic = asanMagic | asanDeferMemoryReuseCount;
468             return false;
469         }
470         // Decrement if count part of asanMagic > 0.
471         if (m_asanMagic & asanDeferMemoryReuseMask)
472             m_asanMagic--;
473         return !(m_asanMagic & asanDeferMemoryReuseMask);
474     }
475 #endif
476
477 private:
478     FreeListEntry* m_next;
479 #if defined(ADDRESS_SANITIZER)
480     unsigned m_asanMagic;
481 #endif
482 };
483
484 // Representation of Blink heap pages.
485 //
486 // Pages are specialized on the type of header on the object they
487 // contain. If a heap page only contains a certain type of object all
488 // of the objects will have the same GCInfo pointer and therefore that
489 // pointer can be stored in the HeapPage instead of in the header of
490 // each object. In that case objects have only a HeapObjectHeader and
491 // not a FinalizedHeapObjectHeader saving a word per object.
492 template<typename Header>
493 class HeapPage : public BaseHeapPage {
494 public:
495     HeapPage(PageMemory*, ThreadHeap<Header>*, const GCInfo*);
496
497     void link(HeapPage**);
498     static void unlink(ThreadHeap<Header>*, HeapPage*, HeapPage**);
499
500     bool isEmpty();
501
502     // Returns true for the whole blinkPageSize page that the page is on, even
503     // for the header, and the unmapped guard page at the start. That ensures
504     // the result can be used to populate the negative page cache.
505     virtual bool contains(Address addr) OVERRIDE
506     {
507         Address blinkPageStart = roundToBlinkPageStart(address());
508         ASSERT(blinkPageStart == address() - osPageSize()); // Page is at aligned address plus guard page size.
509         return blinkPageStart <= addr && addr < blinkPageStart + blinkPageSize;
510     }
511
512     HeapPage* next() { return m_next; }
513
514     Address payload()
515     {
516         return address() + sizeof(*this) + headerPadding<Header>();
517     }
518
519     static size_t payloadSize()
520     {
521         return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header>()) & ~allocationMask;
522     }
523
524     Address end() { return payload() + payloadSize(); }
525
526     void getStats(HeapStats&);
527     void clearLiveAndMarkDead();
528     void sweep(HeapStats*, ThreadHeap<Header>*);
529     void clearObjectStartBitMap();
530     void finalize(Header*);
531     virtual void checkAndMarkPointer(Visitor*, Address) OVERRIDE;
532 #if ENABLE(GC_PROFILE_MARKING)
533     const GCInfo* findGCInfo(Address) OVERRIDE;
534 #endif
535 #if ENABLE(GC_PROFILE_HEAP)
536     virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*);
537 #endif
538
539 #if defined(ADDRESS_SANITIZER)
540     void poisonUnmarkedObjects();
541 #endif
542     NO_SANITIZE_ADDRESS
543     virtual void markOrphaned()
544     {
545         // Zap the payload with a recognizable value to detect any incorrect
546         // cross thread pointer usage.
547 #if defined(ADDRESS_SANITIZER)
548         // Don't use memset when running with ASan since this needs to zap
549         // poisoned memory as well and the NO_SANITIZE_ADDRESS annotation
550         // only works for code in this method and not for calls to memset.
551         for (Address current = payload(); current < payload() + payloadSize(); ++current)
552             *current = orphanedZapValue;
553 #else
554         memset(payload(), orphanedZapValue, payloadSize());
555 #endif
556         BaseHeapPage::markOrphaned();
557     }
558
559 protected:
560     Header* findHeaderFromAddress(Address);
561     void populateObjectStartBitMap();
562     bool isObjectStartBitMapComputed() { return m_objectStartBitMapComputed; }
563     TraceCallback traceCallback(Header*);
564     bool hasVTable(Header*);
565
566     intptr_t padding() const { return m_padding; }
567
568     HeapPage<Header>* m_next;
569     intptr_t m_padding; // Preserve 8-byte alignment on 32-bit systems.
570     bool m_objectStartBitMapComputed;
571     uint8_t m_objectStartBitMap[reservedForObjectBitMap];
572
573     friend class ThreadHeap<Header>;
574 };
575
576 class AddressEntry {
577 public:
578     AddressEntry() : m_address(0) { }
579
580     explicit AddressEntry(Address address) : m_address(address) { }
581
582     Address address() const { return m_address; }
583
584 private:
585     Address m_address;
586 };
587
588 class PositiveEntry : public AddressEntry {
589 public:
590     PositiveEntry()
591         : AddressEntry()
592         , m_containingPage(0)
593     {
594     }
595
596     PositiveEntry(Address address, BaseHeapPage* containingPage)
597         : AddressEntry(address)
598         , m_containingPage(containingPage)
599     {
600     }
601
602     BaseHeapPage* result() const { return m_containingPage; }
603
604     typedef BaseHeapPage* LookupResult;
605
606 private:
607     BaseHeapPage* m_containingPage;
608 };
609
610 class NegativeEntry : public AddressEntry {
611 public:
612     NegativeEntry() : AddressEntry() { }
613
614     NegativeEntry(Address address, bool) : AddressEntry(address) { }
615
616     bool result() const { return true; }
617
618     typedef bool LookupResult;
619 };
620
621 // A HeapExtentCache provides a fast way of taking an arbitrary
622 // pointer-sized word, and determining whether it can be interpreted
623 // as a pointer to an area that is managed by the garbage collected
624 // Blink heap. There is a cache of 'pages' that have previously been
625 // determined to be wholly inside the heap. The size of these pages must be
626 // smaller than the allocation alignment of the heap pages. We determine
627 // on-heap-ness by rounding down the pointer to the nearest page and looking up
628 // the page in the cache. If there is a miss in the cache we can ask the heap
629 // to determine the status of the pointer by iterating over all of the heap.
630 // The result is then cached in the two-way associative page cache.
631 //
632 // A HeapContainsCache is a positive cache. Therefore, it must be flushed when
633 // memory is removed from the Blink heap. The HeapDoesNotContainCache is a
634 // negative cache, so it must be flushed when memory is added to the heap.
635 template<typename Entry>
636 class HeapExtentCache {
637 public:
638     HeapExtentCache()
639         : m_entries(adoptArrayPtr(new Entry[HeapExtentCache::numberOfEntries]))
640         , m_hasEntries(false)
641     {
642     }
643
644     void flush();
645     bool contains(Address);
646     bool isEmpty() { return !m_hasEntries; }
647
648     // Perform a lookup in the cache.
649     //
650     // If lookup returns null/false the argument address was not found in
651     // the cache and it is unknown if the address is in the Blink
652     // heap.
653     //
654     // If lookup returns true/a page, the argument address was found in the
655     // cache. For the HeapContainsCache this means the address is in the heap.
656     // For the HeapDoesNotContainCache this means the address is not in the
657     // heap.
658     PLATFORM_EXPORT typename Entry::LookupResult lookup(Address);
659
660     // Add an entry to the cache.
661     PLATFORM_EXPORT void addEntry(Address, typename Entry::LookupResult);
662
663 private:
664     static const int numberOfEntriesLog2 = 12;
665     static const int numberOfEntries = 1 << numberOfEntriesLog2;
666
667     static size_t hash(Address);
668
669     WTF::OwnPtr<Entry[]> m_entries;
670     bool m_hasEntries;
671
672     friend class ThreadState;
673 };
674
675 // Normally these would be typedefs instead of subclasses, but that makes them
676 // very hard to forward declare.
677 class HeapContainsCache : public HeapExtentCache<PositiveEntry> {
678 public:
679     BaseHeapPage* lookup(Address);
680     void addEntry(Address, BaseHeapPage*);
681 };
682
683 class HeapDoesNotContainCache : public HeapExtentCache<NegativeEntry> { };
684
685 // FIXME: This is currently used by the WebAudio code.
686 // We should attempt to restructure the WebAudio code so that the main thread
687 // alone determines life-time and receives messages about life-time from the
688 // audio thread.
689 template<typename T>
690 class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T>, public WTF::ThreadSafeRefCountedBase {
691     WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected);
692
693 public:
694     ThreadSafeRefCountedGarbageCollected()
695     {
696         makeKeepAlive();
697     }
698
699     // Override ref to deal with a case where a reference count goes up
700     // from 0 to 1. This can happen in the following scenario:
701     // (1) The reference count becomes 0, but on-stack pointers keep references to the object.
702     // (2) The on-stack pointer is assigned to a RefPtr. The reference count becomes 1.
703     // In this case, we have to resurrect m_keepAlive.
704     void ref()
705     {
706         MutexLocker lock(m_mutex);
707         if (UNLIKELY(!refCount())) {
708             makeKeepAlive();
709         }
710         WTF::ThreadSafeRefCountedBase::ref();
711     }
712
713     // Override deref to deal with our own deallocation based on ref counting.
714     void deref()
715     {
716         MutexLocker lock(m_mutex);
717         if (derefBase()) {
718             ASSERT(m_keepAlive);
719             m_keepAlive.clear();
720         }
721     }
722
723     using GarbageCollectedFinalized<T>::operator new;
724     using GarbageCollectedFinalized<T>::operator delete;
725
726 protected:
727     ~ThreadSafeRefCountedGarbageCollected() { }
728
729 private:
730     void makeKeepAlive()
731     {
732         ASSERT(!m_keepAlive);
733         m_keepAlive = adoptPtr(new CrossThreadPersistent<T>(static_cast<T*>(this)));
734     }
735
736     OwnPtr<CrossThreadPersistent<T> > m_keepAlive;
737     mutable Mutex m_mutex;
738 };
739
740 template<typename DataType>
741 class PagePool {
742 protected:
743     PagePool();
744
745     class PoolEntry {
746     public:
747         PoolEntry(DataType* data, PoolEntry* next)
748             : data(data)
749             , next(next)
750         { }
751
752         DataType* data;
753         PoolEntry* next;
754     };
755
756     PoolEntry* m_pool[NumberOfHeaps];
757 };
758
759 // Once pages have been used for one type of thread heap they will never be
760 // reused for another type of thread heap. Instead of unmapping, we add the
761 // pages to a pool of pages to be reused later by a thread heap of the same
762 // type. This is done as a security feature to avoid type confusion. The
763 // heaps are type segregated by having separate thread heaps for different
764 // types of objects. Holding on to pages ensures that the same virtual address
765 // space cannot be used for objects of another type than the type contained
766 // in this page to begin with.
767 class FreePagePool : public PagePool<PageMemory> {
768 public:
769     ~FreePagePool();
770     void addFreePage(int, PageMemory*);
771     PageMemory* takeFreePage(int);
772
773 private:
774     Mutex m_mutex[NumberOfHeaps];
775 };
776
777 class OrphanedPagePool : public PagePool<BaseHeapPage> {
778 public:
779     ~OrphanedPagePool();
780     void addOrphanedPage(int, BaseHeapPage*);
781     void decommitOrphanedPages();
782 #if ENABLE(ASSERT)
783     bool contains(void*);
784 #endif
785 private:
786     void clearMemory(PageMemory*);
787 };
788
789 // Non-template super class used to pass a heap around to other classes.
790 class BaseHeap {
791 public:
792     virtual ~BaseHeap() { }
793     virtual void cleanupPages() = 0;
794
795     // Find the page in this thread heap containing the given
796     // address. Returns 0 if the address is not contained in any
797     // page in this thread heap.
798     virtual BaseHeapPage* heapPageFromAddress(Address) = 0;
799
800 #if ENABLE(GC_PROFILE_MARKING)
801     virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0;
802 #endif
803
804 #if ENABLE(GC_PROFILE_HEAP)
805     virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0;
806 #endif
807
808     // Sweep this part of the Blink heap. This finalizes dead objects
809     // and builds freelists for all the unused memory.
810     virtual void sweep(HeapStats*) = 0;
811     virtual void postSweepProcessing() = 0;
812
813     virtual void clearFreeLists() = 0;
814     virtual void clearLiveAndMarkDead() = 0;
815
816     virtual void makeConsistentForSweeping() = 0;
817
818 #if ENABLE(ASSERT)
819     virtual bool isConsistentForSweeping() = 0;
820
821     virtual void getScannedStats(HeapStats&) = 0;
822 #endif
823
824     virtual void prepareHeapForTermination() = 0;
825
826     virtual int normalPageCount() = 0;
827
828     virtual BaseHeap* split(int normalPages) = 0;
829     virtual void merge(BaseHeap* other) = 0;
830
831     // Returns a bucket number for inserting a FreeListEntry of a
832     // given size. All FreeListEntries in the given bucket, n, have
833     // size >= 2^n.
834     static int bucketIndexForSize(size_t);
835 };
836
837 // Thread heaps represent a part of the per-thread Blink heap.
838 //
839 // Each Blink thread has a number of thread heaps: one general heap
840 // that contains any type of object and a number of heaps specialized
841 // for specific object types (such as Node).
842 //
843 // Each thread heap contains the functionality to allocate new objects
844 // (potentially adding new pages to the heap), to find and mark
845 // objects during conservative stack scanning and to sweep the set of
846 // pages after a GC.
847 template<typename Header>
848 class ThreadHeap : public BaseHeap {
849 public:
850     ThreadHeap(ThreadState*, int);
851     virtual ~ThreadHeap();
852     virtual void cleanupPages();
853
854     virtual BaseHeapPage* heapPageFromAddress(Address);
855 #if ENABLE(GC_PROFILE_MARKING)
856     virtual const GCInfo* findGCInfoOfLargeHeapObject(Address);
857 #endif
858 #if ENABLE(GC_PROFILE_HEAP)
859     virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*);
860 #endif
861
862     virtual void sweep(HeapStats*);
863     virtual void postSweepProcessing();
864
865     virtual void clearFreeLists();
866     virtual void clearLiveAndMarkDead();
867
868     virtual void makeConsistentForSweeping();
869
870 #if ENABLE(ASSERT)
871     virtual bool isConsistentForSweeping();
872
873     virtual void getScannedStats(HeapStats&);
874 #endif
875
876     ThreadState* threadState() { return m_threadState; }
877     HeapStats& stats() { return m_threadState->stats(); }
878     void flushHeapContainsCache()
879     {
880         m_threadState->heapContainsCache()->flush();
881     }
882
883     inline Address allocate(size_t, const GCInfo*);
884     void addToFreeList(Address, size_t);
885     inline static size_t roundedAllocationSize(size_t size)
886     {
887         return allocationSizeFromSize(size) - sizeof(Header);
888     }
889
890     virtual void prepareHeapForTermination();
891
892     virtual int normalPageCount() { return m_numberOfNormalPages; }
893
894     virtual BaseHeap* split(int numberOfNormalPages);
895     virtual void merge(BaseHeap* splitOffBase);
896
897     void removePageFromHeap(HeapPage<Header>*);
898
899     PLATFORM_EXPORT void promptlyFreeObject(Header*);
900
901 private:
902     void addPageToHeap(const GCInfo*);
903     PLATFORM_EXPORT Address outOfLineAllocate(size_t, const GCInfo*);
904     static size_t allocationSizeFromSize(size_t);
905     PLATFORM_EXPORT Address allocateLargeObject(size_t, const GCInfo*);
906     Address currentAllocationPoint() const { return m_currentAllocationPoint; }
907     size_t remainingAllocationSize() const { return m_remainingAllocationSize; }
908     bool ownsNonEmptyAllocationArea() const { return currentAllocationPoint() && remainingAllocationSize(); }
909     void setAllocationPoint(Address point, size_t size)
910     {
911         ASSERT(!point || heapPageFromAddress(point));
912         ASSERT(size <= HeapPage<Header>::payloadSize());
913         m_currentAllocationPoint = point;
914         m_remainingAllocationSize = size;
915     }
916     void ensureCurrentAllocation(size_t, const GCInfo*);
917     bool allocateFromFreeList(size_t);
918
919     void freeLargeObject(LargeHeapObject<Header>*, LargeHeapObject<Header>**);
920     void allocatePage(const GCInfo*);
921
922 #if ENABLE(ASSERT)
923     bool pagesToBeSweptContains(Address);
924     bool pagesAllocatedDuringSweepingContains(Address);
925 #endif
926
927     void sweepNormalPages(HeapStats*);
928     void sweepLargePages(HeapStats*);
929     bool coalesce(size_t);
930
931     Address m_currentAllocationPoint;
932     size_t m_remainingAllocationSize;
933
934     HeapPage<Header>* m_firstPage;
935     LargeHeapObject<Header>* m_firstLargeHeapObject;
936
937     HeapPage<Header>* m_firstPageAllocatedDuringSweeping;
938     HeapPage<Header>* m_lastPageAllocatedDuringSweeping;
939
940     // Merge point for parallel sweep.
941     HeapPage<Header>* m_mergePoint;
942
943     int m_biggestFreeListIndex;
944
945     ThreadState* m_threadState;
946
947     // All FreeListEntries in the nth list have size >= 2^n.
948     FreeListEntry* m_freeLists[blinkPageSizeLog2];
949     FreeListEntry* m_lastFreeListEntries[blinkPageSizeLog2];
950
951     // Index into the page pools. This is used to ensure that the pages of the
952     // same type go into the correct page pool and thus avoid type confusion.
953     int m_index;
954
955     int m_numberOfNormalPages;
956
957     // The promptly freed count contains the number of promptly freed objects
958     // since the last sweep or since it was manually reset to delay coalescing.
959     size_t m_promptlyFreedCount;
960 };
961
962 class PLATFORM_EXPORT Heap {
963 public:
964     static void init();
965     static void shutdown();
966     static void doShutdown();
967
968     static BaseHeapPage* contains(Address);
969     static BaseHeapPage* contains(void* pointer) { return contains(reinterpret_cast<Address>(pointer)); }
970     static BaseHeapPage* contains(const void* pointer) { return contains(const_cast<void*>(pointer)); }
971 #if ENABLE(ASSERT)
972     static bool containedInHeapOrOrphanedPage(void*);
973 #endif
974
975     // Push a trace callback on the marking stack.
976     static void pushTraceCallback(CallbackStack*, void* containerObject, TraceCallback);
977
978     // Push a trace callback on the post-marking callback stack. These callbacks
979     // are called after normal marking (including ephemeron iteration).
980     static void pushPostMarkingCallback(void*, TraceCallback);
981
982     // Add a weak pointer callback to the weak callback work list. General
983     // object pointer callbacks are added to a thread local weak callback work
984     // list and the callback is called on the thread that owns the object, with
985     // the closure pointer as an argument. Most of the time, the closure and
986     // the containerObject can be the same thing, but the containerObject is
987     // constrained to be on the heap, since the heap is used to identify the
988     // correct thread.
989     static void pushWeakObjectPointerCallback(void* closure, void* containerObject, WeakPointerCallback);
990
991     // Similar to the more general pushWeakObjectPointerCallback, but cell
992     // pointer callbacks are added to a static callback work list and the weak
993     // callback is performed on the thread performing garbage collection. This
994     // is OK because cells are just cleared and no deallocation can happen.
995     static void pushWeakCellPointerCallback(void** cell, WeakPointerCallback);
996
997     // Pop the top of a marking stack and call the callback with the visitor
998     // and the object. Returns false when there is nothing more to do.
999     template<CallbackInvocationMode Mode> static bool popAndInvokeTraceCallback(CallbackStack*, Visitor*);
1000
1001     // Remove an item from the post-marking callback stack and call
1002     // the callback with the visitor and the object pointer. Returns
1003     // false when there is nothing more to do.
1004     static bool popAndInvokePostMarkingCallback(Visitor*);
1005
1006     // Remove an item from the weak callback work list and call the callback
1007     // with the visitor and the closure pointer. Returns false when there is
1008     // nothing more to do.
1009     static bool popAndInvokeWeakPointerCallback(Visitor*);
1010
1011     // Register an ephemeron table for fixed-point iteration.
1012     static void registerWeakTable(void* containerObject, EphemeronCallback, EphemeronCallback);
1013 #if ENABLE(ASSERT)
1014     static bool weakTableRegistered(const void*);
1015 #endif
1016
1017     template<typename T, typename HeapTraits> static Address allocate(size_t);
1018     // FIXME: remove this once c++11 is allowed everywhere:
1019     template<typename T> static Address allocate(size_t);
1020
1021     template<typename T> static Address reallocate(void* previous, size_t);
1022
1023     static void collectGarbage(ThreadState::StackState, ThreadState::CauseOfGC = ThreadState::NormalGC);
1024     static void collectGarbageForTerminatingThread(ThreadState*);
1025     static void collectAllGarbage();
1026     static void processMarkingStackEntries(int* numberOfMarkingThreads);
1027     static void processMarkingStackOnMultipleThreads();
1028     static void processMarkingStackInParallel();
1029     template<CallbackInvocationMode Mode> static void processMarkingStack();
1030     static void postMarkingProcessing();
1031     static void globalWeakProcessing();
1032     static void setForcePreciseGCForTesting();
1033
1034     static void prepareForGC();
1035
1036     // Conservatively checks whether an address is a pointer in any of the thread
1037     // heaps. If so marks the object pointed to as live.
1038     static Address checkAndMarkPointer(Visitor*, Address);
1039
1040 #if ENABLE(GC_PROFILE_MARKING)
1041     // Dump the path to specified object on the next GC. This method is to be invoked from GDB.
1042     static void dumpPathToObjectOnNextGC(void* p);
1043
1044     // Forcibly find GCInfo of the object at Address.
1045     // This is slow and should only be used for debug purposes.
1046     // It involves finding the heap page and scanning the heap page for an object header.
1047     static const GCInfo* findGCInfo(Address);
1048
1049     static String createBacktraceString();
1050 #endif
1051
1052     // Collect heap stats for all threads attached to the Blink
1053     // garbage collector. Should only be called during garbage
1054     // collection where threads are known to be at safe points.
1055     static void getStats(HeapStats*);
1056
1057     static void getHeapSpaceSize(uint64_t*, uint64_t*);
1058
1059     static void makeConsistentForSweeping();
1060
1061 #if ENABLE(ASSERT)
1062     static bool isConsistentForSweeping();
1063 #endif
1064
1065     static void flushHeapDoesNotContainCache();
1066     static bool heapDoesNotContainCacheIsEmpty() { return s_heapDoesNotContainCache->isEmpty(); }
1067
1068     // Return true if the last GC found a pointer into a heap page
1069     // during conservative scanning.
1070     static bool lastGCWasConservative() { return s_lastGCWasConservative; }
1071
1072     static FreePagePool* freePagePool() { return s_freePagePool; }
1073     static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; }
1074
1075 private:
1076     static Visitor* s_markingVisitor;
1077     static Vector<OwnPtr<blink::WebThread> >* s_markingThreads;
1078     static CallbackStack* s_markingStack;
1079     static CallbackStack* s_postMarkingCallbackStack;
1080     static CallbackStack* s_weakCallbackStack;
1081     static CallbackStack* s_ephemeronStack;
1082     static HeapDoesNotContainCache* s_heapDoesNotContainCache;
1083     static bool s_shutdownCalled;
1084     static bool s_lastGCWasConservative;
1085     static FreePagePool* s_freePagePool;
1086     static OrphanedPagePool* s_orphanedPagePool;
1087     friend class ThreadState;
1088 };
1089
1090 // The NoAllocationScope class is used in debug mode to catch unwanted
1091 // allocations. E.g. allocations during GC.
1092 template<ThreadAffinity Affinity>
1093 class NoAllocationScope {
1094 public:
1095     NoAllocationScope() : m_active(true) { enter(); }
1096
1097     explicit NoAllocationScope(bool active) : m_active(active) { enter(); }
1098
1099     NoAllocationScope(const NoAllocationScope& other) : m_active(other.m_active) { enter(); }
1100
1101     NoAllocationScope& operator=(const NoAllocationScope& other)
1102     {
1103         release();
1104         m_active = other.m_active;
1105         enter();
1106         return *this;
1107     }
1108
1109     ~NoAllocationScope() { release(); }
1110
1111     void release()
1112     {
1113         if (m_active) {
1114             ThreadStateFor<Affinity>::state()->leaveNoAllocationScope();
1115             m_active = false;
1116         }
1117     }
1118
1119 private:
1120     void enter() const
1121     {
1122         if (m_active)
1123             ThreadStateFor<Affinity>::state()->enterNoAllocationScope();
1124     }
1125
1126     bool m_active;
1127 };
1128
1129 // Base class for objects allocated in the Blink garbage-collected
1130 // heap.
1131 //
1132 // Defines a 'new' operator that allocates the memory in the
1133 // heap. 'delete' should not be called on objects that inherit from
1134 // GarbageCollected.
1135 //
1136 // Instances of GarbageCollected will *NOT* get finalized. Their
1137 // destructor will not be called. Therefore, only classes that have
1138 // trivial destructors with no semantic meaning (including all their
1139 // subclasses) should inherit from GarbageCollected. If there are
1140 // non-trival destructors in a given class or any of its subclasses,
1141 // GarbageCollectedFinalized should be used which guarantees that the
1142 // destructor is called on an instance when the garbage collector
1143 // determines that it is no longer reachable.
1144 template<typename T>
1145 class GarbageCollected {
1146     WTF_MAKE_NONCOPYABLE(GarbageCollected);
1147
1148     // For now direct allocation of arrays on the heap is not allowed.
1149     void* operator new[](size_t size);
1150 #if OS(WIN) && COMPILER(MSVC)
1151     // Due to some quirkiness in the MSVC compiler we have to provide
1152     // the delete[] operator in the GarbageCollected subclasses as it
1153     // is called when a class is exported in a DLL.
1154 protected:
1155     void operator delete[](void* p)
1156     {
1157         ASSERT_NOT_REACHED();
1158     }
1159 #else
1160     void operator delete[](void* p);
1161 #endif
1162 public:
1163     typedef T GarbageCollectedBase;
1164
1165     void* operator new(size_t size)
1166     {
1167         return Heap::allocate<T>(size);
1168     }
1169
1170     void operator delete(void* p)
1171     {
1172         ASSERT_NOT_REACHED();
1173     }
1174
1175 protected:
1176     GarbageCollected()
1177     {
1178     }
1179 };
1180
1181 // Base class for objects allocated in the Blink garbage-collected
1182 // heap.
1183 //
1184 // Defines a 'new' operator that allocates the memory in the
1185 // heap. 'delete' should not be called on objects that inherit from
1186 // GarbageCollected.
1187 //
1188 // Instances of GarbageCollectedFinalized will have their destructor
1189 // called when the garbage collector determines that the object is no
1190 // longer reachable.
1191 template<typename T>
1192 class GarbageCollectedFinalized : public GarbageCollected<T> {
1193     WTF_MAKE_NONCOPYABLE(GarbageCollectedFinalized);
1194
1195 protected:
1196     // finalizeGarbageCollectedObject is called when the object is
1197     // freed from the heap. By default finalization means calling the
1198     // destructor on the object. finalizeGarbageCollectedObject can be
1199     // overridden to support calling the destructor of a
1200     // subclass. This is useful for objects without vtables that
1201     // require explicit dispatching. The name is intentionally a bit
1202     // long to make name conflicts less likely.
1203     void finalizeGarbageCollectedObject()
1204     {
1205         static_cast<T*>(this)->~T();
1206     }
1207
1208     GarbageCollectedFinalized() { }
1209     ~GarbageCollectedFinalized() { }
1210
1211     template<typename U> friend struct HasFinalizer;
1212     template<typename U, bool> friend struct FinalizerTraitImpl;
1213 };
1214
1215 // Base class for objects that are in the Blink garbage-collected heap
1216 // and are still reference counted.
1217 //
1218 // This class should be used sparingly and only to gradually move
1219 // objects from being reference counted to being managed by the blink
1220 // garbage collector.
1221 //
1222 // While the current reference counting keeps one of these objects
1223 // alive it will have a Persistent handle to itself allocated so we
1224 // will not reclaim the memory. When the reference count reaches 0 the
1225 // persistent handle will be deleted. When the garbage collector
1226 // determines that there are no other references to the object it will
1227 // be reclaimed and the destructor of the reclaimed object will be
1228 // called at that time.
1229 template<typename T>
1230 class RefCountedGarbageCollected : public GarbageCollectedFinalized<T> {
1231     WTF_MAKE_NONCOPYABLE(RefCountedGarbageCollected);
1232
1233 public:
1234     RefCountedGarbageCollected()
1235         : m_refCount(1)
1236     {
1237         makeKeepAlive();
1238     }
1239
1240     // Implement method to increase reference count for use with
1241     // RefPtrs.
1242     //
1243     // In contrast to the normal WTF::RefCounted, the reference count
1244     // can reach 0 and increase again. This happens in the following
1245     // scenario:
1246     //
1247     // (1) The reference count becomes 0, but members, persistents, or
1248     //     on-stack pointers keep references to the object.
1249     //
1250     // (2) The pointer is assigned to a RefPtr again and the reference
1251     //     count becomes 1.
1252     //
1253     // In this case, we have to resurrect m_keepAlive.
1254     void ref()
1255     {
1256         if (UNLIKELY(!m_refCount)) {
1257             ASSERT(ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(reinterpret_cast<Address>(this)));
1258             makeKeepAlive();
1259         }
1260         ++m_refCount;
1261     }
1262
1263     // Implement method to decrease reference count for use with
1264     // RefPtrs.
1265     //
1266     // In contrast to the normal WTF::RefCounted implementation, the
1267     // object itself is not deleted when the reference count reaches
1268     // 0. Instead, the keep-alive persistent handle is deallocated so
1269     // that the object can be reclaimed when the garbage collector
1270     // determines that there are no other references to the object.
1271     void deref()
1272     {
1273         ASSERT(m_refCount > 0);
1274         if (!--m_refCount) {
1275             delete m_keepAlive;
1276             m_keepAlive = 0;
1277         }
1278     }
1279
1280     bool hasOneRef()
1281     {
1282         return m_refCount == 1;
1283     }
1284
1285 protected:
1286     ~RefCountedGarbageCollected() { }
1287
1288 private:
1289     void makeKeepAlive()
1290     {
1291         ASSERT(!m_keepAlive);
1292         m_keepAlive = new Persistent<T>(static_cast<T*>(this));
1293     }
1294
1295     int m_refCount;
1296     Persistent<T>* m_keepAlive;
1297 };
1298
1299 template<typename T>
1300 T* adoptRefCountedGarbageCollected(T* ptr)
1301 {
1302     ASSERT(ptr->hasOneRef());
1303     ptr->deref();
1304     WTF::adopted(ptr);
1305     return ptr;
1306 }
1307
1308 // Classes that contain heap references but aren't themselves heap
1309 // allocated, have some extra macros available which allows their use
1310 // to be restricted to cases where the garbage collector is able
1311 // to discover their heap references.
1312 //
1313 // STACK_ALLOCATED(): Use if the object is only stack allocated. Heap objects
1314 // should be in Members but you do not need the trace method as they are on
1315 // the stack. (Down the line these might turn in to raw pointers, but for
1316 // now Members indicates that we have thought about them and explicitly
1317 // taken care of them.)
1318 //
1319 // DISALLOW_ALLOCATION(): Cannot be allocated with new operators but can
1320 // be a part object. If it has Members you need a trace method and the
1321 // containing object needs to call that trace method.
1322 //
1323 // ALLOW_ONLY_INLINE_ALLOCATION(): Allows only placement new operator.
1324 // This disallows general allocation of this object but allows to put
1325 // the object as a value object in collections. If these have Members you
1326 // need to have a trace method. That trace method will be called
1327 // automatically by the Heap collections.
1328 //
1329 #if COMPILER_SUPPORTS(CXX_DELETED_FUNCTIONS)
1330 #define DISALLOW_ALLOCATION()                                   \
1331     private:                                                    \
1332         void* operator new(size_t) = delete;                    \
1333         void* operator new(size_t, NotNullTag, void*) = delete; \
1334         void* operator new(size_t, void*) = delete;
1335
1336 #define ALLOW_ONLY_INLINE_ALLOCATION()                                              \
1337     public:                                                                         \
1338         void* operator new(size_t, NotNullTag, void* location) { return location; } \
1339         void* operator new(size_t, void* location) { return location; }             \
1340     private:                                                                        \
1341         void* operator new(size_t) = delete;
1342
1343 #define STATIC_ONLY(Type) \
1344     private:              \
1345         Type() = delete;
1346
1347 #else
1348
1349 #define DISALLOW_ALLOCATION()                          \
1350     private:                                           \
1351         void* operator new(size_t);                    \
1352         void* operator new(size_t, NotNullTag, void*); \
1353         void* operator new(size_t, void*)
1354
1355 #define ALLOW_ONLY_INLINE_ALLOCATION()                                              \
1356     public:                                                                         \
1357         void* operator new(size_t, NotNullTag, void* location) { return location; } \
1358         void* operator new(size_t, void* location) { return location; }             \
1359     private:                                                                        \
1360         void* operator new(size_t);
1361
1362 #define STATIC_ONLY(Type)  \
1363     private:               \
1364         Type();
1365
1366 #endif
1367
1368
1369 // These macros insert annotations that the Blink GC plugin for clang uses for
1370 // verification. STACK_ALLOCATED is used to declare that objects of this type
1371 // are always stack allocated. GC_PLUGIN_IGNORE is used to make the plugin
1372 // ignore a particular class or field when checking for proper usage. When using
1373 // GC_PLUGIN_IGNORE a bug-number should be provided as an argument where the
1374 // bug describes what needs to happen to remove the GC_PLUGIN_IGNORE again.
1375 #if COMPILER(CLANG)
1376 #define STACK_ALLOCATED()                                       \
1377     private:                                                    \
1378         __attribute__((annotate("blink_stack_allocated")))      \
1379         void* operator new(size_t) = delete;                    \
1380         void* operator new(size_t, NotNullTag, void*) = delete; \
1381         void* operator new(size_t, void*) = delete;
1382
1383 #define GC_PLUGIN_IGNORE(bug)                           \
1384     __attribute__((annotate("blink_gc_plugin_ignore")))
1385 #else
1386 #define STACK_ALLOCATED() DISALLOW_ALLOCATION()
1387 #define GC_PLUGIN_IGNORE(bug)
1388 #endif
1389
1390 NO_SANITIZE_ADDRESS
1391 void HeapObjectHeader::checkHeader() const
1392 {
1393 #if ENABLE(ASSERT)
1394     BaseHeapPage* page = pageHeaderFromObject(this);
1395     ASSERT(page->orphaned() || m_magic == magic);
1396 #endif
1397 }
1398
1399 Address HeapObjectHeader::payload()
1400 {
1401     return reinterpret_cast<Address>(this) + objectHeaderSize;
1402 }
1403
1404 size_t HeapObjectHeader::payloadSize()
1405 {
1406     return size() - objectHeaderSize;
1407 }
1408
1409 Address HeapObjectHeader::payloadEnd()
1410 {
1411     return reinterpret_cast<Address>(this) + size();
1412 }
1413
1414 NO_SANITIZE_ADDRESS
1415 void HeapObjectHeader::mark()
1416 {
1417     checkHeader();
1418     // The use of atomic ops guarantees that the reads and writes are
1419     // atomic and that no memory operation reorderings take place.
1420     // Multiple threads can still read the old value and all store the
1421     // new value. However, the new value will be the same for all of
1422     // the threads and the end result is therefore consistent.
1423     unsigned size = asanUnsafeAcquireLoad(&m_size);
1424     asanUnsafeReleaseStore(&m_size, size | markBitMask);
1425 }
1426
1427 Address FinalizedHeapObjectHeader::payload()
1428 {
1429     return reinterpret_cast<Address>(this) + finalizedHeaderSize;
1430 }
1431
1432 size_t FinalizedHeapObjectHeader::payloadSize()
1433 {
1434     return size() - finalizedHeaderSize;
1435 }
1436
1437 template<typename Header>
1438 size_t ThreadHeap<Header>::allocationSizeFromSize(size_t size)
1439 {
1440     // Check the size before computing the actual allocation size. The
1441     // allocation size calculation can overflow for large sizes and
1442     // the check therefore has to happen before any calculation on the
1443     // size.
1444     RELEASE_ASSERT(size < maxHeapObjectSize);
1445
1446     // Add space for header.
1447     size_t allocationSize = size + sizeof(Header);
1448     // Align size with allocation granularity.
1449     allocationSize = (allocationSize + allocationMask) & ~allocationMask;
1450     return allocationSize;
1451 }
1452
1453 template<typename Header>
1454 Address ThreadHeap<Header>::allocate(size_t size, const GCInfo* gcInfo)
1455 {
1456     size_t allocationSize = allocationSizeFromSize(size);
1457     bool isLargeObject = allocationSize > blinkPageSize / 2;
1458     if (isLargeObject)
1459         return allocateLargeObject(allocationSize, gcInfo);
1460     if (m_remainingAllocationSize < allocationSize)
1461         return outOfLineAllocate(size, gcInfo);
1462     Address headerAddress = m_currentAllocationPoint;
1463     m_currentAllocationPoint += allocationSize;
1464     m_remainingAllocationSize -= allocationSize;
1465     Header* header = new (NotNull, headerAddress) Header(allocationSize, gcInfo);
1466     size_t payloadSize = allocationSize - sizeof(Header);
1467     stats().increaseObjectSpace(payloadSize);
1468     Address result = headerAddress + sizeof(*header);
1469     ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask));
1470     // Unpoison the memory used for the object (payload).
1471     ASAN_UNPOISON_MEMORY_REGION(result, payloadSize);
1472 #if ENABLE(ASSERT) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
1473     memset(result, 0, payloadSize);
1474 #endif
1475     ASSERT(heapPageFromAddress(headerAddress + allocationSize - 1));
1476     return result;
1477 }
1478
1479 template<typename T, typename HeapTraits>
1480 Address Heap::allocate(size_t size)
1481 {
1482     ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
1483     ASSERT(state->isAllocationAllowed());
1484     const GCInfo* gcInfo = GCInfoTrait<T>::get();
1485     int heapIndex = HeapTraits::index(gcInfo->hasFinalizer());
1486     BaseHeap* heap = state->heap(heapIndex);
1487     return static_cast<typename HeapTraits::HeapType*>(heap)->allocate(size, gcInfo);
1488 }
1489
1490 template<typename T>
1491 Address Heap::allocate(size_t size)
1492 {
1493     return allocate<T, HeapTypeTrait<T> >(size);
1494 }
1495
1496 template<typename T>
1497 Address Heap::reallocate(void* previous, size_t size)
1498 {
1499     if (!size) {
1500         // If the new size is 0 this is equivalent to either
1501         // free(previous) or malloc(0). In both cases we do
1502         // nothing and return 0.
1503         return 0;
1504     }
1505     ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
1506     ASSERT(state->isAllocationAllowed());
1507     const GCInfo* gcInfo = GCInfoTrait<T>::get();
1508     int heapIndex = HeapTypeTrait<T>::index(gcInfo->hasFinalizer());
1509     // FIXME: Currently only supports raw allocation on the
1510     // GeneralHeap. Hence we assume the header is a
1511     // FinalizedHeapObjectHeader.
1512     ASSERT(heapIndex == GeneralHeap || heapIndex == GeneralHeapNonFinalized);
1513     BaseHeap* heap = state->heap(heapIndex);
1514     Address address = static_cast<typename HeapTypeTrait<T>::HeapType*>(heap)->allocate(size, gcInfo);
1515     if (!previous) {
1516         // This is equivalent to malloc(size).
1517         return address;
1518     }
1519     FinalizedHeapObjectHeader* previousHeader = FinalizedHeapObjectHeader::fromPayload(previous);
1520     ASSERT(!previousHeader->hasFinalizer());
1521     ASSERT(previousHeader->gcInfo() == gcInfo);
1522     size_t copySize = previousHeader->payloadSize();
1523     if (copySize > size)
1524         copySize = size;
1525     memcpy(address, previous, copySize);
1526     return address;
1527 }
1528
1529 class HeapAllocatorQuantizer {
1530 public:
1531     template<typename T>
1532     static size_t quantizedSize(size_t count)
1533     {
1534         RELEASE_ASSERT(count <= kMaxUnquantizedAllocation / sizeof(T));
1535         return HeapIndexTrait<CollectionBackingHeap>::HeapType::roundedAllocationSize(count * sizeof(T));
1536     }
1537     static const size_t kMaxUnquantizedAllocation = maxHeapObjectSize;
1538 };
1539
1540 // This is a static-only class used as a trait on collections to make them heap allocated.
1541 // However see also HeapListHashSetAllocator.
1542 class HeapAllocator {
1543 public:
1544     typedef HeapAllocatorQuantizer Quantizer;
1545     typedef blink::Visitor Visitor;
1546     static const bool isGarbageCollected = true;
1547
1548     template <typename Return, typename Metadata>
1549     static Return backingMalloc(size_t size)
1550     {
1551         return reinterpret_cast<Return>(Heap::allocate<Metadata, HeapIndexTrait<CollectionBackingHeap> >(size));
1552     }
1553     template <typename Return, typename Metadata>
1554     static Return zeroedBackingMalloc(size_t size)
1555     {
1556         return backingMalloc<Return, Metadata>(size);
1557     }
1558     template <typename Return, typename Metadata>
1559     static Return malloc(size_t size)
1560     {
1561         return reinterpret_cast<Return>(Heap::allocate<Metadata>(size));
1562     }
1563     PLATFORM_EXPORT static void backingFree(void* address);
1564
1565     static void free(void* address) { }
1566     template<typename T>
1567     static void* newArray(size_t bytes)
1568     {
1569         ASSERT_NOT_REACHED();
1570         return 0;
1571     }
1572
1573     static void deleteArray(void* ptr)
1574     {
1575         ASSERT_NOT_REACHED();
1576     }
1577
1578     static bool isAllocationAllowed()
1579     {
1580         return ThreadState::current()->isAllocationAllowed();
1581     }
1582
1583     static void markUsingGCInfo(Visitor* visitor, const void* buffer)
1584     {
1585         visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->traceCallback());
1586     }
1587
1588     static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNoTracing(t); }
1589
1590     template<typename T, typename Traits>
1591     static void trace(Visitor* visitor, T& t)
1592     {
1593         CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t);
1594     }
1595
1596     static void registerDelayedMarkNoTracing(Visitor* visitor, const void* object)
1597     {
1598         visitor->registerDelayedMarkNoTracing(object);
1599     }
1600
1601     static void registerWeakMembers(Visitor* visitor, const void* closure, const void* object, WeakPointerCallback callback)
1602     {
1603         visitor->registerWeakMembers(closure, object, callback);
1604     }
1605
1606     static void registerWeakTable(Visitor* visitor, const void* closure, EphemeronCallback iterationCallback, EphemeronCallback iterationDoneCallback)
1607     {
1608         visitor->registerWeakTable(closure, iterationCallback, iterationDoneCallback);
1609     }
1610
1611 #if ENABLE(ASSERT)
1612     static bool weakTableRegistered(Visitor* visitor, const void* closure)
1613     {
1614         return visitor->weakTableRegistered(closure);
1615     }
1616 #endif
1617
1618     template<typename T>
1619     struct ResultType {
1620         typedef T* Type;
1621     };
1622
1623     // The WTF classes use Allocator::VectorBackingHelper in order to find a
1624     // class to template their backing allocation operation on. For off-heap
1625     // allocations the VectorBackingHelper is a dummy class, since the class is
1626     // not used during allocation of backing. For on-heap allocations this
1627     // typedef ensures that the allocation is done with the correct templated
1628     // instantiation of the allocation function. This ensures the correct GC
1629     // map is written when backing allocations take place.
1630     template<typename T, typename Traits>
1631     struct VectorBackingHelper {
1632         typedef HeapVectorBacking<T, Traits> Type;
1633     };
1634
1635     // Like the VectorBackingHelper, but this type is used for HashSet and
1636     // HashMap, both of which are implemented using HashTable.
1637     template<typename Table>
1638     struct HashTableBackingHelper {
1639         typedef HeapHashTableBacking<Table> Type;
1640     };
1641
1642     template<typename T>
1643     struct OtherType {
1644         typedef T* Type;
1645     };
1646
1647     template<typename T>
1648     static T& getOther(T* other)
1649     {
1650         return *other;
1651     }
1652
1653     static void enterNoAllocationScope()
1654     {
1655 #if ENABLE(ASSERT)
1656         ThreadStateFor<AnyThread>::state()->enterNoAllocationScope();
1657 #endif
1658     }
1659
1660     static void leaveNoAllocationScope()
1661     {
1662 #if ENABLE(ASSERT)
1663         ThreadStateFor<AnyThread>::state()->leaveNoAllocationScope();
1664 #endif
1665     }
1666
1667 private:
1668     template<typename T, size_t u, typename V> friend class WTF::Vector;
1669     template<typename T, typename U, typename V, typename W> friend class WTF::HashSet;
1670     template<typename T, typename U, typename V, typename W, typename X, typename Y> friend class WTF::HashMap;
1671 };
1672
1673 template<typename Value>
1674 static void traceListHashSetValue(Visitor* visitor, Value& value)
1675 {
1676     // We use the default hash traits for the value in the node, because
1677     // ListHashSet does not let you specify any specific ones.
1678     // We don't allow ListHashSet of WeakMember, so we set that one false
1679     // (there's an assert elsewhere), but we have to specify some value for the
1680     // strongify template argument, so we specify WTF::WeakPointersActWeak,
1681     // arbitrarily.
1682     CollectionBackingTraceTrait<WTF::ShouldBeTraced<WTF::HashTraits<Value> >::value, WTF::NoWeakHandlingInCollections, WTF::WeakPointersActWeak, Value, WTF::HashTraits<Value> >::trace(visitor, value);
1683 }
1684
1685 // The inline capacity is just a dummy template argument to match the off-heap
1686 // allocator.
1687 // This inherits from the static-only HeapAllocator trait class, but we do
1688 // declare pointers to instances. These pointers are always null, and no
1689 // objects are instantiated.
1690 template<typename ValueArg, size_t inlineCapacity>
1691 struct HeapListHashSetAllocator : public HeapAllocator {
1692     typedef HeapAllocator TableAllocator;
1693     typedef WTF::ListHashSetNode<ValueArg, HeapListHashSetAllocator> Node;
1694
1695 public:
1696     class AllocatorProvider {
1697     public:
1698         // For the heap allocation we don't need an actual allocator object, so we just
1699         // return null.
1700         HeapListHashSetAllocator* get() const { return 0; }
1701
1702         // No allocator object is needed.
1703         void createAllocatorIfNeeded() { }
1704
1705         // There is no allocator object in the HeapListHashSet (unlike in
1706         // the regular ListHashSet) so there is nothing to swap.
1707         void swap(AllocatorProvider& other) { }
1708     };
1709
1710     void deallocate(void* dummy) { }
1711
1712     // This is not a static method even though it could be, because it
1713     // needs to match the one that the (off-heap) ListHashSetAllocator
1714     // has. The 'this' pointer will always be null.
1715     void* allocateNode()
1716     {
1717         COMPILE_ASSERT(!WTF::IsWeak<ValueArg>::value, WeakPointersInAListHashSetWillJustResultInNullEntriesInTheSetThatsNotWhatYouWantConsiderUsingLinkedHashSetInstead);
1718         return malloc<void*, Node>(sizeof(Node));
1719     }
1720
1721     static void traceValue(Visitor* visitor, Node* node)
1722     {
1723         traceListHashSetValue(visitor, node->m_value);
1724     }
1725 };
1726
1727 // FIXME: These should just be template aliases:
1728 //
1729 // template<typename T, size_t inlineCapacity = 0>
1730 // using HeapVector = Vector<T, inlineCapacity, HeapAllocator>;
1731 //
1732 // as soon as all the compilers we care about support that.
1733 // MSVC supports it only in MSVC 2013.
1734 template<
1735     typename KeyArg,
1736     typename MappedArg,
1737     typename HashArg = typename DefaultHash<KeyArg>::Hash,
1738     typename KeyTraitsArg = HashTraits<KeyArg>,
1739     typename MappedTraitsArg = HashTraits<MappedArg> >
1740 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, HeapAllocator> { };
1741
1742 template<
1743     typename ValueArg,
1744     typename HashArg = typename DefaultHash<ValueArg>::Hash,
1745     typename TraitsArg = HashTraits<ValueArg> >
1746 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> { };
1747
1748 template<
1749     typename ValueArg,
1750     typename HashArg = typename DefaultHash<ValueArg>::Hash,
1751     typename TraitsArg = HashTraits<ValueArg> >
1752 class HeapLinkedHashSet : public LinkedHashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> { };
1753
1754 template<
1755     typename ValueArg,
1756     size_t inlineCapacity = 0, // The inlineCapacity is just a dummy to match ListHashSet (off-heap).
1757     typename HashArg = typename DefaultHash<ValueArg>::Hash>
1758 class HeapListHashSet : public ListHashSet<ValueArg, inlineCapacity, HashArg, HeapListHashSetAllocator<ValueArg, inlineCapacity> > { };
1759
1760 template<
1761     typename Value,
1762     typename HashFunctions = typename DefaultHash<Value>::Hash,
1763     typename Traits = HashTraits<Value> >
1764 class HeapHashCountedSet : public HashCountedSet<Value, HashFunctions, Traits, HeapAllocator> { };
1765
1766 template<typename T, size_t inlineCapacity = 0>
1767 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
1768 public:
1769     HeapVector() { }
1770
1771     explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(size)
1772     {
1773     }
1774
1775     HeapVector(size_t size, const T& val) : Vector<T, inlineCapacity, HeapAllocator>(size, val)
1776     {
1777     }
1778
1779     template<size_t otherCapacity>
1780     HeapVector(const HeapVector<T, otherCapacity>& other)
1781         : Vector<T, inlineCapacity, HeapAllocator>(other)
1782     {
1783     }
1784
1785     template<typename U>
1786     void append(const U& other)
1787     {
1788         Vector<T, inlineCapacity, HeapAllocator>::append(other);
1789     }
1790
1791     template<typename U, size_t otherCapacity>
1792     void appendVector(const HeapVector<U, otherCapacity>& other)
1793     {
1794         const Vector<U, otherCapacity, HeapAllocator>& otherVector = other;
1795         Vector<T, inlineCapacity, HeapAllocator>::appendVector(otherVector);
1796     }
1797 };
1798
1799 template<typename T, size_t inlineCapacity = 0>
1800 class HeapDeque : public Deque<T, inlineCapacity, HeapAllocator> {
1801 public:
1802     HeapDeque() { }
1803
1804     explicit HeapDeque(size_t size) : Deque<T, inlineCapacity, HeapAllocator>(size)
1805     {
1806     }
1807
1808     HeapDeque(size_t size, const T& val) : Deque<T, inlineCapacity, HeapAllocator>(size, val)
1809     {
1810     }
1811
1812     // FIXME: Doesn't work if there is an inline buffer, due to crbug.com/360572
1813     HeapDeque<T, 0>& operator=(const HeapDeque& other)
1814     {
1815         HeapDeque<T> copy(other);
1816         swap(copy);
1817         return *this;
1818     }
1819
1820     // FIXME: Doesn't work if there is an inline buffer, due to crbug.com/360572
1821     inline void swap(HeapDeque& other)
1822     {
1823         Deque<T, inlineCapacity, HeapAllocator>::swap(other);
1824     }
1825
1826     template<size_t otherCapacity>
1827     HeapDeque(const HeapDeque<T, otherCapacity>& other)
1828         : Deque<T, inlineCapacity, HeapAllocator>(other)
1829     {
1830     }
1831
1832     template<typename U>
1833     void append(const U& other)
1834     {
1835         Deque<T, inlineCapacity, HeapAllocator>::append(other);
1836     }
1837 };
1838
1839 template<typename T, size_t i>
1840 inline void swap(HeapVector<T, i>& a, HeapVector<T, i>& b) { a.swap(b); }
1841 template<typename T, size_t i>
1842 inline void swap(HeapDeque<T, i>& a, HeapDeque<T, i>& b) { a.swap(b); }
1843 template<typename T, typename U, typename V>
1844 inline void swap(HeapHashSet<T, U, V>& a, HeapHashSet<T, U, V>& b) { a.swap(b); }
1845 template<typename T, typename U, typename V, typename W, typename X>
1846 inline void swap(HeapHashMap<T, U, V, W, X>& a, HeapHashMap<T, U, V, W, X>& b) { a.swap(b); }
1847 template<typename T, size_t i, typename U>
1848 inline void swap(HeapListHashSet<T, i, U>& a, HeapListHashSet<T, i, U>& b) { a.swap(b); }
1849 template<typename T, typename U, typename V>
1850 inline void swap(HeapLinkedHashSet<T, U, V>& a, HeapLinkedHashSet<T, U, V>& b) { a.swap(b); }
1851 template<typename T, typename U, typename V>
1852 inline void swap(HeapHashCountedSet<T, U, V>& a, HeapHashCountedSet<T, U, V>& b) { a.swap(b); }
1853
1854 template<typename T>
1855 struct ThreadingTrait<Member<T> > {
1856     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1857 };
1858
1859 template<typename T>
1860 struct ThreadingTrait<WeakMember<T> > {
1861     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1862 };
1863
1864 template<typename Key, typename Value, typename T, typename U, typename V>
1865 struct ThreadingTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > {
1866     static const ThreadAffinity Affinity =
1867         (ThreadingTrait<Key>::Affinity == MainThreadOnly)
1868         && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
1869 };
1870
1871 template<typename First, typename Second>
1872 struct ThreadingTrait<WTF::KeyValuePair<First, Second> > {
1873     static const ThreadAffinity Affinity =
1874         (ThreadingTrait<First>::Affinity == MainThreadOnly)
1875         && (ThreadingTrait<Second>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
1876 };
1877
1878 template<typename T, typename U, typename V>
1879 struct ThreadingTrait<HashSet<T, U, V, HeapAllocator> > {
1880     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1881 };
1882
1883
1884 template<typename T, size_t inlineCapacity>
1885 struct ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator> > {
1886     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1887 };
1888
1889 template<typename T, typename Traits>
1890 struct ThreadingTrait<HeapVectorBacking<T, Traits> > {
1891     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1892 };
1893
1894 template<typename T, size_t inlineCapacity>
1895 struct ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator> > {
1896     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1897 };
1898
1899 template<typename T, typename U, typename V>
1900 struct ThreadingTrait<HashCountedSet<T, U, V, HeapAllocator> > {
1901     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1902 };
1903
1904 template<typename Table>
1905 struct ThreadingTrait<HeapHashTableBacking<Table> > {
1906     typedef typename Table::KeyType Key;
1907     typedef typename Table::ValueType Value;
1908     static const ThreadAffinity Affinity =
1909         (ThreadingTrait<Key>::Affinity == MainThreadOnly)
1910         && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
1911 };
1912
1913 template<typename T, typename U, typename V, typename W, typename X>
1914 struct ThreadingTrait<HeapHashMap<T, U, V, W, X> > : public ThreadingTrait<HashMap<T, U, V, W, X, HeapAllocator> > { };
1915
1916 template<typename T, typename U, typename V>
1917 struct ThreadingTrait<HeapHashSet<T, U, V> > : public ThreadingTrait<HashSet<T, U, V, HeapAllocator> > { };
1918
1919 template<typename T, size_t inlineCapacity>
1920 struct ThreadingTrait<HeapVector<T, inlineCapacity> > : public ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator> > { };
1921
1922 template<typename T, size_t inlineCapacity>
1923 struct ThreadingTrait<HeapDeque<T, inlineCapacity> > : public ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator> > { };
1924
1925 template<typename T, typename U, typename V>
1926 struct ThreadingTrait<HeapHashCountedSet<T, U, V> > : public ThreadingTrait<HashCountedSet<T, U, V, HeapAllocator> > { };
1927
1928 // The standard implementation of GCInfoTrait<T>::get() just returns a static
1929 // from the class T, but we can't do that for HashMap, HashSet, Vector, etc.
1930 // because they are in WTF and know nothing of GCInfos. Instead we have a
1931 // specialization of GCInfoTrait for these four classes here.
1932
1933 template<typename Key, typename Value, typename T, typename U, typename V>
1934 struct GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > {
1935     static const GCInfo* get()
1936     {
1937         typedef HashMap<Key, Value, T, U, V, HeapAllocator> TargetType;
1938         static const GCInfo info = {
1939             TraceTrait<TargetType>::trace,
1940             0,
1941             false, // HashMap needs no finalizer.
1942             WTF::IsPolymorphic<TargetType>::value,
1943 #if ENABLE(GC_PROFILING)
1944             TypenameStringTrait<TargetType>::get()
1945 #endif
1946         };
1947         return &info;
1948     }
1949 };
1950
1951 template<typename T, typename U, typename V>
1952 struct GCInfoTrait<HashSet<T, U, V, HeapAllocator> > {
1953     static const GCInfo* get()
1954     {
1955         typedef HashSet<T, U, V, HeapAllocator> TargetType;
1956         static const GCInfo info = {
1957             TraceTrait<TargetType>::trace,
1958             0,
1959             false, // HashSet needs no finalizer.
1960             WTF::IsPolymorphic<TargetType>::value,
1961 #if ENABLE(GC_PROFILING)
1962             TypenameStringTrait<TargetType>::get()
1963 #endif
1964         };
1965         return &info;
1966     }
1967 };
1968
1969 template<typename T, typename U, typename V>
1970 struct GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> > {
1971     static const GCInfo* get()
1972     {
1973         typedef LinkedHashSet<T, U, V, HeapAllocator> TargetType;
1974         static const GCInfo info = {
1975             TraceTrait<TargetType>::trace,
1976             LinkedHashSet<T, U, V, HeapAllocator>::finalize,
1977             true, // Needs finalization. The anchor needs to unlink itself from the chain.
1978             WTF::IsPolymorphic<TargetType>::value,
1979 #if ENABLE(GC_PROFILING)
1980             TypenameStringTrait<TargetType>::get()
1981 #endif
1982         };
1983         return &info;
1984     }
1985 };
1986
1987 template<typename ValueArg, size_t inlineCapacity, typename U>
1988 struct GCInfoTrait<ListHashSet<ValueArg, inlineCapacity, U, HeapListHashSetAllocator<ValueArg, inlineCapacity> > > {
1989     static const GCInfo* get()
1990     {
1991         typedef WTF::ListHashSet<ValueArg, inlineCapacity, U, HeapListHashSetAllocator<ValueArg, inlineCapacity> > TargetType;
1992         static const GCInfo info = {
1993             TraceTrait<TargetType>::trace,
1994             0,
1995             false, // ListHashSet needs no finalization though its backing might.
1996             false, // no vtable.
1997 #if ENABLE(GC_PROFILING)
1998             TypenameStringTrait<TargetType>::get()
1999 #endif
2000         };
2001         return &info;
2002     }
2003 };
2004
2005 template<typename T, typename Allocator>
2006 struct GCInfoTrait<WTF::ListHashSetNode<T, Allocator> > {
2007     static const GCInfo* get()
2008     {
2009         typedef WTF::ListHashSetNode<T, Allocator> TargetType;
2010         static const GCInfo info = {
2011             TraceTrait<TargetType>::trace,
2012             TargetType::finalize,
2013             WTF::HashTraits<T>::needsDestruction, // The node needs destruction if its data does.
2014             false, // no vtable.
2015 #if ENABLE(GC_PROFILING)
2016             TypenameStringTrait<TargetType>::get()
2017 #endif
2018         };
2019         return &info;
2020     }
2021 };
2022
2023 template<typename T>
2024 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > {
2025     static const GCInfo* get()
2026     {
2027 #if ENABLE(GC_PROFILING)
2028         typedef Vector<T, 0, HeapAllocator> TargetType;
2029 #endif
2030         static const GCInfo info = {
2031             TraceTrait<Vector<T, 0, HeapAllocator> >::trace,
2032             0,
2033             false, // Vector needs no finalizer if it has no inline capacity.
2034             WTF::IsPolymorphic<Vector<T, 0, HeapAllocator> >::value,
2035 #if ENABLE(GC_PROFILING)
2036             TypenameStringTrait<TargetType>::get()
2037 #endif
2038         };
2039         return &info;
2040     }
2041 };
2042
2043 template<typename T, size_t inlineCapacity>
2044 struct FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator> > : public FinalizerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>, true> { };
2045
2046 template<typename T, size_t inlineCapacity>
2047 struct GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> > {
2048     static const GCInfo* get()
2049     {
2050         typedef Vector<T, inlineCapacity, HeapAllocator> TargetType;
2051         static const GCInfo info = {
2052             TraceTrait<TargetType>::trace,
2053             FinalizerTrait<TargetType>::finalize,
2054             // Finalizer is needed to destruct things stored in the inline capacity.
2055             inlineCapacity && VectorTraits<T>::needsDestruction,
2056             WTF::IsPolymorphic<TargetType>::value,
2057 #if ENABLE(GC_PROFILING)
2058             TypenameStringTrait<TargetType>::get()
2059 #endif
2060         };
2061         return &info;
2062     }
2063 };
2064
2065 template<typename T>
2066 struct GCInfoTrait<Deque<T, 0, HeapAllocator> > {
2067     static const GCInfo* get()
2068     {
2069         typedef Deque<T, 0, HeapAllocator> TargetType;
2070         static const GCInfo info = {
2071             TraceTrait<TargetType>::trace,
2072             0,
2073             false, // Deque needs no finalizer if it has no inline capacity.
2074             WTF::IsPolymorphic<TargetType>::value,
2075 #if ENABLE(GC_PROFILING)
2076             TypenameStringTrait<TargetType>::get()
2077 #endif
2078         };
2079         return &info;
2080     }
2081     static const GCInfo info;
2082 };
2083
2084 template<typename T, typename U, typename V>
2085 struct GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator> > {
2086     static const GCInfo* get()
2087     {
2088         typedef HashCountedSet<T, U, V, HeapAllocator> TargetType;
2089         static const GCInfo info = {
2090             TraceTrait<TargetType>::trace,
2091             0,
2092             false, // HashCountedSet is just a HashTable, and needs no finalizer.
2093             WTF::IsPolymorphic<TargetType>::value,
2094 #if ENABLE(GC_PROFILING)
2095             TypenameStringTrait<TargetType>::get()
2096 #endif
2097         };
2098         return &info;
2099     }
2100     static const GCInfo info;
2101 };
2102
2103 template<typename T, size_t inlineCapacity>
2104 struct FinalizerTrait<Deque<T, inlineCapacity, HeapAllocator> > : public FinalizerTraitImpl<Deque<T, inlineCapacity, HeapAllocator>, true> { };
2105
2106 template<typename T, size_t inlineCapacity>
2107 struct GCInfoTrait<Deque<T, inlineCapacity, HeapAllocator> > {
2108     static const GCInfo* get()
2109     {
2110         typedef Deque<T, inlineCapacity, HeapAllocator> TargetType;
2111         static const GCInfo info = {
2112             TraceTrait<TargetType>::trace,
2113             FinalizerTrait<TargetType>::finalize,
2114             // Finalizer is needed to destruct things stored in the inline capacity.
2115             inlineCapacity && VectorTraits<T>::needsDestruction,
2116             WTF::IsPolymorphic<TargetType>::value,
2117 #if ENABLE(GC_PROFILING)
2118             TypenameStringTrait<TargetType>::get()
2119 #endif
2120         };
2121         return &info;
2122     }
2123     static const GCInfo info;
2124 };
2125
2126 template<typename T, typename Traits>
2127 struct GCInfoTrait<HeapVectorBacking<T, Traits> > {
2128     static const GCInfo* get()
2129     {
2130         typedef HeapVectorBacking<T, Traits> TargetType;
2131         static const GCInfo info = {
2132             TraceTrait<TargetType>::trace,
2133             FinalizerTrait<TargetType>::finalize,
2134             Traits::needsDestruction,
2135             false, // We don't support embedded objects in HeapVectors with vtables.
2136 #if ENABLE(GC_PROFILING)
2137             TypenameStringTrait<TargetType>::get()
2138 #endif
2139         };
2140         return &info;
2141     }
2142 };
2143
2144 template<typename Table>
2145 struct GCInfoTrait<HeapHashTableBacking<Table> > {
2146     static const GCInfo* get()
2147     {
2148         typedef HeapHashTableBacking<Table> TargetType;
2149         static const GCInfo info = {
2150             TraceTrait<TargetType>::trace,
2151             HeapHashTableBacking<Table>::finalize,
2152             Table::ValueTraits::needsDestruction,
2153             WTF::IsPolymorphic<TargetType>::value,
2154 #if ENABLE(GC_PROFILING)
2155             TypenameStringTrait<TargetType>::get()
2156 #endif
2157         };
2158         return &info;
2159     }
2160 };
2161
2162 } // namespace blink
2163
2164 namespace WTF {
2165
2166 // Catch-all for types that have a way to trace that don't have special
2167 // handling for weakness in collections. This means that if this type
2168 // contains WeakMember fields, they will simply be zeroed, but the entry
2169 // will not be removed from the collection. This always happens for
2170 // things in vectors, which don't currently support special handling of
2171 // weak elements.
2172 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
2173 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits> {
2174     static bool trace(blink::Visitor* visitor, T& t)
2175     {
2176         blink::TraceTrait<T>::trace(visitor, &t);
2177         return false;
2178     }
2179 };
2180
2181 // Catch-all for things that have HashTrait support for tracing with weakness.
2182 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
2183 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> {
2184     static bool trace(blink::Visitor* visitor, T& t)
2185     {
2186         return Traits::traceInCollection(visitor, t, strongify);
2187     }
2188 };
2189
2190 // Vector backing that needs marking. We don't support weak members in vectors.
2191 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
2192 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::HeapVectorBacking<T, Traits>, void> {
2193     static bool trace(blink::Visitor* visitor, void* self)
2194     {
2195         // The allocator can oversize the allocation a little, according to
2196         // the allocation granularity. The extra size is included in the
2197         // payloadSize call below, since there is nowhere to store the
2198         // originally allocated memory. This assert ensures that visiting the
2199         // last bit of memory can't cause trouble.
2200         COMPILE_ASSERT(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::allocationGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSpuriousVisits);
2201
2202         T* array = reinterpret_cast<T*>(self);
2203         blink::FinalizedHeapObjectHeader* header = blink::FinalizedHeapObjectHeader::fromPayload(self);
2204         // Use the payload size as recorded by the heap to determine how many
2205         // elements to mark.
2206         size_t length = header->payloadSize() / sizeof(T);
2207         for (size_t i = 0; i < length; i++)
2208             blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[i]);
2209         return false;
2210     }
2211 };
2212
2213 // Almost all hash table backings are visited with this specialization.
2214 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Table>
2215 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::HeapHashTableBacking<Table>, void> {
2216     typedef typename Table::ValueType Value;
2217     typedef typename Table::ValueTraits Traits;
2218     static bool trace(blink::Visitor* visitor, void* self)
2219     {
2220         Value* array = reinterpret_cast<Value*>(self);
2221         blink::FinalizedHeapObjectHeader* header = blink::FinalizedHeapObjectHeader::fromPayload(self);
2222         size_t length = header->payloadSize() / sizeof(Value);
2223         for (size_t i = 0; i < length; i++) {
2224             if (!HashTableHelper<Value, typename Table::ExtractorType, typename Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i]))
2225                 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, strongify, Value, Traits>::trace(visitor, array[i]);
2226         }
2227         return false;
2228     }
2229 };
2230
2231 // This specialization of TraceInCollectionTrait is for the backing of
2232 // HeapListHashSet. This is for the case that we find a reference to the
2233 // backing from the stack. That probably means we have a GC while we are in a
2234 // ListHashSet method since normal API use does not put pointers to the backing
2235 // on the stack.
2236 template<ShouldWeakPointersBeMarkedStrongly strongify, typename NodeContents, size_t inlineCapacity, typename T, typename U, typename V, typename W, typename X, typename Y>
2237 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::HeapHashTableBacking<HashTable<ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T, inlineCapacity> >*, U, V, W, X, Y, blink::HeapAllocator> >, void> {
2238     typedef ListHashSetNode<NodeContents, blink::HeapListHashSetAllocator<T, inlineCapacity> > Node;
2239     typedef HashTable<Node*, U, V, W, X, Y, blink::HeapAllocator> Table;
2240     static bool trace(blink::Visitor* visitor, void* self)
2241     {
2242         Node** array = reinterpret_cast<Node**>(self);
2243         blink::FinalizedHeapObjectHeader* header = blink::FinalizedHeapObjectHeader::fromPayload(self);
2244         size_t length = header->payloadSize() / sizeof(Node*);
2245         for (size_t i = 0; i < length; i++) {
2246             if (!HashTableHelper<Node*, typename Table::ExtractorType, typename Table::KeyTraitsType>::isEmptyOrDeletedBucket(array[i])) {
2247                 traceListHashSetValue(visitor, array[i]->m_value);
2248                 // Just mark the node without tracing because we already traced
2249                 // the contents, and there is no need to trace the next and
2250                 // prev fields since iterating over the hash table backing will
2251                 // find the whole chain.
2252                 visitor->markNoTracing(array[i]);
2253             }
2254         }
2255         return false;
2256     }
2257 };
2258
2259 // Key value pairs, as used in HashMap. To disambiguate template choice we have
2260 // to have two versions, first the one with no special weak handling, then the
2261 // one with weak handling.
2262 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Value, typename Traits>
2263 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, KeyValuePair<Key, Value>, Traits>  {
2264     static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self)
2265     {
2266         ASSERT(ShouldBeTraced<Traits>::value);
2267         blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTraits>::value, NoWeakHandlingInCollections, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key);
2268         blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::ValueTraits>::value, NoWeakHandlingInCollections, strongify, Value, typename Traits::ValueTraits>::trace(visitor, self.value);
2269         return false;
2270     }
2271 };
2272
2273 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Key, typename Value, typename Traits>
2274 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, KeyValuePair<Key, Value>, Traits> {
2275     static bool trace(blink::Visitor* visitor, KeyValuePair<Key, Value>& self)
2276     {
2277         // This is the core of the ephemeron-like functionality. If there is
2278         // weakness on the key side then we first check whether there are
2279         // dead weak pointers on that side, and if there are we don't mark the
2280         // value side (yet). Conversely if there is weakness on the value side
2281         // we check that first and don't mark the key side yet if we find dead
2282         // weak pointers.
2283         // Corner case: If there is weakness on both the key and value side,
2284         // and there are also strong pointers on the both sides then we could
2285         // unexpectedly leak. The scenario is that the weak pointer on the key
2286         // side is alive, which causes the strong pointer on the key side to be
2287         // marked. If that then results in the object pointed to by the weak
2288         // pointer on the value side being marked live, then the whole
2289         // key-value entry is leaked. To avoid unexpected leaking, we disallow
2290         // this case, but if you run into this assert, please reach out to Blink
2291         // reviewers, and we may relax it.
2292         const bool keyIsWeak = Traits::KeyTraits::weakHandlingFlag == WeakHandlingInCollections;
2293         const bool valueIsWeak = Traits::ValueTraits::weakHandlingFlag == WeakHandlingInCollections;
2294         const bool keyHasStrongRefs = ShouldBeTraced<typename Traits::KeyTraits>::value;
2295         const bool valueHasStrongRefs = ShouldBeTraced<typename Traits::ValueTraits>::value;
2296         COMPILE_ASSERT(!keyIsWeak || !valueIsWeak || !keyHasStrongRefs || !valueHasStrongRefs, ThisConfigurationWasDisallowedToAvoidUnexpectedLeaks);
2297         if ((valueIsWeak && !keyIsWeak) || (valueIsWeak && keyIsWeak && !valueHasStrongRefs)) {
2298             // Check value first.
2299             bool deadWeakObjectsFoundOnValueSide = blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor, self.value);
2300             if (deadWeakObjectsFoundOnValueSide)
2301                 return true;
2302             return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTraits>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key);
2303         }
2304         // Check key first.
2305         bool deadWeakObjectsFoundOnKeySide = blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::KeyTraits>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key);
2306         if (deadWeakObjectsFoundOnKeySide)
2307             return true;
2308         return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Traits::ValueTraits>::value, Traits::ValueTraits::weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor, self.value);
2309     }
2310 };
2311
2312 // Nodes used by LinkedHashSet. Again we need two versions to disambiguate the
2313 // template.
2314 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Allocator, typename Traits>
2315 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, LinkedHashSetNode<Value, Allocator>, Traits> {
2316     static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocator>& self)
2317     {
2318         ASSERT(ShouldBeTraced<Traits>::value);
2319         blink::TraceTrait<Value>::trace(visitor, &self.m_value);
2320         return false;
2321     }
2322 };
2323
2324 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, typename Allocator, typename Traits>
2325 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, LinkedHashSetNode<Value, Allocator>, Traits> {
2326     static bool trace(blink::Visitor* visitor, LinkedHashSetNode<Value, Allocator>& self)
2327     {
2328         return TraceInCollectionTrait<WeakHandlingInCollections, strongify, Value, typename Traits::ValueTraits>::trace(visitor, self.m_value);
2329     }
2330 };
2331
2332 // ListHashSetNode pointers (a ListHashSet is implemented as a hash table of these pointers).
2333 template<ShouldWeakPointersBeMarkedStrongly strongify, typename Value, size_t inlineCapacity, typename Traits>
2334 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity> >*, Traits> {
2335     typedef ListHashSetNode<Value, blink::HeapListHashSetAllocator<Value, inlineCapacity> > Node;
2336     static bool trace(blink::Visitor* visitor, Node* node)
2337     {
2338         traceListHashSetValue(visitor, node->m_value);
2339         // Just mark the node without tracing because we already traced the
2340         // contents, and there is no need to trace the next and prev fields
2341         // since iterating over the hash table backing will find the whole
2342         // chain.
2343         visitor->markNoTracing(node);
2344         return false;
2345     }
2346 };
2347
2348 } // namespace WTF
2349
2350 namespace blink {
2351
2352 // CollectionBackingTraceTrait. Do nothing for things in collections that don't
2353 // need tracing, or call TraceInCollectionTrait for those that do.
2354
2355 // Specialization for things that don't need marking and have no weak pointers. We
2356 // do nothing, even if WTF::WeakPointersActStrong.
2357 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
2358 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, strongify, T, Traits> {
2359     static bool trace(Visitor*, T&) { return false; }
2360 };
2361
2362 // Specialization for things that either need marking or have weak pointers or
2363 // both.
2364 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits>
2365 struct CollectionBackingTraceTrait {
2366     static bool trace(Visitor* visitor, T&t)
2367     {
2368         Visitor::verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0));
2369         return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Traits>::trace(visitor, t);
2370     }
2371 };
2372
2373 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<T> {
2374     // We want to treat the object as a weak object in the sense that it can
2375     // disappear from hash sets and hash maps.
2376     static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCollections;
2377     // Normally whether or not an object needs tracing is inferred
2378     // automatically from the presence of the trace method, but we don't
2379     // necessarily have a trace method, and we may not need one because T
2380     // can perhaps only be allocated inside collections, never as indpendent
2381     // objects. Explicitly mark this as needing tracing and it will be traced
2382     // in collections using the traceInCollection method, which it must have.
2383     template<typename U = void> struct NeedsTracingLazily {
2384         static const bool value = true;
2385     };
2386     // The traceInCollection method traces differently depending on whether we
2387     // are strongifying the trace operation. We strongify the trace operation
2388     // when there are active iterators on the object. In this case all
2389     // WeakMembers are marked like strong members so that elements do not
2390     // suddenly disappear during iteration. Returns true if weak pointers to
2391     // dead objects were found: In this case any strong pointers were not yet
2392     // traced and the entry should be removed from the collection.
2393     static bool traceInCollection(Visitor* visitor, T& t, WTF::ShouldWeakPointersBeMarkedStrongly strongify)
2394     {
2395         return t.traceInCollection(visitor, strongify);
2396     }
2397 };
2398
2399 template<typename T, typename Traits>
2400 struct TraceTrait<HeapVectorBacking<T, Traits> > {
2401     typedef HeapVectorBacking<T, Traits> Backing;
2402     static void trace(Visitor* visitor, void* self)
2403     {
2404         COMPILE_ASSERT(!WTF::IsWeak<T>::value, WeDontSupportWeaknessInHeapVectorsOrDeques);
2405         if (WTF::ShouldBeTraced<Traits>::value)
2406             WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::WeakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self);
2407     }
2408     static void mark(Visitor* visitor, const Backing* backing)
2409     {
2410         visitor->mark(backing, &trace);
2411     }
2412     static void checkGCInfo(Visitor* visitor, const Backing* backing)
2413     {
2414 #if ENABLE(ASSERT)
2415         visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>::get());
2416 #endif
2417     }
2418 };
2419
2420 // The trace trait for the heap hashtable backing is used when we find a
2421 // direct pointer to the backing from the conservative stack scanner. This
2422 // normally indicates that there is an ongoing iteration over the table, and so
2423 // we disable weak processing of table entries. When the backing is found
2424 // through the owning hash table we mark differently, in order to do weak
2425 // processing.
2426 template<typename Table>
2427 struct TraceTrait<HeapHashTableBacking<Table> > {
2428     typedef HeapHashTableBacking<Table> Backing;
2429     typedef typename Table::ValueTraits Traits;
2430     static void trace(Visitor* visitor, void* self)
2431     {
2432         if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WTF::WeakHandlingInCollections)
2433             WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::WeakPointersActStrong, Backing, void>::trace(visitor, self);
2434     }
2435     static void mark(Visitor* visitor, const Backing* backing)
2436     {
2437         if (WTF::ShouldBeTraced<Traits>::value || Traits::weakHandlingFlag == WTF::WeakHandlingInCollections)
2438             visitor->mark(backing, &trace);
2439         else
2440             visitor->markNoTracing(backing); // If we know the trace function will do nothing there is no need to call it.
2441     }
2442     static void checkGCInfo(Visitor* visitor, const Backing* backing)
2443     {
2444 #if ENABLE(ASSERT)
2445         visitor->checkGCInfo(const_cast<Backing*>(backing), GCInfoTrait<Backing>::get());
2446 #endif
2447     }
2448 };
2449
2450 template<typename Table>
2451 void HeapHashTableBacking<Table>::finalize(void* pointer)
2452 {
2453     typedef typename Table::ValueType Value;
2454     ASSERT(Table::ValueTraits::needsDestruction);
2455     FinalizedHeapObjectHeader* header = FinalizedHeapObjectHeader::fromPayload(pointer);
2456     // Use the payload size as recorded by the heap to determine how many
2457     // elements to finalize.
2458     size_t length = header->payloadSize() / sizeof(Value);
2459     Value* table = reinterpret_cast<Value*>(pointer);
2460     for (unsigned i = 0; i < length; i++) {
2461         if (!Table::isEmptyOrDeletedBucket(table[i]))
2462             table[i].~Value();
2463     }
2464 }
2465
2466 template<typename T, typename U, typename V, typename W, typename X>
2467 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator> > { };
2468 template<typename T, typename U, typename V>
2469 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V, HeapAllocator> > { };
2470 template<typename T, typename U, typename V>
2471 struct GCInfoTrait<HeapLinkedHashSet<T, U, V> > : public GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> > { };
2472 template<typename T, size_t inlineCapacity, typename U>
2473 struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U> > : public GCInfoTrait<ListHashSet<T, inlineCapacity, U, HeapListHashSetAllocator<T, inlineCapacity> > > { };
2474 template<typename T, size_t inlineCapacity>
2475 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> > { };
2476 template<typename T, size_t inlineCapacity>
2477 struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T, inlineCapacity, HeapAllocator> > { };
2478 template<typename T, typename U, typename V>
2479 struct GCInfoTrait<HeapHashCountedSet<T, U, V> > : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator> > { };
2480
2481 template<typename T>
2482 struct IfWeakMember;
2483
2484 template<typename T>
2485 struct IfWeakMember {
2486     template<typename U>
2487     static bool isDead(Visitor*, const U&) { return false; }
2488 };
2489
2490 template<typename T>
2491 struct IfWeakMember<WeakMember<T> > {
2492     static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visitor->isAlive(t.get()); }
2493 };
2494
2495 }
2496
2497 #endif // Heap_h