Optimize V8 getDOMNodeMap(), a hot function in Dromaeo DOM tests, by increasing inlining.
[WebKit-https.git] / WebCore / bindings / v8 / V8DOMMap.cpp
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 "MainThreadDOMData.h"
38 #include "ScopedDOMDataStore.h"
39
40 namespace WebCore {
41
42 DOMDataStoreHandle::DOMDataStoreHandle()
43     : m_store(new ScopedDOMDataStore(DOMData::getCurrent()))
44 {
45 }
46
47 DOMDataStoreHandle::~DOMDataStoreHandle()
48 {
49 }
50
51 DOMWrapperMap<Node>& getDOMNodeMap()
52 {
53     return MainThreadDOMData::getCurrentMainThreadStore().domNodeMap();
54 }
55
56 DOMWrapperMap<void>& getDOMObjectMap()
57 {
58     return DOMData::getCurrent()->getStore().domObjectMap();
59 }
60
61 DOMWrapperMap<void>& getActiveDOMObjectMap()
62 {
63     return DOMData::getCurrent()->getStore().activeDomObjectMap();
64 }
65
66 #if ENABLE(SVG)
67
68 DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap()
69 {
70     return DOMData::getCurrent()->getStore().domSvgElementInstanceMap();
71 }
72
73 // Map of SVG objects with contexts to V8 objects
74 DOMWrapperMap<void>& getDOMSVGObjectWithContextMap()
75 {
76     return DOMData::getCurrent()->getStore().domSvgObjectWithContextMap();
77 }
78
79 #endif // ENABLE(SVG)
80
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
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
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
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
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
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
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