1/*
2 * Copyright (C) 2009 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#include "config.h"
32#include "V8DOMMap.h"
33
34#include "DOMData.h"
35#include "DOMDataStore.h"
36#include "MainThreadDOMData.h"
37#include "ScopedDOMDataStore.h"
38
39namespace WebCore {
40
41DOMDataStoreHandle::DOMDataStoreHandle()
42    : m_store(new ScopedDOMDataStore(DOMData::getCurrent()))
43{
44}
45
46DOMDataStoreHandle::~DOMDataStoreHandle()
47{
48}
49
50static bool fasterDOMStoreAccess = false;
51
52static inline DOMDataStore& getDOMDataStore()
53{
54    if (LIKELY(fasterDOMStoreAccess)) {
55        ASSERT(WTF::isMainThread());
56        return MainThreadDOMData::getCurrentMainThreadStore();
57    }
58
59    return DOMData::getCurrent()->getStore();
60}
61
62void enableFasterDOMStoreAccess()
63{
64    fasterDOMStoreAccess = true;
65}
66
67DOMNodeMapping& getDOMNodeMap()
68{
69    return getDOMDataStore().domNodeMap();
70}
71
72DOMWrapperMap<void>& getDOMObjectMap()
73{
74    return getDOMDataStore().domObjectMap();
75}
76
77DOMWrapperMap<void>& getActiveDOMObjectMap()
78{
79    return getDOMDataStore().activeDomObjectMap();
80}
81
82#if ENABLE(SVG)
83
84DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap()
85{
86    return getDOMDataStore().domSvgElementInstanceMap();
87}
88
89#endif // ENABLE(SVG)
90
91void removeAllDOMObjectsInCurrentThread()
92{
93    DOMDataStore& store = getDOMDataStore();
94
95    v8::HandleScope scope;
96
97    // The DOM objects with the following types only exist on the main thread.
98    if (WTF::isMainThread()) {
99        // Remove all DOM nodes.
100        DOMData::removeObjectsFromWrapperMap<Node>(&store, store.domNodeMap());
101
102#if ENABLE(SVG)
103        // Remove all SVG element instances in the wrapper map.
104        DOMData::removeObjectsFromWrapperMap<SVGElementInstance>(&store, store.domSvgElementInstanceMap());
105#endif
106    }
107
108    // Remove all DOM objects in the wrapper map.
109    DOMData::removeObjectsFromWrapperMap<void>(&store, store.domObjectMap());
110
111    // Remove all active DOM objects in the wrapper map.
112    DOMData::removeObjectsFromWrapperMap<void>(&store, store.activeDomObjectMap());
113}
114
115void visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor* visitor)
116{
117    v8::HandleScope scope;
118
119    WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
120    DOMDataList& list = DOMDataStore::allStores();
121    for (size_t i = 0; i < list.size(); ++i) {
122        DOMDataStore* store = list[i];
123        if (!store->domData()->owningThread() == WTF::currentThread())
124            continue;
125
126        store->domNodeMap().visit(store, visitor);
127    }
128}
129
130void visitDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
131{
132    v8::HandleScope scope;
133
134    WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
135    DOMDataList& list = DOMDataStore::allStores();
136    for (size_t i = 0; i < list.size(); ++i) {
137        DOMDataStore* store = list[i];
138        if (!store->domData()->owningThread() == WTF::currentThread())
139            continue;
140
141        store->domObjectMap().visit(store, visitor);
142    }
143}
144
145void visitActiveDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
146{
147    v8::HandleScope scope;
148
149    WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
150    DOMDataList& list = DOMDataStore::allStores();
151    for (size_t i = 0; i < list.size(); ++i) {
152        DOMDataStore* store = list[i];
153        if (!store->domData()->owningThread() == WTF::currentThread())
154            continue;
155
156        store->activeDomObjectMap().visit(store, visitor);
157    }
158}
159
160#if ENABLE(SVG)
161
162void visitDOMSVGElementInstancesInCurrentThread(DOMWrapperMap<SVGElementInstance>::Visitor* visitor)
163{
164    v8::HandleScope scope;
165
166    WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
167    DOMDataList& list = DOMDataStore::allStores();
168    for (size_t i = 0; i < list.size(); ++i) {
169        DOMDataStore* store = list[i];
170        if (!store->domData()->owningThread() == WTF::currentThread())
171            continue;
172
173        store->domSvgElementInstanceMap().visit(store, visitor);
174    }
175}
176
177#endif
178
179} // namespace WebCore
180