10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 Google 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 are
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * met:
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *     * Redistributions of source code must retain the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * notice, this list of conditions and the following disclaimer.
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *     * Redistributions in binary form must reproduce the above
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * in the documentation and/or other materials provided with the
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * distribution.
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * contributors may be used to endorse or promote products derived from
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * this software without specific prior written permission.
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#ifndef DOMDataStore_h
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define DOMDataStore_h
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "DOMObjectsInclude.h"
35d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8Node.h"
360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <v8.h>
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/HashMap.h>
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/MainThread.h>
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Noncopyable.h>
410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/OwnPtr.h>
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/StdLibExtras.h>
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Threading.h>
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/ThreadSpecific.h>
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Vector.h>
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore {
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    class DOMData;
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    typedef WTF::Vector<DOMDataStore*> DOMDataList;
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
53d0825bca7fe65beaee391d30da42e937db621564Steve Block    template <class T, int CHUNK_SIZE, class Traits>
54d0825bca7fe65beaee391d30da42e937db621564Steve Block    class ChunkedTable {
55d0825bca7fe65beaee391d30da42e937db621564Steve Block      public:
56d0825bca7fe65beaee391d30da42e937db621564Steve Block        ChunkedTable() : m_chunks(0), m_current(0), m_last(0) { }
57d0825bca7fe65beaee391d30da42e937db621564Steve Block
58d0825bca7fe65beaee391d30da42e937db621564Steve Block        T* add(T element)
59d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
60d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (m_current == m_last) {
61d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_chunks = new Chunk(m_chunks);
62d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_current = m_chunks->m_entries;
63d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_last = m_current + CHUNK_SIZE;
64d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
65d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT((m_chunks->m_entries <= m_current) && (m_current < m_last));
66d0825bca7fe65beaee391d30da42e937db621564Steve Block            T* p = m_current++;
67d0825bca7fe65beaee391d30da42e937db621564Steve Block            *p = element;
68d0825bca7fe65beaee391d30da42e937db621564Steve Block            return p;
69d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
70d0825bca7fe65beaee391d30da42e937db621564Steve Block
71d0825bca7fe65beaee391d30da42e937db621564Steve Block        void remove(T* element)
72d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
73d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(element);
74d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(m_current > m_chunks->m_entries);
75d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_current--;
76d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (element != m_current)
77d0825bca7fe65beaee391d30da42e937db621564Steve Block                Traits::move(element, m_current);
78d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (m_current == m_chunks->m_entries) {
79d0825bca7fe65beaee391d30da42e937db621564Steve Block                Chunk* toDelete = m_chunks;
80d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_chunks = toDelete->m_previous;
81d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_current = m_last = m_chunks ? m_chunks->m_entries + CHUNK_SIZE : 0;
82d0825bca7fe65beaee391d30da42e937db621564Steve Block                delete toDelete;
83d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
84d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT(!m_chunks || ((m_chunks->m_entries < m_current) && (m_current <= m_last)));
85d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
86d0825bca7fe65beaee391d30da42e937db621564Steve Block
87d0825bca7fe65beaee391d30da42e937db621564Steve Block        void clear()
88d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
89d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!m_chunks)
90d0825bca7fe65beaee391d30da42e937db621564Steve Block                return;
91d0825bca7fe65beaee391d30da42e937db621564Steve Block
92d0825bca7fe65beaee391d30da42e937db621564Steve Block            clearEntries(m_chunks->m_entries, m_current);
93d0825bca7fe65beaee391d30da42e937db621564Steve Block            Chunk* last = m_chunks;
94d0825bca7fe65beaee391d30da42e937db621564Steve Block            while (true) {
95d0825bca7fe65beaee391d30da42e937db621564Steve Block                Chunk* previous = last->m_previous;
96d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (!previous)
97d0825bca7fe65beaee391d30da42e937db621564Steve Block                    break;
98d0825bca7fe65beaee391d30da42e937db621564Steve Block                delete last;
99d0825bca7fe65beaee391d30da42e937db621564Steve Block                clearEntries(previous->m_entries, previous->m_entries + CHUNK_SIZE);
100d0825bca7fe65beaee391d30da42e937db621564Steve Block                last = previous;
101d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
102d0825bca7fe65beaee391d30da42e937db621564Steve Block
103d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_chunks = last;
104d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_current = m_chunks->m_entries;
105d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_last = m_current + CHUNK_SIZE;
106d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
107d0825bca7fe65beaee391d30da42e937db621564Steve Block
108d0825bca7fe65beaee391d30da42e937db621564Steve Block        void visit(typename Traits::Visitor* visitor)
109d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
110d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!m_chunks)
111d0825bca7fe65beaee391d30da42e937db621564Steve Block                return;
112d0825bca7fe65beaee391d30da42e937db621564Steve Block
113d0825bca7fe65beaee391d30da42e937db621564Steve Block            visitEntries(m_chunks->m_entries, m_current, visitor);
114d0825bca7fe65beaee391d30da42e937db621564Steve Block            for (Chunk* chunk = m_chunks->m_previous; chunk; chunk = chunk->m_previous)
115d0825bca7fe65beaee391d30da42e937db621564Steve Block                visitEntries(chunk->m_entries, chunk->m_entries + CHUNK_SIZE, visitor);
116d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
117d0825bca7fe65beaee391d30da42e937db621564Steve Block
118d0825bca7fe65beaee391d30da42e937db621564Steve Block      private:
119d0825bca7fe65beaee391d30da42e937db621564Steve Block        struct Chunk {
120d0825bca7fe65beaee391d30da42e937db621564Steve Block            explicit Chunk(Chunk* previous) : m_previous(previous) { }
121d0825bca7fe65beaee391d30da42e937db621564Steve Block            Chunk* const m_previous;
122d0825bca7fe65beaee391d30da42e937db621564Steve Block            T m_entries[CHUNK_SIZE];
123d0825bca7fe65beaee391d30da42e937db621564Steve Block        };
124d0825bca7fe65beaee391d30da42e937db621564Steve Block
125d0825bca7fe65beaee391d30da42e937db621564Steve Block        static void clearEntries(T* first, T* last)
126d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
127d0825bca7fe65beaee391d30da42e937db621564Steve Block            for (T* entry = first; entry < last; entry++)
128d0825bca7fe65beaee391d30da42e937db621564Steve Block                Traits::clear(entry);
129d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
130d0825bca7fe65beaee391d30da42e937db621564Steve Block
131d0825bca7fe65beaee391d30da42e937db621564Steve Block        static void visitEntries(T* first, T* last, typename Traits::Visitor* visitor)
132d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
133d0825bca7fe65beaee391d30da42e937db621564Steve Block            for (T* entry = first; entry < last; entry++)
134d0825bca7fe65beaee391d30da42e937db621564Steve Block                Traits::visit(entry, visitor);
135d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
136d0825bca7fe65beaee391d30da42e937db621564Steve Block
137d0825bca7fe65beaee391d30da42e937db621564Steve Block        Chunk* m_chunks;
138d0825bca7fe65beaee391d30da42e937db621564Steve Block        T* m_current;
139d0825bca7fe65beaee391d30da42e937db621564Steve Block        T* m_last;
140d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
141d0825bca7fe65beaee391d30da42e937db621564Steve Block
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // DOMDataStore
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    //
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // DOMDataStore is the backing store that holds the maps between DOM objects
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // and JavaScript objects.  In general, each thread can have multiple backing
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // stores, one per isolated world.
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    //
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // This class doesn't manage the lifetime of the store.  The data store
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // lifetime is managed by subclasses.
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    //
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    class DOMDataStore : public Noncopyable {
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    public:
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        enum DOMWrapperMapType {
1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DOMNodeMap,
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DOMObjectMap,
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ActiveDOMObjectMap,
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(SVG)
1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DOMSVGElementInstanceMap,
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DOMSVGObjectWithContextMap
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        template <class KeyType>
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        class InternalDOMWrapperMap : public DOMWrapperMap<KeyType> {
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        public:
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            InternalDOMWrapperMap(DOMData* domData, v8::WeakReferenceCallback callback)
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : DOMWrapperMap<KeyType>(callback), m_domData(domData) { }
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            virtual void forget(KeyType* object)
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                DOMWrapperMap<KeyType>::forget(object);
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                forgetDelayedObject(m_domData, object);
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        private:
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DOMData* m_domData;
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
179d0825bca7fe65beaee391d30da42e937db621564Steve Block        class IntrusiveDOMWrapperMap : public AbstractWeakReferenceMap<Node, v8::Object> {
180d0825bca7fe65beaee391d30da42e937db621564Steve Block        public:
181d0825bca7fe65beaee391d30da42e937db621564Steve Block            IntrusiveDOMWrapperMap(v8::WeakReferenceCallback callback)
182d0825bca7fe65beaee391d30da42e937db621564Steve Block                : AbstractWeakReferenceMap<Node, v8::Object>(callback) { }
183d0825bca7fe65beaee391d30da42e937db621564Steve Block
184d0825bca7fe65beaee391d30da42e937db621564Steve Block            virtual v8::Persistent<v8::Object> get(Node* obj)
185d0825bca7fe65beaee391d30da42e937db621564Steve Block            {
186d0825bca7fe65beaee391d30da42e937db621564Steve Block                v8::Persistent<v8::Object>* wrapper = obj->wrapper();
187d0825bca7fe65beaee391d30da42e937db621564Steve Block                return wrapper ? *wrapper : v8::Persistent<v8::Object>();
188d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
189d0825bca7fe65beaee391d30da42e937db621564Steve Block
190d0825bca7fe65beaee391d30da42e937db621564Steve Block            virtual void set(Node* obj, v8::Persistent<v8::Object> wrapper)
191d0825bca7fe65beaee391d30da42e937db621564Steve Block            {
192d0825bca7fe65beaee391d30da42e937db621564Steve Block                ASSERT(obj);
193d0825bca7fe65beaee391d30da42e937db621564Steve Block                ASSERT(!obj->wrapper());
194d0825bca7fe65beaee391d30da42e937db621564Steve Block                v8::Persistent<v8::Object>* entry = m_table.add(wrapper);
195d0825bca7fe65beaee391d30da42e937db621564Steve Block                obj->setWrapper(entry);
196d0825bca7fe65beaee391d30da42e937db621564Steve Block                wrapper.MakeWeak(obj, weakReferenceCallback());
197d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
198d0825bca7fe65beaee391d30da42e937db621564Steve Block
199d0825bca7fe65beaee391d30da42e937db621564Steve Block            virtual bool contains(Node* obj)
200d0825bca7fe65beaee391d30da42e937db621564Steve Block            {
201d0825bca7fe65beaee391d30da42e937db621564Steve Block                return obj->wrapper();
202d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
203d0825bca7fe65beaee391d30da42e937db621564Steve Block
204d0825bca7fe65beaee391d30da42e937db621564Steve Block            virtual void visit(Visitor* visitor)
205d0825bca7fe65beaee391d30da42e937db621564Steve Block            {
206d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_table.visit(visitor);
207d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
208d0825bca7fe65beaee391d30da42e937db621564Steve Block
209d0825bca7fe65beaee391d30da42e937db621564Steve Block            virtual bool removeIfPresent(Node* key, v8::Persistent<v8::Data> value);
210d0825bca7fe65beaee391d30da42e937db621564Steve Block
211d0825bca7fe65beaee391d30da42e937db621564Steve Block            virtual void clear()
212d0825bca7fe65beaee391d30da42e937db621564Steve Block            {
213d0825bca7fe65beaee391d30da42e937db621564Steve Block                m_table.clear();
214d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
215d0825bca7fe65beaee391d30da42e937db621564Steve Block
216d0825bca7fe65beaee391d30da42e937db621564Steve Block        private:
217d0825bca7fe65beaee391d30da42e937db621564Steve Block            static int const numberOfEntries = (1 << 10) - 1;
218d0825bca7fe65beaee391d30da42e937db621564Steve Block
219d0825bca7fe65beaee391d30da42e937db621564Steve Block            struct ChunkedTableTraits {
220d0825bca7fe65beaee391d30da42e937db621564Steve Block                typedef IntrusiveDOMWrapperMap::Visitor Visitor;
221d0825bca7fe65beaee391d30da42e937db621564Steve Block
222d0825bca7fe65beaee391d30da42e937db621564Steve Block                static void move(v8::Persistent<v8::Object>* target, v8::Persistent<v8::Object>* source)
223d0825bca7fe65beaee391d30da42e937db621564Steve Block                {
224d0825bca7fe65beaee391d30da42e937db621564Steve Block                    *target = *source;
225d0825bca7fe65beaee391d30da42e937db621564Steve Block                    Node* node = V8Node::toNative(*target);
226d0825bca7fe65beaee391d30da42e937db621564Steve Block                    ASSERT(node);
227d0825bca7fe65beaee391d30da42e937db621564Steve Block                    node->setWrapper(target);
228d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
229d0825bca7fe65beaee391d30da42e937db621564Steve Block
230d0825bca7fe65beaee391d30da42e937db621564Steve Block                static void clear(v8::Persistent<v8::Object>* entry)
231d0825bca7fe65beaee391d30da42e937db621564Steve Block                {
232d0825bca7fe65beaee391d30da42e937db621564Steve Block                    Node* node = V8Node::toNative(*entry);
233d0825bca7fe65beaee391d30da42e937db621564Steve Block                    ASSERT(node->wrapper() == entry);
234d0825bca7fe65beaee391d30da42e937db621564Steve Block
235d0825bca7fe65beaee391d30da42e937db621564Steve Block                    node->clearWrapper();
236d0825bca7fe65beaee391d30da42e937db621564Steve Block                    entry->Dispose();
237d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
238d0825bca7fe65beaee391d30da42e937db621564Steve Block
239d0825bca7fe65beaee391d30da42e937db621564Steve Block                static void visit(v8::Persistent<v8::Object>* entry, Visitor* visitor)
240d0825bca7fe65beaee391d30da42e937db621564Steve Block                {
241d0825bca7fe65beaee391d30da42e937db621564Steve Block                    Node* node = V8Node::toNative(*entry);
242d0825bca7fe65beaee391d30da42e937db621564Steve Block                    ASSERT(node->wrapper() == entry);
243d0825bca7fe65beaee391d30da42e937db621564Steve Block
244d0825bca7fe65beaee391d30da42e937db621564Steve Block                    visitor->visitDOMWrapper(node, *entry);
245d0825bca7fe65beaee391d30da42e937db621564Steve Block                }
246d0825bca7fe65beaee391d30da42e937db621564Steve Block            };
247d0825bca7fe65beaee391d30da42e937db621564Steve Block
248d0825bca7fe65beaee391d30da42e937db621564Steve Block            typedef ChunkedTable<v8::Persistent<v8::Object>, numberOfEntries, ChunkedTableTraits> Table;
249d0825bca7fe65beaee391d30da42e937db621564Steve Block            Table m_table;
250d0825bca7fe65beaee391d30da42e937db621564Steve Block        };
251d0825bca7fe65beaee391d30da42e937db621564Steve Block
2520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        DOMDataStore(DOMData*);
2530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        virtual ~DOMDataStore();
2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // A list of all DOMDataStore objects.  Traversed during GC to find a thread-specific map that
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // contains the object - so we can schedule the object to be deleted on the thread which created it.
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static DOMDataList& allStores();
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Mutex to protect against concurrent access of DOMDataList.
2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static WTF::Mutex& allStoresMutex();
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Helper function to avoid circular includes.
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void forgetDelayedObject(DOMData*, void* object);
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        DOMData* domData() const { return m_domData; }
2650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void* getDOMWrapperMap(DOMWrapperMapType);
2670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
268d0825bca7fe65beaee391d30da42e937db621564Steve Block        DOMNodeMapping& domNodeMap() { return *m_domNodeMap; }
2690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; }
2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; }
2710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(SVG)
2720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; }
2730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; }
2740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
2750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Need by V8GCController.
2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
2780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    protected:
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void weakNodeCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(SVG)
2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // SVG non-node elements may have a reference to a context node which should be notified when the element is change.
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
288d0825bca7fe65beaee391d30da42e937db621564Steve Block        DOMNodeMapping* m_domNodeMap;
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<void>* m_domObjectMap;
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<void>* m_activeDomObjectMap;
2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if ENABLE(SVG)
2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap;
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        InternalDOMWrapperMap<void>* m_domSvgObjectWithContextMap;
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    private:
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // A back-pointer to the DOMData to which we belong.
2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        DOMData* m_domData;
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    };
3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace WebCore
3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif // DOMDataStore_h
304