Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / 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 "heap/AddressSanitizer.h"
35 #include "heap/HeapExport.h"
36 #include "heap/ThreadState.h"
37 #include "heap/Visitor.h"
38
39 #include "wtf/Assertions.h"
40 #include "wtf/OwnPtr.h"
41 #include "wtf/PassRefPtr.h"
42
43 #include <stdint.h>
44
45 namespace WebCore {
46
47 const size_t blinkPageSizeLog2 = 17;
48 const size_t blinkPageSize = 1 << blinkPageSizeLog2;
49 const size_t blinkPageOffsetMask = blinkPageSize - 1;
50 const size_t blinkPageBaseMask = ~blinkPageOffsetMask;
51 // Double precision floats are more efficient when 8 byte aligned, so we 8 byte
52 // align all allocations even on 32 bit.
53 const size_t allocationGranularity = 8;
54 const size_t allocationMask = allocationGranularity - 1;
55 const size_t objectStartBitMapSize = (blinkPageSize + ((8 * allocationGranularity) - 1)) / (8 * allocationGranularity);
56 const size_t reservedForObjectBitMap = ((objectStartBitMapSize + allocationMask) & ~allocationMask);
57 const size_t maxHeapObjectSize = 1 << 27;
58
59 const size_t markBitMask = 1;
60 const size_t freeListMask = 2;
61 const size_t debugBitMask = 4;
62 const size_t sizeMask = ~7;
63 const uint8_t freelistZapValue = 42;
64 const uint8_t finalizedZapValue = 24;
65
66 class HeapStats;
67 class PageMemory;
68 template<ThreadAffinity affinity> class ThreadLocalPersistents;
69 template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > > class Persistent;
70
71 HEAP_EXPORT size_t osPageSize();
72
73 // Blink heap pages are set up with a guard page before and after the
74 // payload.
75 inline size_t blinkPagePayloadSize()
76 {
77     return blinkPageSize - 2 * osPageSize();
78 }
79
80 // Blink heap pages are aligned to the Blink heap page size.
81 // Therefore, the start of a Blink page can be obtained by
82 // rounding down to the Blink page size.
83 inline Address roundToBlinkPageStart(Address address)
84 {
85     return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blinkPageBaseMask);
86 }
87
88 // Compute the amount of padding we have to add to a header to make
89 // the size of the header plus the padding a multiple of 8 bytes.
90 template<typename Header>
91 inline size_t headerPadding()
92 {
93     return (allocationGranularity - (sizeof(Header) % allocationGranularity)) % allocationGranularity;
94 }
95
96 // Masks an address down to the enclosing blink page base address.
97 inline Address blinkPageAddress(Address address)
98 {
99     return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) & blinkPageBaseMask);
100 }
101
102 #ifndef NDEBUG
103
104 // Sanity check for a page header address: the address of the page
105 // header should be OS page size away from being Blink page size
106 // aligned.
107 inline bool isPageHeaderAddress(Address address)
108 {
109     return !((reinterpret_cast<uintptr_t>(address) & blinkPageOffsetMask) - osPageSize());
110 }
111 #endif
112
113 // Mask an address down to the enclosing oilpan heap page base address.
114 // All oilpan heap pages are aligned at blinkPageBase plus an OS page size.
115 // FIXME: Remove HEAP_EXPORT once we get a proper public interface to our typed heaps.
116 // This is only exported to enable tests in HeapTest.cpp.
117 HEAP_EXPORT inline Address pageHeaderAddress(Address address)
118 {
119     return blinkPageAddress(address) + osPageSize();
120 }
121
122 // Common header for heap pages.
123 class BaseHeapPage {
124 public:
125     BaseHeapPage(PageMemory* storage, const GCInfo* gcInfo)
126         : m_storage(storage)
127         , m_gcInfo(gcInfo)
128     {
129         ASSERT(isPageHeaderAddress(reinterpret_cast<Address>(this)));
130     }
131
132     // Check if the given address could point to an object in this
133     // heap page. If so, find the start of that object and mark it
134     // using the given Visitor.
135     //
136     // Returns true if the object was found and marked, returns false
137     // otherwise.
138     //
139     // This is used during conservative stack scanning to
140     // conservatively mark all objects that could be referenced from
141     // the stack.
142     virtual bool checkAndMarkPointer(Visitor*, Address) = 0;
143
144     Address address() { return reinterpret_cast<Address>(this); }
145     PageMemory* storage() const { return m_storage; }
146     const GCInfo* gcInfo() { return m_gcInfo; }
147
148 private:
149     PageMemory* m_storage;
150     const GCInfo* m_gcInfo;
151 };
152
153 // Large allocations are allocated as separate objects and linked in a
154 // list.
155 //
156 // In order to use the same memory allocation routines for everything
157 // allocated in the heap, large objects are considered heap pages
158 // containing only one object.
159 //
160 // The layout of a large heap object is as follows:
161 //
162 // | BaseHeapPage | next pointer | FinalizedHeapObjectHeader or HeapObjectHeader | payload |
163 template<typename Header>
164 class LargeHeapObject : public BaseHeapPage {
165 public:
166     LargeHeapObject(PageMemory* storage, const GCInfo* gcInfo) : BaseHeapPage(storage, gcInfo)
167     {
168         COMPILE_ASSERT(!(sizeof(LargeHeapObject<Header>) & allocationMask), large_heap_object_header_misaligned);
169     }
170
171     virtual bool checkAndMarkPointer(Visitor*, Address);
172
173     void link(LargeHeapObject<Header>** previousNext)
174     {
175         m_next = *previousNext;
176         *previousNext = this;
177     }
178
179     void unlink(LargeHeapObject<Header>** previousNext)
180     {
181         *previousNext = m_next;
182     }
183
184     bool contains(Address object)
185     {
186         return (address() <= object) && (object <= (address() + size()));
187     }
188
189     LargeHeapObject<Header>* next()
190     {
191         return m_next;
192     }
193
194     size_t size()
195     {
196         return heapObjectHeader()->size() + sizeof(LargeHeapObject<Header>) + headerPadding<Header>();
197     }
198
199     Address payload() { return heapObjectHeader()->payload(); }
200     size_t payloadSize() { return heapObjectHeader()->payloadSize(); }
201
202     Header* heapObjectHeader()
203     {
204         Address headerAddress = address() + sizeof(LargeHeapObject<Header>) + headerPadding<Header>();
205         return reinterpret_cast<Header*>(headerAddress);
206     }
207
208     bool isMarked();
209     void unmark();
210     void getStats(HeapStats&);
211     void mark(Visitor*);
212     void finalize();
213
214 private:
215     friend class Heap;
216     friend class ThreadHeap<Header>;
217
218     LargeHeapObject<Header>* m_next;
219 };
220
221 // The BasicObjectHeader is the minimal object header. It is used when
222 // encountering heap space of size allocationGranularity to mark it as
223 // as freelist entry.
224 class BasicObjectHeader {
225 public:
226     NO_SANITIZE_ADDRESS
227     explicit BasicObjectHeader(size_t encodedSize)
228         : m_size(encodedSize) { }
229
230     static size_t freeListEncodedSize(size_t size) { return size | freeListMask; }
231
232     NO_SANITIZE_ADDRESS
233     bool isFree() { return m_size & freeListMask; }
234
235     NO_SANITIZE_ADDRESS
236     size_t size() const { return m_size & sizeMask; }
237
238 protected:
239     size_t m_size;
240 };
241
242 // Our heap object layout is layered with the HeapObjectHeader closest
243 // to the payload, this can be wrapped in a FinalizedObjectHeader if the
244 // object is on the GeneralHeap and not on a specific TypedHeap.
245 // Finally if the object is a large object (> blinkPageSize/2) then it is
246 // wrapped with a LargeObjectHeader.
247 //
248 // Object memory layout:
249 // [ LargeObjectHeader | ] [ FinalizedObjectHeader | ] HeapObjectHeader | payload
250 // The [ ] notation denotes that the LargeObjectHeader and the FinalizedObjectHeader
251 // are independently optional.
252 class HeapObjectHeader : public BasicObjectHeader {
253 public:
254     NO_SANITIZE_ADDRESS
255     explicit HeapObjectHeader(size_t encodedSize)
256         : BasicObjectHeader(encodedSize)
257 #ifndef NDEBUG
258         , m_magic(magic)
259 #endif
260     { }
261
262     NO_SANITIZE_ADDRESS
263     HeapObjectHeader(size_t encodedSize, const GCInfo*)
264         : BasicObjectHeader(encodedSize)
265 #ifndef NDEBUG
266         , m_magic(magic)
267 #endif
268     { }
269
270     inline void checkHeader() const;
271     inline bool isMarked() const;
272
273     inline void mark();
274     inline void unmark();
275
276     inline Address payload();
277     inline size_t payloadSize();
278     inline Address payloadEnd();
279
280     inline void setDebugMark();
281     inline void clearDebugMark();
282     inline bool hasDebugMark() const;
283
284     // Zap magic number with a new magic number that means there was once an
285     // object allocated here, but it was freed because nobody marked it during
286     // GC.
287     void zapMagic();
288
289     static void finalize(const GCInfo*, Address, size_t);
290     HEAP_EXPORT static HeapObjectHeader* fromPayload(const void*);
291
292     static const intptr_t magic = 0xc0de247;
293     static const intptr_t zappedMagic = 0xC0DEdead;
294     // The zap value for vtables should be < 4K to ensure it cannot be
295     // used for dispatch.
296     static const intptr_t zappedVTable = 0xd0d;
297
298 private:
299 #ifndef NDEBUG
300     intptr_t m_magic;
301 #endif
302 };
303
304 const size_t objectHeaderSize = sizeof(HeapObjectHeader);
305
306 // Each object on the GeneralHeap needs to carry a pointer to its
307 // own GCInfo structure for tracing and potential finalization.
308 class FinalizedHeapObjectHeader : public HeapObjectHeader {
309 public:
310     NO_SANITIZE_ADDRESS
311     FinalizedHeapObjectHeader(size_t encodedSize, const GCInfo* gcInfo)
312         : HeapObjectHeader(encodedSize)
313         , m_gcInfo(gcInfo)
314     {
315     }
316
317     inline Address payload();
318     inline size_t payloadSize();
319
320     NO_SANITIZE_ADDRESS
321     const GCInfo* gcInfo() { return m_gcInfo; }
322
323     NO_SANITIZE_ADDRESS
324     const char* typeMarker() { return m_gcInfo->m_typeMarker; }
325
326     NO_SANITIZE_ADDRESS
327     TraceCallback traceCallback() { return m_gcInfo->m_trace; }
328
329     void finalize();
330
331     NO_SANITIZE_ADDRESS
332     inline bool hasFinalizer() { return m_gcInfo->hasFinalizer(); }
333
334     HEAP_EXPORT static FinalizedHeapObjectHeader* fromPayload(const void*);
335
336 private:
337     const GCInfo* m_gcInfo;
338 };
339
340 const size_t finalizedHeaderSize = sizeof(FinalizedHeapObjectHeader);
341
342 class FreeListEntry : public HeapObjectHeader {
343 public:
344     NO_SANITIZE_ADDRESS
345     explicit FreeListEntry(size_t size)
346         : HeapObjectHeader(freeListEncodedSize(size))
347         , m_next(0)
348     {
349 #if !defined(NDEBUG) && !ASAN
350         // Zap free area with asterisks, aka 0x2a2a2a2a.
351         // For ASAN don't zap since we keep accounting in the freelist entry.
352         for (size_t i = sizeof(*this); i < size; i++)
353             reinterpret_cast<Address>(this)[i] = freelistZapValue;
354         ASSERT(size >= objectHeaderSize);
355         zapMagic();
356 #endif
357     }
358
359     Address address() { return reinterpret_cast<Address>(this); }
360
361     NO_SANITIZE_ADDRESS
362     void unlink(FreeListEntry** prevNext)
363     {
364         *prevNext = m_next;
365         m_next = 0;
366     }
367
368     NO_SANITIZE_ADDRESS
369     void link(FreeListEntry** prevNext)
370     {
371         m_next = *prevNext;
372         *prevNext = this;
373     }
374
375 #if defined(ADDRESS_SANITIZER)
376     NO_SANITIZE_ADDRESS
377     bool shouldAddToFreeList()
378     {
379         // Init if not already magic.
380         if ((m_asanMagic & ~asanDeferMemoryReuseMask) != asanMagic) {
381             m_asanMagic = asanMagic | asanDeferMemoryReuseCount;
382             return false;
383         }
384         // Decrement if count part of asanMagic > 0.
385         if (m_asanMagic & asanDeferMemoryReuseMask)
386             m_asanMagic--;
387         return !(m_asanMagic & asanDeferMemoryReuseMask);
388     }
389 #endif
390
391 private:
392     FreeListEntry* m_next;
393 #if defined(ADDRESS_SANITIZER)
394     unsigned m_asanMagic;
395 #endif
396 };
397
398 // Representation of Blink heap pages.
399 //
400 // Pages are specialized on the type of header on the object they
401 // contain. If a heap page only contains a certain type of object all
402 // of the objects will have the same GCInfo pointer and therefore that
403 // pointer can be stored in the HeapPage instead of in the header of
404 // each object. In that case objects have only a HeapObjectHeader and
405 // not a FinalizedHeapObjectHeader saving a word per object.
406 template<typename Header>
407 class HeapPage : public BaseHeapPage {
408 public:
409     HeapPage(PageMemory*, ThreadHeap<Header>*, const GCInfo*);
410
411     void link(HeapPage**);
412     static void unlink(HeapPage*, HeapPage**);
413
414     bool isEmpty();
415
416     bool contains(Address addr)
417     {
418         Address blinkPageStart = roundToBlinkPageStart(address());
419         return blinkPageStart <= addr && (blinkPageStart + blinkPageSize) > addr;
420     }
421
422     HeapPage* next() { return m_next; }
423
424     Address payload()
425     {
426         return address() + sizeof(*this) + headerPadding<Header>();
427     }
428
429     static size_t payloadSize()
430     {
431         return (blinkPagePayloadSize() - sizeof(HeapPage) - headerPadding<Header>()) & ~allocationMask;
432     }
433
434     Address end() { return payload() + payloadSize(); }
435
436     void getStats(HeapStats&);
437     void clearMarks();
438     void sweep();
439     void clearObjectStartBitMap();
440     void finalize(Header*);
441     virtual bool checkAndMarkPointer(Visitor*, Address);
442     ThreadHeap<Header>* heap() { return m_heap; }
443 #if defined(ADDRESS_SANITIZER)
444     void poisonUnmarkedObjects();
445 #endif
446
447 protected:
448     void populateObjectStartBitMap();
449     bool isObjectStartBitMapComputed() { return m_objectStartBitMapComputed; }
450     TraceCallback traceCallback(Header*);
451
452     HeapPage<Header>* m_next;
453     ThreadHeap<Header>* m_heap;
454     bool m_objectStartBitMapComputed;
455     uint8_t m_objectStartBitMap[reservedForObjectBitMap];
456
457     friend class ThreadHeap<Header>;
458 };
459
460 // A HeapContainsCache provides a fast way of taking an arbitrary
461 // pointer-sized word, and determining whether it can be interpreted
462 // as a pointer to an area that is managed by the garbage collected
463 // Blink heap. There is a cache of 'pages' that have previously been
464 // determined to be either wholly inside or wholly outside the
465 // heap. The size of these pages must be smaller than the allocation
466 // alignment of the heap pages. We determine on-heap-ness by rounding
467 // down the pointer to the nearest page and looking up the page in the
468 // cache. If there is a miss in the cache we ask the heap to determine
469 // the status of the pointer by iterating over all of the heap. The
470 // result is then cached in the two-way associative page cache.
471 //
472 // A HeapContainsCache is both a positive and negative
473 // cache. Therefore, it must be flushed both when new memory is added
474 // and when memory is removed from the Blink heap.
475 class HeapContainsCache {
476 public:
477     HeapContainsCache();
478
479     void flush();
480     bool contains(Address);
481
482     // Perform a lookup in the cache.
483     //
484     // If lookup returns false the argument address was not found in
485     // the cache and it is unknown if the address is in the Blink
486     // heap.
487     //
488     // If lookup returns true the argument address was found in the
489     // cache. In that case, the address is in the heap if the base
490     // heap page out parameter is different from 0 and is not in the
491     // heap if the base heap page out parameter is 0.
492     bool lookup(Address, BaseHeapPage**);
493
494     // Add an entry to the cache. Use a 0 base heap page pointer to
495     // add a negative entry.
496     void addEntry(Address, BaseHeapPage*);
497
498 private:
499     class Entry {
500     public:
501         Entry()
502             : m_address(0)
503             , m_containingPage(0)
504         {
505         }
506
507         Entry(Address address, BaseHeapPage* containingPage)
508             : m_address(address)
509             , m_containingPage(containingPage)
510         {
511         }
512
513         BaseHeapPage* containingPage() { return m_containingPage; }
514         Address address() { return m_address; }
515
516     private:
517         Address m_address;
518         BaseHeapPage* m_containingPage;
519     };
520
521     static const int numberOfEntriesLog2 = 12;
522     static const int numberOfEntries = 1 << numberOfEntriesLog2;
523
524     static size_t hash(Address);
525
526     WTF::OwnPtr<HeapContainsCache::Entry[]> m_entries;
527
528     friend class ThreadState;
529 };
530
531 // The CallbackStack contains all the visitor callbacks used to trace and mark
532 // objects. A specific CallbackStack instance contains at most bufferSize elements.
533 // If more space is needed a new CallbackStack instance is created and chained
534 // together with the former instance. I.e. a logical CallbackStack can be made of
535 // multiple chained CallbackStack object instances.
536 // There are two logical callback stacks. One containing all the marking callbacks and
537 // one containing the weak pointer callbacks.
538 class CallbackStack {
539 public:
540     CallbackStack(CallbackStack** first)
541         : m_limit(&(m_buffer[bufferSize]))
542         , m_current(&(m_buffer[0]))
543         , m_next(*first)
544     {
545 #ifndef NDEBUG
546         clearUnused();
547 #endif
548         *first = this;
549     }
550
551     ~CallbackStack();
552     void clearUnused();
553
554     void assertIsEmpty();
555
556     class Item {
557     public:
558         Item() { }
559         Item(void* object, VisitorCallback callback)
560             : m_object(object)
561             , m_callback(callback)
562         {
563         }
564         void* object() { return m_object; }
565         VisitorCallback callback() { return m_callback; }
566
567     private:
568         void* m_object;
569         VisitorCallback m_callback;
570     };
571
572     static void init(CallbackStack** first);
573     static void shutdown(CallbackStack** first);
574     bool popAndInvokeCallback(CallbackStack** first, Visitor*);
575
576     Item* allocateEntry(CallbackStack** first)
577     {
578         if (m_current < m_limit)
579             return m_current++;
580         return (new CallbackStack(first))->allocateEntry(first);
581     }
582
583 private:
584     static const size_t bufferSize = 8000;
585     Item m_buffer[bufferSize];
586     Item* m_limit;
587     Item* m_current;
588     CallbackStack* m_next;
589 };
590
591 // Non-template super class used to pass a heap around to other classes.
592 class BaseHeap {
593 public:
594     virtual ~BaseHeap() { }
595
596     // Find the page in this thread heap containing the given
597     // address. Returns 0 if the address is not contained in any
598     // page in this thread heap.
599     virtual BaseHeapPage* heapPageFromAddress(Address) = 0;
600
601     // Find the large object in this thread heap containing the given
602     // address. Returns 0 if the address is not contained in any
603     // page in this thread heap.
604     virtual BaseHeapPage* largeHeapObjectFromAddress(Address) = 0;
605
606     // Check if the given address could point to an object in this
607     // heap. If so, find the start of that object and mark it using
608     // the given Visitor.
609     //
610     // Returns true if the object was found and marked, returns false
611     // otherwise.
612     //
613     // This is used during conservative stack scanning to
614     // conservatively mark all objects that could be referenced from
615     // the stack.
616     virtual bool checkAndMarkLargeHeapObject(Visitor*, Address) = 0;
617
618     // Sweep this part of the Blink heap. This finalizes dead objects
619     // and builds freelists for all the unused memory.
620     virtual void sweep() = 0;
621
622     // Forcefully finalize all objects in this part of the Blink heap
623     // (potentially with the exception of one object). This is used
624     // during thread termination to make sure that all objects for the
625     // dying thread are finalized.
626     virtual void assertEmpty() = 0;
627
628     virtual void clearFreeLists() = 0;
629     virtual void clearMarks() = 0;
630 #ifndef NDEBUG
631     virtual void getScannedStats(HeapStats&) = 0;
632 #endif
633
634     virtual void makeConsistentForGC() = 0;
635     virtual bool isConsistentForGC() = 0;
636
637     // Returns a bucket number for inserting a FreeListEntry of a
638     // given size. All FreeListEntries in the given bucket, n, have
639     // size >= 2^n.
640     static int bucketIndexForSize(size_t);
641 };
642
643 // Thread heaps represent a part of the per-thread Blink heap.
644 //
645 // Each Blink thread has a number of thread heaps: one general heap
646 // that contains any type of object and a number of heaps specialized
647 // for specific object types (such as Node).
648 //
649 // Each thread heap contains the functionality to allocate new objects
650 // (potentially adding new pages to the heap), to find and mark
651 // objects during conservative stack scanning and to sweep the set of
652 // pages after a GC.
653 template<typename Header>
654 class ThreadHeap : public BaseHeap {
655 public:
656     ThreadHeap(ThreadState*);
657     virtual ~ThreadHeap();
658
659     virtual BaseHeapPage* heapPageFromAddress(Address);
660     virtual BaseHeapPage* largeHeapObjectFromAddress(Address);
661     virtual bool checkAndMarkLargeHeapObject(Visitor*, Address);
662     virtual void sweep();
663     virtual void assertEmpty();
664     virtual void clearFreeLists();
665     virtual void clearMarks();
666 #ifndef NDEBUG
667     virtual void getScannedStats(HeapStats&);
668 #endif
669
670     virtual void makeConsistentForGC();
671     virtual bool isConsistentForGC();
672
673     ThreadState* threadState() { return m_threadState; }
674     HeapStats& stats() { return m_threadState->stats(); }
675     HeapContainsCache* heapContainsCache() { return m_threadState->heapContainsCache(); }
676
677     inline Address allocate(size_t, const GCInfo*);
678     void addToFreeList(Address, size_t);
679     void addPageToPool(HeapPage<Header>*);
680     inline static size_t roundedAllocationSize(size_t size)
681     {
682         return allocationSizeFromSize(size) - sizeof(Header);
683     }
684
685 private:
686     // Once pages have been used for one thread heap they will never
687     // be reused for another thread heap. Instead of unmapping, we add
688     // the pages to a pool of pages to be reused later by this thread
689     // heap. This is done as a security feature to avoid type
690     // confusion. The heap is type segregated by having separate
691     // thread heaps for various types of objects. Holding on to pages
692     // ensures that the same virtual address space cannot be used for
693     // objects of another type than the type contained in this thread
694     // heap.
695     class PagePoolEntry {
696     public:
697         PagePoolEntry(PageMemory* storage, PagePoolEntry* next)
698             : m_storage(storage)
699             , m_next(next)
700         { }
701
702         PageMemory* storage() { return m_storage; }
703         PagePoolEntry* next() { return m_next; }
704
705     private:
706         PageMemory* m_storage;
707         PagePoolEntry* m_next;
708     };
709
710     HEAP_EXPORT Address outOfLineAllocate(size_t, const GCInfo*);
711     static size_t allocationSizeFromSize(size_t);
712     void addPageToHeap(const GCInfo*);
713     HEAP_EXPORT Address allocateLargeObject(size_t, const GCInfo*);
714     Address currentAllocationPoint() const { return m_currentAllocationPoint; }
715     size_t remainingAllocationSize() const { return m_remainingAllocationSize; }
716     bool ownsNonEmptyAllocationArea() const { return currentAllocationPoint() && remainingAllocationSize(); }
717     void setAllocationPoint(Address point, size_t size)
718     {
719         ASSERT(!point || heapPageFromAddress(point));
720         ASSERT(size <= HeapPage<Header>::payloadSize());
721         m_currentAllocationPoint = point;
722         m_remainingAllocationSize = size;
723     }
724     void ensureCurrentAllocation(size_t, const GCInfo*);
725     bool allocateFromFreeList(size_t);
726
727     void freeLargeObject(LargeHeapObject<Header>*, LargeHeapObject<Header>**);
728
729     void allocatePage(const GCInfo*);
730     PageMemory* takePageFromPool();
731     void clearPagePool();
732     void deletePages();
733
734     Address m_currentAllocationPoint;
735     size_t m_remainingAllocationSize;
736
737     HeapPage<Header>* m_firstPage;
738     LargeHeapObject<Header>* m_firstLargeHeapObject;
739
740     int m_biggestFreeListIndex;
741     ThreadState* m_threadState;
742
743     // All FreeListEntries in the nth list have size >= 2^n.
744     FreeListEntry* m_freeLists[blinkPageSizeLog2];
745
746     // List of pages that have been previously allocated, but are now
747     // unused.
748     PagePoolEntry* m_pagePool;
749 };
750
751 class HEAP_EXPORT Heap {
752 public:
753     enum GCType {
754         Normal,
755         ForcedForTesting
756     };
757
758     static void init();
759     static void shutdown();
760
761     static bool contains(Address);
762     static bool contains(void* pointer) { return contains(reinterpret_cast<Address>(pointer)); }
763     static bool contains(const void* pointer) { return contains(const_cast<void*>(pointer)); }
764
765     // Push a trace callback on the marking stack.
766     static void pushTraceCallback(void* containerObject, TraceCallback);
767
768     // Push a weak pointer callback on the weak callback stack.
769     static void pushWeakPointerCallback(void* containerObject, WeakPointerCallback);
770
771     // Pop the top of the marking stack and call the callback with the visitor
772     // and the object. Returns false when there is nothing more to do.
773     static bool popAndInvokeTraceCallback(Visitor*);
774
775     // Pop the top of the weak callback stack and call the callback with the visitor
776     // and the object. Returns false when there is nothing more to do.
777     static bool popAndInvokeWeakPointerCallback(Visitor*);
778
779     template<typename T> static Address allocate(size_t);
780     template<typename T> static Address reallocate(void* previous, size_t);
781
782     static void collectGarbage(ThreadState::StackState, GCType = Normal);
783
784     static void prepareForGC();
785
786     // Conservatively checks whether an address is a pointer in any of the thread
787     // heaps. If so marks the object pointed to as live.
788     static Address checkAndMarkPointer(Visitor*, Address);
789
790     // Collect heap stats for all threads attached to the Blink
791     // garbage collector. Should only be called during garbage
792     // collection where threads are known to be at safe points.
793     static void getStats(HeapStats*);
794
795     static bool isConsistentForGC();
796     static void makeConsistentForGC();
797
798     static CallbackStack* s_markingStack;
799     static CallbackStack* s_weakCallbackStack;
800 };
801
802 // The NoAllocationScope class is used in debug mode to catch unwanted
803 // allocations. E.g. allocations during GC.
804 template<ThreadAffinity Affinity>
805 class NoAllocationScope {
806 public:
807     NoAllocationScope() : m_active(true) { enter(); }
808
809     explicit NoAllocationScope(bool active) : m_active(active) { enter(); }
810
811     NoAllocationScope(const NoAllocationScope& other) : m_active(other.m_active) { enter(); }
812
813     NoAllocationScope& operator=(const NoAllocationScope& other)
814     {
815         release();
816         m_active = other.m_active;
817         enter();
818         return *this;
819     }
820
821     ~NoAllocationScope() { release(); }
822
823     void release()
824     {
825         if (m_active) {
826             ThreadStateFor<Affinity>::state()->leaveNoAllocationScope();
827             m_active = false;
828         }
829     }
830
831 private:
832     void enter() const
833     {
834         if (m_active)
835             ThreadStateFor<Affinity>::state()->enterNoAllocationScope();
836     }
837
838     bool m_active;
839 };
840
841 // Base class for objects allocated in the Blink garbage-collected
842 // heap.
843 //
844 // Defines a 'new' operator that allocates the memory in the
845 // heap. 'delete' should not be called on objects that inherit from
846 // GarbageCollected.
847 //
848 // Instances of GarbageCollected will *NOT* get finalized. Their
849 // destructor will not be called. Therefore, only classes that have
850 // trivial destructors with no semantic meaning (including all their
851 // subclasses) should inherit from GarbageCollected. If there are
852 // non-trival destructors in a given class or any of its subclasses,
853 // GarbageCollectedFinalized should be used which guarantees that the
854 // destructor is called on an instance when the garbage collector
855 // determines that it is no longer reachable.
856 template<typename T>
857 class GarbageCollected {
858     WTF_MAKE_NONCOPYABLE(GarbageCollected);
859
860     // For now direct allocation of arrays on the heap is not allowed.
861     void* operator new[](size_t size);
862     void operator delete[](void* p);
863 public:
864     void* operator new(size_t size)
865     {
866         return Heap::allocate<T>(size);
867     }
868
869     void operator delete(void* p)
870     {
871         ASSERT_NOT_REACHED();
872     }
873
874 protected:
875     GarbageCollected()
876     {
877         ASSERT(ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(reinterpret_cast<Address>(this)));
878     }
879     ~GarbageCollected() { }
880 };
881
882 // Base class for objects allocated in the Blink garbage-collected
883 // heap.
884 //
885 // Defines a 'new' operator that allocates the memory in the
886 // heap. 'delete' should not be called on objects that inherit from
887 // GarbageCollected.
888 //
889 // Instances of GarbageCollectedFinalized will have their destructor
890 // called when the garbage collector determines that the object is no
891 // longer reachable.
892 template<typename T>
893 class GarbageCollectedFinalized : public GarbageCollected<T> {
894     WTF_MAKE_NONCOPYABLE(GarbageCollectedFinalized);
895
896 protected:
897     // Finalize is called when the object is freed from the heap. By
898     // default finalization means calling the destructor on the
899     // object. Finalize can be overridden to support calling the
900     // destructor of a subclass. This is useful for objects without
901     // vtables that require explicit dispatching.
902     void finalize()
903     {
904         static_cast<T*>(this)->~T();
905     }
906
907     GarbageCollectedFinalized() { }
908     ~GarbageCollectedFinalized() { }
909
910     template<typename U> friend struct HasFinalizer;
911     template<typename U, bool> friend struct FinalizerTraitImpl;
912 };
913
914 // Base class for objects that are in the Blink garbage-collected heap
915 // and are still reference counted.
916 //
917 // This class should be used sparingly and only to gradually move
918 // objects from being reference counted to being managed by the blink
919 // garbage collector.
920 //
921 // While the current reference counting keeps one of these objects
922 // alive it will have a Persistent handle to itself allocated so we
923 // will not reclaim the memory. When the reference count reaches 0 the
924 // persistent handle will be deleted. When the garbage collector
925 // determines that there are no other references to the object it will
926 // be reclaimed and the destructor of the reclaimed object will be
927 // called at that time.
928 template<typename T>
929 class RefCountedGarbageCollected : public GarbageCollectedFinalized<T> {
930     WTF_MAKE_NONCOPYABLE(RefCountedGarbageCollected);
931
932 public:
933     RefCountedGarbageCollected()
934         : m_refCount(1)
935     {
936         m_keepAlive = new Persistent<T>(static_cast<T*>(this));
937     }
938
939     // Implement method to increase reference count for use with
940     // RefPtrs.
941     //
942     // In contrast to the normal WTF::RefCounted, the reference count
943     // can reach 0 and increase again. This happens in the following
944     // scenario:
945     //
946     // (1) The reference count becomes 0, but members, persistents, or
947     //     on-stack pointers keep references to the object.
948     //
949     // (2) The pointer is assigned to a RefPtr again and the reference
950     //     count becomes 1.
951     //
952     // In this case, we have to resurrect m_keepAlive.
953     void ref()
954     {
955         if (UNLIKELY(!m_refCount)) {
956             ASSERT(!m_keepAlive);
957             ASSERT(ThreadStateFor<ThreadingTrait<T>::Affinity>::state()->contains(reinterpret_cast<Address>(this)));
958             m_keepAlive = new Persistent<T>(static_cast<T*>(this));
959         }
960         ++m_refCount;
961     }
962
963     // Implement method to decrease reference count for use with
964     // RefPtrs.
965     //
966     // In contrast to the normal WTF::RefCounted implementation, the
967     // object itself is not deleted when the reference count reaches
968     // 0. Instead, the keep-alive persistent handle is deallocated so
969     // that the object can be reclaimed when the garbage collector
970     // determines that there are no other references to the object.
971     void deref()
972     {
973         ASSERT(m_refCount > 0);
974         if (!--m_refCount) {
975             delete m_keepAlive;
976             m_keepAlive = 0;
977         }
978     }
979
980     bool hasOneRef()
981     {
982         return m_refCount == 1;
983     }
984
985 protected:
986     ~RefCountedGarbageCollected() { }
987
988 private:
989     int m_refCount;
990     Persistent<T>* m_keepAlive;
991 };
992
993 template<typename T>
994 T* adoptRefCountedGarbageCollected(T* ptr)
995 {
996     ASSERT(ptr->hasOneRef());
997     ptr->deref();
998     WTF::adopted(ptr);
999     return ptr;
1000 }
1001
1002 #if COMPILER_SUPPORTS(CXX_DELETED_FUNCTIONS)
1003 #define DISALLOW_ALLOCATION() \
1004     private: \
1005         void* operator new(size_t) = delete;
1006 #else
1007 #define DISALLOW_ALLOCATION() \
1008     private: \
1009         void* operator new(size_t);
1010 #endif
1011
1012 #define ALLOW_ONLY_INLINE_ALLOCATION()                                              \
1013     public:                                                                         \
1014         void* operator new(size_t, NotNullTag, void* location) { return location; } \
1015         void* operator new(size_t, void* location) { return location; }             \
1016     DISALLOW_ALLOCATION()
1017
1018 NO_SANITIZE_ADDRESS
1019 void HeapObjectHeader::checkHeader() const
1020 {
1021     ASSERT(m_magic == magic);
1022 }
1023
1024 Address HeapObjectHeader::payload()
1025 {
1026     return reinterpret_cast<Address>(this) + objectHeaderSize;
1027 }
1028
1029 size_t HeapObjectHeader::payloadSize()
1030 {
1031     return size() - objectHeaderSize;
1032 }
1033
1034 Address HeapObjectHeader::payloadEnd()
1035 {
1036     return reinterpret_cast<Address>(this) + size();
1037 }
1038
1039 NO_SANITIZE_ADDRESS
1040 void HeapObjectHeader::mark()
1041 {
1042     checkHeader();
1043     m_size |= markBitMask;
1044 }
1045
1046 Address FinalizedHeapObjectHeader::payload()
1047 {
1048     return reinterpret_cast<Address>(this) + finalizedHeaderSize;
1049 }
1050
1051 size_t FinalizedHeapObjectHeader::payloadSize()
1052 {
1053     return size() - finalizedHeaderSize;
1054 }
1055
1056 template<typename Header>
1057 size_t ThreadHeap<Header>::allocationSizeFromSize(size_t size)
1058 {
1059     // Check the size before computing the actual allocation size. The
1060     // allocation size calculation can overflow for large sizes and
1061     // the check therefore has to happen before any calculation on the
1062     // size.
1063     RELEASE_ASSERT(size < maxHeapObjectSize);
1064
1065     // Add space for header.
1066     size_t allocationSize = size + sizeof(Header);
1067     // Align size with allocation granularity.
1068     allocationSize = (allocationSize + allocationMask) & ~allocationMask;
1069     return allocationSize;
1070 }
1071
1072 template<typename Header>
1073 Address ThreadHeap<Header>::allocate(size_t size, const GCInfo* gcInfo)
1074 {
1075     size_t allocationSize = allocationSizeFromSize(size);
1076     bool isLargeObject = allocationSize > blinkPageSize / 2;
1077     if (isLargeObject)
1078         return allocateLargeObject(allocationSize, gcInfo);
1079     if (m_remainingAllocationSize < allocationSize)
1080         return outOfLineAllocate(size, gcInfo);
1081     Address headerAddress = m_currentAllocationPoint;
1082     m_currentAllocationPoint += allocationSize;
1083     m_remainingAllocationSize -= allocationSize;
1084     Header* header = new (NotNull, headerAddress) Header(allocationSize, gcInfo);
1085     size_t payloadSize = allocationSize - sizeof(Header);
1086     stats().increaseObjectSpace(payloadSize);
1087     Address result = headerAddress + sizeof(*header);
1088     ASSERT(!(reinterpret_cast<uintptr_t>(result) & allocationMask));
1089     // Unpoison the memory used for the object (payload).
1090     ASAN_UNPOISON_MEMORY_REGION(result, payloadSize);
1091     memset(result, 0, payloadSize);
1092     ASSERT(heapPageFromAddress(headerAddress + allocationSize - 1));
1093     return result;
1094 }
1095
1096 // FIXME: Allocate objects that do not need finalization separately
1097 // and use separate sweeping to not have to check for finalizers.
1098 template<typename T>
1099 Address Heap::allocate(size_t size)
1100 {
1101     ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
1102     ASSERT(state->isAllocationAllowed());
1103     BaseHeap* heap = state->heap(HeapTrait<T>::index);
1104     Address addr =
1105         static_cast<typename HeapTrait<T>::HeapType*>(heap)->allocate(size, GCInfoTrait<T>::get());
1106     return addr;
1107 }
1108
1109 // FIXME: Allocate objects that do not need finalization separately
1110 // and use separate sweeping to not have to check for finalizers.
1111 template<typename T>
1112 Address Heap::reallocate(void* previous, size_t size)
1113 {
1114     if (!size) {
1115         // If the new size is 0 this is equivalent to either
1116         // free(previous) or malloc(0). In both cases we do
1117         // nothing and return 0.
1118         return 0;
1119     }
1120     ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state();
1121     ASSERT(state->isAllocationAllowed());
1122     // FIXME: Currently only supports raw allocation on the
1123     // GeneralHeap. Hence we assume the header is a
1124     // FinalizedHeapObjectHeader.
1125     ASSERT(HeapTrait<T>::index == GeneralHeap);
1126     BaseHeap* heap = state->heap(HeapTrait<T>::index);
1127     Address address = static_cast<typename HeapTrait<T>::HeapType*>(heap)->allocate(size, GCInfoTrait<T>::get());
1128     if (!previous) {
1129         // This is equivalent to malloc(size).
1130         return address;
1131     }
1132     FinalizedHeapObjectHeader* previousHeader = FinalizedHeapObjectHeader::fromPayload(previous);
1133     ASSERT(!previousHeader->hasFinalizer());
1134     ASSERT(previousHeader->gcInfo() == GCInfoTrait<T>::get());
1135     size_t copySize = previousHeader->payloadSize();
1136     if (copySize > size)
1137         copySize = size;
1138     memcpy(address, previous, copySize);
1139     return address;
1140 }
1141
1142 class HeapAllocatorQuantizer {
1143 public:
1144     template<typename T>
1145     static size_t quantizedSize(size_t count)
1146     {
1147         RELEASE_ASSERT(count <= kMaxUnquantizedAllocation / sizeof(T));
1148         return HeapTrait<T>::HeapType::roundedAllocationSize(count * sizeof(T));
1149     }
1150     static const size_t kMaxUnquantizedAllocation = maxHeapObjectSize;
1151 };
1152
1153 class HeapAllocator {
1154 public:
1155     typedef HeapAllocatorQuantizer Quantizer;
1156     typedef WebCore::Visitor Visitor;
1157     static const bool isGarbageCollected = true;
1158
1159     template <typename Return, typename Metadata>
1160     static Return backingMalloc(size_t size)
1161     {
1162         return malloc<Return, Metadata>(size);
1163     }
1164     template <typename Return, typename Metadata>
1165     static Return zeroedBackingMalloc(size_t size)
1166     {
1167         return malloc<Return, Metadata>(size);
1168     }
1169     template <typename Return, typename Metadata>
1170     static Return malloc(size_t size)
1171     {
1172         return reinterpret_cast<Return>(Heap::allocate<Metadata>(size));
1173     }
1174     static void backingFree(void* address) { }
1175     static void free(void* address) { }
1176     template<typename T>
1177     static void* newArray(size_t bytes)
1178     {
1179         ASSERT_NOT_REACHED();
1180         return 0;
1181     }
1182
1183     static void deleteArray(void* ptr)
1184     {
1185         ASSERT_NOT_REACHED();
1186     }
1187
1188     static void markUsingGCInfo(Visitor* visitor, const void* buffer)
1189     {
1190         visitor->mark(buffer, FinalizedHeapObjectHeader::fromPayload(buffer)->traceCallback());
1191     }
1192
1193     static void markNoTracing(Visitor* visitor, const void* t)
1194     {
1195         visitor->mark(t);
1196     }
1197
1198     template<typename T, typename Traits>
1199     static void trace(Visitor* visitor, T& t)
1200     {
1201         CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, false, T, Traits>::mark(visitor, t);
1202     }
1203
1204     template<typename T>
1205     static bool hasDeadMember(Visitor*, const T&)
1206     {
1207         return false;
1208     }
1209
1210     template<typename T>
1211     static bool hasDeadMember(Visitor* visitor, const Member<T>& t)
1212     {
1213         ASSERT(visitor->isAlive(t));
1214         return false;
1215     }
1216
1217     template<typename T>
1218     static bool hasDeadMember(Visitor* visitor, const WeakMember<T>& t)
1219     {
1220         return !visitor->isAlive(t);
1221     }
1222
1223     template<typename T, typename U>
1224     static bool hasDeadMember(Visitor* visitor, const WTF::KeyValuePair<T, U>& t)
1225     {
1226         return hasDeadMember(visitor, t.key) || hasDeadMember(visitor, t.value);
1227     }
1228
1229     static void registerWeakMembers(Visitor* visitor, const void* object, WeakPointerCallback callback)
1230     {
1231         visitor->registerWeakMembers(object, callback);
1232     }
1233
1234     template<typename T>
1235     struct ResultType {
1236         typedef T* Type;
1237     };
1238
1239     // The WTF classes use Allocator::VectorBackingHelper in order to find a
1240     // class to template their backing allocation operation on. For off-heap
1241     // allocations the VectorBackingHelper is a dummy class, since the class is
1242     // not used during allocation of backing. For on-heap allocations this
1243     // typedef ensures that the allocation is done with the correct templated
1244     // instantiation of the allocation function. This ensures the correct GC
1245     // map is written when backing allocations take place.
1246     template<typename T, typename Traits>
1247     struct VectorBackingHelper {
1248         typedef HeapVectorBacking<T, Traits> Type;
1249     };
1250
1251     // Like the VectorBackingHelper, but this type is used for HashSet and
1252     // HashMap, both of which are implemented using HashTable.
1253     template<typename T, typename U, typename V, typename W, typename X>
1254     struct HashTableBackingHelper {
1255         typedef HeapHashTableBacking<T, U, V, W, X> Type;
1256     };
1257
1258     template<typename T>
1259     struct OtherType {
1260         typedef T* Type;
1261     };
1262
1263     template<typename T>
1264     static T& getOther(T* other)
1265     {
1266         return *other;
1267     }
1268
1269 private:
1270     template<typename T, size_t u, typename V> friend class WTF::Vector;
1271     template<typename T, typename U, typename V, typename W> friend class WTF::HashSet;
1272     template<typename T, typename U, typename V, typename W, typename X, typename Y> friend class WTF::HashMap;
1273 };
1274
1275 // FIXME: These should just be template aliases:
1276 //
1277 // template<typename T, size_t inlineCapacity = 0>
1278 // using HeapVector = Vector<T, inlineCapacity, HeapAllocator>;
1279 //
1280 // as soon as all the compilers we care about support that.
1281 // MSVC supports it only in MSVC 2013.
1282 template<
1283     typename KeyArg,
1284     typename MappedArg,
1285     typename HashArg = typename DefaultHash<KeyArg>::Hash,
1286     typename KeyTraitsArg = HashTraits<KeyArg>,
1287     typename MappedTraitsArg = HashTraits<MappedArg> >
1288 class HeapHashMap : public HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, HeapAllocator> { };
1289
1290 template<
1291     typename ValueArg,
1292     typename HashArg = typename DefaultHash<ValueArg>::Hash,
1293     typename TraitsArg = HashTraits<ValueArg> >
1294 class HeapHashSet : public HashSet<ValueArg, HashArg, TraitsArg, HeapAllocator> { };
1295
1296 template<typename T, size_t inlineCapacity = 0>
1297 class HeapVector : public Vector<T, inlineCapacity, HeapAllocator> {
1298 public:
1299     HeapVector() { }
1300
1301     explicit HeapVector(size_t size) : Vector<T, inlineCapacity, HeapAllocator>(size)
1302     {
1303     }
1304
1305     template<size_t otherCapacity>
1306     HeapVector(const HeapVector<T, otherCapacity>& other)
1307         : Vector<T, inlineCapacity, HeapAllocator>(other)
1308     {
1309     }
1310
1311     template<typename U>
1312     void append(const U& other)
1313     {
1314         Vector<T, inlineCapacity, HeapAllocator>::append(other);
1315     }
1316
1317     template<typename U, size_t otherCapacity>
1318     void append(const HeapVector<U, otherCapacity>& other)
1319     {
1320         const Vector<U, otherCapacity, HeapAllocator>& otherVector = other;
1321         Vector<T, inlineCapacity, HeapAllocator>::append(otherVector);
1322     }
1323 };
1324
1325 template<typename T>
1326 struct ThreadingTrait<Member<T> > {
1327     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1328 };
1329
1330 template<typename T>
1331 struct ThreadingTrait<WeakMember<T> > {
1332     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1333 };
1334
1335 template<typename Key, typename Value, typename T, typename U, typename V>
1336 struct ThreadingTrait<HashMap<Key, Value, HeapAllocator, T, U, V> > {
1337     static const ThreadAffinity Affinity =
1338         (ThreadingTrait<Key>::Affinity == MainThreadOnly)
1339         && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
1340 };
1341
1342 template<typename T, typename U, typename V>
1343 struct ThreadingTrait<HashSet<T, HeapAllocator, U, V> > {
1344     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1345 };
1346
1347
1348 template<typename T, size_t inlineCapacity>
1349 struct ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator> > {
1350     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1351 };
1352
1353 template<typename T, typename Traits>
1354 struct ThreadingTrait<HeapVectorBacking<T, Traits> > {
1355     static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
1356 };
1357
1358 template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
1359 struct ThreadingTrait<HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > {
1360     static const ThreadAffinity Affinity =
1361         (ThreadingTrait<Key>::Affinity == MainThreadOnly)
1362         && (ThreadingTrait<Value>::Affinity == MainThreadOnly) ? MainThreadOnly : AnyThread;
1363 };
1364
1365 template<typename Key, typename Value>
1366 struct ThreadingTrait<HeapHashMap<Key, Value> > : public ThreadingTrait<HashMap<Key, Value, HeapAllocator> > { };
1367 template<typename Value>
1368 struct ThreadingTrait<HeapHashSet<Value> > : public ThreadingTrait<HashSet<Value, HeapAllocator> > { };
1369 template<typename T, size_t inlineCapacity>
1370 struct ThreadingTrait<HeapVector<T, inlineCapacity> > : public ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator> > { };
1371
1372 // The standard implementation of GCInfoTrait<T>::get() just returns a static
1373 // from the class T, but we can't do that for HashMap, HashSet and Vector
1374 // because they are in WTF and know nothing of GCInfos. Instead we have a
1375 // specialization of GCInfoTrait for these three classes here.
1376
1377 template<typename Key, typename Value, typename T, typename U, typename V>
1378 struct GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > {
1379     static const GCInfo* get() { return &info; }
1380     static const GCInfo info;
1381 };
1382
1383 template<typename Key, typename Value, typename T, typename U, typename V>
1384 const GCInfo GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> >::info = {
1385     "HashMap",
1386     TraceTrait<HashMap<Key, Value, T, U, V, HeapAllocator> >::trace,
1387     0,
1388     false, // HashMap needs no finalizer.
1389 };
1390
1391 template<typename T, typename U, typename V>
1392 struct GCInfoTrait<HashSet<T, U, V, HeapAllocator> > {
1393     static const GCInfo* get() { return &info; }
1394     static const GCInfo info;
1395 };
1396
1397 template<typename T, typename U, typename V>
1398 const GCInfo GCInfoTrait<HashSet<T, U, V, HeapAllocator> >::info = {
1399     "HashSet",
1400     TraceTrait<HashSet<T, U, V, HeapAllocator> >::trace,
1401     0,
1402     false, // HashSet needs no finalizer.
1403 };
1404
1405 template<typename T>
1406 struct GCInfoTrait<Vector<T, 0, HeapAllocator> > {
1407     static const GCInfo* get() { return &info; }
1408     static const GCInfo info;
1409 };
1410
1411 template<typename T>
1412 const GCInfo GCInfoTrait<Vector<T, 0, HeapAllocator> >::info = {
1413     "Vector",
1414     TraceTrait<Vector<T, 0, HeapAllocator> >::trace,
1415     0,
1416     false, // Vector needs no finalizer if it has no inline capacity.
1417 };
1418
1419 template<typename T, size_t inlineCapacity>
1420 struct GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> > {
1421     static const GCInfo* get() { return &info; }
1422     static const GCInfo info;
1423 };
1424
1425 template<typename T, size_t inlineCapacity>
1426 struct FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator> > : public FinalizerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>, true> { };
1427
1428 template<typename T, size_t inlineCapacity>
1429 const GCInfo GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> >::info = {
1430     "Vector",
1431     TraceTrait<Vector<T, inlineCapacity, HeapAllocator> >::trace,
1432     FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator> >::finalize,
1433     // Finalizer is needed to destruct things stored in the inline capacity.
1434     inlineCapacity && VectorTraits<T>::needsDestruction,
1435 };
1436
1437 template<typename T, typename Traits>
1438 struct GCInfoTrait<HeapVectorBacking<T, Traits> > {
1439     static const GCInfo* get() { return &info; }
1440     static const GCInfo info;
1441 };
1442
1443 template<typename T, typename Traits>
1444 const GCInfo GCInfoTrait<HeapVectorBacking<T, Traits> >::info = {
1445     "VectorBacking",
1446     TraceTrait<HeapVectorBacking<T, Traits> >::trace,
1447     FinalizerTrait<HeapVectorBacking<T, Traits> >::finalize,
1448     Traits::needsDestruction,
1449 };
1450
1451 template<typename T, typename U, typename V, typename W, typename X>
1452 struct GCInfoTrait<HeapHashTableBacking<T, U, V, W, X> > {
1453     static const GCInfo* get() { return &info; }
1454     static const GCInfo info;
1455 };
1456
1457 template<typename T, typename U, typename V, typename Traits, typename W>
1458 const GCInfo GCInfoTrait<HeapHashTableBacking<T, U, V, Traits, W> >::info = {
1459     "HashTableBacking",
1460     TraceTrait<HeapHashTableBacking<T, U, V, Traits, W> >::trace,
1461     FinalizerTrait<HeapHashTableBacking<T, U, V, Traits, W> >::finalize,
1462     Traits::needsDestruction,
1463 };
1464
1465 template<bool markWeakMembersStrongly, typename T, typename Traits>
1466 struct BaseVisitVectorBackingTrait {
1467     static void mark(WebCore::Visitor* visitor, void* self)
1468     {
1469         // The allocator can oversize the allocation a little, according to
1470         // the allocation granularity. The extra size is included in the
1471         // payloadSize call below, since there is nowhere to store the
1472         // originally allocated memory. This assert ensures that visiting the
1473         // last bit of memory can't cause trouble.
1474         COMPILE_ASSERT(!Traits::needsTracing || sizeof(T) > allocationGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCauseSpuriousVisits);
1475
1476         T* array = reinterpret_cast<T*>(self);
1477         WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjectHeader::fromPayload(self);
1478         // Use the payload size as recorded by the heap to determine how many
1479         // elements to mark.
1480         size_t length = header->payloadSize() / sizeof(T);
1481         for (size_t i = 0; i < length; i++)
1482             CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, markWeakMembersStrongly, T, Traits>::mark(visitor, array[i]);
1483     }
1484 };
1485
1486 template<bool markWeakMembersStrongly, typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
1487 struct BaseVisitHashTableBackingTrait {
1488     static void mark(WebCore::Visitor* visitor, void* self)
1489     {
1490         Value* array = reinterpret_cast<Value*>(self);
1491         WebCore::FinalizedHeapObjectHeader* header = WebCore::FinalizedHeapObjectHeader::fromPayload(self);
1492         size_t length = header->payloadSize() / sizeof(Value);
1493         for (size_t i = 0; i < length; i++) {
1494             if (!WTF::HashTableHelper<Value, Extractor, KeyTraits>::isEmptyOrDeletedBucket(array[i]))
1495                 CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, markWeakMembersStrongly, Value, Traits>::mark(visitor, array[i]);
1496         }
1497     }
1498 };
1499
1500 template<bool markWeakMembersStrongly, typename Key, typename Value, typename Traits>
1501 struct BaseVisitKeyValuePairTrait {
1502     static void mark(WebCore::Visitor* visitor, WTF::KeyValuePair<Key, Value>& self)
1503     {
1504         ASSERT(Traits::needsTracing || (Traits::isWeak && markWeakMembersStrongly));
1505         CollectionBackingTraceTrait<Traits::KeyTraits::needsTracing, Traits::KeyTraits::isWeak, markWeakMembersStrongly, Key, typename Traits::KeyTraits>::mark(visitor, self.key);
1506         CollectionBackingTraceTrait<Traits::ValueTraits::needsTracing, Traits::ValueTraits::isWeak, markWeakMembersStrongly, Value, typename Traits::ValueTraits>::mark(visitor, self.value);
1507     }
1508 };
1509
1510 // FFX - Things that don't need marking and have no weak pointers.
1511 template<bool markWeakMembersStrongly, typename T, typename U>
1512 struct CollectionBackingTraceTrait<false, false, markWeakMembersStrongly, T, U> {
1513     static void mark(Visitor*, const T&) { }
1514     static void mark(Visitor*, const void*) { }
1515 };
1516
1517 // FTF - Things that don't need marking. They have weak pointers, but we are
1518 // not marking weak pointers in this object in this GC.
1519 template<typename T, typename U>
1520 struct CollectionBackingTraceTrait<false, true, false, T, U> {
1521     static void mark(Visitor*, const T&) { }
1522     static void mark(Visitor*, const void*) { }
1523 };
1524
1525 // For each type that we understand we have the FTT case and the TXX case. The
1526 // FTT case is where we would not normally need to mark it, but it has weak
1527 // pointers, and we are marking them as strong. The TXX case is the regular
1528 // case for things that need marking.
1529
1530 // FTT (vector)
1531 template<typename T, typename Traits>
1532 struct CollectionBackingTraceTrait<false, true, true, HeapVectorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<true, T, Traits> {
1533 };
1534
1535 // TXX (vector)
1536 template<bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits>
1537 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapVectorBacking<T, Traits>, void> : public BaseVisitVectorBackingTrait<markWeakMembersStrongly, T, Traits> {
1538 };
1539
1540 // FTT (hash table)
1541 template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
1542 struct CollectionBackingTraceTrait<false, true, true, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVisitHashTableBackingTrait<true, Key, Value, Extractor, Traits, KeyTraits> {
1543 };
1544
1545 // TXX (hash table)
1546 template<bool isWeak, bool markWeakMembersStrongly, typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
1547 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void> : public BaseVisitHashTableBackingTrait<markWeakMembersStrongly, Key, Value, Extractor, Traits, KeyTraits> {
1548 };
1549
1550 // FTT (key value pair)
1551 template<typename Key, typename Value, typename Traits>
1552 struct CollectionBackingTraceTrait<false, true, true, WTF::KeyValuePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<true, Key, Value, Traits> {
1553 };
1554
1555 // TXX (key value pair)
1556 template<bool isWeak, bool markWeakMembersStrongly, typename Key, typename Value, typename Traits>
1557 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, WTF::KeyValuePair<Key, Value>, Traits> : public BaseVisitKeyValuePairTrait<markWeakMembersStrongly, Key, Value, Traits> {
1558 };
1559
1560
1561 // TFX (member)
1562 template<bool markWeakMembersStrongly, typename T, typename Traits>
1563 struct CollectionBackingTraceTrait<true, false, markWeakMembersStrongly, Member<T>, Traits> {
1564     static void mark(WebCore::Visitor* visitor, Member<T> self)
1565     {
1566         visitor->mark(self.get());
1567     }
1568 };
1569
1570 // FTT (weak member)
1571 template<typename T, typename Traits>
1572 struct CollectionBackingTraceTrait<false, true, true, WeakMember<T>, Traits> {
1573     static void mark(WebCore::Visitor* visitor, WeakMember<T> self)
1574     {
1575         // This can mark weak members as if they were strong. The reason we
1576         // need this is that we don't do weak processing unless we reach the
1577         // backing only through the hash table. Reaching it in any other way
1578         // makes it impossible to update the size and deleted slot count of the
1579         // table, and exposes us to weak processing during iteration issues.
1580         visitor->mark(self.get());
1581     }
1582 };
1583
1584 // Catch-all for things that have a way to trace. For things that contain weak
1585 // pointers they will generally be visited weakly even if
1586 // markWeakMembersStrongly is true. This is what you want.
1587 template<bool isWeak, bool markWeakMembersStrongly, typename T, typename Traits>
1588 struct CollectionBackingTraceTrait<true, isWeak, markWeakMembersStrongly, T, Traits> {
1589     static void mark(WebCore::Visitor* visitor, T& t)
1590     {
1591         TraceTrait<T>::trace(visitor, reinterpret_cast<void*>(&t));
1592     }
1593 };
1594
1595 template<typename T, typename Traits>
1596 struct TraceTrait<HeapVectorBacking<T, Traits> > {
1597     typedef HeapVectorBacking<T, Traits> Backing;
1598     static void trace(WebCore::Visitor* visitor, void* self)
1599     {
1600         COMPILE_ASSERT(!Traits::isWeak, WeDontSupportWeaknessInHeapVectors);
1601         if (Traits::needsTracing)
1602             CollectionBackingTraceTrait<Traits::needsTracing, false, false, HeapVectorBacking<T, Traits>, void>::mark(visitor, self);
1603     }
1604     static void mark(Visitor* visitor, const Backing* backing)
1605     {
1606         visitor->mark(backing, &trace);
1607     }
1608     static void checkTypeMarker(Visitor* visitor, const Backing* backing)
1609     {
1610 #ifndef NDEBUG
1611         visitor->checkTypeMarker(const_cast<Backing*>(backing), getTypeMarker<Backing>());
1612 #endif
1613     }
1614 };
1615
1616 // The trace trait for the heap hashtable backing is used when we find a
1617 // direct pointer to the backing from the conservative stack scanner. This
1618 // normally indicates that there is an ongoing iteration over the table, and so
1619 // we disable weak processing of table entries. When the backing is found
1620 // through the owning hash table we mark differently, in order to do weak
1621 // processing.
1622 template<typename Key, typename Value, typename Extractor, typename Traits, typename KeyTraits>
1623 struct TraceTrait<HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> > {
1624     typedef HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits> Backing;
1625     static const bool needsTracing = (Traits::needsTracing || Traits::isWeak);
1626     static void trace(WebCore::Visitor* visitor, void* self)
1627     {
1628         if (needsTracing)
1629             CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak, true, HeapHashTableBacking<Key, Value, Extractor, Traits, KeyTraits>, void>::mark(visitor, self);
1630     }
1631     static void mark(Visitor* visitor, const Backing* backing)
1632     {
1633         if (needsTracing)
1634             visitor->mark(backing, &trace);
1635         else
1636             visitor->mark(backing, 0);
1637     }
1638     static void checkTypeMarker(Visitor* visitor, const Backing* backing)
1639     {
1640 #ifndef NDEBUG
1641         visitor->checkTypeMarker(const_cast<Backing*>(backing), getTypeMarker<Backing>());
1642 #endif
1643     }
1644 };
1645
1646 template<typename T, typename U, typename V, typename W, typename X>
1647 struct GCInfoTrait<HeapHashMap<T, U, V, W, X> > : public GCInfoTrait<HashMap<T, U, V, W, X, HeapAllocator> > { };
1648 template<typename T, typename U, typename V>
1649 struct GCInfoTrait<HeapHashSet<T, U, V> > : public GCInfoTrait<HashSet<T, U, V, HeapAllocator> > { };
1650 template<typename T, size_t inlineCapacity>
1651 struct GCInfoTrait<HeapVector<T, inlineCapacity> > : public GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> > { };
1652
1653 template<typename T>
1654 struct IfWeakMember;
1655
1656 template<typename T>
1657 struct IfWeakMember {
1658     template<typename U>
1659     static bool isDead(Visitor*, const U&) { return false; }
1660 };
1661
1662 template<typename T>
1663 struct IfWeakMember<WeakMember<T> > {
1664     static bool isDead(Visitor* visitor, const WeakMember<T>& t) { return !visitor->isAlive(t.get()); }
1665 };
1666
1667 #if COMPILER(CLANG)
1668 // Clang does not export the symbols that we have explicitly asked it
1669 // to export. This forces it to export all the methods from ThreadHeap.
1670 template<> void ThreadHeap<FinalizedHeapObjectHeader>::addPageToHeap(const GCInfo*);
1671 template<> void ThreadHeap<HeapObjectHeader>::addPageToHeap(const GCInfo*);
1672 extern template class HEAP_EXPORT ThreadHeap<FinalizedHeapObjectHeader>;
1673 extern template class HEAP_EXPORT ThreadHeap<HeapObjectHeader>;
1674 #endif
1675
1676 }
1677
1678 #endif // Heap_h