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 "DOMObjectsInclude.h"
37 #include "ScopedDOMDataStore.h"
38
39 namespace WebCore {
40
DOMDataStoreHandle()41 DOMDataStoreHandle::DOMDataStoreHandle()
42 : m_store(new ScopedDOMDataStore(DOMData::getCurrent()))
43 {
44 }
45
~DOMDataStoreHandle()46 DOMDataStoreHandle::~DOMDataStoreHandle()
47 {
48 }
49
getDOMNodeMap()50 DOMWrapperMap<Node>& getDOMNodeMap()
51 {
52 // Nodes only exist on the main thread.
53 return DOMData::getCurrentMainThread()->getStore().domNodeMap();
54 }
55
getDOMObjectMap()56 DOMWrapperMap<void>& getDOMObjectMap()
57 {
58 return DOMData::getCurrent()->getStore().domObjectMap();
59 }
60
getActiveDOMObjectMap()61 DOMWrapperMap<void>& getActiveDOMObjectMap()
62 {
63 return DOMData::getCurrent()->getStore().activeDomObjectMap();
64 }
65
66 #if ENABLE(SVG)
67
getDOMSVGElementInstanceMap()68 DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap()
69 {
70 return DOMData::getCurrent()->getStore().domSvgElementInstanceMap();
71 }
72
73 // Map of SVG objects with contexts to V8 objects
getDOMSVGObjectWithContextMap()74 DOMWrapperMap<void>& getDOMSVGObjectWithContextMap()
75 {
76 return DOMData::getCurrent()->getStore().domSvgObjectWithContextMap();
77 }
78
79 #endif // ENABLE(SVG)
80
removeAllDOMObjectsInCurrentThreadHelper()81 static void removeAllDOMObjectsInCurrentThreadHelper()
82 {
83 v8::HandleScope scope;
84
85 // Deref all objects in the delayed queue.
86 DOMData::getCurrent()->derefDelayedObjects();
87
88 // The DOM objects with the following types only exist on the main thread.
89 if (WTF::isMainThread()) {
90 // Remove all DOM nodes.
91 DOMData::removeObjectsFromWrapperMap<Node>(getDOMNodeMap());
92
93 #if ENABLE(SVG)
94 // Remove all SVG element instances in the wrapper map.
95 DOMData::removeObjectsFromWrapperMap<SVGElementInstance>(getDOMSVGElementInstanceMap());
96
97 // Remove all SVG objects with context in the wrapper map.
98 DOMData::removeObjectsFromWrapperMap<void>(getDOMSVGObjectWithContextMap());
99 #endif
100 }
101
102 // Remove all DOM objects in the wrapper map.
103 DOMData::removeObjectsFromWrapperMap<void>(getDOMObjectMap());
104
105 // Remove all active DOM objects in the wrapper map.
106 DOMData::removeObjectsFromWrapperMap<void>(getActiveDOMObjectMap());
107 }
108
removeAllDOMObjectsInCurrentThread()109 void removeAllDOMObjectsInCurrentThread()
110 {
111 // Use the locker only if it has already been invoked before, as by worker thread.
112 if (v8::Locker::IsActive()) {
113 v8::Locker locker;
114 removeAllDOMObjectsInCurrentThreadHelper();
115 } else
116 removeAllDOMObjectsInCurrentThreadHelper();
117 }
118
119
visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor * visitor)120 void visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor* visitor)
121 {
122 v8::HandleScope scope;
123
124 WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
125 DOMDataList& list = DOMDataStore::allStores();
126 for (size_t i = 0; i < list.size(); ++i) {
127 DOMDataStore* store = list[i];
128 if (!store->domData()->owningThread() == WTF::currentThread())
129 continue;
130
131 HashMap<Node*, v8::Object*>& map = store->domNodeMap().impl();
132 for (HashMap<Node*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
133 visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
134 }
135 }
136
visitDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor * visitor)137 void visitDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
138 {
139 v8::HandleScope scope;
140
141 WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
142 DOMDataList& list = DOMDataStore::allStores();
143 for (size_t i = 0; i < list.size(); ++i) {
144 DOMDataStore* store = list[i];
145 if (!store->domData()->owningThread() == WTF::currentThread())
146 continue;
147
148 HashMap<void*, v8::Object*> & map = store->domObjectMap().impl();
149 for (HashMap<void*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
150 visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
151 }
152 }
153
visitActiveDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor * visitor)154 void visitActiveDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
155 {
156 v8::HandleScope scope;
157
158 WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
159 DOMDataList& list = DOMDataStore::allStores();
160 for (size_t i = 0; i < list.size(); ++i) {
161 DOMDataStore* store = list[i];
162 if (!store->domData()->owningThread() == WTF::currentThread())
163 continue;
164
165 HashMap<void*, v8::Object*>& map = store->activeDomObjectMap().impl();
166 for (HashMap<void*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
167 visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
168 }
169 }
170
171 #if ENABLE(SVG)
172
visitDOMSVGElementInstancesInCurrentThread(DOMWrapperMap<SVGElementInstance>::Visitor * visitor)173 void visitDOMSVGElementInstancesInCurrentThread(DOMWrapperMap<SVGElementInstance>::Visitor* visitor)
174 {
175 v8::HandleScope scope;
176
177 WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
178 DOMDataList& list = DOMDataStore::allStores();
179 for (size_t i = 0; i < list.size(); ++i) {
180 DOMDataStore* store = list[i];
181 if (!store->domData()->owningThread() == WTF::currentThread())
182 continue;
183
184 HashMap<SVGElementInstance*, v8::Object*> & map = store->domSvgElementInstanceMap().impl();
185 for (HashMap<SVGElementInstance*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
186 visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
187 }
188 }
189
visitSVGObjectsInCurrentThread(DOMWrapperMap<void>::Visitor * visitor)190 void visitSVGObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
191 {
192 v8::HandleScope scope;
193
194 WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
195 DOMDataList& list = DOMDataStore::allStores();
196 for (size_t i = 0; i < list.size(); ++i) {
197 DOMDataStore* store = list[i];
198 if (!store->domData()->owningThread() == WTF::currentThread())
199 continue;
200
201 HashMap<void*, v8::Object*>& map = store->domSvgObjectWithContextMap().impl();
202 for (HashMap<void*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
203 visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
204 }
205 }
206
207 #endif
208
209 } // namespace WebCore
210