diff options
author | nsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 03:22:01 +0000 |
---|---|---|
committer | nsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 03:22:01 +0000 |
commit | d815db156387600cdad5466be6b172421df420d8 (patch) | |
tree | 5d0caa4bac10f5aca3083287e7a5cbbaa47cd439 /webkit/port | |
parent | bad54ae6fbe10711638c29a1436690f4b4b7e18f (diff) | |
download | chromium_src-d815db156387600cdad5466be6b172421df420d8.zip chromium_src-d815db156387600cdad5466be6b172421df420d8.tar.gz chromium_src-d815db156387600cdad5466be6b172421df420d8.tar.bz2 |
Revert change 12507 and 12532 because it breaks the
tree and the purify tests.
Review URL: http://codereview.chromium.org/42634
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12534 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port')
-rw-r--r-- | webkit/port/bindings/v8/DOMObjectsInclude.h | 181 | ||||
-rw-r--r-- | webkit/port/bindings/v8/V8DOMMap.cpp | 510 | ||||
-rw-r--r-- | webkit/port/bindings/v8/V8DOMMap.h | 58 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 419 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.h | 7 |
5 files changed, 388 insertions, 787 deletions
diff --git a/webkit/port/bindings/v8/DOMObjectsInclude.h b/webkit/port/bindings/v8/DOMObjectsInclude.h deleted file mode 100644 index 7759065..0000000 --- a/webkit/port/bindings/v8/DOMObjectsInclude.h +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DOMObjectsInclude_h -#define DOMObjectsInclude_h - -#include "BarInfo.h" -#include "CanvasGradient.h" -#include "CanvasPattern.h" -#include "CanvasPixelArray.h" -#include "CanvasRenderingContext2D.h" -#include "CanvasStyle.h" -#include "CharacterData.h" -#include "ClientRect.h" -#include "ClientRectList.h" -#include "Clipboard.h" -#include "Console.h" -#include "Counter.h" -#include "CSSCharsetRule.h" -#include "CSSFontFaceRule.h" -#include "CSSImportRule.h" -#include "CSSMediaRule.h" -#include "CSSPageRule.h" -#include "CSSRule.h" -#include "CSSRuleList.h" -#include "CSSValueList.h" -#include "CSSStyleRule.h" -#include "CSSStyleSheet.h" -#include "CSSVariablesDeclaration.h" -#include "CSSVariablesRule.h" -#include "Database.h" -#include "DocumentType.h" -#include "DocumentFragment.h" -#include "DOMCoreException.h" -#include "DOMImplementation.h" -#include "DOMParser.h" -#include "DOMSelection.h" -#include "DOMStringList.h" -#include "DOMWindow.h" -#include "Entity.h" -#include "EventListener.h" -#include "EventTarget.h" -#include "Event.h" -#include "EventException.h" -#include "ExceptionCode.h" -#include "File.h" -#include "FileList.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameTree.h" -#include "History.h" -#include "HTMLNames.h" -#include "HTMLDocument.h" -#include "HTMLElement.h" -#include "HTMLImageElement.h" -#include "HTMLInputElement.h" -#include "HTMLSelectElement.h" -#include "HTMLOptionsCollection.h" -#include "ImageData.h" -#include "InspectorController.h" -#include "KeyboardEvent.h" -#include "Location.h" -#include "MediaError.h" -#include "MediaList.h" -#include "MediaPlayer.h" -#include "MessageChannel.h" -#include "MessageEvent.h" -#include "MessagePort.h" -#include "MimeTypeArray.h" -#include "MouseEvent.h" -#include "MutationEvent.h" -#include "Navigator.h" // for MimeTypeArray -#include "NodeFilter.h" -#include "Notation.h" -#include "NodeList.h" -#include "NodeIterator.h" -#include "OverflowEvent.h" -#include "Page.h" -#include "Plugin.h" -#include "PluginArray.h" -#include "ProcessingInstruction.h" -#include "ProgressEvent.h" -#include "Range.h" -#include "RangeException.h" -#include "Rect.h" -#include "RGBColor.h" -#include "Screen.h" -#include "ScriptExecutionContext.h" -#include "SecurityOrigin.h" -#include "Settings.h" -#include "SQLTransaction.h" -#include "SQLResultSet.h" -#include "SQLResultSetRowList.h" -#include "StyleSheet.h" -#include "StyleSheetList.h" -#include "SVGColor.h" -#include "SVGPaint.h" -#include "TextEvent.h" -#include "TextMetrics.h" -#include "TimeRanges.h" -#include "TreeWalker.h" -#include "XSLTProcessor.h" -#include "V8AbstractEventListener.h" -#include "V8CustomEventListener.h" -#include "V8DOMWindow.h" -#include "V8HTMLElement.h" -#include "V8LazyEventListener.h" -#include "V8ObjectEventListener.h" -#include "WebKitAnimationEvent.h" -#include "WebKitCSSKeyframeRule.h" -#include "WebKitCSSKeyframesRule.h" -#include "WebKitCSSMatrix.h" -#include "WebKitCSSTransformValue.h" -#include "WebKitPoint.h" -#include "WebKitTransitionEvent.h" -#include "WheelEvent.h" -#include "XMLHttpRequest.h" -#include "XMLHttpRequestException.h" -#include "XMLHttpRequestProgressEvent.h" -#include "XMLHttpRequestUpload.h" -#include "XMLSerializer.h" -#include "XPathException.h" -#include "XPathExpression.h" -#include "XPathNSResolver.h" -#include "XPathResult.h" - -#if ENABLE(SVG) -#include "SVGAngle.h" -#include "SVGAnimatedPoints.h" -#include "SVGElement.h" -#include "SVGElementInstance.h" -#include "SVGElementInstanceList.h" -#include "SVGException.h" -#include "SVGLength.h" -#include "SVGLengthList.h" -#include "SVGNumberList.h" -#include "SVGPathSeg.h" -#include "SVGPathSegArc.h" -#include "SVGPathSegClosePath.h" -#include "SVGPathSegCurvetoCubic.h" -#include "SVGPathSegCurvetoCubicSmooth.h" -#include "SVGPathSegCurvetoQuadratic.h" -#include "SVGPathSegCurvetoQuadraticSmooth.h" -#include "SVGPathSegLineto.h" -#include "SVGPathSegLinetoHorizontal.h" -#include "SVGPathSegLinetoVertical.h" -#include "SVGPathSegList.h" -#include "SVGPathSegMoveto.h" -#include "SVGPointList.h" -#include "SVGPreserveAspectRatio.h" -#include "SVGRenderingIntent.h" -#include "SVGStringList.h" -#include "SVGTransform.h" -#include "SVGTransformList.h" -#include "SVGUnitTypes.h" -#include "SVGURIReference.h" -#include "SVGZoomEvent.h" -#include "V8SVGPODTypeWrapper.h" -#endif - -#if ENABLE(WORKERS) -#include "Worker.h" -#include "WorkerContext.h" -#include "WorkerLocation.h" -#include "WorkerNavigator.h" -#endif - -#if ENABLE(XPATH) -#include "XPathEvaluator.h" -#endif - -namespace WebCore { - -// A helper class for undetectable document.all -class UndetectableHTMLCollection : public HTMLCollection { -}; - -} // namespace WebCore - -#endif // DOMObjectsInclude_h diff --git a/webkit/port/bindings/v8/V8DOMMap.cpp b/webkit/port/bindings/v8/V8DOMMap.cpp deleted file mode 100644 index 912dad7..0000000 --- a/webkit/port/bindings/v8/V8DOMMap.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include <v8.h> - -#include "DOMObjectsInclude.h" -#include "V8DOMMap.h" - -#include <wtf/HashMap.h> -#include <wtf/MainThread.h> -#include <wtf/Threading.h> -#include <wtf/ThreadSpecific.h> - -namespace WebCore { - -// DOM binding algorithm: -// -// There are two kinds of DOM objects: -// 1. DOM tree nodes, such as Document, HTMLElement, ... -// there classes implements TreeShared<T> interface; -// 2. Non-node DOM objects, such as CSSRule, Location, etc. -// these classes implement a ref-counted scheme. -// -// A DOM object may have a JS wrapper object. If a tree node -// is alive, its JS wrapper must be kept alive even it is not -// reachable from JS roots. -// However, JS wrappers of non-node objects can go away if -// not reachable from other JS objects. It works like a cache. -// -// DOM objects are ref-counted, and JS objects are traced from -// a set of root objects. They can create a cycle. To break -// cycles, we do following: -// Handles from DOM objects to JS wrappers are always weak, -// so JS wrappers of non-node object cannot create a cycle. -// Before starting a global GC, we create a virtual connection -// between nodes in the same tree in the JS heap. If the wrapper -// of one node in a tree is alive, wrappers of all nodes in -// the same tree are considered alive. This is done by creating -// object groups in GC prologue callbacks. The mark-compact -// collector will remove these groups after each GC. -// -// DOM objects should be deref-ed from the owning thread, not the GC thread -// that does not own them. In V8, GC can kick in from any thread. To ensure -// that DOM objects are always deref-ed from the owning thread when running -// V8 in multi-threading environment, we do following: -// 1. Maintain a thread specific DOM wrapper map for each object map. -// (We're using TLS support from WTF instead of base since V8Bindings -// does not depend on base. We further assume that all child threads -// running V8 instances are created by WTF and thus a destructor will -// be called to clean up all thread specific data.) -// 2. When GC happens: -// 2.1. If the dead object is in GC thread's map, remove the JS reference -// and deref the DOM object. -// 2.2. Otherwise, go through all thread maps to find the owning thread. -// Remove the JS reference from the owning thread's map and move the -// DOM object to a delayed queue. Post a task to the owning thread -// to have it deref-ed from the owning thread at later time. -// 3. When a thread is tearing down, invoke a cleanup routine to go through -// all objects in the delayed queue and the thread map and deref all of -// them. - -static void weakDOMObjectCallback(v8::Persistent<v8::Value> obj, void* param); -static void weakNodeCallback(v8::Persistent<v8::Value> obj, void* param); - -#if ENABLE(SVG) -static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> obj, void* param); - -// SVG non-node elements may have a reference to a context node which should be notified when the element is change -static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> obj, void* domObj); -#endif - -// This is to ensure that we will deref DOM objects from the owning thread, not the GC thread. -// The helper function will be scheduled by the GC thread to get called from the owning thread. -static void derefDelayedObjectsInCurrentThread(void*); - -// This should be called to remove all DOM objects associated with the current thread when it is tearing down. -static void removeAllDOMObjectsInCurrentThread(); - -// A map from a thread ID to thread's specific data. -class ThreadSpecificDOMData; -typedef WTF::HashMap<WTF::ThreadIdentifier, ThreadSpecificDOMData*> DOMThreadMap; -static DOMThreadMap domThreadMap; - -// Mutex to protect against concurrent access of domThreadMap. -static WTF::Mutex domThreadMapMutex; - -class ThreadSpecificDOMData { -public: - enum DOMWrapperMapType - { - DOMNodeMap, - DOMObjectMap, - ActiveDOMObjectMap, -#if ENABLE(SVG) - DOMSVGElementInstanceMap, - DOMSVGObjectWithContextMap -#endif - }; - - typedef WTF::HashMap<void*, V8ClassIndex::V8WrapperType> DelayedObjectMap; - - template <class KeyType> - class InternalDOMWrapperMap : public DOMWrapperMap<KeyType> { - public: - InternalDOMWrapperMap(v8::WeakReferenceCallback callback) - : DOMWrapperMap<KeyType>(callback) { } - - virtual void forget(KeyType* obj); - - void forgetOnly(KeyType* obj) - { - DOMWrapperMap<KeyType>::forget(obj); - } - }; - - ThreadSpecificDOMData() - : m_domNodeMap(new InternalDOMWrapperMap<Node>(&weakNodeCallback)) - , m_domObjectMap(new InternalDOMWrapperMap<void>(weakDOMObjectCallback)) - , m_activeDomObjectMap(new InternalDOMWrapperMap<void>(weakActiveDOMObjectCallback)) -#if ENABLE(SVG) - , m_domSvgElementInstanceMap(new InternalDOMWrapperMap<SVGElementInstance>(weakSVGElementInstanceCallback)) - , m_domSvgObjectWithContextMap(new InternalDOMWrapperMap<void>(weakSVGObjectWithContextCallback)) -#endif - , m_delayedProcessingScheduled(false) - , m_isMainThread(WTF::isMainThread()) - { - WTF::MutexLocker locker(domThreadMapMutex); - domThreadMap.set(WTF::currentThread(), this); - } - - // This is called when WTF thread is tearing down. - // We assume that all child threads running V8 instances are created by WTF. - ~ThreadSpecificDOMData() - { - removeAllDOMObjectsInCurrentThread(); - - delete m_domNodeMap; - delete m_domObjectMap; - delete m_activeDomObjectMap; -#if ENABLE(SVG) - delete m_domSvgElementInstanceMap; - delete m_domSvgObjectWithContextMap; -#endif - - WTF::MutexLocker locker(domThreadMapMutex); - domThreadMap.remove(WTF::currentThread()); - } - - void* getDOMWrapperMap(DOMWrapperMapType type) - { - switch (type) { - case DOMNodeMap: - return m_domNodeMap; - case DOMObjectMap: - return m_domObjectMap; - case ActiveDOMObjectMap: - return m_activeDomObjectMap; -#if ENABLE(SVG) - case DOMSVGElementInstanceMap: - return m_domSvgElementInstanceMap; - case DOMSVGObjectWithContextMap: - return m_domSvgObjectWithContextMap; -#endif - default: - ASSERT(false); - return NULL; - } - } - - InternalDOMWrapperMap<Node>& domNodeMap() { return *m_domNodeMap; } - InternalDOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; } - InternalDOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; } -#if ENABLE(SVG) - InternalDOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; } - InternalDOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; } -#endif - - DelayedObjectMap& delayedObjectMap() { return m_delayedObjectMap; } - bool delayedProcessingScheduled() const { return m_delayedProcessingScheduled; } - void setDelayedProcessingScheduled(bool value) { m_delayedProcessingScheduled = value; } - bool isMainThread() const { return m_isMainThread; } - -private: - InternalDOMWrapperMap<Node>* m_domNodeMap; - InternalDOMWrapperMap<void>* m_domObjectMap; - InternalDOMWrapperMap<void>* m_activeDomObjectMap; -#if ENABLE(SVG) - InternalDOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap; - InternalDOMWrapperMap<void>* m_domSvgObjectWithContextMap; -#endif - - // Stores all the DOM objects that are delayed to be processed when the owning thread gains control. - DelayedObjectMap m_delayedObjectMap; - - // The flag to indicate if the task to do the delayed process has already been posted. - bool m_delayedProcessingScheduled; - - bool m_isMainThread; -}; - -static WTF::ThreadSpecific<ThreadSpecificDOMData> threadSpecificDOMData; - -template<typename T> -static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapType mapType, V8ClassIndex::V8WrapperType objType, T* obj); - -template <class KeyType> -void ThreadSpecificDOMData::InternalDOMWrapperMap<KeyType>::forget(KeyType* obj) -{ - DOMWrapperMap<KeyType>::forget(obj); - - ThreadSpecificDOMData::DelayedObjectMap& delayedObjectMap = (*threadSpecificDOMData).delayedObjectMap(); - delayedObjectMap.take(obj); -} - -DOMWrapperMap<Node>& getDOMNodeMap() -{ - return (*threadSpecificDOMData).domNodeMap(); -} - -DOMWrapperMap<void>& getDOMObjectMap() -{ - return (*threadSpecificDOMData).domObjectMap(); -} - -DOMWrapperMap<void>& getActiveDOMObjectMap() -{ - return (*threadSpecificDOMData).activeDomObjectMap(); -} - -#if ENABLE(SVG) -DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap() -{ - return (*threadSpecificDOMData).domSvgElementInstanceMap(); -} - -static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> obj, void* param) -{ - SVGElementInstance* instance = static_cast<SVGElementInstance*>(param); - - ThreadSpecificDOMData::InternalDOMWrapperMap<SVGElementInstance>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<SVGElementInstance>&>(getDOMSVGElementInstanceMap()); - if (map.contains(instance)) { - instance->deref(); - map.forgetOnly(instance); - } else { - handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMSVGElementInstanceMap, V8ClassIndex::SVGELEMENTINSTANCE, instance); - } -} - -// Map of SVG objects with contexts to V8 objects -DOMWrapperMap<void>& getDOMSVGObjectWithContextMap() -{ - return (*threadSpecificDOMData).domSvgObjectWithContextMap(); -} - -static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> obj, void* domObj) -{ - v8::HandleScope scope; - ASSERT(obj->IsObject()); - - V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); - - ThreadSpecificDOMData::InternalDOMWrapperMap<void>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<void>&>(getDOMSVGObjectWithContextMap()); - if (map.contains(domObj)) { - // Forget function removes object from the map and dispose the wrapper. - map.forgetOnly(domObj); - - switch (type) { -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: static_cast<NAME*>(domObj)->deref(); break; - SVG_OBJECT_TYPES(MakeCase) -#undef MakeCase -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: \ - static_cast<V8SVGPODTypeWrapper<NAME>*>(domObj)->deref(); break; - SVG_POD_NATIVE_TYPES(MakeCase) -#undef MakeCase - default: - ASSERT(false); - } - } else { - handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMSVGObjectWithContextMap, type, domObj); - } -} -#endif - -// Called when the dead object is not in GC thread's map. Go through all thread maps to find the one containing it. -// Then clear the JS reference and push the DOM object into the delayed queue for it to be deref-ed at later time from the owning thread. -// * This is called when the GC thread is not the owning thread. -// * This can be called on any thread that has GC running. -// * Only one V8 instance is running at a time due to V8::Locker. So we don't need to worry about concurrency. -template<typename T> -static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapType mapType, V8ClassIndex::V8WrapperType objType, T* obj) -{ - WTF::MutexLocker locker(domThreadMapMutex); - for (typename DOMThreadMap::iterator iter(domThreadMap.begin()); iter != domThreadMap.end(); ++iter) { - WTF::ThreadIdentifier threadID = iter->first; - ThreadSpecificDOMData* threadData = iter->second; - - // Skip the current thread that is GC thread. - if (threadID == WTF::currentThread()) { - ASSERT(!static_cast<DOMWrapperMap<T>*>(threadData->getDOMWrapperMap(mapType))->contains(obj)); - continue; - } - - ThreadSpecificDOMData::InternalDOMWrapperMap<T>* domMap = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<T>*>(threadData->getDOMWrapperMap(mapType)); - if (domMap->contains(obj)) { - // Clear the JS reference. - domMap->forgetOnly(obj); - - // Push into the delayed queue. - threadData->delayedObjectMap().set(obj, objType); - - // Post a task to the owning thread in order to process the delayed queue. - // FIXME(jianli): For now, we can only post to main thread due to WTF task posting limitation. We will fix this when we work on nested worker. - if (!threadData->delayedProcessingScheduled()) { - threadData->setDelayedProcessingScheduled(true); - if (threadData->isMainThread()) - WTF::callOnMainThread(&derefDelayedObjectsInCurrentThread, NULL); - } - - break; - } - } -} - -// Called when obj is near death (not reachable from JS roots). -// It is time to remove the entry from the table and dispose the handle. -static void weakDOMObjectCallback(v8::Persistent<v8::Value> obj, void* domObj) -{ - v8::HandleScope scope; - ASSERT(obj->IsObject()); - - V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); - - ThreadSpecificDOMData::InternalDOMWrapperMap<void>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<void>&>(getDOMObjectMap()); - if (map.contains(domObj)) { - // Forget function removes object from the map and dispose the wrapper. - map.forgetOnly(domObj); - - switch (type) { -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: static_cast<NAME*>(domObj)->deref(); break; - DOM_OBJECT_TYPES(MakeCase) -#undef MakeCase - default: - ASSERT(false); - } - } else { - handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMObjectMap, type, domObj); - } -} - -void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> obj, void* domObj) -{ - v8::HandleScope scope; - ASSERT(obj->IsObject()); - - V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); - - ThreadSpecificDOMData::InternalDOMWrapperMap<void>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<void>&>(getActiveDOMObjectMap()); - if (map.contains(domObj)) { - // Forget function removes object from the map and dispose the wrapper. - map.forgetOnly(domObj); - - switch (type) { -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: static_cast<NAME*>(domObj)->deref(); break; - ACTIVE_DOM_OBJECT_TYPES(MakeCase) -#undef MakeCase - default: - ASSERT(false); - } - } else { - handleWeakObjectInOwningThread(ThreadSpecificDOMData::ActiveDOMObjectMap, type, domObj); - } -} - -static void weakNodeCallback(v8::Persistent<v8::Value> obj, void* param) -{ - Node* node = static_cast<Node*>(param); - - ThreadSpecificDOMData::InternalDOMWrapperMap<Node>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<Node>&>(getDOMNodeMap()); - if (map.contains(node)) { - map.forgetOnly(node); - node->deref(); - } else { - handleWeakObjectInOwningThread<Node>(ThreadSpecificDOMData::DOMNodeMap, V8ClassIndex::NODE, node); - } -} - -static void derefObject(V8ClassIndex::V8WrapperType type, void* domObj) -{ - switch (type) { - case V8ClassIndex::NODE: - static_cast<Node*>(domObj)->deref(); - break; - -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: static_cast<NAME*>(domObj)->deref(); break; - DOM_OBJECT_TYPES(MakeCase) // This includes both active and non-active. -#undef MakeCase - -#if ENABLE(SVG) -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: static_cast<NAME*>(domObj)->deref(); break; - SVG_OBJECT_TYPES(MakeCase) // This also includes SVGElementInstance. -#undef MakeCase - -#define MakeCase(TYPE, NAME) \ - case V8ClassIndex::TYPE: \ - static_cast<V8SVGPODTypeWrapper<NAME>*>(domObj)->deref(); break; - SVG_POD_NATIVE_TYPES(MakeCase) -#undef MakeCase -#endif - - default: - ASSERT(false); - } -} - -static void derefDelayedObjects() -{ - WTF::MutexLocker locker(domThreadMapMutex); - ThreadSpecificDOMData::DelayedObjectMap& delayedObjectMap = (*threadSpecificDOMData).delayedObjectMap(); - for (ThreadSpecificDOMData::DelayedObjectMap::iterator iter(delayedObjectMap.begin()); iter != delayedObjectMap.end(); ++iter) { - derefObject(iter->second, iter->first); - } - delayedObjectMap.clear(); -} - -static void derefDelayedObjectsInCurrentThread(void*) -{ - (*threadSpecificDOMData).setDelayedProcessingScheduled(false); - derefDelayedObjects(); -} - -template<typename T> -static void removeObjectsFromWrapperMap(DOMWrapperMap<T>& domMap) -{ - for (typename WTF::HashMap<T*, v8::Object*>::iterator iter(domMap.impl().begin()); iter != domMap.impl().end(); ++iter) { - T* domObj = static_cast<T*>(iter->first); - v8::Persistent<v8::Object> obj(iter->second); - - V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); - - // Deref the DOM object. - derefObject(type, domObj); - - // Clear the JS wrapper. - obj.Dispose(); - } - domMap.impl().clear(); -} - -static void removeAllDOMObjectsInCurrentThread() -{ - v8::Locker locker; - v8::HandleScope scope; - - // Deref all objects in the delayed queue. - derefDelayedObjects(); - - // Remove all DOM nodes. - removeObjectsFromWrapperMap<Node>(getDOMNodeMap()); - - // Remove all DOM objects in the wrapper map. - removeObjectsFromWrapperMap<void>(getDOMObjectMap()); - - // Remove all active DOM objects in the wrapper map. - removeObjectsFromWrapperMap<void>(getActiveDOMObjectMap()); - -#if ENABLE(SVG) - // Remove all SVG element instances in the wrapper map. - removeObjectsFromWrapperMap<SVGElementInstance>(getDOMSVGElementInstanceMap()); - - // Remove all SVG objects with context in the wrapper map. - removeObjectsFromWrapperMap<void>(getDOMSVGObjectWithContextMap()); -#endif -} - -} // namespace WebCore diff --git a/webkit/port/bindings/v8/V8DOMMap.h b/webkit/port/bindings/v8/V8DOMMap.h deleted file mode 100644 index 835f064..0000000 --- a/webkit/port/bindings/v8/V8DOMMap.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef V8DOMMap_h -#define V8DOMMap_h - -#include "dom_wrapper_map.h" - -namespace WebCore { - // Callback when JS wrapper of active DOM object is dead. - void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> obj, void* domObj); - - // A map from DOM node to its JS wrapper. - DOMWrapperMap<Node>& getDOMNodeMap(); - - // A map from a DOM object (non-node) to its JS wrapper. This map does not contain the DOM objects which can have pending activity (active dom objects). - DOMWrapperMap<void>& getDOMObjectMap(); - - // A map from a DOM object to its JS wrapper for DOM objects which can have pending activity. - DOMWrapperMap<void>& getActiveDOMObjectMap(); - -#if ENABLE(SVG) - // A map for SVGElementInstances to its JS wrapper. - DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap(); - - // Map of SVG objects with contexts to V8 objects - DOMWrapperMap<void>& getDOMSVGObjectWithContextMap(); -#endif -} // namespace WebCore - -#endif // V8DOMMap_h diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index 3f9e4da..ca00058 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -36,6 +36,7 @@ #include <v8-debug.h> #include "v8_proxy.h" +#include "dom_wrapper_map.h" #include "v8_index.h" #include "v8_binding.h" #include "v8_custom.h" @@ -44,12 +45,206 @@ #include "V8DOMWindow.h" #include "ChromiumBridge.h" -#include "DOMObjectsInclude.h" + +#include "BarInfo.h" +#include "CanvasGradient.h" +#include "CanvasPattern.h" +#include "CanvasPixelArray.h" +#include "CanvasRenderingContext2D.h" +#include "CanvasStyle.h" +#include "CharacterData.h" +#include "ClientRect.h" +#include "ClientRectList.h" +#include "Clipboard.h" +#include "Console.h" +#include "Counter.h" +#include "CSSCharsetRule.h" +#include "CSSFontFaceRule.h" +#include "CSSImportRule.h" +#include "CSSMediaRule.h" +#include "CSSPageRule.h" +#include "CSSRule.h" +#include "CSSRuleList.h" +#include "CSSValueList.h" +#include "CSSStyleRule.h" +#include "CSSStyleSheet.h" +#include "CSSVariablesDeclaration.h" +#include "CSSVariablesRule.h" +#include "Database.h" +#include "DocumentType.h" +#include "DocumentFragment.h" +#include "DOMCoreException.h" +#include "DOMImplementation.h" +#include "DOMParser.h" +#include "DOMSelection.h" +#include "DOMStringList.h" +#include "DOMWindow.h" +#include "Entity.h" +#include "EventListener.h" +#include "EventTarget.h" +#include "Event.h" +#include "EventException.h" +#include "ExceptionCode.h" +#include "File.h" +#include "FileList.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameTree.h" +#include "History.h" +#include "HTMLNames.h" +#include "HTMLDocument.h" +#include "HTMLElement.h" +#include "HTMLImageElement.h" +#include "HTMLInputElement.h" +#include "HTMLSelectElement.h" +#include "HTMLOptionsCollection.h" +#include "ImageData.h" +#include "InspectorController.h" +#include "KeyboardEvent.h" +#include "Location.h" +#include "MediaError.h" +#include "MediaList.h" +#include "MediaPlayer.h" +#include "MessageChannel.h" +#include "MessageEvent.h" +#include "MessagePort.h" +#include "MimeTypeArray.h" +#include "MouseEvent.h" +#include "MutationEvent.h" +#include "Navigator.h" // for MimeTypeArray +#include "NodeFilter.h" +#include "Notation.h" +#include "NodeList.h" +#include "NodeIterator.h" +#include "OverflowEvent.h" +#include "Page.h" +#include "Plugin.h" +#include "PluginArray.h" +#include "ProcessingInstruction.h" +#include "ProgressEvent.h" +#include "Range.h" +#include "RangeException.h" +#include "Rect.h" +#include "RGBColor.h" +#include "Screen.h" +#include "ScriptExecutionContext.h" +#include "SecurityOrigin.h" +#include "Settings.h" +#include "SQLTransaction.h" +#include "SQLResultSet.h" +#include "SQLResultSetRowList.h" +#include "StyleSheet.h" +#include "StyleSheetList.h" +#include "SVGColor.h" +#include "SVGPaint.h" +#include "TextEvent.h" +#include "TextMetrics.h" +#include "TimeRanges.h" +#include "TreeWalker.h" +#include "XSLTProcessor.h" +#include "V8AbstractEventListener.h" +#include "V8CustomEventListener.h" +#include "V8DOMWindow.h" +#include "V8HTMLElement.h" +#include "V8LazyEventListener.h" +#include "V8ObjectEventListener.h" +#include "WebKitAnimationEvent.h" +#include "WebKitCSSKeyframeRule.h" +#include "WebKitCSSKeyframesRule.h" +#include "WebKitCSSMatrix.h" +#include "WebKitCSSTransformValue.h" +#include "WebKitPoint.h" +#include "WebKitTransitionEvent.h" +#include "WheelEvent.h" +#include "XMLHttpRequest.h" +#include "XMLHttpRequestException.h" +#include "XMLHttpRequestProgressEvent.h" +#include "XMLHttpRequestUpload.h" +#include "XMLSerializer.h" +#include "XPathException.h" +#include "XPathExpression.h" +#include "XPathNSResolver.h" +#include "XPathResult.h" + #include "ScriptController.h" +#if ENABLE(SVG) +#include "SVGAngle.h" +#include "SVGAnimatedPoints.h" +#include "SVGElement.h" +#include "SVGElementInstance.h" +#include "SVGElementInstanceList.h" +#include "SVGException.h" +#include "SVGLength.h" +#include "SVGLengthList.h" +#include "SVGNumberList.h" +#include "SVGPathSeg.h" +#include "SVGPathSegArc.h" +#include "SVGPathSegClosePath.h" +#include "SVGPathSegCurvetoCubic.h" +#include "SVGPathSegCurvetoCubicSmooth.h" +#include "SVGPathSegCurvetoQuadratic.h" +#include "SVGPathSegCurvetoQuadraticSmooth.h" +#include "SVGPathSegLineto.h" +#include "SVGPathSegLinetoHorizontal.h" +#include "SVGPathSegLinetoVertical.h" +#include "SVGPathSegList.h" +#include "SVGPathSegMoveto.h" +#include "SVGPointList.h" +#include "SVGPreserveAspectRatio.h" +#include "SVGRenderingIntent.h" +#include "SVGStringList.h" +#include "SVGTransform.h" +#include "SVGTransformList.h" +#include "SVGUnitTypes.h" +#include "SVGURIReference.h" +#include "SVGZoomEvent.h" +#include "V8SVGPODTypeWrapper.h" +#endif // SVG + +#if ENABLE(WORKERS) +#include "Worker.h" +#include "WorkerContext.h" +#include "WorkerLocation.h" +#include "WorkerNavigator.h" +#endif // WORKERS + +#if ENABLE(XPATH) +#include "XPathEvaluator.h" +#endif + + namespace WebCore { + +// DOM binding algorithm: +// +// There are two kinds of DOM objects: +// 1. DOM tree nodes, such as Document, HTMLElement, ... +// there classes implements TreeShared<T> interface; +// 2. Non-node DOM objects, such as CSSRule, Location, etc. +// these classes implement a ref-counted scheme. +// +// A DOM object may have a JS wrapper object. If a tree node +// is alive, its JS wrapper must be kept alive even it is not +// reachable from JS roots. +// However, JS wrappers of non-node objects can go away if +// not reachable from other JS objects. It works like a cache. +// +// DOM objects are ref-counted, and JS objects are traced from +// a set of root objects. They can create a cycle. To break +// cycles, we do following: +// Handles from DOM objects to JS wrappers are always weak, +// so JS wrappers of non-node object cannot create a cycle. +// Before starting a global GC, we create a virtual connection +// between nodes in the same tree in the JS heap. If the wrapper +// of one node in a tree is alive, wrappers of all nodes in +// the same tree are considered alive. This is done by creating +// object groups in GC prologue callbacks. The mark-compact +// collector will remove these groups after each GC. + + // Static utility context. v8::Persistent<v8::Context> V8Proxy::m_utilityContext; @@ -57,6 +252,10 @@ v8::Persistent<v8::Context> V8Proxy::m_utilityContext; V8ExtensionList V8Proxy::m_extensions; +// A helper class for undetectable document.all +class UndetectableHTMLCollection : public HTMLCollection { +}; + #ifndef NDEBUG // Keeps track of global handles created (not JS wrappers // of DOM objects). Often these global handles are source @@ -186,14 +385,66 @@ static void EnumerateDOMNodeMap(DOMNodeMap& node_map) } #endif // NDEBUG +static void WeakDOMObjectCallback(v8::Persistent<v8::Value> obj, void* para); +static void WeakActiveDOMObjectCallback(v8::Persistent<v8::Value> obj, + void* para); +static void WeakNodeCallback(v8::Persistent<v8::Value> obj, void* para); +// A map from DOM node to its JS wrapper. +static DOMWrapperMap<Node>& GetDOMNodeMap() +{ + static DOMWrapperMap<Node> static_dom_node_map(&WeakNodeCallback); + return static_dom_node_map; +} + + +// A map from a DOM object (non-node) to its JS wrapper. This map does not +// contain the DOM objects which can have pending activity (active dom objects). +DOMWrapperMap<void>& GetDOMObjectMap() +{ + static DOMWrapperMap<void> + static_dom_object_map(&WeakDOMObjectCallback); + return static_dom_object_map; +} + + +// A map from a DOM object to its JS wrapper for DOM objects which +// can have pending activity. +static DOMWrapperMap<void>& GetActiveDOMObjectMap() +{ + static DOMWrapperMap<void> + static_active_dom_object_map(&WeakActiveDOMObjectCallback); + return static_active_dom_object_map; +} + #if ENABLE(SVG) +static void WeakSVGElementInstanceCallback(v8::Persistent<v8::Value> obj, + void* param); + +// A map for SVGElementInstances. +static DOMWrapperMap<SVGElementInstance>& dom_svg_element_instance_map() +{ + static DOMWrapperMap<SVGElementInstance> + static_dom_svg_element_instance_map(&WeakSVGElementInstanceCallback); + return static_dom_svg_element_instance_map; +} + +static void WeakSVGElementInstanceCallback(v8::Persistent<v8::Value> obj, + void* param) +{ + SVGElementInstance* instance = static_cast<SVGElementInstance*>(param); + ASSERT(dom_svg_element_instance_map().contains(instance)); + + instance->deref(); + dom_svg_element_instance_map().forget(instance); +} + v8::Handle<v8::Value> V8Proxy::SVGElementInstanceToV8Object( SVGElementInstance* instance) { if (!instance) return v8::Null(); - v8::Handle<v8::Object> existing_instance = getDOMSVGElementInstanceMap().get(instance); + v8::Handle<v8::Object> existing_instance = dom_svg_element_instance_map().get(instance); if (!existing_instance.IsEmpty()) return existing_instance; @@ -206,12 +457,32 @@ v8::Handle<v8::Value> V8Proxy::SVGElementInstanceToV8Object( instance); if (!result.IsEmpty()) { // Only update the DOM SVG element map if the result is non-empty. - getDOMSVGElementInstanceMap().set(instance, + dom_svg_element_instance_map().set(instance, v8::Persistent<v8::Object>::New(result)); } return result; } + +// SVG non-node elements may have a reference to a context node which +// should be notified when the element is change +static void WeakSVGObjectWithContext(v8::Persistent<v8::Value> obj, + void* dom_obj); + +// Map of SVG objects with contexts to V8 objects +static DOMWrapperMap<void>& dom_svg_object_with_context_map() { + static DOMWrapperMap<void> + static_dom_svg_object_with_context_map(&WeakSVGObjectWithContext); + return static_dom_svg_object_with_context_map; +} + +// Map of SVG objects with contexts to their contexts +static HashMap<void*, SVGElement*>& svg_object_to_context_map() +{ + static HashMap<void*, SVGElement*> static_svg_object_to_context_map; + return static_svg_object_to_context_map; +} + v8::Handle<v8::Value> V8Proxy::SVGObjectWithContextToV8Object( V8ClassIndex::V8WrapperType type, void* object) { @@ -219,7 +490,7 @@ v8::Handle<v8::Value> V8Proxy::SVGObjectWithContextToV8Object( return v8::Null(); v8::Persistent<v8::Object> result = - getDOMSVGObjectWithContextMap().get(object); + dom_svg_object_with_context_map().get(object); if (!result.IsEmpty()) return result; // Special case: SVGPathSegs need to be downcast to their real type @@ -242,16 +513,38 @@ SVG_POD_NATIVE_TYPES(MAKE_CASE) default: ASSERT(false); } - getDOMSVGObjectWithContextMap().set(object, result); + dom_svg_object_with_context_map().set(object, result); } return result; } -// Map of SVG objects with contexts to their contexts -static HashMap<void*, SVGElement*>& svg_object_to_context_map() { - static HashMap<void*, SVGElement*> static_svg_object_to_context_map; - return static_svg_object_to_context_map; +static void WeakSVGObjectWithContext(v8::Persistent<v8::Value> obj, + void* dom_obj) +{ + v8::HandleScope handle_scope; + ASSERT(dom_svg_object_with_context_map().contains(dom_obj)); + ASSERT(obj->IsObject()); + + // Forget function removes object from the map and dispose the wrapper. + dom_svg_object_with_context_map().forget(dom_obj); + + V8ClassIndex::V8WrapperType type = + V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); + + switch (type) { +#define MAKE_CASE(TYPE, NAME) \ + case V8ClassIndex::TYPE: static_cast<NAME*>(dom_obj)->deref(); break; +SVG_OBJECT_TYPES(MAKE_CASE) +#undef MAKE_CASE +#define MAKE_CASE(TYPE, NAME) \ + case V8ClassIndex::TYPE: \ + static_cast<V8SVGPODTypeWrapper<NAME>*>(dom_obj)->deref(); break; +SVG_POD_NATIVE_TYPES(MAKE_CASE) +#undef MAKE_CASE + default: + ASSERT(false); + } } void V8Proxy::SetSVGContext(void* obj, SVGElement* context) @@ -274,8 +567,66 @@ SVGElement* V8Proxy::GetSVGContext(void* obj) { return svg_object_to_context_map().get(obj); } + #endif +// Called when obj is near death (not reachable from JS roots) +// It is time to remove the entry from the table and dispose +// the handle. +static void WeakDOMObjectCallback(v8::Persistent<v8::Value> obj, + void* dom_obj) { + v8::HandleScope scope; + ASSERT(GetDOMObjectMap().contains(dom_obj)); + ASSERT(obj->IsObject()); + + // Forget function removes object from the map and dispose the wrapper. + GetDOMObjectMap().forget(dom_obj); + + V8ClassIndex::V8WrapperType type = + V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); + switch (type) { +#define MAKE_CASE(TYPE, NAME) \ + case V8ClassIndex::TYPE: static_cast<NAME*>(dom_obj)->deref(); break; + DOM_OBJECT_TYPES(MAKE_CASE) +#undef MAKE_CASE + default: + ASSERT(false); + } +} + + +static void WeakActiveDOMObjectCallback(v8::Persistent<v8::Value> obj, + void* dom_obj) +{ + v8::HandleScope scope; + ASSERT(GetActiveDOMObjectMap().contains(dom_obj)); + ASSERT(obj->IsObject()); + + // Forget function removes object from the map and dispose the wrapper. + GetActiveDOMObjectMap().forget(dom_obj); + + V8ClassIndex::V8WrapperType type = + V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(obj)); + switch (type) { +#define MAKE_CASE(TYPE, NAME) \ + case V8ClassIndex::TYPE: static_cast<NAME*>(dom_obj)->deref(); break; + ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) +#undef MAKE_CASE + default: + ASSERT(false); + } +} + +static void WeakNodeCallback(v8::Persistent<v8::Value> obj, void* param) +{ + Node* node = static_cast<Node*>(param); + ASSERT(GetDOMNodeMap().contains(node)); + + GetDOMNodeMap().forget(node); + node->deref(); +} + + // A map from a DOM node to its JS wrapper, the wrapper // is kept as a strong reference to survive GCs. static DOMObjectMap& gc_protected_map() { @@ -290,11 +641,11 @@ void V8Proxy::GCProtect(void* dom_object) return; if (gc_protected_map().contains(dom_object)) return; - if (!getDOMObjectMap().contains(dom_object)) + if (!GetDOMObjectMap().contains(dom_object)) return; // Create a new (strong) persistent handle for the object. - v8::Persistent<v8::Object> wrapper = getDOMObjectMap().get(dom_object); + v8::Persistent<v8::Object> wrapper = GetDOMObjectMap().get(dom_object); if (wrapper.IsEmpty()) return; gc_protected_map().set(dom_object, *v8::Persistent<v8::Object>::New(wrapper)); @@ -321,12 +672,12 @@ static void GCPrologue() v8::HandleScope scope; #ifndef NDEBUG - EnumerateDOMObjectMap(getDOMObjectMap().impl()); + EnumerateDOMObjectMap(GetDOMObjectMap().impl()); #endif // Run through all objects with possible pending activity making their // wrappers non weak if there is pending activity. - DOMObjectMap active_map = getActiveDOMObjectMap().impl(); + DOMObjectMap active_map = GetActiveDOMObjectMap().impl(); for (DOMObjectMap::iterator it = active_map.begin(), end = active_map.end(); it != end; ++it) { void* obj = it->first; @@ -389,7 +740,7 @@ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) typedef std::pair<uintptr_t, Node*> GrouperPair; typedef Vector<GrouperPair> GrouperList; - DOMNodeMap node_map = getDOMNodeMap().impl(); + DOMNodeMap node_map = GetDOMNodeMap().impl(); GrouperList grouper; grouper.reserveCapacity(node_map.size()); @@ -455,7 +806,7 @@ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) group.reserveCapacity(next_key_index - i); for (; i < next_key_index; ++i) { v8::Persistent<v8::Value> wrapper = - getDOMNodeMap().get(grouper[i].second); + GetDOMNodeMap().get(grouper[i].second); if (!wrapper.IsEmpty()) group.append(wrapper); } @@ -474,7 +825,7 @@ static void GCEpilogue() // Run through all objects with pending activity making their wrappers weak // again. - DOMObjectMap active_map = getActiveDOMObjectMap().impl(); + DOMObjectMap active_map = GetActiveDOMObjectMap().impl(); for (DOMObjectMap::iterator it = active_map.begin(), end = active_map.end(); it != end; ++it) { void* obj = it->first; @@ -486,7 +837,7 @@ static void GCEpilogue() NAME* impl = static_cast<NAME*>(obj); \ if (impl->hasPendingActivity()) { \ ASSERT(!wrapper.IsWeak()); \ - wrapper.MakeWeak(impl, &weakActiveDOMObjectCallback); \ + wrapper.MakeWeak(impl, &WeakActiveDOMObjectCallback); \ } \ break; \ } @@ -499,8 +850,8 @@ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) #ifndef NDEBUG // Check all survivals are weak. - EnumerateDOMObjectMap(getDOMObjectMap().impl()); - EnumerateDOMNodeMap(getDOMNodeMap().impl()); + EnumerateDOMObjectMap(GetDOMObjectMap().impl()); + EnumerateDOMNodeMap(GetDOMNodeMap().impl()); EnumerateDOMObjectMap(gc_protected_map()); EnumerateGlobalHandles(); #undef USE_VAR @@ -762,8 +1113,8 @@ void V8Proxy::DestroyGlobal() bool V8Proxy::DOMObjectHasJSWrapper(void* obj) { - return getDOMObjectMap().contains(obj) || - getActiveDOMObjectMap().contains(obj); + return GetDOMObjectMap().contains(obj) || + GetActiveDOMObjectMap().contains(obj); } @@ -781,7 +1132,7 @@ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) default: break; } #endif - getDOMObjectMap().set(obj, wrapper); + GetDOMObjectMap().set(obj, wrapper); } // The caller must have increased obj's ref count. @@ -797,14 +1148,14 @@ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE) #undef MAKE_CASE } #endif - getActiveDOMObjectMap().set(obj, wrapper); + GetActiveDOMObjectMap().set(obj, wrapper); } // The caller must have increased node's ref count. void V8Proxy::SetJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object> wrapper) { ASSERT(MaybeDOMWrapper(wrapper)); - getDOMNodeMap().set(node, wrapper); + GetDOMNodeMap().set(node, wrapper); } PassRefPtr<EventListener> V8Proxy::createInlineEventListener( @@ -2281,8 +2632,8 @@ v8::Handle<v8::Value> V8Proxy::ToV8Object(V8ClassIndex::V8WrapperType type, void // Non DOM node v8::Persistent<v8::Object> result = is_active_dom_object ? - getActiveDOMObjectMap().get(imp) : - getDOMObjectMap().get(imp); + GetActiveDOMObjectMap().get(imp) : + GetDOMObjectMap().get(imp); if (result.IsEmpty()) { v8::Local<v8::Object> v8obj = InstantiateV8Object(type, type, imp); if (!v8obj.IsEmpty()) { @@ -2752,7 +3103,7 @@ v8::Handle<v8::Value> V8Proxy::EventToV8Object(Event* event) if (!event) return v8::Null(); - v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(event); + v8::Handle<v8::Object> wrapper = GetDOMObjectMap().get(event); if (!wrapper.IsEmpty()) return wrapper; @@ -2811,7 +3162,7 @@ v8::Handle<v8::Value> V8Proxy::NodeToV8Object(Node* node) { if (!node) return v8::Null(); - v8::Handle<v8::Object> wrapper = getDOMNodeMap().get(node); + v8::Handle<v8::Object> wrapper = GetDOMNodeMap().get(node); if (!wrapper.IsEmpty()) return wrapper; @@ -2957,7 +3308,7 @@ v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target) // XMLHttpRequest is created within its JS counterpart. XMLHttpRequest* xhr = target->toXMLHttpRequest(); if (xhr) { - v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(xhr); + v8::Handle<v8::Object> wrapper = GetActiveDOMObjectMap().get(xhr); ASSERT(!wrapper.IsEmpty()); return wrapper; } @@ -2965,14 +3316,14 @@ v8::Handle<v8::Value> V8Proxy::EventTargetToV8Object(EventTarget* target) // MessagePort is created within its JS counterpart MessagePort* port = target->toMessagePort(); if (port) { - v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(port); + v8::Handle<v8::Object> wrapper = GetActiveDOMObjectMap().get(port); ASSERT(!wrapper.IsEmpty()); return wrapper; } XMLHttpRequestUpload* upload = target->toXMLHttpRequestUpload(); if (upload) { - v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(upload); + v8::Handle<v8::Object> wrapper = GetDOMObjectMap().get(upload); ASSERT(!wrapper.IsEmpty()); return wrapper; } @@ -3014,7 +3365,7 @@ v8::Handle<v8::Value> V8Proxy::StyleSheetToV8Object(StyleSheet* sheet) { if (!sheet) return v8::Null(); - v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(sheet); + v8::Handle<v8::Object> wrapper = GetDOMObjectMap().get(sheet); if (!wrapper.IsEmpty()) return wrapper; @@ -3046,7 +3397,7 @@ v8::Handle<v8::Value> V8Proxy::CSSValueToV8Object(CSSValue* value) { if (!value) return v8::Null(); - v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(value); + v8::Handle<v8::Object> wrapper = GetDOMObjectMap().get(value); if (!wrapper.IsEmpty()) return wrapper; @@ -3083,7 +3434,7 @@ v8::Handle<v8::Value> V8Proxy::CSSRuleToV8Object(CSSRule* rule) { if (!rule) return v8::Null(); - v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(rule); + v8::Handle<v8::Object> wrapper = GetDOMObjectMap().get(rule); if (!wrapper.IsEmpty()) return wrapper; diff --git a/webkit/port/bindings/v8/v8_proxy.h b/webkit/port/bindings/v8/v8_proxy.h index 017293e..e403751 100644 --- a/webkit/port/bindings/v8/v8_proxy.h +++ b/webkit/port/bindings/v8/v8_proxy.h @@ -6,6 +6,7 @@ #define V8_PROXY_H__ #include <v8.h> +#include "dom_wrapper_map.h" #include "v8_index.h" #include "v8_custom.h" #include "v8_utility.h" @@ -15,7 +16,6 @@ #include "PlatformString.h" // for WebCore::String #include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode #include "SecurityOrigin.h" // for WebCore::SecurityOrigin -#include "V8DOMMap.h" #include <wtf/Assertions.h> #include <wtf/PassRefPtr.h> // so generated bindings don't have to #include <wtf/Vector.h> @@ -29,9 +29,6 @@ #define INC_STATS(name) #endif -// FIXME: Remove the following hack when we replace all references to GetDOMObjectMap. -#define GetDOMObjectMap getDOMObjectMap - namespace WebCore { class CSSStyleDeclaration; @@ -147,6 +144,8 @@ void BatchConfigureConstants(v8::Handle<v8::FunctionTemplate> desc, const BatchedConstant* consts, size_t num_consts); +DOMWrapperMap<void>& GetDOMObjectMap(); + const int kMaxRecursionDepth = 20; // Information about an extension that is registered for use with V8. If scheme |