summaryrefslogtreecommitdiffstats
path: root/webkit/port
diff options
context:
space:
mode:
authornsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-26 03:22:01 +0000
committernsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-26 03:22:01 +0000
commitd815db156387600cdad5466be6b172421df420d8 (patch)
tree5d0caa4bac10f5aca3083287e7a5cbbaa47cd439 /webkit/port
parentbad54ae6fbe10711638c29a1436690f4b4b7e18f (diff)
downloadchromium_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.h181
-rw-r--r--webkit/port/bindings/v8/V8DOMMap.cpp510
-rw-r--r--webkit/port/bindings/v8/V8DOMMap.h58
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp419
-rw-r--r--webkit/port/bindings/v8/v8_proxy.h7
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