Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/WebKit/WebCore/bindings/v8/V8DOMMap.cpp

Issue 67061: Fix ASSERTS in worker code in OSX.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 22 matching lines...) Expand all
33 33
34 #include "DOMObjectsInclude.h" 34 #include "DOMObjectsInclude.h"
35 35
36 #include <v8.h> 36 #include <v8.h>
37 #include <wtf/HashMap.h> 37 #include <wtf/HashMap.h>
38 #include <wtf/MainThread.h> 38 #include <wtf/MainThread.h>
39 #include <wtf/Noncopyable.h> 39 #include <wtf/Noncopyable.h>
40 #include <wtf/StdLibExtras.h> 40 #include <wtf/StdLibExtras.h>
41 #include <wtf/Threading.h> 41 #include <wtf/Threading.h>
42 #include <wtf/ThreadSpecific.h> 42 #include <wtf/ThreadSpecific.h>
43 #include <wtf/Vector.h>
43 44
44 namespace WebCore { 45 namespace WebCore {
45 46
46 // DOM binding algorithm: 47 // DOM binding algorithm:
47 // 48 //
48 // There are two kinds of DOM objects: 49 // There are two kinds of DOM objects:
49 // 1. DOM tree nodes, such as Document, HTMLElement, ... 50 // 1. DOM tree nodes, such as Document, HTMLElement, ...
50 // there classes implement TreeShared<T> interface; 51 // there classes implement TreeShared<T> interface;
51 // 2. Non-node DOM objects, such as CSSRule, Location, etc. 52 // 2. Non-node DOM objects, such as CSSRule, Location, etc.
52 // these classes implement a ref-counted scheme. 53 // these classes implement a ref-counted scheme.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> v8Object, v oid* domObject); 97 static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> v8Object, v oid* domObject);
97 98
98 // SVG non-node elements may have a reference to a context node which should be notified when the element is change. 99 // SVG non-node elements may have a reference to a context node which should be notified when the element is change.
99 static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, void* domObject); 100 static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
100 #endif 101 #endif
101 102
102 // This is to ensure that we will deref DOM objects from the owning thread, not the GC thread. 103 // This is to ensure that we will deref DOM objects from the owning thread, not the GC thread.
103 // The helper function will be scheduled by the GC thread to get called from the owning thread. 104 // The helper function will be scheduled by the GC thread to get called from the owning thread.
104 static void derefDelayedObjectsInCurrentThread(void*); 105 static void derefDelayedObjectsInCurrentThread(void*);
105 106
106 // This should be called to remove all DOM objects associated with the current t hread when it is tearing down. 107 // A list of all ThreadSpecific DOM Data objects. Traversed during GC to find a thread-specific map that
107 static void removeAllDOMObjectsInCurrentThread(); 108 // contains the object - so we can schedule the object to be deleted on the thre ad which created it.
108
109 // A map from a thread ID to thread's specific data.
110 class ThreadSpecificDOMData; 109 class ThreadSpecificDOMData;
111 typedef WTF::HashMap<WTF::ThreadIdentifier, ThreadSpecificDOMData*> DOMThreadMap ; 110 typedef WTF::Vector<ThreadSpecificDOMData*> DOMDataList;
112 static DOMThreadMap& domThreadMap() 111 static DOMDataList& domDataList()
113 { 112 {
114 DEFINE_STATIC_LOCAL(DOMThreadMap, staticDOMThreadMap, ()); 113 DEFINE_STATIC_LOCAL(DOMDataList, staticDOMDataList, ());
115 return staticDOMThreadMap; 114 return staticDOMDataList;
116 } 115 }
117 116
118 // Mutex to protect against concurrent access of domThreadMap. 117 // Mutex to protect against concurrent access of DOMDataList.
119 static WTF::Mutex& domThreadMapMutex() 118 static WTF::Mutex& domDataListMutex()
120 { 119 {
121 DEFINE_STATIC_LOCAL(WTF::Mutex, staticDOMThreadMapMutex, ()); 120 DEFINE_STATIC_LOCAL(WTF::Mutex, staticDOMDataListMutex, ());
122 return staticDOMThreadMapMutex; 121 return staticDOMDataListMutex;
123 } 122 }
124 123
125 class ThreadSpecificDOMData : Noncopyable { 124 class ThreadSpecificDOMData : Noncopyable {
126 public: 125 public:
127 enum DOMWrapperMapType { 126 enum DOMWrapperMapType {
128 DOMNodeMap, 127 DOMNodeMap,
129 DOMObjectMap, 128 DOMObjectMap,
130 ActiveDOMObjectMap, 129 ActiveDOMObjectMap,
131 #if ENABLE(SVG) 130 #if ENABLE(SVG)
132 DOMSVGElementInstanceMap, 131 DOMSVGElementInstanceMap,
(...skipping 21 matching lines...) Expand all
154 : m_domNodeMap(0) 153 : m_domNodeMap(0)
155 , m_domObjectMap(0) 154 , m_domObjectMap(0)
156 , m_activeDomObjectMap(0) 155 , m_activeDomObjectMap(0)
157 #if ENABLE(SVG) 156 #if ENABLE(SVG)
158 , m_domSvgElementInstanceMap(0) 157 , m_domSvgElementInstanceMap(0)
159 , m_domSvgObjectWithContextMap(0) 158 , m_domSvgObjectWithContextMap(0)
160 #endif 159 #endif
161 , m_delayedProcessingScheduled(false) 160 , m_delayedProcessingScheduled(false)
162 , m_isMainThread(WTF::isMainThread()) 161 , m_isMainThread(WTF::isMainThread())
163 { 162 {
164 WTF::MutexLocker locker(domThreadMapMutex()); 163 WTF::MutexLocker locker(domDataListMutex());
165 domThreadMap().set(WTF::currentThread(), this); 164 domDataList().append(this);
166 } 165 }
167 166
168 virtual ~ThreadSpecificDOMData() 167 virtual ~ThreadSpecificDOMData()
169 { 168 {
170 WTF::MutexLocker locker(domThreadMapMutex()); 169 WTF::MutexLocker locker(domDataListMutex());
171 domThreadMap().remove(WTF::currentThread()); 170 domDataList().remove(domDataList().find(this));
172 } 171 }
173 172
174 void* getDOMWrapperMap(DOMWrapperMapType type) 173 void* getDOMWrapperMap(DOMWrapperMapType type)
175 { 174 {
176 switch (type) { 175 switch (type) {
177 case DOMNodeMap: 176 case DOMNodeMap:
178 return m_domNodeMap; 177 return m_domNodeMap;
179 case DOMObjectMap: 178 case DOMObjectMap:
180 return m_domObjectMap; 179 return m_domObjectMap;
181 case ActiveDOMObjectMap: 180 case ActiveDOMObjectMap:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 #if ENABLE(SVG) 233 #if ENABLE(SVG)
235 m_domSvgElementInstanceMap = new InternalDOMWrapperMap<SVGElementInstanc e>(weakSVGElementInstanceCallback); 234 m_domSvgElementInstanceMap = new InternalDOMWrapperMap<SVGElementInstanc e>(weakSVGElementInstanceCallback);
236 m_domSvgObjectWithContextMap = new InternalDOMWrapperMap<void>(weakSVGOb jectWithContextCallback); 235 m_domSvgObjectWithContextMap = new InternalDOMWrapperMap<void>(weakSVGOb jectWithContextCallback);
237 #endif 236 #endif
238 } 237 }
239 238
240 // This is called when WTF thread is tearing down. 239 // This is called when WTF thread is tearing down.
241 // We assume that all child threads running V8 instances are created by WTF. 240 // We assume that all child threads running V8 instances are created by WTF.
242 virtual ~NonMainThreadSpecificDOMData() 241 virtual ~NonMainThreadSpecificDOMData()
243 { 242 {
244 removeAllDOMObjectsInCurrentThread();
245
246 delete m_domNodeMap; 243 delete m_domNodeMap;
247 delete m_domObjectMap; 244 delete m_domObjectMap;
248 delete m_activeDomObjectMap; 245 delete m_activeDomObjectMap;
249 #if ENABLE(SVG) 246 #if ENABLE(SVG)
250 delete m_domSvgElementInstanceMap; 247 delete m_domSvgElementInstanceMap;
251 delete m_domSvgObjectWithContextMap; 248 delete m_domSvgObjectWithContextMap;
252 #endif 249 #endif
253 } 250 }
254 }; 251 };
255 252
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 #endif // ENABLE(SVG) 375 #endif // ENABLE(SVG)
379 376
380 // Called when the dead object is not in GC thread's map. Go through all thread maps to find the one containing it. 377 // Called when the dead object is not in GC thread's map. Go through all thread maps to find the one containing it.
381 // Then clear the JS reference and push the DOM object into the delayed queue fo r it to be deref-ed at later time from the owning thread. 378 // Then clear the JS reference and push the DOM object into the delayed queue fo r it to be deref-ed at later time from the owning thread.
382 // * This is called when the GC thread is not the owning thread. 379 // * This is called when the GC thread is not the owning thread.
383 // * This can be called on any thread that has GC running. 380 // * This can be called on any thread that has GC running.
384 // * Only one V8 instance is running at a time due to V8::Locker. So we don't ne ed to worry about concurrency. 381 // * Only one V8 instance is running at a time due to V8::Locker. So we don't ne ed to worry about concurrency.
385 template<typename T> 382 template<typename T>
386 static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapT ype mapType, V8ClassIndex::V8WrapperType objectType, T* object) 383 static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapT ype mapType, V8ClassIndex::V8WrapperType objectType, T* object)
387 { 384 {
388 WTF::MutexLocker locker(domThreadMapMutex()); 385 WTF::MutexLocker locker(domDataListMutex());
389 for (typename DOMThreadMap::iterator iter(domThreadMap().begin()); iter != d omThreadMap().end(); ++iter) { 386 DOMDataList& list = domDataList();
390 WTF::ThreadIdentifier threadID = iter->first; 387 for (size_t i = 0; i < list.size(); ++i) {
391 ThreadSpecificDOMData* threadData = iter->second; 388 ThreadSpecificDOMData* threadData = list[i];
392
393 // Skip the current thread that is GC thread.
394 if (threadID == WTF::currentThread()) {
395 ASSERT(!static_cast<DOMWrapperMap<T>*>(threadData->getDOMWrapperMap( mapType))->contains(object));
396 continue;
397 }
398 389
399 ThreadSpecificDOMData::InternalDOMWrapperMap<T>* domMap = static_cast<Th readSpecificDOMData::InternalDOMWrapperMap<T>*>(threadData->getDOMWrapperMap(map Type)); 390 ThreadSpecificDOMData::InternalDOMWrapperMap<T>* domMap = static_cast<Th readSpecificDOMData::InternalDOMWrapperMap<T>*>(threadData->getDOMWrapperMap(map Type));
400 if (domMap->contains(object)) { 391 if (domMap->contains(object)) {
401 // Clear the JS reference. 392 // Clear the JS reference.
402 domMap->forgetOnly(object); 393 domMap->forgetOnly(object);
403 394
404 // Push into the delayed queue. 395 // Push into the delayed queue.
405 threadData->delayedObjectMap().set(object, objectType); 396 threadData->delayedObjectMap().set(object, objectType);
406 397
407 // Post a task to the owning thread in order to process the delayed queue. 398 // Post a task to the owning thread in order to process the delayed queue.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 #endif 498 #endif
508 499
509 default: 500 default:
510 ASSERT_NOT_REACHED(); 501 ASSERT_NOT_REACHED();
511 break; 502 break;
512 } 503 }
513 } 504 }
514 505
515 static void derefDelayedObjects() 506 static void derefDelayedObjects()
516 { 507 {
517 WTF::MutexLocker locker(domThreadMapMutex()); 508 WTF::MutexLocker locker(domDataListMutex());
518 509
519 getThreadSpecificDOMData().setDelayedProcessingScheduled(false); 510 getThreadSpecificDOMData().setDelayedProcessingScheduled(false);
520 511
521 ThreadSpecificDOMData::DelayedObjectMap& delayedObjectMap = getThreadSpecifi cDOMData().delayedObjectMap(); 512 ThreadSpecificDOMData::DelayedObjectMap& delayedObjectMap = getThreadSpecifi cDOMData().delayedObjectMap();
522 for (ThreadSpecificDOMData::DelayedObjectMap::iterator iter(delayedObjectMap .begin()); iter != delayedObjectMap.end(); ++iter) { 513 for (ThreadSpecificDOMData::DelayedObjectMap::iterator iter(delayedObjectMap .begin()); iter != delayedObjectMap.end(); ++iter) {
523 derefObject(iter->second, iter->first); 514 derefObject(iter->second, iter->first);
524 } 515 }
525 delayedObjectMap.clear(); 516 delayedObjectMap.clear();
526 } 517 }
527 518
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 557
567 #if ENABLE(SVG) 558 #if ENABLE(SVG)
568 // Remove all SVG element instances in the wrapper map. 559 // Remove all SVG element instances in the wrapper map.
569 removeObjectsFromWrapperMap<SVGElementInstance>(getDOMSVGElementInstanceMap( )); 560 removeObjectsFromWrapperMap<SVGElementInstance>(getDOMSVGElementInstanceMap( ));
570 561
571 // Remove all SVG objects with context in the wrapper map. 562 // Remove all SVG objects with context in the wrapper map.
572 removeObjectsFromWrapperMap<void>(getDOMSVGObjectWithContextMap()); 563 removeObjectsFromWrapperMap<void>(getDOMSVGObjectWithContextMap());
573 #endif 564 #endif
574 } 565 }
575 566
576 static void removeAllDOMObjectsInCurrentThread() 567 void removeAllDOMObjectsInCurrentThread()
577 { 568 {
578 // Use the locker only if it has already been invoked before, as by worker t hread. 569 // Use the locker only if it has already been invoked before, as by worker t hread.
579 if (v8::Locker::IsActive()) { 570 if (v8::Locker::IsActive()) {
580 v8::Locker locker; 571 v8::Locker locker;
581 removeAllDOMObjectsInCurrentThreadHelper(); 572 removeAllDOMObjectsInCurrentThreadHelper();
582 } else 573 } else
583 removeAllDOMObjectsInCurrentThreadHelper(); 574 removeAllDOMObjectsInCurrentThreadHelper();
584 } 575 }
585 576
586 } // namespace WebCore 577 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698