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