ASSERTION FAILED: "!m_isolatedWorld->isNormal() || m_wrapper || !m_jsFunction" in...
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Apr 2014 07:55:19 +0000 (07:55 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 25 Apr 2014 07:55:19 +0000 (07:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=132148

Reviewed by Andreas Kling.

Changed how JSCustomMarkFunction generation works. Instead of leaving out
the generated visitChildren function, just generate a call to visitAdditionalChildren.
This eliminates the need to repeat boilerplate.

The fix for the above bug was to correct mistaken logic where JSSVGElementInstance
had a visitChildren that did not properly mark event listeners because it explicitly
did not call through to the base class visitChildren. The new arrangement makes that
mistake impossible.

* bindings/js/JSAttrCustom.cpp:
(WebCore::JSAttr::visitAdditionalChildren): Use this instead of visitChildren.
* bindings/js/JSAudioTrackCustom.cpp:
(WebCore::JSAudioTrack::visitAdditionalChildren): Ditto.
* bindings/js/JSAudioTrackListCustom.cpp:
(WebCore::JSAudioTrackList::visitAdditionalChildren): Ditto.
* bindings/js/JSCSSRuleCustom.cpp:
(WebCore::JSCSSRule::visitAdditionalChildren): Ditto.
* bindings/js/JSCSSStyleDeclarationCustom.cpp:
(WebCore::JSCSSStyleDeclaration::visitAdditionalChildren): Ditto.
* bindings/js/JSCanvasRenderingContextCustom.cpp:
(WebCore::JSCanvasRenderingContext::visitAdditionalChildren): Ditto.
* bindings/js/JSCryptoKeyPairCustom.cpp:
(WebCore::JSCryptoKeyPair::visitAdditionalChildren): Ditto.
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::visitAdditionalChildren): Ditto.
* bindings/js/JSMessageChannelCustom.cpp:
(WebCore::JSMessageChannel::visitAdditionalChildren): Ditto.
* bindings/js/JSMessagePortCustom.cpp:
(WebCore::JSMessagePort::visitAdditionalChildren): Ditto.
* bindings/js/JSNodeCustom.cpp:
(WebCore::JSNode::visitAdditionalChildren): Ditto.
* bindings/js/JSNodeFilterCustom.cpp:
(WebCore::JSNodeFilter::visitAdditionalChildren): Ditto.
* bindings/js/JSNodeIteratorCustom.cpp:
(WebCore::JSNodeIterator::visitAdditionalChildren): Ditto.
* bindings/js/JSSVGElementInstanceCustom.cpp:
(WebCore::JSSVGElementInstance::visitAdditionalChildren): Ditto.
* bindings/js/JSSharedWorkerCustom.cpp:
(WebCore::JSSharedWorker::visitAdditionalChildren): Ditto.
* bindings/js/JSStyleSheetCustom.cpp:
(WebCore::JSStyleSheet::visitAdditionalChildren): Ditto.
* bindings/js/JSTextTrackCueCustom.cpp:
(WebCore::JSTextTrackCue::visitAdditionalChildren): Ditto.
* bindings/js/JSTextTrackCustom.cpp:
(WebCore::JSTextTrack::visitAdditionalChildren): Ditto.
* bindings/js/JSTextTrackListCustom.cpp:
(WebCore::JSTextTrackList::visitAdditionalChildren): Ditto.
* bindings/js/JSTreeWalkerCustom.cpp:
(WebCore::JSTreeWalker::visitAdditionalChildren): Ditto.
* bindings/js/JSVideoTrackCustom.cpp:
(WebCore::JSVideoTrack::visitAdditionalChildren): Ditto.
* bindings/js/JSVideoTrackListCustom.cpp:
(WebCore::JSVideoTrackList::visitAdditionalChildren): Ditto.
* bindings/js/JSWebGLRenderingContextCustom.cpp:
(WebCore::JSWebGLRenderingContext::visitAdditionalChildren): Ditto.
* bindings/js/JSWorkerGlobalScopeCustom.cpp:
(WebCore::JSWorkerGlobalScope::visitAdditionalChildren): Ditto.
* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::JSXMLHttpRequest::visitAdditionalChildren): Ditto.
* bindings/js/JSXPathResultCustom.cpp:
(WebCore::JSXPathResult::visitAdditionalChildren): Ditto.

* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::visitChildren): Rewrote to use modern for loops.

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader): Generate declaration of visitAdditionalChildren.
(GenerateImplementation): Generate call to visitAdditionalChildren.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@167794 268f45cc-cd09-0410-ab3c-d52691b4dbfc

29 files changed:
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSAttrCustom.cpp
Source/WebCore/bindings/js/JSAudioTrackCustom.cpp
Source/WebCore/bindings/js/JSAudioTrackListCustom.cpp
Source/WebCore/bindings/js/JSCSSRuleCustom.cpp
Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
Source/WebCore/bindings/js/JSCanvasRenderingContextCustom.cpp
Source/WebCore/bindings/js/JSCryptoKeyPairCustom.cpp
Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp
Source/WebCore/bindings/js/JSMessageChannelCustom.cpp
Source/WebCore/bindings/js/JSMessagePortCustom.cpp
Source/WebCore/bindings/js/JSNodeCustom.cpp
Source/WebCore/bindings/js/JSNodeFilterCustom.cpp
Source/WebCore/bindings/js/JSNodeIteratorCustom.cpp
Source/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
Source/WebCore/bindings/js/JSSharedWorkerCustom.cpp
Source/WebCore/bindings/js/JSStyleSheetCustom.cpp
Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp
Source/WebCore/bindings/js/JSTextTrackCustom.cpp
Source/WebCore/bindings/js/JSTextTrackListCustom.cpp
Source/WebCore/bindings/js/JSTreeWalkerCustom.cpp
Source/WebCore/bindings/js/JSVideoTrackCustom.cpp
Source/WebCore/bindings/js/JSVideoTrackListCustom.cpp
Source/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp
Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp
Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
Source/WebCore/bindings/js/JSXPathResultCustom.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

index fab44e6..fb6727b 100644 (file)
@@ -1,3 +1,79 @@
+2014-04-25  Darin Adler  <darin@apple.com>
+
+        ASSERTION FAILED: "!m_isolatedWorld->isNormal() || m_wrapper || !m_jsFunction" in svg/custom/use-instanceRoot-event-listeners.xhtml
+        https://bugs.webkit.org/show_bug.cgi?id=132148
+
+        Reviewed by Andreas Kling.
+
+        Changed how JSCustomMarkFunction generation works. Instead of leaving out
+        the generated visitChildren function, just generate a call to visitAdditionalChildren.
+        This eliminates the need to repeat boilerplate.
+
+        The fix for the above bug was to correct mistaken logic where JSSVGElementInstance
+        had a visitChildren that did not properly mark event listeners because it explicitly
+        did not call through to the base class visitChildren. The new arrangement makes that
+        mistake impossible.
+
+        * bindings/js/JSAttrCustom.cpp:
+        (WebCore::JSAttr::visitAdditionalChildren): Use this instead of visitChildren.
+        * bindings/js/JSAudioTrackCustom.cpp:
+        (WebCore::JSAudioTrack::visitAdditionalChildren): Ditto.
+        * bindings/js/JSAudioTrackListCustom.cpp:
+        (WebCore::JSAudioTrackList::visitAdditionalChildren): Ditto.
+        * bindings/js/JSCSSRuleCustom.cpp:
+        (WebCore::JSCSSRule::visitAdditionalChildren): Ditto.
+        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+        (WebCore::JSCSSStyleDeclaration::visitAdditionalChildren): Ditto.
+        * bindings/js/JSCanvasRenderingContextCustom.cpp:
+        (WebCore::JSCanvasRenderingContext::visitAdditionalChildren): Ditto.
+        * bindings/js/JSCryptoKeyPairCustom.cpp:
+        (WebCore::JSCryptoKeyPair::visitAdditionalChildren): Ditto.
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::JSDOMWindow::visitAdditionalChildren): Ditto.
+        * bindings/js/JSMessageChannelCustom.cpp:
+        (WebCore::JSMessageChannel::visitAdditionalChildren): Ditto.
+        * bindings/js/JSMessagePortCustom.cpp:
+        (WebCore::JSMessagePort::visitAdditionalChildren): Ditto.
+        * bindings/js/JSNodeCustom.cpp:
+        (WebCore::JSNode::visitAdditionalChildren): Ditto.
+        * bindings/js/JSNodeFilterCustom.cpp:
+        (WebCore::JSNodeFilter::visitAdditionalChildren): Ditto.
+        * bindings/js/JSNodeIteratorCustom.cpp:
+        (WebCore::JSNodeIterator::visitAdditionalChildren): Ditto.
+        * bindings/js/JSSVGElementInstanceCustom.cpp:
+        (WebCore::JSSVGElementInstance::visitAdditionalChildren): Ditto.
+        * bindings/js/JSSharedWorkerCustom.cpp:
+        (WebCore::JSSharedWorker::visitAdditionalChildren): Ditto.
+        * bindings/js/JSStyleSheetCustom.cpp:
+        (WebCore::JSStyleSheet::visitAdditionalChildren): Ditto.
+        * bindings/js/JSTextTrackCueCustom.cpp:
+        (WebCore::JSTextTrackCue::visitAdditionalChildren): Ditto.
+        * bindings/js/JSTextTrackCustom.cpp:
+        (WebCore::JSTextTrack::visitAdditionalChildren): Ditto.
+        * bindings/js/JSTextTrackListCustom.cpp:
+        (WebCore::JSTextTrackList::visitAdditionalChildren): Ditto.
+        * bindings/js/JSTreeWalkerCustom.cpp:
+        (WebCore::JSTreeWalker::visitAdditionalChildren): Ditto.
+        * bindings/js/JSVideoTrackCustom.cpp:
+        (WebCore::JSVideoTrack::visitAdditionalChildren): Ditto.
+        * bindings/js/JSVideoTrackListCustom.cpp:
+        (WebCore::JSVideoTrackList::visitAdditionalChildren): Ditto.
+        * bindings/js/JSWebGLRenderingContextCustom.cpp:
+        (WebCore::JSWebGLRenderingContext::visitAdditionalChildren): Ditto.
+        * bindings/js/JSWorkerGlobalScopeCustom.cpp:
+        (WebCore::JSWorkerGlobalScope::visitAdditionalChildren): Ditto.
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::JSXMLHttpRequest::visitAdditionalChildren): Ditto.
+        * bindings/js/JSXPathResultCustom.cpp:
+        (WebCore::JSXPathResult::visitAdditionalChildren): Ditto.
+
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::visitChildren): Rewrote to use modern for loops.
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeader): Generate declaration of visitAdditionalChildren.
+        (GenerateImplementation): Generate call to visitAdditionalChildren.
+
 2014-04-24  Andreas Kling  <akling@apple.com>
 
         [iOS WebKit2] Enable optimization to mmap downloaded resources once they become file-backed.
index 4180d63..42f12f0 100644 (file)
 #include "config.h"
 #include "JSAttr.h"
 
-#include "Document.h"
 #include "Element.h"
-#include "HTMLNames.h"
-
-using namespace JSC;
 
 namespace WebCore {
 
-using namespace HTMLNames;
-
-void JSAttr::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSAttr::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSAttr* thisObject = jsCast<JSAttr*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    Base::visitChildren(thisObject, visitor);
-    Element* element = thisObject->impl().ownerElement();
-    if (!element)
-        return;
-    visitor.addOpaqueRoot(root(element));
+    if (Element* element = impl().ownerElement())
+        visitor.addOpaqueRoot(root(element));
 }
 
 } // namespace WebCore
index 7204c94..a3aaba6 100644 (file)
@@ -35,43 +35,34 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSAudioTrack::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSAudioTrack::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSAudioTrack* jsAudioTrack = jsCast<JSAudioTrack*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsAudioTrack, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsAudioTrack->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsAudioTrack, visitor);
-
-    AudioTrack& audioTrack = jsAudioTrack->impl();
-    visitor.addOpaqueRoot(root(&audioTrack));
+    visitor.addOpaqueRoot(root(&impl()));
 }
 
 void JSAudioTrack::setKind(ExecState* exec, JSValue value)
 {
-    UNUSED_PARAM(exec);
 #if ENABLE(MEDIA_SOURCE)
     const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
     if (exec->hadException())
         return;
     impl().setKind(nativeValue);
 #else
+    UNUSED_PARAM(exec);
     UNUSED_PARAM(value);
-    return;
 #endif
 }
 
 void JSAudioTrack::setLanguage(ExecState* exec, JSValue value)
 {
-    UNUSED_PARAM(exec);
 #if ENABLE(MEDIA_SOURCE)
     const String& nativeValue(value.isEmpty() ? String() : value.toString(exec)->value(exec));
     if (exec->hadException())
         return;
     impl().setLanguage(nativeValue);
 #else
+    UNUSED_PARAM(exec);
     UNUSED_PARAM(value);
-    return;
 #endif
 }
 
index 2a2a7c2..831e425 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 
 #if ENABLE(VIDEO_TRACK)
+
 #include "JSAudioTrackList.h"
 
 #include "Element.h"
@@ -35,17 +36,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSAudioTrackList::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSAudioTrackList::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSAudioTrackList* jsAudioTrackList = jsCast<JSAudioTrackList*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsAudioTrackList, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsAudioTrackList->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsAudioTrackList, visitor);
-
-    AudioTrackList& audioTrackList = jsAudioTrackList->impl();
-    visitor.addOpaqueRoot(root(audioTrackList.element()));
-    audioTrackList.visitJSEventListeners(visitor);
+    visitor.addOpaqueRoot(root(impl().element()));
 }
 
 } // namespace WebCore
index d039b7d..9e835c0 100644 (file)
@@ -55,14 +55,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSCSSRule::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSCSSRule::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSCSSRule* thisObject = jsCast<JSCSSRule*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-    visitor.addOpaqueRoot(root(&thisObject->impl()));
+    visitor.addOpaqueRoot(root(&impl()));
 }
 
 JSValue toJS(ExecState*, JSDOMGlobalObject* globalObject, CSSRule* rule)
index 7bc69bf..94577c2 100644 (file)
 #include <wtf/text/WTFString.h>
 
 using namespace JSC;
-using namespace WTF;
 
 namespace WebCore {
 
-void JSCSSStyleDeclaration::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSCSSStyleDeclaration::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSCSSStyleDeclaration* thisObject = jsCast<JSCSSStyleDeclaration*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-    visitor.addOpaqueRoot(root(&thisObject->impl()));
+    visitor.addOpaqueRoot(root(&impl()));
 }
 
 class CSSPropertyInfo {
@@ -65,8 +59,7 @@ public:
     bool hadPixelOrPosPrefix;
 };
 
-enum PropertyNamePrefix
-{
+enum PropertyNamePrefix {
     PropertyNamePrefixNone,
     PropertyNamePrefixCSS,
     PropertyNamePrefixPixel,
index b2a7fa3..3bd2af4 100644 (file)
 #include "HTMLCanvasElement.h"
 #include "JSCanvasRenderingContext2D.h"
 #include "JSNode.h"
+
 #if ENABLE(WEBGL)
-#include "WebGLRenderingContext.h"
 #include "JSWebGLRenderingContext.h"
+#include "WebGLRenderingContext.h"
 #endif
 
 using namespace JSC;
 
 namespace WebCore {
 
-void JSCanvasRenderingContext::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSCanvasRenderingContext::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSCanvasRenderingContext* thisObject = jsCast<JSCanvasRenderingContext*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.addOpaqueRoot(root(thisObject->impl().canvas()));
+    visitor.addOpaqueRoot(root(impl().canvas()));
 }
 
 JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject* globalObject, CanvasRenderingContext* object)
index 6806a0f..bcfe00c 100644 (file)
 
 #if ENABLE(SUBTLE_CRYPTO)
 
-using namespace JSC;
-
 namespace WebCore {
 
-void JSCryptoKeyPair::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSCryptoKeyPair::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSCryptoKeyPair* thisObject = jsCast<JSCryptoKeyPair*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    visitor.addOpaqueRoot(thisObject->m_impl->publicKey());
-    visitor.addOpaqueRoot(thisObject->m_impl->privateKey());
+    visitor.addOpaqueRoot(impl().publicKey());
+    visitor.addOpaqueRoot(impl().privateKey());
 }
 
 } // namespace WebCore
index c9573b8..f55fbef 100644 (file)
@@ -91,13 +91,11 @@ void JSDOMGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
     Base::visitChildren(thisObject, visitor);
 
-    JSDOMStructureMap::iterator end = thisObject->structures().end();
-    for (JSDOMStructureMap::iterator it = thisObject->structures().begin(); it != end; ++it)
-        visitor.append(&it->value);
+    for (auto& structure : thisObject->structures().values())
+        visitor.append(&structure);
 
-    JSDOMConstructorMap::iterator end2 = thisObject->constructors().end();
-    for (JSDOMConstructorMap::iterator it2 = thisObject->constructors().begin(); it2 != end2; ++it2)
-        visitor.append(&it2->value);
+    for (auto& constructor : thisObject->constructors().values())
+        visitor.append(&constructor);
 }
 
 void JSDOMGlobalObject::setCurrentEvent(Event* currentEvent)
index 94b75e1..6feda6f 100644 (file)
@@ -58,16 +58,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSDOMWindow::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSDOMWindow::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    thisObject->impl().visitJSEventListeners(visitor);
-    if (Frame* frame = thisObject->impl().frame())
+    if (Frame* frame = impl().frame())
         visitor.addOpaqueRoot(frame);
 }
 
index 3b2b261..f714f83 100644 (file)
 
 #include "JSMessageChannel.h"
 
-#include "MessageChannel.h"
-#include <runtime/Error.h>
-
-using namespace JSC;
-
 namespace WebCore {
 
-void JSMessageChannel::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSMessageChannel::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSMessageChannel* thisObject = jsCast<JSMessageChannel*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    if (MessagePort* port = thisObject->m_impl->port1())
+    if (MessagePort* port = impl().port1())
         visitor.addOpaqueRoot(port);
 
-    if (MessagePort* port = thisObject->m_impl->port2())
+    if (MessagePort* port = impl().port2())
         visitor.addOpaqueRoot(port);
 }
 
index 4deebee..11c1c4b 100644 (file)
@@ -43,19 +43,11 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSMessagePort::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSMessagePort::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSMessagePort* thisObject = jsCast<JSMessagePort*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
     // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext().
-    if (MessagePort* port = thisObject->m_impl->locallyEntangledPort())
+    if (MessagePort* port = impl().locallyEntangledPort())
         visitor.addOpaqueRoot(port);
-
-    thisObject->m_impl->visitJSEventListeners(visitor);
 }
 
 JSC::JSValue JSMessagePort::postMessage(JSC::ExecState* exec)
index d9c665d..d3624e1 100644 (file)
@@ -179,18 +179,9 @@ JSScope* JSNode::pushEventHandlerScope(ExecState* exec, JSScope* node) const
     return node;
 }
 
-void JSNode::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSNode::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSNode* thisObject = jsCast<JSNode*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    Node& node = thisObject->impl();
-    node.visitJSEventListeners(visitor);
-
-    visitor.addOpaqueRoot(root(node));
+    visitor.addOpaqueRoot(root(impl()));
 }
 
 static ALWAYS_INLINE JSValue createWrapperInline(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
index 123ff20..28c16c1 100644 (file)
 #include "config.h"
 #include "JSNodeFilter.h"
 
-#include "JSDOMWindowBase.h"
-#include "JSNode.h"
 #include "JSNodeFilterCondition.h"
-#include "NodeFilter.h"
-#include "JSDOMBinding.h"
-
-using namespace JSC;
 
 namespace WebCore {
 
-void JSNodeFilter::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSNodeFilter::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSNodeFilter* thisObject = jsCast<JSNodeFilter*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-    visitor.addOpaqueRoot(&thisObject->impl());
+    visitor.addOpaqueRoot(&impl());
 }
 
-PassRefPtr<NodeFilter> toNodeFilter(VM& vm, JSValue value)
+PassRefPtr<NodeFilter> toNodeFilter(JSC::VM& vm, JSC::JSValue value)
 {
     if (value.inherits(JSNodeFilter::info()))
-        return &jsCast<JSNodeFilter*>(asObject(value))->impl();
+        return &JSC::jsCast<JSNodeFilter*>(asObject(value))->impl();
 
     RefPtr<NodeFilter> result = NodeFilter::create();
     result->setCondition(JSNodeFilterCondition::create(vm, result.get(), value));
index 49cde01..97caa50 100644 (file)
 #include "config.h"
 #include "JSNodeIterator.h"
 
-#include "JSNode.h"
 #include "Node.h"
-#include "NodeFilter.h"
-#include "NodeIterator.h"
-
-using namespace JSC;
 
 namespace WebCore {
 
-void JSNodeIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSNodeIterator::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSNodeIterator* thisObject = jsCast<JSNodeIterator*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    if (NodeFilter* filter = thisObject->m_impl->filter())
+    if (NodeFilter* filter = impl().filter())
         visitor.addOpaqueRoot(filter);
 }
 
index 7e2e534..e66b710 100644 (file)
 #include "config.h"
 #include "JSSVGElementInstance.h"
 
-#include "JSEventTarget.h"
 #include "JSNodeCustom.h"
 
 namespace WebCore {
 
-void JSSVGElementInstance::visitChildren(JSC::JSCell* cell, JSC::SlotVisitor& visitor)
+void JSSVGElementInstance::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSSVGElementInstance* thisObject = JSC::jsCast<JSSVGElementInstance*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & JSC::OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    // Skip JSEventTarget::visitChildren because event listener registration is
-    // forwarded to the corresponding element.
-    JSEventTarget::Base::visitChildren(thisObject, visitor);
-    visitor.addOpaqueRoot(root(thisObject->impl().correspondingElement()));
+    visitor.addOpaqueRoot(root(impl().correspondingElement()));
 }
 
 } // namespace WebCore
index 2c27864..a0bd866 100644 (file)
@@ -44,15 +44,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSSharedWorker::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSSharedWorker::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSSharedWorker* thisObject = jsCast<JSSharedWorker*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    if (MessagePort* port = thisObject->impl().port())
+    if (MessagePort* port = impl().port())
         visitor.addOpaqueRoot(port);
 }
 
index 20a267f..0a69a2e 100644 (file)
 #include "config.h"
 #include "JSStyleSheet.h"
 
-#include "CSSStyleSheet.h"
-#include "Node.h"
 #include "JSCSSStyleSheet.h"
-#include "JSNode.h"
-
-using namespace JSC;
 
 namespace WebCore {
 
-void JSStyleSheet::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSStyleSheet::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSStyleSheet* thisObject = jsCast<JSStyleSheet*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-    visitor.addOpaqueRoot(root(&thisObject->impl()));
+    visitor.addOpaqueRoot(root(&impl()));
 }
 
-JSValue toJS(ExecState*, JSDOMGlobalObject* globalObject, StyleSheet* styleSheet)
+JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject* globalObject, StyleSheet* styleSheet)
 {
     if (!styleSheet)
-        return jsNull();
+        return JSC::jsNull();
 
-    JSObject* wrapper = getCachedWrapper(globalObject->world(), styleSheet);
-    if (wrapper)
+    if (JSC::JSObject* wrapper = getCachedWrapper(globalObject->world(), styleSheet))
         return wrapper;
 
     if (styleSheet->isCSSStyleSheet())
-        wrapper = CREATE_DOM_WRAPPER(globalObject, CSSStyleSheet, styleSheet);
-    else
-        wrapper = CREATE_DOM_WRAPPER(globalObject, StyleSheet, styleSheet);
+        return CREATE_DOM_WRAPPER(globalObject, CSSStyleSheet, styleSheet);
 
-    return wrapper;
+    return CREATE_DOM_WRAPPER(globalObject, StyleSheet, styleSheet);
 }
 
 } // namespace WebCore
index f75abf0..57f88b9 100644 (file)
@@ -27,8 +27,9 @@
 
 #if ENABLE(VIDEO_TRACK)
 
-#include "JSDataCue.h"
 #include "JSTextTrackCue.h"
+
+#include "JSDataCue.h"
 #include "JSTrackCustom.h"
 #include "JSVTTCue.h"
 #include "TextTrack.h"
@@ -81,20 +82,10 @@ JSValue toJS(ExecState*, JSDOMGlobalObject* globalObject, TextTrackCue* cue)
     }
 }
 
-void JSTextTrackCue::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSTextTrackCue::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSTextTrackCue* jsTextTrackCue = jsCast<JSTextTrackCue*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsTextTrackCue, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsTextTrackCue->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsTextTrackCue, visitor);
-
-    // Mark the cue's track root if it has one.
-    TextTrackCue& textTrackCue = jsTextTrackCue->impl();
-    if (TextTrack* textTrack = textTrackCue.track())
+    if (TextTrack* textTrack = impl().track())
         visitor.addOpaqueRoot(root(textTrack));
-    
-    textTrackCue.visitJSEventListeners(visitor);
 }
 
 } // namespace WebCore
index 5821970..bb96c20 100644 (file)
@@ -26,7 +26,9 @@
 #include "config.h"
 
 #if ENABLE(VIDEO_TRACK)
+
 #include "JSTextTrack.h"
+
 #include "JSTextTrackCueList.h"
 #include "JSTrackCustom.h"
 
@@ -34,18 +36,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSTextTrack::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSTextTrack::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSTextTrack* jsTextTrack = jsCast<JSTextTrack*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsTextTrack, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsTextTrack->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsTextTrack, visitor);
-
-    TextTrack& textTrack = jsTextTrack->impl();
-    visitor.addOpaqueRoot(root(&textTrack));
-
-    textTrack.visitJSEventListeners(visitor);
+    visitor.addOpaqueRoot(root(&impl()));
 }
 
 void JSTextTrack::setKind(ExecState* exec, JSValue value)
index ecb5905..e1b8c63 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 
 #if ENABLE(VIDEO_TRACK)
+
 #include "JSTextTrackList.h"
 
 #include "Element.h"
@@ -35,17 +36,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSTextTrackList::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSTextTrackList::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSTextTrackList* jsTextTrackList = jsCast<JSTextTrackList*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsTextTrackList, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsTextTrackList->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsTextTrackList, visitor);
-    
-    TextTrackList& textTrackList = jsTextTrackList->impl();
-    visitor.addOpaqueRoot(root(textTrackList.element()));
-    textTrackList.visitJSEventListeners(visitor);
+    visitor.addOpaqueRoot(root(impl().element()));
 }
     
 } // namespace WebCore
index 9f01659..05c5304 100644 (file)
 #include "config.h"
 #include "JSTreeWalker.h"
 
-#include "JSNode.h"
 #include "Node.h"
-#include "NodeFilter.h"
-#include "TreeWalker.h"
-
-using namespace JSC;
 
 namespace WebCore {
 
-void JSTreeWalker::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSTreeWalker::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSTreeWalker* thisObject = jsCast<JSTreeWalker*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    if (NodeFilter* filter = thisObject->m_impl->filter())
+    if (NodeFilter* filter = impl().filter())
         visitor.addOpaqueRoot(filter);
 }
 
index 3a4daa5..e7bcba2 100644 (file)
@@ -35,16 +35,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSVideoTrack::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSVideoTrack::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSVideoTrack* jsVideoTrack = jsCast<JSVideoTrack*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsVideoTrack, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsVideoTrack->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsVideoTrack, visitor);
-
-    VideoTrack& videoTrack = jsVideoTrack->impl();
-    visitor.addOpaqueRoot(root(&videoTrack));
+    visitor.addOpaqueRoot(root(&impl()));
 }
 
 void JSVideoTrack::setKind(ExecState* exec, JSValue value)
index 205107b..66d7bea 100644 (file)
 #include "config.h"
 
 #if ENABLE(VIDEO_TRACK)
+
 #include "JSVideoTrackList.h"
 
-#include "Element.h"
 #include "JSNodeCustom.h"
 
 using namespace JSC;
 
 namespace WebCore {
 
-void JSVideoTrackList::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSVideoTrackList::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSVideoTrackList* jsVideoTrackList = jsCast<JSVideoTrackList*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(jsVideoTrackList, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(jsVideoTrackList->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(jsVideoTrackList, visitor);
-
-    VideoTrackList& videoTrackList = jsVideoTrackList->impl();
-    visitor.addOpaqueRoot(root(videoTrackList.element()));
-    videoTrackList.visitJSEventListeners(visitor);
+    visitor.addOpaqueRoot(root(impl().element()));
 }
 
 } // namespace WebCore
index 082c5cf..c2fe16e 100644 (file)
@@ -242,14 +242,9 @@ static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, WebGLExten
     return jsNull();
 }
 
-void JSWebGLRenderingContext::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSWebGLRenderingContext* thisObject = jsCast<JSWebGLRenderingContext*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-    visitor.addOpaqueRoot(&thisObject->impl());
+void JSWebGLRenderingContext::visitAdditionalChildren(SlotVisitor& visitor)
+{
+    visitor.addOpaqueRoot(&impl());
 }
 
 JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec)
index 6977196..8e612a4 100644 (file)
@@ -51,20 +51,12 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSWorkerGlobalScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSWorkerGlobalScope::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSWorkerGlobalScope* thisObject = jsCast<JSWorkerGlobalScope*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    if (WorkerLocation* location = thisObject->impl().optionalLocation())
+    if (WorkerLocation* location = impl().optionalLocation())
         visitor.addOpaqueRoot(location);
-    if (WorkerNavigator* navigator = thisObject->impl().optionalNavigator())
+    if (WorkerNavigator* navigator = impl().optionalNavigator())
         visitor.addOpaqueRoot(navigator);
-
-    thisObject->impl().visitJSEventListeners(visitor);
 }
 
 bool JSWorkerGlobalScope::getOwnPropertySlotDelegate(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
index a8b2c2b..c9edcfa 100644 (file)
@@ -56,30 +56,22 @@ using namespace JSC;
 
 namespace WebCore {
 
-void JSXMLHttpRequest::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSXMLHttpRequest::visitAdditionalChildren(SlotVisitor& visitor)
 {
-    JSXMLHttpRequest* thisObject = jsCast<JSXMLHttpRequest*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    if (XMLHttpRequestUpload* upload = thisObject->m_impl->optionalUpload())
+    if (XMLHttpRequestUpload* upload = impl().optionalUpload())
         visitor.addOpaqueRoot(upload);
 
-    if (Document* responseDocument = thisObject->m_impl->optionalResponseXML())
+    if (Document* responseDocument = impl().optionalResponseXML())
         visitor.addOpaqueRoot(responseDocument);
 
-    if (ArrayBuffer* responseArrayBuffer = thisObject->m_impl->optionalResponseArrayBuffer())
+    if (ArrayBuffer* responseArrayBuffer = impl().optionalResponseArrayBuffer())
         visitor.addOpaqueRoot(responseArrayBuffer);
 
-    if (Blob* responseBlob = thisObject->m_impl->optionalResponseBlob())
+    if (Blob* responseBlob = impl().optionalResponseBlob())
         visitor.addOpaqueRoot(responseBlob);
 
-    if (thisObject->m_response)
-        visitor.append(&thisObject->m_response);
-
-    thisObject->m_impl->visitJSEventListeners(visitor);
+    if (m_response)
+        visitor.append(&m_response);
 }
 
 // Custom functions
index 35ba892..2416d67 100644 (file)
 #include "config.h"
 #include "JSXPathResult.h"
 
-#include "JSDOMBinding.h"
 #include "JSNodeCustom.h"
-#include "XPathResult.h"
 #include "XPathValue.h"
 
-using namespace JSC;
-
 namespace WebCore {
 
-void JSXPathResult::visitChildren(JSCell* cell, SlotVisitor& visitor)
+void JSXPathResult::visitAdditionalChildren(JSC::SlotVisitor& visitor)
 {
-    JSXPathResult* thisObject = jsCast<JSXPathResult*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-    Base::visitChildren(thisObject, visitor);
-
-    const XPath::Value& xpathValue = thisObject->impl().value();
-    if (xpathValue.isNodeSet()) {
-        const XPath::NodeSet& nodesToMark = xpathValue.toNodeSet();
-        for (size_t i = 0; i < nodesToMark.size(); ++i) {
-            Node* node = nodesToMark[i];
-            visitor.addOpaqueRoot(root(node));
-        }
+    auto& value = impl().value();
+    if (value.isNodeSet()) {
+        for (auto& node : value.toNodeSet())
+            visitor.addOpaqueRoot(root(node.get()));
     }
 }
 
index fb12a4d..c070bba 100644 (file)
@@ -766,9 +766,9 @@ sub InstanceNeedsVisitChildren
 {
     my $interface = shift;
     return $interface->extendedAttributes->{"JSCustomMarkFunction"}
-    || $interface->extendedAttributes->{"EventTarget"}
-    || $interface->name eq "EventTarget"
-    || $interface->extendedAttributes->{"ReportExtraMemoryCost"};
+        || $interface->extendedAttributes->{"EventTarget"}
+        || $interface->name eq "EventTarget"
+        || $interface->extendedAttributes->{"ReportExtraMemoryCost"};
 }
 
 sub GenerateHeader
@@ -1017,7 +1017,9 @@ sub GenerateHeader
 
     # visit function
     if ($needsVisitChildren) {
-        push(@headerContent, "    static void visitChildren(JSCell*, JSC::SlotVisitor&);\n\n");
+        push(@headerContent, "    static void visitChildren(JSCell*, JSC::SlotVisitor&);\n");
+        push(@headerContent, "    void visitAdditionalChildren(JSC::SlotVisitor&);\n") if $interface->extendedAttributes->{"JSCustomMarkFunction"};
+        push(@headerContent, "\n");
         $structureFlags{"JSC::OverridesVisitChildren"} = 1;
     }
 
@@ -2776,7 +2778,7 @@ sub GenerateImplementation
 
     }
 
-    if ($needsVisitChildren && !$interface->extendedAttributes->{"JSCustomMarkFunction"}) {
+    if ($needsVisitChildren) {
         push(@implContent, "void ${className}::visitChildren(JSCell* cell, SlotVisitor& visitor)\n");
         push(@implContent, "{\n");
         push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(cell);\n");
@@ -2787,6 +2789,7 @@ sub GenerateImplementation
         if ($interface->extendedAttributes->{"EventTarget"} || $interface->name eq "EventTarget") {
             push(@implContent, "    thisObject->impl().visitJSEventListeners(visitor);\n");
         }
+        push(@implContent, "    thisObject->visitAdditionalChildren(visitor);\n") if $interface->extendedAttributes->{"JSCustomMarkFunction"};
         if ($interface->extendedAttributes->{"ReportExtraMemoryCost"}) {
             push(@implContent, "    visitor.reportExtraMemoryUsage(cell, thisObject->impl().memoryCost());\n");
         }