10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2009, 2011 Apple Inc. All rights reserved.
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * are met:
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 1. Redistributions of source code must retain the above copyright
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer.
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    documentation and/or other materials provided with the distribution.
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#ifndef MarkStack_h
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define MarkStack_h
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "JSValue.h"
302bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "Register.h"
312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "WriteBarrier.h"
322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <wtf/HashSet.h>
332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/Vector.h>
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Noncopyable.h>
35f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <wtf/OSAllocator.h>
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace JSC {
38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
392bde8e466a4451c7319e3a072d118917957d6554Steve Block    class ConservativeRoots;
40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    class JSGlobalData;
410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    class Register;
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    enum MarkSetProperties { MayContainNullValues, NoNullValues };
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
45ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    class MarkStack {
46ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        WTF_MAKE_NONCOPYABLE(MarkStack);
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    public:
48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        MarkStack(void* jsArrayVPtr)
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            : m_jsArrayVPtr(jsArrayVPtr)
50f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if !ASSERT_DISABLED
51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            , m_isCheckingForDefaultMarkViolation(false)
52f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            , m_isDraining(false)
53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
562bde8e466a4451c7319e3a072d118917957d6554Steve Block
572bde8e466a4451c7319e3a072d118917957d6554Steve Block        ~MarkStack()
582bde8e466a4451c7319e3a072d118917957d6554Steve Block        {
592bde8e466a4451c7319e3a072d118917957d6554Steve Block            ASSERT(m_markSets.isEmpty());
602bde8e466a4451c7319e3a072d118917957d6554Steve Block            ASSERT(m_values.isEmpty());
612bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
622bde8e466a4451c7319e3a072d118917957d6554Steve Block
632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        void deprecatedAppend(JSCell**);
642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        template <typename T> void append(WriteBarrierBase<T>*);
650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        void appendValues(WriteBarrierBase<Unknown>* barriers, size_t count, MarkSetProperties properties = NoNullValues)
670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            JSValue* values = barriers->slot();
690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (count)
700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_markSets.append(MarkSet(values, values + count, properties));
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
722bde8e466a4451c7319e3a072d118917957d6554Steve Block
732bde8e466a4451c7319e3a072d118917957d6554Steve Block        void append(ConservativeRoots&);
740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        bool addOpaqueRoot(void* root) { return m_opaqueRoots.add(root).second; }
762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        bool containsOpaqueRoot(void* root) { return m_opaqueRoots.contains(root); }
772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        int opaqueRootCount() { return m_opaqueRoots.size(); }
782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
792bde8e466a4451c7319e3a072d118917957d6554Steve Block        void drain();
802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        void reset();
810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    private:
832bde8e466a4451c7319e3a072d118917957d6554Steve Block        friend class HeapRootMarker; // Allowed to mark a JSValue* or JSCell** directly.
842bde8e466a4451c7319e3a072d118917957d6554Steve Block        void append(JSValue*);
852bde8e466a4451c7319e3a072d118917957d6554Steve Block        void append(JSValue*, size_t count);
862bde8e466a4451c7319e3a072d118917957d6554Steve Block        void append(JSCell**);
872bde8e466a4451c7319e3a072d118917957d6554Steve Block
882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        void internalAppend(JSCell*);
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        void internalAppend(JSValue);
90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        void markChildren(JSCell*);
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        struct MarkSet {
930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MarkSet(JSValue* values, JSValue* end, MarkSetProperties properties)
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : m_values(values)
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                , m_end(end)
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                , m_properties(properties)
970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ASSERT(values);
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JSValue* m_values;
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JSValue* m_end;
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MarkSetProperties m_properties;
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
105f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        static void* allocateStack(size_t size) { return OSAllocator::reserveAndCommit(size); }
106f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        static void releaseStack(void* addr, size_t size) { OSAllocator::decommitAndRelease(addr, size); }
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void initializePagesize();
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static size_t pageSize()
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (!s_pageSize)
1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                initializePagesize();
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return s_pageSize;
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        template <typename T> struct MarkStackArray {
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MarkStackArray()
1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : m_top(0)
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                , m_allocated(MarkStack::pageSize())
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                , m_capacity(m_allocated / sizeof(T))
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_data = reinterpret_cast<T*>(allocateStack(m_allocated));
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ~MarkStackArray()
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                releaseStack(m_data, m_allocated);
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            void expand()
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                size_t oldAllocation = m_allocated;
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_allocated *= 2;
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_capacity = m_allocated / sizeof(T);
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                void* newData = allocateStack(m_allocated);
1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                memcpy(newData, m_data, oldAllocation);
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                releaseStack(m_data, oldAllocation);
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_data = reinterpret_cast<T*>(newData);
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            inline void append(const T& v)
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (m_top == m_capacity)
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    expand();
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_data[m_top++] = v;
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            inline T removeLast()
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                ASSERT(m_top);
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                return m_data[--m_top];
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            inline T& last()
155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            {
156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ASSERT(m_top);
157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                return m_data[m_top - 1];
158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            inline bool isEmpty()
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                return m_top == 0;
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            inline size_t size() { return m_top; }
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            inline void shrinkAllocation(size_t size)
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                ASSERT(size <= m_allocated);
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                ASSERT(0 == (size % MarkStack::pageSize()));
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                if (size == m_allocated)
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    return;
173d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS) || OS(SYMBIAN) || PLATFORM(BREWMP)
174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // We cannot release a part of a region with VirtualFree.  To get around this,
175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // we'll release the entire region and reallocate the size that we want.
176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                releaseStack(m_data, m_allocated);
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                m_data = reinterpret_cast<T*>(allocateStack(size));
178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#else
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                releaseStack(reinterpret_cast<char*>(m_data) + size, m_allocated - size);
180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_allocated = size;
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                m_capacity = m_allocated / sizeof(T);
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        private:
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            size_t m_top;
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            size_t m_allocated;
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            size_t m_capacity;
1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            T* m_data;
1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        void* m_jsArrayVPtr;
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        MarkStackArray<MarkSet> m_markSets;
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        MarkStackArray<JSCell*> m_values;
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static size_t s_pageSize;
1962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector.
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if !ASSERT_DISABLED
199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    public:
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        bool m_isCheckingForDefaultMarkViolation;
201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        bool m_isDraining;
202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif
2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    };
2042bde8e466a4451c7319e3a072d118917957d6554Steve Block
2052bde8e466a4451c7319e3a072d118917957d6554Steve Block    inline void MarkStack::append(JSValue* slot, size_t count)
2062bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2072bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!count)
2082bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
2092bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_markSets.append(MarkSet(slot, slot + count, NoNullValues));
2102bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
211ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    template <typename T> inline void MarkStack::append(WriteBarrierBase<T>* slot)
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block        internalAppend(*slot->slot());
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block
2172bde8e466a4451c7319e3a072d118917957d6554Steve Block    ALWAYS_INLINE void MarkStack::deprecatedAppend(JSCell** value)
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(value);
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block        internalAppend(*value);
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block
2232bde8e466a4451c7319e3a072d118917957d6554Steve Block    ALWAYS_INLINE void MarkStack::append(JSValue* value)
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(value);
2262bde8e466a4451c7319e3a072d118917957d6554Steve Block        internalAppend(*value);
2272bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2282bde8e466a4451c7319e3a072d118917957d6554Steve Block
2292bde8e466a4451c7319e3a072d118917957d6554Steve Block    ALWAYS_INLINE void MarkStack::append(JSCell** value)
2302bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(value);
2322bde8e466a4451c7319e3a072d118917957d6554Steve Block        internalAppend(*value);
2332bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block
2352bde8e466a4451c7319e3a072d118917957d6554Steve Block    ALWAYS_INLINE void MarkStack::internalAppend(JSValue value)
2362bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2372bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(value);
2382bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (value.isCell())
2392bde8e466a4451c7319e3a072d118917957d6554Steve Block            internalAppend(value.asCell());
2402bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2412bde8e466a4451c7319e3a072d118917957d6554Steve Block
2422bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Privileged class for marking JSValues directly. It is only safe to use
2432bde8e466a4451c7319e3a072d118917957d6554Steve Block    // this class to mark direct heap roots that are marked during every GC pass.
2442bde8e466a4451c7319e3a072d118917957d6554Steve Block    // All other references should be wrapped in WriteBarriers and marked through
2452bde8e466a4451c7319e3a072d118917957d6554Steve Block    // the MarkStack.
2462bde8e466a4451c7319e3a072d118917957d6554Steve Block    class HeapRootMarker {
2472bde8e466a4451c7319e3a072d118917957d6554Steve Block    private:
2482bde8e466a4451c7319e3a072d118917957d6554Steve Block        friend class Heap;
2492bde8e466a4451c7319e3a072d118917957d6554Steve Block        HeapRootMarker(MarkStack&);
2502bde8e466a4451c7319e3a072d118917957d6554Steve Block
2512bde8e466a4451c7319e3a072d118917957d6554Steve Block    public:
2522bde8e466a4451c7319e3a072d118917957d6554Steve Block        void mark(JSValue*);
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block        void mark(JSValue*, size_t);
2542bde8e466a4451c7319e3a072d118917957d6554Steve Block        void mark(JSString**);
2552bde8e466a4451c7319e3a072d118917957d6554Steve Block        void mark(JSCell**);
2562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        MarkStack& markStack();
2582bde8e466a4451c7319e3a072d118917957d6554Steve Block
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block    private:
2602bde8e466a4451c7319e3a072d118917957d6554Steve Block        MarkStack& m_markStack;
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block    };
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block
2632bde8e466a4451c7319e3a072d118917957d6554Steve Block    inline HeapRootMarker::HeapRootMarker(MarkStack& markStack)
2642bde8e466a4451c7319e3a072d118917957d6554Steve Block        : m_markStack(markStack)
2652bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2662bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2672bde8e466a4451c7319e3a072d118917957d6554Steve Block
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block    inline void HeapRootMarker::mark(JSValue* slot)
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_markStack.append(slot);
2712bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2722bde8e466a4451c7319e3a072d118917957d6554Steve Block
2732bde8e466a4451c7319e3a072d118917957d6554Steve Block    inline void HeapRootMarker::mark(JSValue* slot, size_t count)
2742bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2752bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_markStack.append(slot, count);
2762bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block
2782bde8e466a4451c7319e3a072d118917957d6554Steve Block    inline void HeapRootMarker::mark(JSString** slot)
2792bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_markStack.append(reinterpret_cast<JSCell**>(slot));
2812bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2822bde8e466a4451c7319e3a072d118917957d6554Steve Block
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block    inline void HeapRootMarker::mark(JSCell** slot)
2842bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_markStack.append(slot);
2862bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2872bde8e466a4451c7319e3a072d118917957d6554Steve Block
2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    inline MarkStack& HeapRootMarker::markStack()
2892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
2902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return m_markStack;
2912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
2922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2932bde8e466a4451c7319e3a072d118917957d6554Steve Block} // namespace JSC
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
296