Title: [133169] trunk/Source/WebCore
Revision
133169
Author
aba...@webkit.org
Date
2012-11-01 07:52:07 -0700 (Thu, 01 Nov 2012)

Log Message

[V8] Unify the V8GCController visitors
https://bugs.webkit.org/show_bug.cgi?id=100897

Reviewed by Eric Seidel.

After this patch, we use a single visitor for all DOM wrappers,
regardless of type. We also visit all the wrappers in one pass by
calling v8::V8::VisitHandlesWithClassIds directly rather than via
visitAllDOMNodes.

This patch also introduces a wrapper class ID for non-Node DOM objects.
Previously, only DOM nodes had a class ID.

* bindings/v8/IntrusiveDOMWrapperMap.h:
* bindings/v8/ScriptProfiler.cpp:
(WebCore::retainedDOMInfo):
(WebCore::ScriptProfiler::initialize):
* bindings/v8/V8DOMMap.cpp:
(WebCore::visitAllDOMNodes):
* bindings/v8/V8DOMWrapper.cpp:
(WebCore::V8DOMWrapper::setJSWrapperForDOMNode):
* bindings/v8/V8DOMWrapper.h:
(WebCore::V8DOMWrapper::setJSWrapperForDOMObject):
* bindings/v8/V8GCController.cpp:
(WebCore::GCHandleVisitor::notifyFinished):
(GCHandleVisitor):
(WebCore::V8GCController::majorGCPrologue):
* bindings/v8/WrapperTypeInfo.h:
(WebCore):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (133168 => 133169)


--- trunk/Source/WebCore/ChangeLog	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/ChangeLog	2012-11-01 14:52:07 UTC (rev 133169)
@@ -1,3 +1,35 @@
+2012-11-01  Adam Barth  <aba...@webkit.org>
+
+        [V8] Unify the V8GCController visitors
+        https://bugs.webkit.org/show_bug.cgi?id=100897
+
+        Reviewed by Eric Seidel.
+
+        After this patch, we use a single visitor for all DOM wrappers,
+        regardless of type. We also visit all the wrappers in one pass by
+        calling v8::V8::VisitHandlesWithClassIds directly rather than via
+        visitAllDOMNodes.
+
+        This patch also introduces a wrapper class ID for non-Node DOM objects.
+        Previously, only DOM nodes had a class ID.
+
+        * bindings/v8/IntrusiveDOMWrapperMap.h:
+        * bindings/v8/ScriptProfiler.cpp:
+        (WebCore::retainedDOMInfo):
+        (WebCore::ScriptProfiler::initialize):
+        * bindings/v8/V8DOMMap.cpp:
+        (WebCore::visitAllDOMNodes):
+        * bindings/v8/V8DOMWrapper.cpp:
+        (WebCore::V8DOMWrapper::setJSWrapperForDOMNode):
+        * bindings/v8/V8DOMWrapper.h:
+        (WebCore::V8DOMWrapper::setJSWrapperForDOMObject):
+        * bindings/v8/V8GCController.cpp:
+        (WebCore::GCHandleVisitor::notifyFinished):
+        (GCHandleVisitor):
+        (WebCore::V8GCController::majorGCPrologue):
+        * bindings/v8/WrapperTypeInfo.h:
+        (WebCore):
+
 2012-11-01  Stephen White  <senorbla...@chromium.org>
 
         Unreviewed, rolling out r133143.

Modified: trunk/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/IntrusiveDOMWrapperMap.h	2012-11-01 14:52:07 UTC (rev 133169)
@@ -45,7 +45,7 @@
     virtual void set(Node* node, v8::Persistent<v8::Object> wrapper) OVERRIDE
     {
         ASSERT(node && node->wrapper().IsEmpty());
-        ASSERT(wrapper.WrapperClassId() == v8DOMSubtreeClassId);
+        ASSERT(wrapper.WrapperClassId() == v8DOMNodeClassId);
         node->setWrapper(wrapper);
         wrapper.MakeWeak(node, weakCallback);
     }

Modified: trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/ScriptProfiler.cpp	2012-11-01 14:52:07 UTC (rev 133169)
@@ -165,7 +165,7 @@
 
 static v8::RetainedObjectInfo* retainedDOMInfo(uint16_t classId, v8::Handle<v8::Value> wrapper)
 {
-    ASSERT(classId == v8DOMSubtreeClassId);
+    ASSERT(classId == v8DOMNodeClassId);
     if (!wrapper->IsObject())
         return 0;
     Node* node = V8Node::toNative(wrapper.As<v8::Object>());
@@ -174,7 +174,7 @@
 
 void ScriptProfiler::initialize()
 {
-    v8::HeapProfiler::DefineWrapperClass(v8DOMSubtreeClassId, &retainedDOMInfo);
+    v8::HeapProfiler::DefineWrapperClass(v8DOMNodeClassId, &retainedDOMInfo);
 }
 
 void ScriptProfiler::visitNodeWrappers(WrappedNodeVisitor* visitor)

Modified: trunk/Source/WebCore/bindings/v8/V8DOMMap.cpp (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/V8DOMMap.cpp	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/V8DOMMap.cpp	2012-11-01 14:52:07 UTC (rev 133169)
@@ -69,7 +69,7 @@
 
         virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId)
         {
-            if (classId != v8DOMSubtreeClassId)
+            if (classId != v8DOMNodeClassId)
                 return;
             ASSERT(V8Node::HasInstance(value));
             ASSERT(value->IsObject());

Modified: trunk/Source/WebCore/bindings/v8/V8DOMWrapper.cpp (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/V8DOMWrapper.cpp	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/V8DOMWrapper.cpp	2012-11-01 14:52:07 UTC (rev 133169)
@@ -72,7 +72,7 @@
 {
     v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper);
     ASSERT(maybeDOMWrapper(wrapperHandle));
-    wrapperHandle.SetWrapperClassId(v8DOMSubtreeClassId);
+    wrapperHandle.SetWrapperClassId(v8DOMNodeClassId);
     getDOMNodeMap(isolate).set(node.leakRef(), wrapperHandle);
     return wrapperHandle;
 }

Modified: trunk/Source/WebCore/bindings/v8/V8DOMWrapper.h (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/V8DOMWrapper.h	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/V8DOMWrapper.h	2012-11-01 14:52:07 UTC (rev 133169)
@@ -131,6 +131,7 @@
     {
         v8::Persistent<v8::Object> wrapperHandle = v8::Persistent<v8::Object>::New(wrapper);
         ASSERT(maybeDOMWrapper(wrapperHandle));
+        wrapperHandle.SetWrapperClassId(v8DOMObjectClassId);
         getDOMObjectMap(isolate).set(object.leakRef(), wrapperHandle);
         return wrapperHandle;
     }

Modified: trunk/Source/WebCore/bindings/v8/V8GCController.cpp (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/V8GCController.cpp	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/V8GCController.cpp	2012-11-01 14:52:07 UTC (rev 133169)
@@ -132,40 +132,6 @@
     Vector<ImplicitConnection> m_connections;
 };
 
-class ObjectVisitor : public DOMWrapperVisitor<void> {
-public:
-    explicit ObjectVisitor(WrapperGrouper* grouper)
-        : m_grouper(grouper)
-    {
-    }
-
-    void visitDOMWrapper(DOMDataStore*, void* object, v8::Persistent<v8::Object> wrapper)
-    {
-        if (wrapper.IsIndependent())
-            return;
-
-        WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
-
-        if (V8MessagePort::info.equals(type)) {
-            // Mark each port as in-use if it's entangled. For simplicity's sake,
-            // we assume all ports are remotely entangled, since the Chromium port
-            // implementation can't tell the difference.
-            MessagePort* port = static_cast<MessagePort*>(object);
-            if (port->isEntangled() || port->hasPendingActivity())
-                m_grouper->keepAlive(wrapper);
-        } else {
-            ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
-            if (activeDOMObject && activeDOMObject->hasPendingActivity())
-                m_grouper->keepAlive(wrapper);
-        }
-
-        m_grouper->addToGroup(type->opaqueRootForGC(object, wrapper), wrapper);
-    }
-
-private:
-    WrapperGrouper* m_grouper;
-};
-
 // FIXME: This should use opaque GC roots.
 static void addImplicitReferencesForNodeWithEventListeners(Node* node, v8::Persistent<v8::Object> wrapper)
 {
@@ -207,29 +173,61 @@
     return node;
 }
 
-class NodeVisitor : public NodeWrapperVisitor {
+class WrapperVisitor : public v8::PersistentHandleVisitor {
 public:
-    explicit NodeVisitor(WrapperGrouper* grouper)
-        : m_grouper(grouper)
+    virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE
     {
-    }
+        ASSERT(value->IsObject());
+        v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(value);
 
-    void visitNodeWrapper(Node* node, v8::Persistent<v8::Object> wrapper)
-    {
-        if (node->hasEventListeners())
-            addImplicitReferencesForNodeWithEventListeners(node, wrapper);
+        if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId)
+            return;
 
-        WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);  
+        ASSERT(V8DOMWrapper::maybeDOMWrapper(value));
 
-        ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
-        if (activeDOMObject && activeDOMObject->hasPendingActivity())
-            m_grouper->keepAlive(wrapper);
+        if (value.IsIndependent())
+            return;
 
-        m_grouper->addToGroup(V8GCController::opaqueRootForGC(node), wrapper);
+        WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(wrapper);
+        void* object = toNative(wrapper);
+
+        if (V8MessagePort::info.equals(type)) {
+            // Mark each port as in-use if it's entangled. For simplicity's sake,
+            // we assume all ports are remotely entangled, since the Chromium port
+            // implementation can't tell the difference.
+            MessagePort* port = static_cast<MessagePort*>(object);
+            if (port->isEntangled() || port->hasPendingActivity())
+                m_grouper.keepAlive(wrapper);
+        } else {
+            ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
+            if (activeDOMObject && activeDOMObject->hasPendingActivity())
+                m_grouper.keepAlive(wrapper);
+        }
+
+        if (classId == v8DOMNodeClassId) {
+            ASSERT(V8Node::HasInstance(wrapper));
+            ASSERT(!wrapper.IsIndependent());
+
+            Node* node = static_cast<Node*>(object);
+
+            if (node->hasEventListeners())
+                addImplicitReferencesForNodeWithEventListeners(node, wrapper);
+
+            m_grouper.addToGroup(V8GCController::opaqueRootForGC(node), wrapper);
+        } else if (classId == v8DOMObjectClassId) {
+            m_grouper.addToGroup(type->opaqueRootForGC(object, wrapper), wrapper);
+        } else {
+            ASSERT_NOT_REACHED();
+        }
     }
 
+    void notifyFinished()
+    {
+        m_grouper.apply();
+    }
+
 private:
-    WrapperGrouper* m_grouper;
+    WrapperGrouper m_grouper;
 };
 
 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
@@ -250,15 +248,10 @@
 
     v8::HandleScope scope;
 
-    WrapperGrouper grouper;
+    WrapperVisitor visitor;
+    v8::V8::VisitHandlesWithClassIds(&visitor);
+    visitor.notifyFinished();
 
-    NodeVisitor nodeVisitor(&grouper);
-    ObjectVisitor objectVisitor(&grouper);
-    visitAllDOMNodes(&nodeVisitor);
-    visitDOMObjects(&objectVisitor);
-
-    grouper.apply();
-
     V8PerIsolateData* data = ""
     data->stringCache()->clearOnGC();
 }

Modified: trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h (133168 => 133169)


--- trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h	2012-11-01 14:44:52 UTC (rev 133168)
+++ trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h	2012-11-01 14:52:07 UTC (rev 133169)
@@ -42,7 +42,8 @@
     static const int v8DOMWrapperObjectIndex = 1;
     static const int v8DefaultWrapperInternalFieldCount = 2;
 
-    static const uint16_t v8DOMSubtreeClassId = 1;
+    static const uint16_t v8DOMNodeClassId = 1;
+    static const uint16_t v8DOMObjectClassId = 2;
 
     typedef v8::Persistent<v8::FunctionTemplate> (*GetTemplateFunction)();
     typedef void (*DerefObjectFunction)(void*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to