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