Changeset 235271 in webkit


Ignore:
Timestamp:
Aug 23, 2018, 9:10:31 PM (7 years ago)
Author:
Simon Fraser
Message:

Add support for dumping GC heap snapshots, and a viewer
https://bugs.webkit.org/show_bug.cgi?id=186416

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

Make a way to dump information about the GC heap that is useful for looking for leaked
or abandoned objects. This dump is obtained (on Apple platforms) via:

notifyutil -p com.apple.WebKit.dumpGCHeap

which writes a JSON file to /tmp which can then be loaded into the viewer in Tools/GCHeapInspector.

This leverages the heap snapshot used by Web Inspector, adding an alternate format for
the snapshot JSON that adds additional data about objects and why they are GC roots.

SlotVisitor maintains a RootMarkReason (via SetRootMarkReasonScope) that allows
the HeapSnapshotBuilder to keep track of why a JSCell was treated as a GC root. For
objects visited via opaque roots, we record the reason why via a new out param to
isReachableFromOpaqueRoots().

HeapSnapshotBuilder is enhanced to produce GCDebuggingSnapshot JSON output. This contains
additional information including the address of the JSCell* and the wrapped object (for
JSDOMWrappers), the root reasons, and for some objects like JSDocument a label which can
be the document URL.

GCDebuggingSnapshots are always full snapshots (previous snapshots are not kept around).

  • API/JSAPIWrapperObject.mm:

(JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):

  • API/JSManagedValue.mm:

(JSManagedValueHandleOwner::isReachableFromOpaqueRoots):

  • API/glib/JSAPIWrapperObjectGLib.cpp:

(JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):

  • CMakeLists.txt:
  • heap/ConservativeRoots.h:

(JSC::ConservativeRoots::size const):
(JSC::ConservativeRoots::size): Deleted.

  • heap/Heap.cpp:

(JSC::Heap::addCoreConstraints):

  • heap/HeapSnapshotBuilder.cpp:

(JSC::HeapSnapshotBuilder::getNextObjectIdentifier):
(JSC::HeapSnapshotBuilder::HeapSnapshotBuilder):
(JSC::HeapSnapshotBuilder::~HeapSnapshotBuilder):
(JSC::HeapSnapshotBuilder::buildSnapshot):
(JSC::HeapSnapshotBuilder::appendNode):
(JSC::HeapSnapshotBuilder::appendEdge):
(JSC::HeapSnapshotBuilder::setOpaqueRootReachabilityReasonForCell):
(JSC::HeapSnapshotBuilder::setWrappedObjectForCell):
(JSC::HeapSnapshotBuilder::previousSnapshotHasNodeForCell):
(JSC::snapshotTypeToString):
(JSC::rootTypeToString):
(JSC::HeapSnapshotBuilder::setLabelForCell):
(JSC::HeapSnapshotBuilder::descriptionForCell const):
(JSC::HeapSnapshotBuilder::json):
(JSC::HeapSnapshotBuilder::hasExistingNodeForCell): Deleted.

  • heap/HeapSnapshotBuilder.h:
  • heap/SlotVisitor.cpp:

(JSC::SlotVisitor::appendSlow):

  • heap/SlotVisitor.h:

(JSC::SlotVisitor::heapSnapshotBuilder const):
(JSC::SlotVisitor::rootMarkReason const):
(JSC::SlotVisitor::setRootMarkReason):
(JSC::SetRootMarkReasonScope::SetRootMarkReasonScope):
(JSC::SetRootMarkReasonScope::~SetRootMarkReasonScope):

  • heap/WeakBlock.cpp:

(JSC::WeakBlock::specializedVisit):

  • heap/WeakHandleOwner.cpp:

(JSC::WeakHandleOwner::isReachableFromOpaqueRoots):

  • heap/WeakHandleOwner.h:
  • runtime/SimpleTypedArrayController.cpp:

(JSC::SimpleTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots):

  • runtime/SimpleTypedArrayController.h:
  • tools/JSDollarVM.cpp:

Source/WebCore:

Make a way to dump information about the GC heap that is useful for looking for leaked
or abandoned objects. This dump is obtained (on Apple platforms) via:

notifyutil -p com.apple.WebKit.dumpGCHeap

which writes a JSON file to /tmp which can then be loaded into the viewer in Tools/GCHeapInspector.

This leverages the heap snapshot used by Web Inspector, adding an alternate format for
the snapshot JSON that adds additional data about objects and why they are GC roots.

The generated bindings code is changed to include the output root reason from isReachableFromOpaqueRoots(),
and to implement heapSnapshot() which provides the address of the wrapped object. A new IDL attribute,
CustomHeapSnapshot, is used to allow custom heapSnapshot() implementations for classes like JSDocument
that need to decorate the heap snapshot cell data with things like the document URL.

GCController registers a notifyutil callback which gathers the debug heap snapshot, and dumps it
to a file in /tmp. The file path is printed out to the system log.

  • bindings/js/DOMGCOutputConstraint.cpp:

(WebCore::DOMGCOutputConstraint::executeImpl):

  • bindings/js/GCController.cpp:

(WebCore::GCController::GCController):
(WebCore::GCController::dumpHeap):

  • bindings/js/GCController.h:
  • bindings/js/JSCSSRuleListCustom.cpp:

(WebCore::JSCSSRuleListOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSCallbackData.cpp:

(WebCore::JSCallbackDataWeak::WeakOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSCallbackData.h:
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp:

(WebCore::JSCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSDOMWindowCustom.cpp:

(WebCore::JSDOMWindow::getOwnPropertySlot):
(WebCore::JSDOMWindow::heapSnapshot):

  • bindings/js/JSDeprecatedCSSOMValueCustom.cpp:

(WebCore::JSDeprecatedCSSOMValueOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSDocumentCustom.cpp:

(WebCore::JSDocument::heapSnapshot):

  • bindings/js/JSMicrotaskCallback.h:

(WebCore::JSMicrotaskCallback::call):

  • bindings/js/JSMutationObserverCustom.cpp:

(WebCore::JSMutationObserverOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSNavigatorCustom.cpp:

(WebCore::JSNavigator::visitAdditionalChildren):

  • bindings/js/JSNodeCustom.cpp:

(WebCore::isReachableFromDOM):
(WebCore::JSNodeOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSNodeListCustom.cpp:

(WebCore::JSNodeListOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSOffscreenCanvasRenderingContext2DCustom.cpp:

(WebCore::JSOffscreenCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSPerformanceObserverCustom.cpp:

(WebCore::JSPerformanceObserverOwner::isReachableFromOpaqueRoots):

  • bindings/js/JSPopStateEventCustom.cpp:
  • bindings/js/JSTextTrackCueCustom.cpp:

(WebCore::JSTextTrackCueOwner::isReachableFromOpaqueRoots):

  • bindings/js/WebCoreTypedArrayController.cpp:

(WebCore::WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots):

  • bindings/js/WebCoreTypedArrayController.h:
  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateHeader):
(GenerateImplementation):

  • bindings/scripts/IDLAttributes.json:
  • bindings/scripts/test/JS/JSInterfaceName.cpp:

(WebCore::JSInterfaceName::heapSnapshot):
(WebCore::JSInterfaceNameOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSInterfaceName.h:
  • bindings/scripts/test/JS/JSMapLike.cpp:

(WebCore::JSMapLike::heapSnapshot):
(WebCore::JSMapLikeOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSMapLike.h:
  • bindings/scripts/test/JS/JSReadOnlyMapLike.cpp:

(WebCore::JSReadOnlyMapLike::heapSnapshot):
(WebCore::JSReadOnlyMapLikeOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSReadOnlyMapLike.h:
  • bindings/scripts/test/JS/JSTestActiveDOMObject.cpp:

(WebCore::JSTestActiveDOMObject::heapSnapshot):
(WebCore::JSTestActiveDOMObjectOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestActiveDOMObject.h:
  • bindings/scripts/test/JS/JSTestCEReactions.cpp:

(WebCore::JSTestCEReactions::heapSnapshot):
(WebCore::JSTestCEReactionsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestCEReactions.h:
  • bindings/scripts/test/JS/JSTestCEReactionsStringifier.cpp:

(WebCore::JSTestCEReactionsStringifier::heapSnapshot):
(WebCore::JSTestCEReactionsStringifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestCEReactionsStringifier.h:
  • bindings/scripts/test/JS/JSTestCallTracer.cpp:

(WebCore::JSTestCallTracer::heapSnapshot):
(WebCore::JSTestCallTracerOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestCallTracer.h:
  • bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.cpp:

(WebCore::JSTestClassWithJSBuiltinConstructor::heapSnapshot):
(WebCore::JSTestClassWithJSBuiltinConstructorOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.h:
  • bindings/scripts/test/JS/JSTestCustomConstructorWithNoInterfaceObject.cpp:

(WebCore::JSTestCustomConstructorWithNoInterfaceObject::heapSnapshot):
(WebCore::JSTestCustomConstructorWithNoInterfaceObjectOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestCustomConstructorWithNoInterfaceObject.h:
  • bindings/scripts/test/JS/JSTestDOMJIT.cpp:

(WebCore::JSTestDOMJIT::heapSnapshot):

  • bindings/scripts/test/JS/JSTestDOMJIT.h:
  • bindings/scripts/test/JS/JSTestEnabledBySetting.cpp:

(WebCore::JSTestEnabledBySetting::heapSnapshot):
(WebCore::JSTestEnabledBySettingOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestEnabledBySetting.h:
  • bindings/scripts/test/JS/JSTestEventConstructor.cpp:

(WebCore::JSTestEventConstructor::heapSnapshot):

  • bindings/scripts/test/JS/JSTestEventConstructor.h:
  • bindings/scripts/test/JS/JSTestEventTarget.cpp:

(WebCore::JSTestEventTarget::heapSnapshot):

  • bindings/scripts/test/JS/JSTestEventTarget.h:
  • bindings/scripts/test/JS/JSTestException.cpp:

(WebCore::JSTestException::heapSnapshot):
(WebCore::JSTestExceptionOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestException.h:
  • bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp:

(WebCore::JSTestGenerateIsReachable::heapSnapshot):
(WebCore::JSTestGenerateIsReachableOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestGenerateIsReachable.h:
  • bindings/scripts/test/JS/JSTestGlobalObject.cpp:

(WebCore::JSTestGlobalObject::heapSnapshot):
(WebCore::JSTestGlobalObjectOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestGlobalObject.h:
  • bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.cpp:

(WebCore::JSTestIndexedSetterNoIdentifier::heapSnapshot):
(WebCore::JSTestIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.h:
  • bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.cpp:

(WebCore::JSTestIndexedSetterThrowingException::heapSnapshot):
(WebCore::JSTestIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.h:
  • bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.cpp:

(WebCore::JSTestIndexedSetterWithIdentifier::heapSnapshot):
(WebCore::JSTestIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.h:
  • bindings/scripts/test/JS/JSTestInterface.cpp:

(WebCore::JSTestInterface::heapSnapshot):
(WebCore::JSTestInterfaceOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestInterface.h:
  • bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.cpp:

(WebCore::JSTestInterfaceLeadingUnderscore::heapSnapshot):
(WebCore::JSTestInterfaceLeadingUnderscoreOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.h:
  • bindings/scripts/test/JS/JSTestIterable.cpp:

(WebCore::JSTestIterable::heapSnapshot):
(WebCore::JSTestIterableOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestIterable.h:
  • bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp:

(WebCore::JSTestMediaQueryListListener::heapSnapshot):
(WebCore::JSTestMediaQueryListListenerOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestMediaQueryListListener.h:
  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp:

(WebCore::JSTestNamedAndIndexedSetterNoIdentifier::heapSnapshot):
(WebCore::JSTestNamedAndIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp:

(WebCore::JSTestNamedAndIndexedSetterThrowingException::heapSnapshot):
(WebCore::JSTestNamedAndIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.h:
  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp:

(WebCore::JSTestNamedAndIndexedSetterWithIdentifier::heapSnapshot):
(WebCore::JSTestNamedAndIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedConstructor.cpp:

(WebCore::JSTestNamedConstructor::heapSnapshot):
(WebCore::JSTestNamedConstructorOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedConstructor.h:
  • bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.cpp:

(WebCore::JSTestNamedDeleterNoIdentifier::heapSnapshot):
(WebCore::JSTestNamedDeleterNoIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.cpp:

(WebCore::JSTestNamedDeleterThrowingException::heapSnapshot):
(WebCore::JSTestNamedDeleterThrowingExceptionOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.h:
  • bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.cpp:

(WebCore::JSTestNamedDeleterWithIdentifier::heapSnapshot):
(WebCore::JSTestNamedDeleterWithIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.cpp:

(WebCore::JSTestNamedDeleterWithIndexedGetter::heapSnapshot):
(WebCore::JSTestNamedDeleterWithIndexedGetterOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.h:
  • bindings/scripts/test/JS/JSTestNamedGetterCallWith.cpp:

(WebCore::JSTestNamedGetterCallWith::heapSnapshot):
(WebCore::JSTestNamedGetterCallWithOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedGetterCallWith.h:
  • bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.cpp:

(WebCore::JSTestNamedGetterNoIdentifier::heapSnapshot):
(WebCore::JSTestNamedGetterNoIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.cpp:

(WebCore::JSTestNamedGetterWithIdentifier::heapSnapshot):
(WebCore::JSTestNamedGetterWithIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp:

(WebCore::JSTestNamedSetterNoIdentifier::heapSnapshot):
(WebCore::JSTestNamedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp:

(WebCore::JSTestNamedSetterThrowingException::heapSnapshot):
(WebCore::JSTestNamedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterThrowingException.h:
  • bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp:

(WebCore::JSTestNamedSetterWithIdentifier::heapSnapshot):
(WebCore::JSTestNamedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.h:
  • bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp:

(WebCore::JSTestNamedSetterWithIndexedGetter::heapSnapshot):
(WebCore::JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h:
  • bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp:

(WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::heapSnapshot):
(WebCore::JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h:
  • bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.cpp:

(WebCore::JSTestNamedSetterWithOverrideBuiltins::heapSnapshot):
(WebCore::JSTestNamedSetterWithOverrideBuiltinsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.h:
  • bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp:

(WebCore::JSTestNamedSetterWithUnforgableProperties::heapSnapshot):
(WebCore::JSTestNamedSetterWithUnforgablePropertiesOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.h:
  • bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.cpp:

(WebCore::JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins::heapSnapshot):
(WebCore::JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.h:
  • bindings/scripts/test/JS/JSTestNode.cpp:

(WebCore::JSTestNode::heapSnapshot):

  • bindings/scripts/test/JS/JSTestNode.h:
  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::JSTestObj::heapSnapshot):
(WebCore::JSTestObjOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestObj.h:
  • bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:

(WebCore::JSTestOverloadedConstructors::heapSnapshot):
(WebCore::JSTestOverloadedConstructorsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestOverloadedConstructors.h:
  • bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.cpp:

(WebCore::JSTestOverloadedConstructorsWithSequence::heapSnapshot):
(WebCore::JSTestOverloadedConstructorsWithSequenceOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.h:
  • bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp:

(WebCore::JSTestOverrideBuiltins::heapSnapshot):
(WebCore::JSTestOverrideBuiltinsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestOverrideBuiltins.h:
  • bindings/scripts/test/JS/JSTestPluginInterface.cpp:

(WebCore::JSTestPluginInterface::heapSnapshot):
(WebCore::JSTestPluginInterfaceOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestPluginInterface.h:
  • bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp:

(WebCore::JSTestPromiseRejectionEvent::heapSnapshot):

  • bindings/scripts/test/JS/JSTestPromiseRejectionEvent.h:
  • bindings/scripts/test/JS/JSTestSerialization.cpp:

(WebCore::JSTestSerialization::heapSnapshot):
(WebCore::JSTestSerializationOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestSerialization.h:
  • bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.cpp:

(WebCore::JSTestSerializationIndirectInheritance::heapSnapshot):

  • bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.h:
  • bindings/scripts/test/JS/JSTestSerializationInherit.cpp:

(WebCore::JSTestSerializationInherit::heapSnapshot):

  • bindings/scripts/test/JS/JSTestSerializationInherit.h:
  • bindings/scripts/test/JS/JSTestSerializationInheritFinal.cpp:

(WebCore::JSTestSerializationInheritFinal::heapSnapshot):

  • bindings/scripts/test/JS/JSTestSerializationInheritFinal.h:
  • bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:

(WebCore::JSTestSerializedScriptValueInterface::heapSnapshot):
(WebCore::JSTestSerializedScriptValueInterfaceOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h:
  • bindings/scripts/test/JS/JSTestStringifier.cpp:

(WebCore::JSTestStringifier::heapSnapshot):
(WebCore::JSTestStringifierOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifier.h:
  • bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.cpp:

(WebCore::JSTestStringifierAnonymousOperation::heapSnapshot):
(WebCore::JSTestStringifierAnonymousOperationOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.h:
  • bindings/scripts/test/JS/JSTestStringifierNamedOperation.cpp:

(WebCore::JSTestStringifierNamedOperation::heapSnapshot):
(WebCore::JSTestStringifierNamedOperationOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifierNamedOperation.h:
  • bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.cpp:

(WebCore::JSTestStringifierOperationImplementedAs::heapSnapshot):
(WebCore::JSTestStringifierOperationImplementedAsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.h:
  • bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.cpp:

(WebCore::JSTestStringifierOperationNamedToString::heapSnapshot):
(WebCore::JSTestStringifierOperationNamedToStringOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.h:
  • bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.cpp:

(WebCore::JSTestStringifierReadOnlyAttribute::heapSnapshot):
(WebCore::JSTestStringifierReadOnlyAttributeOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.h:
  • bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.cpp:

(WebCore::JSTestStringifierReadWriteAttribute::heapSnapshot):
(WebCore::JSTestStringifierReadWriteAttributeOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.h:
  • bindings/scripts/test/JS/JSTestTypedefs.cpp:

(WebCore::JSTestTypedefs::heapSnapshot):
(WebCore::JSTestTypedefsOwner::isReachableFromOpaqueRoots):

  • bindings/scripts/test/JS/JSTestTypedefs.h:
  • dom/Document.idl:
  • page/DOMWindow.idl:

Source/WebInspectorUI:

Make a way to dump information about the GC heap that is useful for looking for leaked
or abandoned objects. This dump is obtained (on Apple platforms) via:

notifyutil -p com.apple.WebKit.dumpGCHeap

which writes a JSON file to /tmp which can then be loaded into the viewer in Tools/GCHeapInspector.

This leverages the heap snapshot used by Web Inspector, adding an alternate format for
the snapshot JSON that adds additional data about objects and why they are GC roots.

The generated bindings code is changed to include the output root reason from isReachableFromOpaqueRoots(),
and to implement heapSnapshot() which provides the address of the wrapped object. A new IDL attribute,
CustomHeapSnapshot, is used to allow custom heapSnapshot() implementations for classes like JSDocument
that need to decorate the heap snapshot cell data with things like the document URL.

GCController registers a notifyutil callback which gathers the debug heap snapshot, and dumps it
to a file in /tmp. The file path is printed out to the system log.

  • UserInterface/Workers/HeapSnapshot/HeapSnapshot.js:

(HeapSnapshot):

Tools:

Add a viewer for GC heap snapshots. A snapshot JSON file can be dragged into this
page for inspection (or set via the 'filename' URL parameter).

For now, this page shows all objects, all roots, and the shortest path from a root
to all HTMLDocuments and Windows.

  • GCHeapInspector/gc-heap-inspector.html: Added.
  • GCHeapInspector/heap-analysis/HeapSnapshot.js: Copied from Source/WebInspectorUI/UserInterface/Workers/HeapSnapshot/HeapSnapshot.js.
  • GCHeapInspector/script/interface.js: Added.
Location:
trunk
Files:
5 added
170 edited
1 copied

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/Source/JavaScriptCore/API/JSAPIWrapperObject.mm

    r226752 r235271  
    3838public:
    3939    void finalize(JSC::Handle<JSC::Unknown>, void*) override;
    40     bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&) override;
     40    bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**) override;
    4141};
    4242
     
    5757}
    5858
    59 bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
     59bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor, const char**)
    6060{
    6161    JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast<JSC::JSAPIWrapperObject*>(handle.get().asCell());
  • TabularUnified trunk/Source/JavaScriptCore/API/JSManagedValue.mm

    r233409 r235271  
    4444public:
    4545    void finalize(JSC::Handle<JSC::Unknown>, void* context) override;
    46     bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&) override;
     46    bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**) override;
    4747};
    4848
     
    183183@end
    184184
    185 bool JSManagedValueHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor& visitor)
     185bool JSManagedValueHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor& visitor, const char** reason)
    186186{
     187    if (UNLIKELY(reason))
     188        *reason = "JSManagedValue is opaque root";
    187189    JSManagedValue *managedValue = (__bridge JSManagedValue *)context;
    188190    return visitor.containsOpaqueRoot((__bridge void*)managedValue);
  • TabularUnified trunk/Source/JavaScriptCore/API/glib/JSAPIWrapperObjectGLib.cpp

    r229798 r235271  
    3737public:
    3838    void finalize(JSC::Handle<JSC::Unknown>, void*) override;
    39     bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&) override;
     39    bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**) override;
    4040};
    4141
     
    5656}
    5757
    58 bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
     58bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor, const char**)
    5959{
    6060    JSC::JSAPIWrapperObject* wrapperObject = JSC::jsCast<JSC::JSAPIWrapperObject*>(handle.get().asCell());
  • TabularUnified trunk/Source/JavaScriptCore/CMakeLists.txt

    r234491 r235271  
    535535    heap/HeapInlines.h
    536536    heap/HeapObserver.h
     537    heap/HeapSnapshotBuilder.h
    537538    heap/IncrementalSweeper.h
    538539    heap/IsoCellSet.h
  • TabularUnified trunk/Source/JavaScriptCore/ChangeLog

    r235261 r235271  
     12018-08-23  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add support for dumping GC heap snapshots, and a viewer
     4        https://bugs.webkit.org/show_bug.cgi?id=186416
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Make a way to dump information about the GC heap that is useful for looking for leaked
     9        or abandoned objects. This dump is obtained (on Apple platforms) via:
     10            notifyutil -p com.apple.WebKit.dumpGCHeap
     11        which writes a JSON file to /tmp which can then be loaded into the viewer in Tools/GCHeapInspector.
     12       
     13        This leverages the heap snapshot used by Web Inspector, adding an alternate format for
     14        the snapshot JSON that adds additional data about objects and why they are GC roots.
     15
     16        SlotVisitor maintains a RootMarkReason (via SetRootMarkReasonScope) that allows
     17        the HeapSnapshotBuilder to keep track of why a JSCell was treated as a GC root. For
     18        objects visited via opaque roots, we record the reason why via a new out param to
     19        isReachableFromOpaqueRoots().
     20
     21        HeapSnapshotBuilder is enhanced to produce GCDebuggingSnapshot JSON output. This contains
     22        additional information including the address of the JSCell* and the wrapped object (for
     23        JSDOMWrappers), the root reasons, and for some objects like JSDocument a label which can
     24        be the document URL.
     25
     26        GCDebuggingSnapshots are always full snapshots (previous snapshots are not kept around).
     27
     28        * API/JSAPIWrapperObject.mm:
     29        (JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
     30        * API/JSManagedValue.mm:
     31        (JSManagedValueHandleOwner::isReachableFromOpaqueRoots):
     32        * API/glib/JSAPIWrapperObjectGLib.cpp:
     33        (JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots):
     34        * CMakeLists.txt:
     35        * heap/ConservativeRoots.h:
     36        (JSC::ConservativeRoots::size const):
     37        (JSC::ConservativeRoots::size): Deleted.
     38        * heap/Heap.cpp:
     39        (JSC::Heap::addCoreConstraints):
     40        * heap/HeapSnapshotBuilder.cpp:
     41        (JSC::HeapSnapshotBuilder::getNextObjectIdentifier):
     42        (JSC::HeapSnapshotBuilder::HeapSnapshotBuilder):
     43        (JSC::HeapSnapshotBuilder::~HeapSnapshotBuilder):
     44        (JSC::HeapSnapshotBuilder::buildSnapshot):
     45        (JSC::HeapSnapshotBuilder::appendNode):
     46        (JSC::HeapSnapshotBuilder::appendEdge):
     47        (JSC::HeapSnapshotBuilder::setOpaqueRootReachabilityReasonForCell):
     48        (JSC::HeapSnapshotBuilder::setWrappedObjectForCell):
     49        (JSC::HeapSnapshotBuilder::previousSnapshotHasNodeForCell):
     50        (JSC::snapshotTypeToString):
     51        (JSC::rootTypeToString):
     52        (JSC::HeapSnapshotBuilder::setLabelForCell):
     53        (JSC::HeapSnapshotBuilder::descriptionForCell const):
     54        (JSC::HeapSnapshotBuilder::json):
     55        (JSC::HeapSnapshotBuilder::hasExistingNodeForCell): Deleted.
     56        * heap/HeapSnapshotBuilder.h:
     57        * heap/SlotVisitor.cpp:
     58        (JSC::SlotVisitor::appendSlow):
     59        * heap/SlotVisitor.h:
     60        (JSC::SlotVisitor::heapSnapshotBuilder const):
     61        (JSC::SlotVisitor::rootMarkReason const):
     62        (JSC::SlotVisitor::setRootMarkReason):
     63        (JSC::SetRootMarkReasonScope::SetRootMarkReasonScope):
     64        (JSC::SetRootMarkReasonScope::~SetRootMarkReasonScope):
     65        * heap/WeakBlock.cpp:
     66        (JSC::WeakBlock::specializedVisit):
     67        * heap/WeakHandleOwner.cpp:
     68        (JSC::WeakHandleOwner::isReachableFromOpaqueRoots):
     69        * heap/WeakHandleOwner.h:
     70        * runtime/SimpleTypedArrayController.cpp:
     71        (JSC::SimpleTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots):
     72        * runtime/SimpleTypedArrayController.h:
     73        * tools/JSDollarVM.cpp:
     74
    1752018-08-23  Saam barati  <sbarati@apple.com>
    276
  • TabularUnified trunk/Source/JavaScriptCore/heap/ConservativeRoots.h

    r226783 r235271  
    4242    void add(void* begin, void* end, JITStubRoutineSet&, CodeBlockSet&);
    4343   
    44     size_t size();
     44    size_t size() const;
    4545    HeapCell** roots();
    4646
     
    6464};
    6565
    66 inline size_t ConservativeRoots::size()
     66inline size_t ConservativeRoots::size() const
    6767{
    6868    return m_size;
  • TabularUnified trunk/Source/JavaScriptCore/heap/Heap.cpp

    r235261 r235271  
    26422642            TimingScope preConvergenceTimingScope(*this, "Constraint: conservative scan");
    26432643            m_objectSpace.prepareForConservativeScan();
     2644
    26442645            ConservativeRoots conservativeRoots(*this);
    26452646            SuperSamplerScope superSamplerScope(false);
     2647
    26462648            gatherStackRoots(conservativeRoots);
    26472649            gatherJSStackRoots(conservativeRoots);
    26482650            gatherScratchBufferRoots(conservativeRoots);
     2651
     2652            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::ConservativeScan);
    26492653            slotVisitor.append(conservativeRoots);
    26502654           
     
    26562660        "Msr", "Misc Small Roots",
    26572661        [this] (SlotVisitor& slotVisitor) {
     2662
    26582663#if JSC_OBJC_API_ENABLED
    26592664            scanExternalRememberedSet(*m_vm, slotVisitor);
    26602665#endif
    2661 
    2662             if (m_vm->smallStrings.needsToBeVisited(*m_collectionScope))
     2666            if (m_vm->smallStrings.needsToBeVisited(*m_collectionScope)) {
     2667                SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::StrongReferences);
    26632668                m_vm->smallStrings.visitStrongReferences(slotVisitor);
     2669            }
    26642670           
    2665             for (auto& pair : m_protectedValues)
    2666                 slotVisitor.appendUnbarriered(pair.key);
     2671            {
     2672                SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::ProtectedValues);
     2673                for (auto& pair : m_protectedValues)
     2674                    slotVisitor.appendUnbarriered(pair.key);
     2675            }
    26672676           
    2668             if (m_markListSet && m_markListSet->size())
     2677            if (m_markListSet && m_markListSet->size()) {
     2678                SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::ConservativeScan);
    26692679                MarkedArgumentBuffer::markLists(slotVisitor, *m_markListSet);
    2670            
    2671             slotVisitor.appendUnbarriered(m_vm->exception());
    2672             slotVisitor.appendUnbarriered(m_vm->lastException());
     2680            }
     2681
     2682            {
     2683                SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::VMExceptions);
     2684                slotVisitor.appendUnbarriered(m_vm->exception());
     2685                slotVisitor.appendUnbarriered(m_vm->lastException());
     2686            }
    26732687        },
    26742688        ConstraintVolatility::GreyedByExecution);
     
    26772691        "Sh", "Strong Handles",
    26782692        [this] (SlotVisitor& slotVisitor) {
     2693            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::StrongHandles);
    26792694            m_handleSet.visitStrongHandles(slotVisitor);
    26802695        },
     
    26842699        "D", "Debugger",
    26852700        [this] (SlotVisitor& slotVisitor) {
     2701            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::Debugger);
     2702
    26862703#if ENABLE(SAMPLING_PROFILER)
    26872704            if (SamplingProfiler* samplingProfiler = m_vm->samplingProfiler()) {
     
    26932710            }
    26942711#endif // ENABLE(SAMPLING_PROFILER)
    2695            
     2712
    26962713            if (m_vm->typeProfiler())
    26972714                m_vm->typeProfilerLog()->visit(slotVisitor);
     
    27042721        "Jsr", "JIT Stub Routines",
    27052722        [this] (SlotVisitor& slotVisitor) {
     2723            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::JITStubRoutines);
    27062724            m_jitStubRoutines->traceMarkedStubRoutines(slotVisitor);
    27072725        },
     
    27112729        "Ws", "Weak Sets",
    27122730        [this] (SlotVisitor& slotVisitor) {
     2731            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::WeakSets);
    27132732            m_objectSpace.visitWeakSets(slotVisitor);
    27142733        },
     
    27192738        [] (SlotVisitor& slotVisitor) {
    27202739            VM& vm = slotVisitor.vm();
    2721            
     2740
    27222741            auto callOutputConstraint = [] (SlotVisitor& slotVisitor, HeapCell* heapCell, HeapCell::Kind) {
     2742                SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::Output);
    27232743                VM& vm = slotVisitor.vm();
    27242744                JSCell* cell = static_cast<JSCell*>(heapCell);
     
    27402760        "Dw", "DFG Worklists",
    27412761        [this] (SlotVisitor& slotVisitor) {
     2762            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::DFGWorkLists);
     2763
    27422764            for (unsigned i = DFG::numberOfWorklists(); i--;)
    27432765                DFG::existingWorklistForIndex(i).visitWeakReferences(slotVisitor);
     
    27602782        "Cb", "CodeBlocks",
    27612783        [this] (SlotVisitor& slotVisitor) {
     2784            SetRootMarkReasonScope rootScope(slotVisitor, SlotVisitor::RootMarkReason::CodeBlocks);
    27622785            iterateExecutingAndCompilingCodeBlocksWithoutHoldingLocks(
    27632786                [&] (CodeBlock* codeBlock) {
  • TabularUnified trunk/Source/JavaScriptCore/heap/HeapSnapshotBuilder.cpp

    r234082 r235271  
    3838
    3939namespace JSC {
    40    
    41 unsigned HeapSnapshotBuilder::nextAvailableObjectIdentifier = 1;
    42 unsigned HeapSnapshotBuilder::getNextObjectIdentifier() { return nextAvailableObjectIdentifier++; }
     40
     41static const char* rootTypeToString(SlotVisitor::RootMarkReason);
     42
     43NodeIdentifier HeapSnapshotBuilder::nextAvailableObjectIdentifier = 1;
     44NodeIdentifier HeapSnapshotBuilder::getNextObjectIdentifier() { return nextAvailableObjectIdentifier++; }
    4345void HeapSnapshotBuilder::resetNextAvailableObjectIdentifier() { HeapSnapshotBuilder::nextAvailableObjectIdentifier = 1; }
    4446
    45 HeapSnapshotBuilder::HeapSnapshotBuilder(HeapProfiler& profiler)
     47HeapSnapshotBuilder::HeapSnapshotBuilder(HeapProfiler& profiler, SnapshotType type)
    4648    : m_profiler(profiler)
     49    , m_snapshotType(type)
    4750{
    4851}
     
    5053HeapSnapshotBuilder::~HeapSnapshotBuilder()
    5154{
     55    if (m_snapshotType == SnapshotType::GCDebuggingSnapshot)
     56        m_profiler.clearSnapshots();
    5257}
    5358
    5459void HeapSnapshotBuilder::buildSnapshot()
    5560{
     61    // GCDebuggingSnapshot are always full snapshots, so clear any existing snapshots.
     62    if (m_snapshotType == SnapshotType::GCDebuggingSnapshot)
     63        m_profiler.clearSnapshots();
     64
    5665    PreventCollectionScope preventCollectionScope(m_profiler.vm().heap);
    57    
     66
    5867    m_snapshot = std::make_unique<HeapSnapshot>(m_profiler.mostRecentSnapshot());
    5968    {
     
    7079{
    7180    ASSERT(m_profiler.activeSnapshotBuilder() == this);
     81   
    7282    ASSERT(Heap::isMarked(cell));
    7383
    74     if (hasExistingNodeForCell(cell))
     84    NodeIdentifier identifier;
     85    if (previousSnapshotHasNodeForCell(cell, identifier))
    7586        return;
    7687
    7788    std::lock_guard<Lock> lock(m_buildingNodeMutex);
    78 
    7989    m_snapshot->appendNode(HeapSnapshotNode(cell, getNextObjectIdentifier()));
    8090}
    8191
    82 void HeapSnapshotBuilder::appendEdge(JSCell* from, JSCell* to)
     92void HeapSnapshotBuilder::appendEdge(JSCell* from, JSCell* to, SlotVisitor::RootMarkReason rootMarkReason)
    8393{
    8494    ASSERT(m_profiler.activeSnapshotBuilder() == this);
     
    91101    std::lock_guard<Lock> lock(m_buildingEdgeMutex);
    92102
     103    if (m_snapshotType == SnapshotType::GCDebuggingSnapshot && !from) {
     104        if (rootMarkReason == SlotVisitor::RootMarkReason::None && m_snapshotType == SnapshotType::GCDebuggingSnapshot)
     105            WTFLogAlways("Cell %p is a root but no root marking reason was supplied", to);
     106
     107        m_rootData.ensure(to, [] () -> RootData {
     108            return { };
     109        }).iterator->value.markReason = rootMarkReason;
     110    }
     111
    93112    m_edges.append(HeapSnapshotEdge(from, to));
    94113}
     
    124143}
    125144
    126 bool HeapSnapshotBuilder::hasExistingNodeForCell(JSCell* cell)
     145void HeapSnapshotBuilder::setOpaqueRootReachabilityReasonForCell(JSCell* cell, const char* reason)
     146{
     147    if (!reason || !*reason || m_snapshotType != SnapshotType::GCDebuggingSnapshot)
     148        return;
     149
     150    m_rootData.ensure(cell, [] () -> RootData {
     151        return { };
     152    }).iterator->value.reachabilityFromOpaqueRootReasons = reason;
     153}
     154
     155void HeapSnapshotBuilder::setWrappedObjectForCell(JSCell* cell, void* wrappedPtr)
     156{
     157    m_wrappedObjectPointers.set(cell, wrappedPtr);
     158}
     159
     160bool HeapSnapshotBuilder::previousSnapshotHasNodeForCell(JSCell* cell, NodeIdentifier& identifier)
    127161{
    128162    if (!m_snapshot->previous())
    129163        return false;
    130164
    131     return !!m_snapshot->previous()->nodeForCell(cell);
    132 }
    133 
     165    auto existingNode = m_snapshot->previous()->nodeForCell(cell);
     166    if (existingNode) {
     167        identifier = existingNode.value().identifier;
     168        return true;
     169    }
     170
     171    return false;
     172}
    134173
    135174// Heap Snapshot JSON Format:
     175//
     176//  Inspector snapshots:
    136177//
    137178//   {
    138179//      "version": 1.0,
     180//      "type": "Inspector",
     181//      // [<address>, <labelIndex>, <wrappedEddress>] only present in GCDebuggingSnapshot-type snapshots
    139182//      "nodes": [
    140 //          <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>,
    141 //          <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>,
     183//          <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>
     184//          <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>
    142185//          ...
    143186//      ],
     
    158201//   }
    159202//
     203//  GC heap debugger snapshots:
     204//
     205//   {
     206//      "version": 1.0,
     207//      "type": "GCDebugging",
     208//      "nodes": [
     209//          <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>, <labelIndex>, <cellEddress>, <wrappedEddress>,
     210//          <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>, <labelIndex>, <cellEddress>, <wrappedEddress>,
     211//          ...
     212//      ],
     213//      "nodeClassNames": [
     214//          "string", "Structure", "Object", ...
     215//      ],
     216//      "edges": [
     217//          <fromNodeId>, <toNodeId>, <edgeTypeIndex>, <edgeExtraData>,
     218//          <fromNodeId>, <toNodeId>, <edgeTypeIndex>, <edgeExtraData>,
     219//          ...
     220//      ],
     221//      "edgeTypes": [
     222//          "Internal", "Property", "Index", "Variable"
     223//      ],
     224//      "edgeNames": [
     225//          "propertyName", "variableName", ...
     226//      ],
     227//      "roots" : [
     228//          <nodeId>, <rootReasonIndex>, <reachabilityReasonIndex>,
     229//          <nodeId>, <rootReasonIndex>, <reachabilityReasonIndex>,
     230//          ... // <nodeId> may be repeated
     231//      ],
     232//      "labels" : [
     233//          "foo", "bar", ...
     234//      ]
     235//   }
     236//
    160237// Notes:
    161238//
     
    173250//       - for Index edges this is the index value.
    174251//       - for Property or Variable edges this is an index into the "edgeNames" list.
     252//
     253//      <rootReasonIndex>
     254//       - index into the "labels" list.
    175255
    176256static uint8_t edgeTypeToNumber(EdgeType type)
     
    195275}
    196276
     277static const char* snapshotTypeToString(HeapSnapshotBuilder::SnapshotType type)
     278{
     279    switch (type) {
     280    case HeapSnapshotBuilder::SnapshotType::InspectorSnapshot:
     281        return "Inspector";
     282    case HeapSnapshotBuilder::SnapshotType::GCDebuggingSnapshot:
     283        return "GCDebugging";
     284    }
     285    ASSERT_NOT_REACHED();
     286    return "Inspector";
     287}
     288
     289static const char* rootTypeToString(SlotVisitor::RootMarkReason type)
     290{
     291    switch (type) {
     292    case SlotVisitor::RootMarkReason::None:
     293        return "None";
     294    case SlotVisitor::RootMarkReason::ConservativeScan:
     295        return "Conservative scan";
     296    case SlotVisitor::RootMarkReason::StrongReferences:
     297        return "Strong references";
     298    case SlotVisitor::RootMarkReason::ProtectedValues:
     299        return "Protected values";
     300    case SlotVisitor::RootMarkReason::MarkListSet:
     301        return "Mark list set";
     302    case SlotVisitor::RootMarkReason::VMExceptions:
     303        return "VM exceptions";
     304    case SlotVisitor::RootMarkReason::StrongHandles:
     305        return "Strong handles";
     306    case SlotVisitor::RootMarkReason::Debugger:
     307        return "Debugger";
     308    case SlotVisitor::RootMarkReason::JITStubRoutines:
     309        return "JIT stub routines";
     310    case SlotVisitor::RootMarkReason::WeakSets:
     311        return "Weak sets";
     312    case SlotVisitor::RootMarkReason::Output:
     313        return "Output";
     314    case SlotVisitor::RootMarkReason::DFGWorkLists:
     315        return "DFG work lists";
     316    case SlotVisitor::RootMarkReason::CodeBlocks:
     317        return "Code blocks";
     318    case SlotVisitor::RootMarkReason::DOMGCOutput:
     319        return "DOM GC output";
     320    }
     321    ASSERT_NOT_REACHED();
     322    return "None";
     323}
     324
    197325String HeapSnapshotBuilder::json()
    198326{
    199327    return json([] (const HeapSnapshotNode&) { return true; });
     328}
     329
     330void HeapSnapshotBuilder::setLabelForCell(JSCell* cell, const String& label)
     331{
     332    m_cellLabels.set(cell, label);
     333}
     334
     335String HeapSnapshotBuilder::descriptionForCell(JSCell *cell) const
     336{
     337    if (cell->isString())
     338        return emptyString(); // FIXME: get part of string.
     339
     340    VM& vm = m_profiler.vm();
     341    Structure* structure = cell->structure(vm);
     342
     343    if (structure->classInfo()->isSubClassOf(Structure::info())) {
     344        Structure* cellAsStructure = jsCast<Structure*>(cell);
     345        return cellAsStructure->classInfo()->className;
     346    }
     347
     348    return emptyString();
    200349}
    201350
     
    206355
    207356    // Build a node to identifier map of allowed nodes to use when serializing edges.
    208     HashMap<JSCell*, unsigned> allowedNodeIdentifiers;
     357    HashMap<JSCell*, NodeIdentifier> allowedNodeIdentifiers;
    209358
    210359    // Build a list of used class names.
     
    213362    unsigned nextClassNameIndex = 1;
    214363
     364    // Build a list of labels (this is just a string table).
     365    HashMap<String, unsigned> labelIndexes;
     366    labelIndexes.set(emptyString(), 0);
     367    unsigned nextLabelIndex = 1;
     368
    215369    // Build a list of used edge names.
    216370    HashMap<UniquedStringImpl*, unsigned> edgeNameIndexes;
     
    232386
    233387        bool isInternal = false;
     388        void* wrappedAddress = 0;
     389        unsigned labelIndex = 0;
    234390        if (!node.cell->isString()) {
    235391            Structure* structure = node.cell->structure(vm);
    236392            isInternal = !structure || !structure->globalObject();
    237         }
    238 
    239         // <nodeId>, <sizeInBytes>, <className>, <optionalInternalBoolean>
     393
     394            if (m_snapshotType == SnapshotType::GCDebuggingSnapshot) {
     395                String nodeLabel;
     396                auto it = m_cellLabels.find(node.cell);
     397                if (it != m_cellLabels.end())
     398                    nodeLabel = it->value;
     399
     400                if (nodeLabel.isEmpty()) {
     401                    if (auto* object = jsDynamicCast<JSObject*>(vm, node.cell)) {
     402                        if (auto* function = jsDynamicCast<JSFunction*>(vm, object))
     403                            nodeLabel = function->calculatedDisplayName(vm);
     404                    }
     405                }
     406               
     407                String description = descriptionForCell(node.cell);
     408                if (description.length()) {
     409                    if (nodeLabel.length())
     410                        nodeLabel.append(' ');
     411                    nodeLabel.append(description);
     412                }
     413
     414                if (!nodeLabel.isEmpty() && m_snapshotType == SnapshotType::GCDebuggingSnapshot) {
     415                    auto result = labelIndexes.add(nodeLabel, nextLabelIndex);
     416                    if (result.isNewEntry)
     417                        nextLabelIndex++;
     418                    labelIndex = result.iterator->value;
     419                }
     420               
     421                wrappedAddress = m_wrappedObjectPointers.get(node.cell);
     422            }
     423        }
     424
     425        // <nodeId>, <sizeInBytes>, <nodeClassNameIndex>, <internal>, [<labelIndex>, <cellEddress>, <wrappedEddress>]
    240426        json.append(',');
    241427        json.appendNumber(node.identifier);
     
    246432        json.append(',');
    247433        json.append(isInternal ? '1' : '0');
     434        if (m_snapshotType == SnapshotType::GCDebuggingSnapshot) {
     435            json.append(',');
     436            json.appendNumber(labelIndex);
     437            json.append(',');
     438            json.append(String::format("\"%p\"", node.cell)); // FIXME: Should add StringBuilder::appendAddress(void*).
     439            json.append(',');
     440            json.append(String::format("\"%p\"", wrappedAddress));
     441        }
    248442    };
    249443
     
    286480    json.appendLiteral("\"version\":1");
    287481
     482    // type
     483    json.append(',');
     484    json.appendLiteral("\"type\":");
     485    json.appendQuotedJSONString(snapshotTypeToString(m_snapshotType));
     486
    288487    // nodes
    289488    json.append(',');
    290489    json.appendLiteral("\"nodes\":");
    291490    json.append('[');
    292     json.appendLiteral("0,0,0,0"); // <root>
     491    // <root>
     492    if (m_snapshotType == SnapshotType::GCDebuggingSnapshot)
     493        json.appendLiteral("0,0,0,0,0,\"0x0\",\"0x0\"");
     494    else
     495        json.appendLiteral("0,0,0,0");
     496
    293497    for (HeapSnapshot* snapshot = m_profiler.mostRecentSnapshot(); snapshot; snapshot = snapshot->previous()) {
    294498        for (auto& node : snapshot->m_nodes)
     
    324528        else {
    325529            auto fromLookup = allowedNodeIdentifiers.find(edge.from.cell);
    326             if (fromLookup == allowedNodeIdentifiers.end())
     530            if (fromLookup == allowedNodeIdentifiers.end()) {
     531                if (m_snapshotType == SnapshotType::GCDebuggingSnapshot)
     532                    WTFLogAlways("Failed to find node for from-edge cell %p", edge.from.cell);
    327533                return true;
     534            }
    328535            edge.from.identifier = fromLookup->value;
    329536        }
     
    333540        else {
    334541            auto toLookup = allowedNodeIdentifiers.find(edge.to.cell);
    335             if (toLookup == allowedNodeIdentifiers.end())
     542            if (toLookup == allowedNodeIdentifiers.end()) {
     543                if (m_snapshotType == SnapshotType::GCDebuggingSnapshot)
     544                    WTFLogAlways("Failed to find node for to-edge cell %p", edge.to.cell);
    336545                return true;
     546            }
    337547            edge.to.identifier = toLookup->value;
    338548        }
     
    340550        return false;
    341551    });
     552
    342553    allowedNodeIdentifiers.clear();
    343554    m_edges.shrinkToFit();
     
    387598    json.append(']');
    388599
     600    if (m_snapshotType == SnapshotType::GCDebuggingSnapshot) {
     601        json.append(',');
     602        json.appendLiteral("\"roots\":");
     603        json.append('[');
     604       
     605        HeapSnapshot* snapshot = m_profiler.mostRecentSnapshot();
     606
     607        bool firstNode = true;
     608        for (auto it : m_rootData) {
     609            auto snapshotNode = snapshot->nodeForCell(it.key);
     610            if (!snapshotNode) {
     611                WTFLogAlways("Failed to find snapshot node for cell %p", it.key);
     612                continue;
     613            }
     614
     615            if (!firstNode)
     616                json.append(',');
     617
     618            firstNode = false;
     619            json.appendNumber(snapshotNode.value().identifier);
     620           
     621            // Maybe we should just always encode the root names.
     622            const char* rootName = rootTypeToString(it.value.markReason);
     623            auto result = labelIndexes.add(rootName, nextLabelIndex);
     624            if (result.isNewEntry)
     625                nextLabelIndex++;
     626            unsigned labelIndex = result.iterator->value;
     627            json.append(',');
     628            json.appendNumber(labelIndex);
     629
     630            unsigned reachabilityReasonIndex = 0;
     631            if (it.value.reachabilityFromOpaqueRootReasons) {
     632                auto result = labelIndexes.add(it.value.reachabilityFromOpaqueRootReasons, nextLabelIndex);
     633                if (result.isNewEntry)
     634                    nextLabelIndex++;
     635                reachabilityReasonIndex = result.iterator->value;
     636            }
     637            json.append(',');
     638            json.appendNumber(reachabilityReasonIndex);
     639        }
     640
     641        json.append(']');
     642    }
     643
     644    if (m_snapshotType == SnapshotType::GCDebuggingSnapshot) {
     645        // internal node descriptions
     646        json.append(',');
     647        json.appendLiteral("\"labels\":");
     648        json.append('[');
     649
     650        Vector<String> orderedLabels(labelIndexes.size());
     651        for (auto& entry : labelIndexes)
     652            orderedLabels[entry.value] = entry.key;
     653        labelIndexes.clear();
     654        bool firstLabel = true;
     655        for (auto& label : orderedLabels) {
     656            if (!firstLabel)
     657                json.append(',');
     658
     659            firstLabel = false;
     660            json.appendQuotedJSONString(label);
     661        }
     662        orderedLabels.clear();
     663
     664        json.append(']');
     665    }
     666
    389667    json.append('}');
    390668    return json.toString();
  • TabularUnified trunk/Source/JavaScriptCore/heap/HeapSnapshotBuilder.h

    r234082 r235271  
    2626#pragma once
    2727
     28#include "SlotVisitor.h"
    2829#include <functional>
    2930#include <wtf/Lock.h>
     
    3435namespace JSC {
    3536
     37class ConservativeRoots;
    3638class HeapProfiler;
    3739class HeapSnapshot;
    3840class JSCell;
     41
     42typedef unsigned NodeIdentifier;
    3943
    4044struct HeapSnapshotNode {
     
    4549
    4650    JSCell* cell;
    47     unsigned identifier;
     51    NodeIdentifier identifier;
    4852};
    4953
     
    8387    union {
    8488        JSCell *cell;
    85         unsigned identifier;
     89        NodeIdentifier identifier;
    8690    } from;
    8791
    8892    union {
    8993        JSCell *cell;
    90         unsigned identifier;
     94        NodeIdentifier identifier;
    9195    } to;
    9296
     
    102106    WTF_MAKE_FAST_ALLOCATED;
    103107public:
    104     HeapSnapshotBuilder(HeapProfiler&);
     108    enum SnapshotType { InspectorSnapshot, GCDebuggingSnapshot };
     109
     110    HeapSnapshotBuilder(HeapProfiler&, SnapshotType = SnapshotType::InspectorSnapshot);
    105111    ~HeapSnapshotBuilder();
    106112
    107     static unsigned nextAvailableObjectIdentifier;
    108     static unsigned getNextObjectIdentifier();
    109113    static void resetNextAvailableObjectIdentifier();
    110114
     
    112116    void buildSnapshot();
    113117
    114     // A marked cell.
     118    // A root or marked cell.
    115119    void appendNode(JSCell*);
    116120
    117121    // A reference from one cell to another.
    118     void appendEdge(JSCell* from, JSCell* to);
     122    void appendEdge(JSCell* from, JSCell* to, SlotVisitor::RootMarkReason);
    119123    void appendPropertyNameEdge(JSCell* from, JSCell* to, UniquedStringImpl* propertyName);
    120124    void appendVariableNameEdge(JSCell* from, JSCell* to, UniquedStringImpl* variableName);
    121125    void appendIndexEdge(JSCell* from, JSCell* to, uint32_t index);
     126
     127    void setOpaqueRootReachabilityReasonForCell(JSCell*, const char*);
     128    void setWrappedObjectForCell(JSCell*, void*);
     129    void setLabelForCell(JSCell*, const String&);
    122130
    123131    String json();
     
    125133
    126134private:
     135    static NodeIdentifier nextAvailableObjectIdentifier;
     136    static NodeIdentifier getNextObjectIdentifier();
     137
    127138    // Finalized snapshots are not modified during building. So searching them
    128139    // for an existing node can be done concurrently without a lock.
    129     bool hasExistingNodeForCell(JSCell*);
    130 
     140    bool previousSnapshotHasNodeForCell(JSCell*, NodeIdentifier&);
     141   
     142    String descriptionForCell(JSCell*) const;
     143   
     144    struct RootData {
     145        const char* reachabilityFromOpaqueRootReasons { nullptr };
     146        SlotVisitor::RootMarkReason markReason { SlotVisitor::RootMarkReason::None };
     147    };
     148   
    131149    HeapProfiler& m_profiler;
    132150
     
    136154    Lock m_buildingEdgeMutex;
    137155    Vector<HeapSnapshotEdge> m_edges;
     156    HashMap<JSCell*, RootData> m_rootData;
     157    HashMap<JSCell*, void*> m_wrappedObjectPointers;
     158    HashMap<JSCell*, String> m_cellLabels;
     159    SnapshotType m_snapshotType;
    138160};
    139161
  • TabularUnified trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp

    r233236 r235271  
    226226{
    227227    if (UNLIKELY(m_heapSnapshotBuilder))
    228         m_heapSnapshotBuilder->appendEdge(m_currentCell, cell);
     228        m_heapSnapshotBuilder->appendEdge(m_currentCell, cell, m_rootMarkReason);
    229229   
    230230    appendHiddenSlowImpl(cell, dependency);
  • TabularUnified trunk/Source/JavaScriptCore/heap/SlotVisitor.h

    r232443 r235271  
    5858
    5959public:
     60    enum RootMarkReason {
     61        None,
     62        ConservativeScan,
     63        StrongReferences,
     64        ProtectedValues,
     65        MarkListSet,
     66        VMExceptions,
     67        StrongHandles,
     68        Debugger,
     69        JITStubRoutines,
     70        WeakSets,
     71        Output,
     72        DFGWorkLists,
     73        CodeBlocks,
     74        DOMGCOutput,
     75    };
     76
    6077    SlotVisitor(Heap&, CString codeName);
    6178    ~SlotVisitor();
     
    143160
    144161    bool isBuildingHeapSnapshot() const { return !!m_heapSnapshotBuilder; }
    145    
     162    HeapSnapshotBuilder* heapSnapshotBuilder() const { return m_heapSnapshotBuilder; }
     163   
     164    RootMarkReason rootMarkReason() const { return m_rootMarkReason; }
     165    void setRootMarkReason(RootMarkReason reason) { m_rootMarkReason = reason; }
     166
    146167    HeapVersion markingVersion() const { return m_markingVersion; }
    147168
     
    225246    HeapSnapshotBuilder* m_heapSnapshotBuilder { nullptr };
    226247    JSCell* m_currentCell { nullptr };
     248    RootMarkReason m_rootMarkReason { RootMarkReason::None };
    227249    bool m_isFirstVisit { false };
    228250    bool m_mutatorIsStopped { false };
     
    263285};
    264286
     287class SetRootMarkReasonScope {
     288public:
     289    SetRootMarkReasonScope(SlotVisitor& visitor, SlotVisitor::RootMarkReason reason)
     290        : m_visitor(visitor)
     291        , m_previousReason(visitor.rootMarkReason())
     292    {
     293        m_visitor.setRootMarkReason(reason);
     294    }
     295
     296    ~SetRootMarkReasonScope()
     297    {
     298        m_visitor.setRootMarkReason(m_previousReason);
     299    }
     300
     301private:
     302    SlotVisitor& m_visitor;
     303    SlotVisitor::RootMarkReason m_previousReason;
     304};
     305
    265306} // namespace JSC
  • TabularUnified trunk/Source/JavaScriptCore/heap/WeakBlock.cpp

    r225524 r235271  
    2929#include "CellContainerInlines.h"
    3030#include "Heap.h"
     31#include "HeapSnapshotBuilder.h"
    3132#include "JSCInlines.h"
    3233#include "JSObject.h"
     
    115116            continue;
    116117       
    117         if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor))
     118        const char* reason = "";
     119        const char** reasonPtr = nullptr;
     120        if (UNLIKELY(visitor.isBuildingHeapSnapshot()))
     121            reasonPtr = &reason;
     122
     123        if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor, reasonPtr))
    118124            continue;
    119125
    120126        visitor.appendUnbarriered(jsValue);
     127
     128        if (UNLIKELY(visitor.isBuildingHeapSnapshot())) {
     129            if (jsValue.isCell())
     130                visitor.heapSnapshotBuilder()->setOpaqueRootReachabilityReasonForCell(jsValue.asCell(), *reasonPtr);
     131        }
    121132    }
    122133}
  • TabularUnified trunk/Source/JavaScriptCore/heap/WeakHandleOwner.cpp

    r190113 r235271  
    3838}
    3939
    40 bool WeakHandleOwner::isReachableFromOpaqueRoots(Handle<Unknown>, void*, SlotVisitor&)
     40bool WeakHandleOwner::isReachableFromOpaqueRoots(Handle<Unknown>, void*, SlotVisitor&, const char**)
    4141{
    4242    return false;
  • TabularUnified trunk/Source/JavaScriptCore/heap/WeakHandleOwner.h

    r206525 r235271  
    3535public:
    3636    virtual ~WeakHandleOwner();
    37     virtual bool isReachableFromOpaqueRoots(Handle<Unknown>, void* context, SlotVisitor&);
     37    // reason will only be non-null when generating a debug GC heap snapshot.
     38    virtual bool isReachableFromOpaqueRoots(Handle<Unknown>, void* context, SlotVisitor&, char const** reason = nullptr);
    3839    virtual void finalize(Handle<Unknown>, void* context);
    3940};
  • TabularUnified trunk/Source/JavaScriptCore/runtime/SimpleTypedArrayController.cpp

    r208209 r235271  
    5959}
    6060
    61 bool SimpleTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
     61bool SimpleTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor, const char** reason)
    6262{
     63    if (UNLIKELY(reason))
     64        *reason = "JSArrayBuffer is opaque root";
    6365    auto& wrapper = *JSC::jsCast<JSC::JSArrayBuffer*>(handle.slot()->asCell());
    6466    return visitor.containsOpaqueRoot(wrapper.impl());
  • TabularUnified trunk/Source/JavaScriptCore/runtime/SimpleTypedArrayController.h

    r208209 r235271  
    5959    class JSArrayBufferOwner : public WeakHandleOwner {
    6060    public:
    61         bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, SlotVisitor&) override;
     61        bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, SlotVisitor&, const char** reason) override;
    6262        void finalize(JSC::Handle<JSC::Unknown>, void* context) override;
    6363    };
  • TabularUnified trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

    r234728 r235271  
    173173class ElementHandleOwner : public WeakHandleOwner {
    174174public:
    175     bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor) override
    176     {
     175    bool isReachableFromOpaqueRoots(Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason) override
     176    {
     177        if (UNLIKELY(reason))
     178            *reason = "JSC::Element is opaque root";
    177179        Element* element = jsCast<Element*>(handle.slot()->asCell());
    178180        return visitor.containsOpaqueRoot(element->root());
  • TabularUnified trunk/Source/WebCore/ChangeLog

    r235268 r235271  
     12018-08-23  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add support for dumping GC heap snapshots, and a viewer
     4        https://bugs.webkit.org/show_bug.cgi?id=186416
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Make a way to dump information about the GC heap that is useful for looking for leaked
     9        or abandoned objects. This dump is obtained (on Apple platforms) via:
     10            notifyutil -p com.apple.WebKit.dumpGCHeap
     11        which writes a JSON file to /tmp which can then be loaded into the viewer in Tools/GCHeapInspector.
     12
     13        This leverages the heap snapshot used by Web Inspector, adding an alternate format for
     14        the snapshot JSON that adds additional data about objects and why they are GC roots.
     15       
     16        The generated bindings code is changed to include the output root reason from isReachableFromOpaqueRoots(),
     17        and to implement heapSnapshot() which provides the address of the wrapped object. A new IDL attribute,
     18        CustomHeapSnapshot, is used to allow custom heapSnapshot() implementations for classes like JSDocument
     19        that need to decorate the heap snapshot cell data with things like the document URL.
     20
     21        GCController registers a notifyutil callback which gathers the debug heap snapshot, and dumps it
     22        to a file in /tmp. The file path is printed out to the system log.
     23
     24        * bindings/js/DOMGCOutputConstraint.cpp:
     25        (WebCore::DOMGCOutputConstraint::executeImpl):
     26        * bindings/js/GCController.cpp:
     27        (WebCore::GCController::GCController):
     28        (WebCore::GCController::dumpHeap):
     29        * bindings/js/GCController.h:
     30        * bindings/js/JSCSSRuleListCustom.cpp:
     31        (WebCore::JSCSSRuleListOwner::isReachableFromOpaqueRoots):
     32        * bindings/js/JSCallbackData.cpp:
     33        (WebCore::JSCallbackDataWeak::WeakOwner::isReachableFromOpaqueRoots):
     34        * bindings/js/JSCallbackData.h:
     35        * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
     36        (WebCore::JSCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots):
     37        * bindings/js/JSDOMWindowCustom.cpp:
     38        (WebCore::JSDOMWindow::getOwnPropertySlot):
     39        (WebCore::JSDOMWindow::heapSnapshot):
     40        * bindings/js/JSDeprecatedCSSOMValueCustom.cpp:
     41        (WebCore::JSDeprecatedCSSOMValueOwner::isReachableFromOpaqueRoots):
     42        * bindings/js/JSDocumentCustom.cpp:
     43        (WebCore::JSDocument::heapSnapshot):
     44        * bindings/js/JSMicrotaskCallback.h:
     45        (WebCore::JSMicrotaskCallback::call):
     46        * bindings/js/JSMutationObserverCustom.cpp:
     47        (WebCore::JSMutationObserverOwner::isReachableFromOpaqueRoots):
     48        * bindings/js/JSNavigatorCustom.cpp:
     49        (WebCore::JSNavigator::visitAdditionalChildren):
     50        * bindings/js/JSNodeCustom.cpp:
     51        (WebCore::isReachableFromDOM):
     52        (WebCore::JSNodeOwner::isReachableFromOpaqueRoots):
     53        * bindings/js/JSNodeListCustom.cpp:
     54        (WebCore::JSNodeListOwner::isReachableFromOpaqueRoots):
     55        * bindings/js/JSOffscreenCanvasRenderingContext2DCustom.cpp:
     56        (WebCore::JSOffscreenCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots):
     57        * bindings/js/JSPerformanceObserverCustom.cpp:
     58        (WebCore::JSPerformanceObserverOwner::isReachableFromOpaqueRoots):
     59        * bindings/js/JSPopStateEventCustom.cpp:
     60        * bindings/js/JSTextTrackCueCustom.cpp:
     61        (WebCore::JSTextTrackCueOwner::isReachableFromOpaqueRoots):
     62        * bindings/js/WebCoreTypedArrayController.cpp:
     63        (WebCore::WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots):
     64        * bindings/js/WebCoreTypedArrayController.h:
     65        * bindings/scripts/CodeGeneratorJS.pm:
     66        (GenerateHeader):
     67        (GenerateImplementation):
     68        * bindings/scripts/IDLAttributes.json:
     69        * bindings/scripts/test/JS/JSInterfaceName.cpp:
     70        (WebCore::JSInterfaceName::heapSnapshot):
     71        (WebCore::JSInterfaceNameOwner::isReachableFromOpaqueRoots):
     72        * bindings/scripts/test/JS/JSInterfaceName.h:
     73        * bindings/scripts/test/JS/JSMapLike.cpp:
     74        (WebCore::JSMapLike::heapSnapshot):
     75        (WebCore::JSMapLikeOwner::isReachableFromOpaqueRoots):
     76        * bindings/scripts/test/JS/JSMapLike.h:
     77        * bindings/scripts/test/JS/JSReadOnlyMapLike.cpp:
     78        (WebCore::JSReadOnlyMapLike::heapSnapshot):
     79        (WebCore::JSReadOnlyMapLikeOwner::isReachableFromOpaqueRoots):
     80        * bindings/scripts/test/JS/JSReadOnlyMapLike.h:
     81        * bindings/scripts/test/JS/JSTestActiveDOMObject.cpp:
     82        (WebCore::JSTestActiveDOMObject::heapSnapshot):
     83        (WebCore::JSTestActiveDOMObjectOwner::isReachableFromOpaqueRoots):
     84        * bindings/scripts/test/JS/JSTestActiveDOMObject.h:
     85        * bindings/scripts/test/JS/JSTestCEReactions.cpp:
     86        (WebCore::JSTestCEReactions::heapSnapshot):
     87        (WebCore::JSTestCEReactionsOwner::isReachableFromOpaqueRoots):
     88        * bindings/scripts/test/JS/JSTestCEReactions.h:
     89        * bindings/scripts/test/JS/JSTestCEReactionsStringifier.cpp:
     90        (WebCore::JSTestCEReactionsStringifier::heapSnapshot):
     91        (WebCore::JSTestCEReactionsStringifierOwner::isReachableFromOpaqueRoots):
     92        * bindings/scripts/test/JS/JSTestCEReactionsStringifier.h:
     93        * bindings/scripts/test/JS/JSTestCallTracer.cpp:
     94        (WebCore::JSTestCallTracer::heapSnapshot):
     95        (WebCore::JSTestCallTracerOwner::isReachableFromOpaqueRoots):
     96        * bindings/scripts/test/JS/JSTestCallTracer.h:
     97        * bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.cpp:
     98        (WebCore::JSTestClassWithJSBuiltinConstructor::heapSnapshot):
     99        (WebCore::JSTestClassWithJSBuiltinConstructorOwner::isReachableFromOpaqueRoots):
     100        * bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.h:
     101        * bindings/scripts/test/JS/JSTestCustomConstructorWithNoInterfaceObject.cpp:
     102        (WebCore::JSTestCustomConstructorWithNoInterfaceObject::heapSnapshot):
     103        (WebCore::JSTestCustomConstructorWithNoInterfaceObjectOwner::isReachableFromOpaqueRoots):
     104        * bindings/scripts/test/JS/JSTestCustomConstructorWithNoInterfaceObject.h:
     105        * bindings/scripts/test/JS/JSTestDOMJIT.cpp:
     106        (WebCore::JSTestDOMJIT::heapSnapshot):
     107        * bindings/scripts/test/JS/JSTestDOMJIT.h:
     108        * bindings/scripts/test/JS/JSTestEnabledBySetting.cpp:
     109        (WebCore::JSTestEnabledBySetting::heapSnapshot):
     110        (WebCore::JSTestEnabledBySettingOwner::isReachableFromOpaqueRoots):
     111        * bindings/scripts/test/JS/JSTestEnabledBySetting.h:
     112        * bindings/scripts/test/JS/JSTestEventConstructor.cpp:
     113        (WebCore::JSTestEventConstructor::heapSnapshot):
     114        * bindings/scripts/test/JS/JSTestEventConstructor.h:
     115        * bindings/scripts/test/JS/JSTestEventTarget.cpp:
     116        (WebCore::JSTestEventTarget::heapSnapshot):
     117        * bindings/scripts/test/JS/JSTestEventTarget.h:
     118        * bindings/scripts/test/JS/JSTestException.cpp:
     119        (WebCore::JSTestException::heapSnapshot):
     120        (WebCore::JSTestExceptionOwner::isReachableFromOpaqueRoots):
     121        * bindings/scripts/test/JS/JSTestException.h:
     122        * bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp:
     123        (WebCore::JSTestGenerateIsReachable::heapSnapshot):
     124        (WebCore::JSTestGenerateIsReachableOwner::isReachableFromOpaqueRoots):
     125        * bindings/scripts/test/JS/JSTestGenerateIsReachable.h:
     126        * bindings/scripts/test/JS/JSTestGlobalObject.cpp:
     127        (WebCore::JSTestGlobalObject::heapSnapshot):
     128        (WebCore::JSTestGlobalObjectOwner::isReachableFromOpaqueRoots):
     129        * bindings/scripts/test/JS/JSTestGlobalObject.h:
     130        * bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.cpp:
     131        (WebCore::JSTestIndexedSetterNoIdentifier::heapSnapshot):
     132        (WebCore::JSTestIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):
     133        * bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.h:
     134        * bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.cpp:
     135        (WebCore::JSTestIndexedSetterThrowingException::heapSnapshot):
     136        (WebCore::JSTestIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):
     137        * bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.h:
     138        * bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.cpp:
     139        (WebCore::JSTestIndexedSetterWithIdentifier::heapSnapshot):
     140        (WebCore::JSTestIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):
     141        * bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.h:
     142        * bindings/scripts/test/JS/JSTestInterface.cpp:
     143        (WebCore::JSTestInterface::heapSnapshot):
     144        (WebCore::JSTestInterfaceOwner::isReachableFromOpaqueRoots):
     145        * bindings/scripts/test/JS/JSTestInterface.h:
     146        * bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.cpp:
     147        (WebCore::JSTestInterfaceLeadingUnderscore::heapSnapshot):
     148        (WebCore::JSTestInterfaceLeadingUnderscoreOwner::isReachableFromOpaqueRoots):
     149        * bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.h:
     150        * bindings/scripts/test/JS/JSTestIterable.cpp:
     151        (WebCore::JSTestIterable::heapSnapshot):
     152        (WebCore::JSTestIterableOwner::isReachableFromOpaqueRoots):
     153        * bindings/scripts/test/JS/JSTestIterable.h:
     154        * bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp:
     155        (WebCore::JSTestMediaQueryListListener::heapSnapshot):
     156        (WebCore::JSTestMediaQueryListListenerOwner::isReachableFromOpaqueRoots):
     157        * bindings/scripts/test/JS/JSTestMediaQueryListListener.h:
     158        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp:
     159        (WebCore::JSTestNamedAndIndexedSetterNoIdentifier::heapSnapshot):
     160        (WebCore::JSTestNamedAndIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):
     161        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.h:
     162        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp:
     163        (WebCore::JSTestNamedAndIndexedSetterThrowingException::heapSnapshot):
     164        (WebCore::JSTestNamedAndIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):
     165        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.h:
     166        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp:
     167        (WebCore::JSTestNamedAndIndexedSetterWithIdentifier::heapSnapshot):
     168        (WebCore::JSTestNamedAndIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):
     169        * bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.h:
     170        * bindings/scripts/test/JS/JSTestNamedConstructor.cpp:
     171        (WebCore::JSTestNamedConstructor::heapSnapshot):
     172        (WebCore::JSTestNamedConstructorOwner::isReachableFromOpaqueRoots):
     173        * bindings/scripts/test/JS/JSTestNamedConstructor.h:
     174        * bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.cpp:
     175        (WebCore::JSTestNamedDeleterNoIdentifier::heapSnapshot):
     176        (WebCore::JSTestNamedDeleterNoIdentifierOwner::isReachableFromOpaqueRoots):
     177        * bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.h:
     178        * bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.cpp:
     179        (WebCore::JSTestNamedDeleterThrowingException::heapSnapshot):
     180        (WebCore::JSTestNamedDeleterThrowingExceptionOwner::isReachableFromOpaqueRoots):
     181        * bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.h:
     182        * bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.cpp:
     183        (WebCore::JSTestNamedDeleterWithIdentifier::heapSnapshot):
     184        (WebCore::JSTestNamedDeleterWithIdentifierOwner::isReachableFromOpaqueRoots):
     185        * bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.h:
     186        * bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.cpp:
     187        (WebCore::JSTestNamedDeleterWithIndexedGetter::heapSnapshot):
     188        (WebCore::JSTestNamedDeleterWithIndexedGetterOwner::isReachableFromOpaqueRoots):
     189        * bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.h:
     190        * bindings/scripts/test/JS/JSTestNamedGetterCallWith.cpp:
     191        (WebCore::JSTestNamedGetterCallWith::heapSnapshot):
     192        (WebCore::JSTestNamedGetterCallWithOwner::isReachableFromOpaqueRoots):
     193        * bindings/scripts/test/JS/JSTestNamedGetterCallWith.h:
     194        * bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.cpp:
     195        (WebCore::JSTestNamedGetterNoIdentifier::heapSnapshot):
     196        (WebCore::JSTestNamedGetterNoIdentifierOwner::isReachableFromOpaqueRoots):
     197        * bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.h:
     198        * bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.cpp:
     199        (WebCore::JSTestNamedGetterWithIdentifier::heapSnapshot):
     200        (WebCore::JSTestNamedGetterWithIdentifierOwner::isReachableFromOpaqueRoots):
     201        * bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.h:
     202        * bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp:
     203        (WebCore::JSTestNamedSetterNoIdentifier::heapSnapshot):
     204        (WebCore::JSTestNamedSetterNoIdentifierOwner::isReachableFromOpaqueRoots):
     205        * bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.h:
     206        * bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp:
     207        (WebCore::JSTestNamedSetterThrowingException::heapSnapshot):
     208        (WebCore::JSTestNamedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots):
     209        * bindings/scripts/test/JS/JSTestNamedSetterThrowingException.h:
     210        * bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp:
     211        (WebCore::JSTestNamedSetterWithIdentifier::heapSnapshot):
     212        (WebCore::JSTestNamedSetterWithIdentifierOwner::isReachableFromOpaqueRoots):
     213        * bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.h:
     214        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp:
     215        (WebCore::JSTestNamedSetterWithIndexedGetter::heapSnapshot):
     216        (WebCore::JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots):
     217        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h:
     218        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp:
     219        (WebCore::JSTestNamedSetterWithIndexedGetterAndSetter::heapSnapshot):
     220        (WebCore::JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots):
     221        * bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h:
     222        * bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.cpp:
     223        (WebCore::JSTestNamedSetterWithOverrideBuiltins::heapSnapshot):
     224        (WebCore::JSTestNamedSetterWithOverrideBuiltinsOwner::isReachableFromOpaqueRoots):
     225        * bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.h:
     226        * bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp:
     227        (WebCore::JSTestNamedSetterWithUnforgableProperties::heapSnapshot):
     228        (WebCore::JSTestNamedSetterWithUnforgablePropertiesOwner::isReachableFromOpaqueRoots):
     229        * bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.h:
     230        * bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.cpp:
     231        (WebCore::JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins::heapSnapshot):
     232        (WebCore::JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsOwner::isReachableFromOpaqueRoots):
     233        * bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.h:
     234        * bindings/scripts/test/JS/JSTestNode.cpp:
     235        (WebCore::JSTestNode::heapSnapshot):
     236        * bindings/scripts/test/JS/JSTestNode.h:
     237        * bindings/scripts/test/JS/JSTestObj.cpp:
     238        (WebCore::JSTestObj::heapSnapshot):
     239        (WebCore::JSTestObjOwner::isReachableFromOpaqueRoots):
     240        * bindings/scripts/test/JS/JSTestObj.h:
     241        * bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:
     242        (WebCore::JSTestOverloadedConstructors::heapSnapshot):
     243        (WebCore::JSTestOverloadedConstructorsOwner::isReachableFromOpaqueRoots):
     244        * bindings/scripts/test/JS/JSTestOverloadedConstructors.h:
     245        * bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.cpp:
     246        (WebCore::JSTestOverloadedConstructorsWithSequence::heapSnapshot):
     247        (WebCore::JSTestOverloadedConstructorsWithSequenceOwner::isReachableFromOpaqueRoots):
     248        * bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.h:
     249        * bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp:
     250        (WebCore::JSTestOverrideBuiltins::heapSnapshot):
     251        (WebCore::JSTestOverrideBuiltinsOwner::isReachableFromOpaqueRoots):
     252        * bindings/scripts/test/JS/JSTestOverrideBuiltins.h:
     253        * bindings/scripts/test/JS/JSTestPluginInterface.cpp:
     254        (WebCore::JSTestPluginInterface::heapSnapshot):
     255        (WebCore::JSTestPluginInterfaceOwner::isReachableFromOpaqueRoots):
     256        * bindings/scripts/test/JS/JSTestPluginInterface.h:
     257        * bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp:
     258        (WebCore::JSTestPromiseRejectionEvent::heapSnapshot):
     259        * bindings/scripts/test/JS/JSTestPromiseRejectionEvent.h:
     260        * bindings/scripts/test/JS/JSTestSerialization.cpp:
     261        (WebCore::JSTestSerialization::heapSnapshot):
     262        (WebCore::JSTestSerializationOwner::isReachableFromOpaqueRoots):
     263        * bindings/scripts/test/JS/JSTestSerialization.h:
     264        * bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.cpp:
     265        (WebCore::JSTestSerializationIndirectInheritance::heapSnapshot):
     266        * bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.h:
     267        * bindings/scripts/test/JS/JSTestSerializationInherit.cpp:
     268        (WebCore::JSTestSerializationInherit::heapSnapshot):
     269        * bindings/scripts/test/JS/JSTestSerializationInherit.h:
     270        * bindings/scripts/test/JS/JSTestSerializationInheritFinal.cpp:
     271        (WebCore::JSTestSerializationInheritFinal::heapSnapshot):
     272        * bindings/scripts/test/JS/JSTestSerializationInheritFinal.h:
     273        * bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:
     274        (WebCore::JSTestSerializedScriptValueInterface::heapSnapshot):
     275        (WebCore::JSTestSerializedScriptValueInterfaceOwner::isReachableFromOpaqueRoots):
     276        * bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h:
     277        * bindings/scripts/test/JS/JSTestStringifier.cpp:
     278        (WebCore::JSTestStringifier::heapSnapshot):
     279        (WebCore::JSTestStringifierOwner::isReachableFromOpaqueRoots):
     280        * bindings/scripts/test/JS/JSTestStringifier.h:
     281        * bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.cpp:
     282        (WebCore::JSTestStringifierAnonymousOperation::heapSnapshot):
     283        (WebCore::JSTestStringifierAnonymousOperationOwner::isReachableFromOpaqueRoots):
     284        * bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.h:
     285        * bindings/scripts/test/JS/JSTestStringifierNamedOperation.cpp:
     286        (WebCore::JSTestStringifierNamedOperation::heapSnapshot):
     287        (WebCore::JSTestStringifierNamedOperationOwner::isReachableFromOpaqueRoots):
     288        * bindings/scripts/test/JS/JSTestStringifierNamedOperation.h:
     289        * bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.cpp:
     290        (WebCore::JSTestStringifierOperationImplementedAs::heapSnapshot):
     291        (WebCore::JSTestStringifierOperationImplementedAsOwner::isReachableFromOpaqueRoots):
     292        * bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.h:
     293        * bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.cpp:
     294        (WebCore::JSTestStringifierOperationNamedToString::heapSnapshot):
     295        (WebCore::JSTestStringifierOperationNamedToStringOwner::isReachableFromOpaqueRoots):
     296        * bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.h:
     297        * bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.cpp:
     298        (WebCore::JSTestStringifierReadOnlyAttribute::heapSnapshot):
     299        (WebCore::JSTestStringifierReadOnlyAttributeOwner::isReachableFromOpaqueRoots):
     300        * bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.h:
     301        * bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.cpp:
     302        (WebCore::JSTestStringifierReadWriteAttribute::heapSnapshot):
     303        (WebCore::JSTestStringifierReadWriteAttributeOwner::isReachableFromOpaqueRoots):
     304        * bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.h:
     305        * bindings/scripts/test/JS/JSTestTypedefs.cpp:
     306        (WebCore::JSTestTypedefs::heapSnapshot):
     307        (WebCore::JSTestTypedefsOwner::isReachableFromOpaqueRoots):
     308        * bindings/scripts/test/JS/JSTestTypedefs.h:
     309        * dom/Document.idl:
     310        * page/DOMWindow.idl:
     311
    13122018-08-23  Ryosuke Niwa  <rniwa@webkit.org>
    2313
  • TabularUnified trunk/Source/WebCore/bindings/js/DOMGCOutputConstraint.cpp

    r228218 r235271  
    3030#include <JavaScriptCore/BlockDirectoryInlines.h>
    3131#include <JavaScriptCore/HeapInlines.h>
     32#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3233#include <JavaScriptCore/MarkedBlockInlines.h>
    3334#include <JavaScriptCore/SubspaceInlines.h>
     
    6263        [&] (Subspace& subspace) {
    6364            auto func = [] (SlotVisitor& visitor, HeapCell* heapCell, HeapCell::Kind) {
     65                SetRootMarkReasonScope rootScope(visitor, SlotVisitor::RootMarkReason::DOMGCOutput);
    6466                JSCell* cell = static_cast<JSCell*>(heapCell);
    6567                cell->methodTable(visitor.vm())->visitOutputConstraints(cell, visitor);
  • TabularUnified trunk/Source/WebCore/bindings/js/GCController.cpp

    r228218 r235271  
    2828
    2929#include "CommonVM.h"
     30#include "FileSystem.h"
     31#include "JSHTMLDocument.h"
     32#include "Location.h"
    3033#include <JavaScriptCore/Heap.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3135#include <JavaScriptCore/JSLock.h>
    3236#include <JavaScriptCore/VM.h>
     37#include <pal/Logging.h>
    3338#include <wtf/FastMalloc.h>
    3439#include <wtf/NeverDestroyed.h>
     
    5358    : m_GCTimer(*this, &GCController::gcTimerFired)
    5459{
     60    static std::once_flag onceFlag;
     61    std::call_once(onceFlag, [] {
     62        PAL::registerNotifyCallback("com.apple.WebKit.dumpGCHeap", [] {
     63            GCController::singleton().dumpHeap();
     64        });
     65    });
    5566}
    5667
     
    128139}
    129140
     141void GCController::dumpHeap()
     142{
     143    FileSystem::PlatformFileHandle fileHandle;
     144    String tempFilePath = FileSystem::openTemporaryFile("GCHeap"_s, fileHandle);
     145    if (!FileSystem::isHandleValid(fileHandle)) {
     146        WTFLogAlways("Dumping GC heap failed to open temporary file");
     147        return;
     148    }
     149
     150    VM& vm = commonVM();
     151    JSLockHolder lock(vm);
     152
     153    sanitizeStackForVM(&vm);
     154
     155    String jsonData;
     156    {
     157        DeferGCForAWhile deferGC(vm.heap); // Prevent concurrent GC from interfering with the full GC that the snapshot does.
     158
     159        HeapSnapshotBuilder snapshotBuilder(vm.ensureHeapProfiler(), HeapSnapshotBuilder::SnapshotType::GCDebuggingSnapshot);
     160        snapshotBuilder.buildSnapshot();
     161
     162        jsonData = snapshotBuilder.json();
     163    }
     164
     165    CString utf8String = jsonData.utf8();
     166
     167    FileSystem::writeToFile(fileHandle, utf8String.data(), utf8String.length());
     168    FileSystem::closeFile(fileHandle);
     169   
     170    WTFLogAlways("Dumped GC heap to %s", tempFilePath.utf8().data());
     171}
     172
    130173} // namespace WebCore
  • TabularUnified trunk/Source/WebCore/bindings/js/GCController.h

    r228218 r235271  
    5252    GCController(); // Use singleton() instead.
    5353
     54    void dumpHeap();
     55
    5456    void gcTimerFired();
    5557    Timer m_GCTimer;
  • TabularUnified trunk/Source/WebCore/bindings/js/JSCSSRuleListCustom.cpp

    r232337 r235271  
    3737using namespace JSC;
    3838
    39 bool JSCSSRuleListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     39bool JSCSSRuleListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    4040{
    4141    JSCSSRuleList* jsCSSRuleList = jsCast<JSCSSRuleList*>(handle.slot()->asCell());
    4242    if (!jsCSSRuleList->hasCustomProperties(*jsCSSRuleList->vm()))
    4343        return false;
    44     if (CSSStyleSheet* styleSheet = jsCSSRuleList->wrapped().styleSheet())
     44
     45    if (CSSStyleSheet* styleSheet = jsCSSRuleList->wrapped().styleSheet()) {
     46        if (UNLIKELY(reason))
     47            *reason = "CSSStyleSheet is opaque root";
     48
    4549        return visitor.containsOpaqueRoot(root(styleSheet));
    46     if (CSSRule* cssRule = jsCSSRuleList->wrapped().item(0))
     50    }
     51   
     52    if (CSSRule* cssRule = jsCSSRuleList->wrapped().item(0)) {
     53        if (UNLIKELY(reason))
     54            *reason = "CSSRule is opaque root";
     55
    4756        return visitor.containsOpaqueRoot(root(cssRule));
     57    }
    4858    return false;
    4959}
  • TabularUnified trunk/Source/WebCore/bindings/js/JSCallbackData.cpp

    r234586 r235271  
    9191}
    9292
    93 bool JSCallbackDataWeak::WeakOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, SlotVisitor& visitor)
     93bool JSCallbackDataWeak::WeakOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, SlotVisitor& visitor, const char** reason)
    9494{
     95    if (UNLIKELY(reason))
     96        *reason = "Context is opaque root"; // FIXME: what is the context.
    9597    return visitor.containsOpaqueRoot(context);
    9698}
  • TabularUnified trunk/Source/WebCore/bindings/js/JSCallbackData.h

    r228218 r235271  
    117117private:
    118118    class WeakOwner : public JSC::WeakHandleOwner {
    119         bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&) override;
     119        bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**) override;
    120120    };
    121121    WeakOwner m_weakOwner;
  • TabularUnified trunk/Source/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp

    r225816 r235271  
    2323namespace WebCore {
    2424
    25 bool JSCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
     25bool JSCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor, const char** reason)
    2626{
     27    if (UNLIKELY(reason))
     28        *reason = "Canvas is opaque root";
     29
    2730    JSCanvasRenderingContext2D* jsCanvasRenderingContext = jsCast<JSCanvasRenderingContext2D*>(handle.slot()->asCell());
    2831    void* root = WebCore::root(jsCanvasRenderingContext->wrapped().canvas());
  • TabularUnified trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp

    r234491 r235271  
    4646#include "Settings.h"
    4747#include "WebCoreJSClientData.h"
     48#include <JavaScriptCore/HeapSnapshotBuilder.h>
    4849#include <JavaScriptCore/JSCInlines.h>
    4950#include <JavaScriptCore/JSMicrotask.h>
     
    203204        return jsDOMWindowGetOwnPropertySlotRestrictedAccess<DOMWindowType::Local>(thisObject, thisObject->wrapped(), *state, propertyName, slot, errorMessage);
    204205
    205     // FIXME: this need more explanation.
     206    // FIXME: this needs more explanation.
    206207    // (Particularly, is it correct that this exists here but not in getOwnPropertySlotByIndex?)
    207208    slot.setWatchpointSet(thisObject->m_windowCloseWatchpoints);
     
    327328        return false;
    328329    return Base::deletePropertyByIndex(thisObject, exec, propertyName);
     330}
     331
     332void JSDOMWindow::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     333{
     334    JSDOMWindow* thisObject = jsCast<JSDOMWindow*>(cell);
     335    if (auto* location = thisObject->wrapped().location())
     336        builder.setLabelForCell(cell, location->href());
     337
     338    Base::heapSnapshot(cell, builder);
    329339}
    330340
  • TabularUnified trunk/Source/WebCore/bindings/js/JSDeprecatedCSSOMValueCustom.cpp

    r232337 r235271  
    3636using namespace JSC;
    3737
    38 bool JSDeprecatedCSSOMValueOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     38bool JSDeprecatedCSSOMValueOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    3939{
    4040    JSDeprecatedCSSOMValue* jsCSSValue = jsCast<JSDeprecatedCSSOMValue*>(handle.slot()->asCell());
    4141    if (!jsCSSValue->hasCustomProperties(*jsCSSValue->vm()))
    4242        return false;
     43
     44    if (UNLIKELY(reason))
     45        *reason = "CSSStyleDeclaration is opaque root";
     46
    4347    return visitor.containsOpaqueRoot(root(&jsCSSValue->wrapped().owner()));
    4448}
  • TabularUnified trunk/Source/WebCore/bindings/js/JSDocumentCustom.cpp

    r223476 r235271  
    2727#include "NodeTraversal.h"
    2828#include "SVGDocument.h"
     29#include <JavaScriptCore/HeapSnapshotBuilder.h>
    2930
    3031
     
    9495}
    9596
     97void JSDocument::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     98{
     99    Base::heapSnapshot(cell, builder);
     100    auto* thisObject = jsCast<JSDocument*>(cell);
     101    builder.setLabelForCell(cell, thisObject->wrapped().url().string());
     102}
     103
    96104} // namespace WebCore
  • TabularUnified trunk/Source/WebCore/bindings/js/JSMicrotaskCallback.h

    r234586 r235271  
    4141    {
    4242        auto protectedThis { makeRef(*this) };
    43         VM& vm = m_globalObject->vm();
    44         JSLockHolder lock(vm);
     43        JSC::VM& vm = m_globalObject->vm();
     44        JSC::JSLockHolder lock(vm);
    4545        auto scope = DECLARE_THROW_SCOPE(vm);
    4646        JSExecState::runTask(m_globalObject->globalExec(), m_task);
     
    5555    }
    5656
    57     Strong<JSDOMGlobalObject> m_globalObject;
     57    JSC::Strong<JSDOMGlobalObject> m_globalObject;
    5858    Ref<JSC::Microtask> m_task;
    5959};
  • TabularUnified trunk/Source/WebCore/bindings/js/JSMutationObserverCustom.cpp

    r223476 r235271  
    4545}
    4646
    47 bool JSMutationObserverOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     47bool JSMutationObserverOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char**reason)
    4848{
    4949    for (auto* node : jsCast<JSMutationObserver*>(handle.slot()->asCell())->wrapped().observedNodes()) {
    50         if (visitor.containsOpaqueRoot(root(node)))
     50        if (visitor.containsOpaqueRoot(root(node))) {
     51            if (UNLIKELY(reason))
     52                *reason = "Reachable from observed nodes";
    5153            return true;
     54        }
    5255    }
    5356    return false;
  • TabularUnified trunk/Source/WebCore/bindings/js/JSNavigatorCustom.cpp

    r225203 r235271  
    2929namespace WebCore {
    3030
    31 void JSNavigator::visitAdditionalChildren(SlotVisitor& visitor)
     31void JSNavigator::visitAdditionalChildren(JSC::SlotVisitor& visitor)
    3232{
    3333#if ENABLE(SERVICE_WORKER)
  • TabularUnified trunk/Source/WebCore/bindings/js/JSNodeCustom.cpp

    r229410 r235271  
    7272using namespace HTMLNames;
    7373
    74 static inline bool isReachableFromDOM(Node* node, SlotVisitor& visitor)
     74static inline bool isReachableFromDOM(Node* node, SlotVisitor& visitor, const char** reason)
    7575{
    7676    if (!node->isConnected()) {
     
    8484            // FIXME: The DOM should manage this issue without the help of JavaScript wrappers.
    8585            if (is<HTMLImageElement>(element)) {
    86                 if (downcast<HTMLImageElement>(element).hasPendingActivity())
     86                if (downcast<HTMLImageElement>(element).hasPendingActivity()) {
     87                    if (UNLIKELY(reason))
     88                        *reason = "Image element with pending activity";
    8789                    return true;
     90                }
    8891            }
    8992#if ENABLE(VIDEO)
    9093            else if (is<HTMLAudioElement>(element)) {
    91                 if (!downcast<HTMLAudioElement>(element).paused())
     94                if (!downcast<HTMLAudioElement>(element).paused()) {
     95                    if (UNLIKELY(reason))
     96                        *reason = "Audio element which is not paused";
    9297                    return true;
     98                }
    9399            }
    94100#endif
     
    97103        // If a node is firing event listeners, its wrapper is observable because
    98104        // its wrapper is responsible for marking those event listeners.
    99         if (node->isFiringEventListeners())
     105        if (node->isFiringEventListeners()) {
     106            if (UNLIKELY(reason))
     107                *reason = "Node which is firing event listeners";
    100108            return true;
     109        }
    101110    }
    102111
     112    if (UNLIKELY(reason))
     113        *reason = "Connected node";
     114
    103115    return visitor.containsOpaqueRoot(root(node));
    104116}
    105117
    106 bool JSNodeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     118bool JSNodeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    107119{
    108120    JSNode* jsNode = jsCast<JSNode*>(handle.slot()->asCell());
    109     return isReachableFromDOM(&jsNode->wrapped(), visitor);
     121    return isReachableFromDOM(&jsNode->wrapped(), visitor, reason);
    110122}
    111123
  • TabularUnified trunk/Source/WebCore/bindings/js/JSNodeListCustom.cpp

    r232337 r235271  
    3838using namespace JSC;
    3939
    40 bool JSNodeListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     40bool JSNodeListOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    4141{
    4242    JSNodeList* jsNodeList = jsCast<JSNodeList*>(handle.slot()->asCell());
    4343    if (!jsNodeList->hasCustomProperties(*jsNodeList->vm()))
    4444        return false;
    45     if (jsNodeList->wrapped().isLiveNodeList())
     45
     46    if (jsNodeList->wrapped().isLiveNodeList()) {
     47        if (UNLIKELY(reason))
     48            *reason = "LiveNodeList owner is opaque root";
     49
    4650        return visitor.containsOpaqueRoot(root(static_cast<LiveNodeList&>(jsNodeList->wrapped()).ownerNode()));
    47     if (jsNodeList->wrapped().isChildNodeList())
     51    }
     52
     53    if (jsNodeList->wrapped().isChildNodeList()) {
     54        if (UNLIKELY(reason))
     55            *reason = "ChildNodeList owner is opaque root";
     56
    4857        return visitor.containsOpaqueRoot(root(static_cast<ChildNodeList&>(jsNodeList->wrapped()).ownerNode()));
    49     if (jsNodeList->wrapped().isEmptyNodeList())
     58    }
     59
     60    if (jsNodeList->wrapped().isEmptyNodeList()) {
     61        if (UNLIKELY(reason))
     62            *reason = "EmptyNodeList owner is opaque root";
     63
    5064        return visitor.containsOpaqueRoot(root(static_cast<EmptyNodeList&>(jsNodeList->wrapped()).ownerNode()));
     65    }
    5166    return false;
    5267}
  • TabularUnified trunk/Source/WebCore/bindings/js/JSOffscreenCanvasRenderingContext2DCustom.cpp

    r225816 r235271  
    2929}
    3030
    31 bool JSOffscreenCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     31bool JSOffscreenCanvasRenderingContext2DOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    3232{
     33    if (UNLIKELY(reason))
     34        *reason = "Canvas is opaque root";
     35
    3336    JSOffscreenCanvasRenderingContext2D* jsOffscreenCanvasRenderingContext = jsCast<JSOffscreenCanvasRenderingContext2D*>(handle.slot()->asCell());
    3437    void* root = WebCore::root(&jsOffscreenCanvasRenderingContext->wrapped().canvas());
  • TabularUnified trunk/Source/WebCore/bindings/js/JSPerformanceObserverCustom.cpp

    r233053 r235271  
    3636}
    3737
    38 bool JSPerformanceObserverOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor&)
     38bool JSPerformanceObserverOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor&, const char** reason)
    3939{
     40    if (UNLIKELY(reason))
     41        *reason = "Registered PerformanceObserver callback";
     42
    4043    return jsCast<JSPerformanceObserver*>(handle.slot()->asCell())->wrapped().isRegistered();
    4144}
  • TabularUnified trunk/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp

    r228260 r235271  
    3838
    3939namespace WebCore {
     40using namespace JSC;
    4041
    4142JSValue JSPopStateEvent::state(ExecState& state) const
  • TabularUnified trunk/Source/WebCore/bindings/js/JSTextTrackCueCustom.cpp

    r223476 r235271  
    3939using namespace JSC;
    4040
    41 bool JSTextTrackCueOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     41bool JSTextTrackCueOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    4242{
    4343    JSTextTrackCue* jsTextTrackCue = jsCast<JSTextTrackCue*>(handle.slot()->asCell());
     
    4646    // If the cue is firing event listeners, its wrapper is reachable because
    4747    // the wrapper is responsible for marking those event listeners.
    48     if (textTrackCue.isFiringEventListeners())
     48    if (textTrackCue.isFiringEventListeners()) {
     49        if (UNLIKELY(reason))
     50            *reason = "TextTrackCue is firing event listeners";
    4951        return true;
     52    }
    5053
    5154    // If the cue is not associated with a track, it is not reachable.
    5255    if (!textTrackCue.track())
    5356        return false;
     57
     58    if (UNLIKELY(reason))
     59        *reason = "TextTrack is an opaque root";
    5460
    5561    return visitor.containsOpaqueRoot(root(textTrackCue.track()));
  • TabularUnified trunk/Source/WebCore/bindings/js/WebCoreTypedArrayController.cpp

    r228218 r235271  
    5454}
    5555
    56 bool WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor)
     56bool WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, JSC::SlotVisitor& visitor, const char** reason)
    5757{
     58    if (UNLIKELY(reason))
     59        *reason = "ArrayBuffer is opaque root";
    5860    auto& wrapper = *JSC::jsCast<JSC::JSArrayBuffer*>(handle.slot()->asCell());
    5961    return visitor.containsOpaqueRoot(wrapper.impl());
  • TabularUnified trunk/Source/WebCore/bindings/js/WebCoreTypedArrayController.h

    r228218 r235271  
    4949    class JSArrayBufferOwner : public JSC::WeakHandleOwner {
    5050    public:
    51         bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&) override;
     51        bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**) override;
    5252        void finalize(JSC::Handle<JSC::Unknown>, void* context) override;
    5353    };
  • TabularUnified trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r234636 r235271  
    26582658        push(@headerContent, "    static bool preventExtensions(JSC::JSObject*, JSC::ExecState*);\n");
    26592659    }
    2660    
     2660
    26612661    if (InstanceNeedsEstimatedSize($interface)) {
    26622662        push(@headerContent, "    static size_t estimatedSize(JSCell*, JSC::VM&);\n");
     
    27592759        }
    27602760    }
     2761
     2762    if (NeedsImplementationClass($interface)) {
     2763        push(@headerContent, "    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);\n");
     2764    }
    27612765   
    27622766    if ($numCustomAttributes > 0) {
     
    28682872        $headerIncludes{"<wtf/NeverDestroyed.h>"} = 1;
    28692873        push(@headerContent, "public:\n");
    2870         push(@headerContent, "    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);\n");
     2874        push(@headerContent, "    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);\n");
    28712875        push(@headerContent, "    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);\n");
    28722876        push(@headerContent, "};\n");
     
    45224526    }
    45234527
     4528    if (NeedsImplementationClass($interface) && !$interface->extendedAttributes->{CustomHeapSnapshot}) {
     4529        AddToImplIncludes("<JavaScriptCore/HeapSnapshotBuilder.h>");
     4530        AddToImplIncludes("ScriptExecutionContext.h");
     4531        AddToImplIncludes("URL.h");
     4532        push(@implContent, "void ${className}::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)\n");
     4533        push(@implContent, "{\n");
     4534        push(@implContent, "    auto* thisObject = jsCast<${className}*>(cell);\n");
     4535        push(@implContent, "    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());\n");
     4536        push(@implContent, "    if (thisObject->scriptExecutionContext())\n");
     4537        push(@implContent, "        builder.setLabelForCell(cell, String::format(\"url %s\", thisObject->scriptExecutionContext()->url().string().utf8().data()));\n");
     4538        push(@implContent, "    Base::heapSnapshot(cell, builder);\n");
     4539        push(@implContent, "}\n\n");
     4540    }
     4541
    45244542    if ($indexedGetterOperation) {
    45254543        $implIncludes{"URL.h"} = 1 if $indexedGetterOperation->type->name eq "DOMString";
     
    45314549
    45324550    if (ShouldGenerateWrapperOwnerCode($hasParent, $interface) && !GetCustomIsReachable($interface)) {
    4533         push(@implContent, "bool JS${interfaceName}Owner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)\n");
     4551        push(@implContent, "bool JS${interfaceName}Owner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)\n");
    45344552        push(@implContent, "{\n");
    45354553        # All ActiveDOMObjects implement hasPendingActivity(), but not all of them
     
    45444562            push(@implContent, "    auto* js${interfaceName} = jsCast<JS${interfaceName}*>(handle.slot()->asCell());\n");
    45454563            $emittedJSCast = 1;
    4546             push(@implContent, "    if (js${interfaceName}->wrapped().hasPendingActivity())\n");
     4564            push(@implContent, "    if (js${interfaceName}->wrapped().hasPendingActivity()) {\n");
     4565            push(@implContent, "        if (UNLIKELY(reason))\n");
     4566            push(@implContent, "            *reason = \"ActiveDOMObject with pending activity\";\n");
    45474567            push(@implContent, "        return true;\n");
     4568            push(@implContent, "     }\n");
    45484569        }
    45494570        if ($codeGenerator->InheritsInterface($interface, "EventTarget")) {
     
    45524573                $emittedJSCast = 1;
    45534574            }
    4554             push(@implContent, "    if (js${interfaceName}->wrapped().isFiringEventListeners())\n");
     4575            push(@implContent, "    if (js${interfaceName}->wrapped().isFiringEventListeners()) {\n");
     4576            push(@implContent, "        if (UNLIKELY(reason))\n");
     4577            push(@implContent, "            *reason = \"EventTarget firing event listeners\";\n");
    45554578            push(@implContent, "        return true;\n");
     4579            push(@implContent, "    }\n");
    45564580        }
    45574581        if ($codeGenerator->InheritsInterface($interface, "Node")) {
     
    45604584                $emittedJSCast = 1;
    45614585            }
    4562             push(@implContent, "    if (JSNodeOwner::isReachableFromOpaqueRoots(handle, 0, visitor))\n");
     4586            push(@implContent, "    if (JSNodeOwner::isReachableFromOpaqueRoots(handle, 0, visitor, reason))\n");
    45634587            push(@implContent, "        return true;\n");
    45644588        }
     
    45724596            if (GetGenerateIsReachable($interface) eq "Impl") {
    45734597                $rootString  = "    ${implType}* root = &js${interfaceName}->wrapped();\n";
     4598                $rootString .= "    if (UNLIKELY(reason))\n";
     4599                $rootString .= "        *reason = \"Reachable from ${interfaceName}\";\n";
    45744600            } elsif (GetGenerateIsReachable($interface) eq "ImplWebGLRenderingContext") {
    45754601                $rootString  = "    WebGLRenderingContextBase* root = WTF::getPtr(js${interfaceName}->wrapped().context());\n";
     4602                $rootString .= "    if (UNLIKELY(reason))\n";
     4603                $rootString .= "        *reason = \"Reachable from ${interfaceName}\";\n";
    45764604            } elsif (GetGenerateIsReachable($interface) eq "ImplFrame") {
    45774605                $rootString  = "    Frame* root = WTF::getPtr(js${interfaceName}->wrapped().frame());\n";
    45784606                $rootString .= "    if (!root)\n";
    45794607                $rootString .= "        return false;\n";
     4608                $rootString .= "    if (UNLIKELY(reason))\n";
     4609                $rootString .= "        *reason = \"Reachable from Frame\";\n";
    45804610            } elsif (GetGenerateIsReachable($interface) eq "ImplDocument") {
    45814611                $rootString  = "    Document* root = WTF::getPtr(js${interfaceName}->wrapped().document());\n";
    45824612                $rootString .= "    if (!root)\n";
    45834613                $rootString .= "        return false;\n";
     4614                $rootString .= "    if (UNLIKELY(reason))\n";
     4615                $rootString .= "        *reason = \"Reachable from Document\";\n";
    45844616            } elsif (GetGenerateIsReachable($interface) eq "ImplElementRoot") {
    45854617                $implIncludes{"Element.h"} = 1;
     
    45884620                $rootString .= "    if (!element)\n";
    45894621                $rootString .= "        return false;\n";
     4622                $rootString .= "    if (UNLIKELY(reason))\n";
     4623                $rootString .= "        *reason = \"Reachable from ${interfaceName}Owner\";\n";
    45904624                $rootString .= "    void* root = WebCore::root(element);\n";
    45914625            } elsif (GetGenerateIsReachable($interface) eq "ImplOwnerNodeRoot") {
     
    45934627                $implIncludes{"JSNodeCustom.h"} = 1;
    45944628                $rootString  = "    void* root = WebCore::root(js${interfaceName}->wrapped().ownerNode());\n";
     4629                $rootString .= "    if (UNLIKELY(reason))\n";
     4630                $rootString .= "        *reason = \"Reachable from ${interfaceName} ownerNode\";\n";
    45954631            } elsif (GetGenerateIsReachable($interface) eq "ImplScriptExecutionContext") {
    45964632                $rootString  = "    ScriptExecutionContext* root = WTF::getPtr(js${interfaceName}->wrapped().scriptExecutionContext());\n";
    45974633                $rootString .= "    if (!root)\n";
    45984634                $rootString .= "        return false;\n";
     4635                $rootString .= "    if (UNLIKELY(reason))\n";
     4636                $rootString .= "        *reason = \"Reachable from ScriptExecutionContext\";\n";
    45994637            } else {
    46004638                $rootString  = "    void* root = WebCore::root(&js${interfaceName}->wrapped());\n";
     4639                $rootString .= "    if (UNLIKELY(reason))\n";
     4640                $rootString .= "        *reason = \"Reachable from js${interfaceName}\";\n";
    46014641            }
    46024642
     
    46084648            }
    46094649            push(@implContent, "    UNUSED_PARAM(visitor);\n");
     4650            push(@implContent, "    UNUSED_PARAM(reason);\n");
    46104651            push(@implContent, "    return false;\n");
    46114652        }
  • TabularUnified trunk/Source/WebCore/bindings/scripts/IDLAttributes.json

    r232499 r235271  
    119119            "contextsAllowed": ["attribute"]
    120120        },
     121        "CustomHeapSnapshot": {
     122            "contextsAllowed": ["interface"]
     123        },
    121124        "CustomIndexedSetter": {
    122125            "contextsAllowed": ["interface"]
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSInterfaceName.cpp

    r233765 r235271  
    2626#include "JSDOMExceptionHandling.h"
    2727#include "JSDOMWrapperCache.h"
     28#include "ScriptExecutionContext.h"
     29#include "URL.h"
    2830#include <JavaScriptCore/FunctionPrototype.h>
     31#include <JavaScriptCore/HeapSnapshotBuilder.h>
    2932#include <JavaScriptCore/JSCInlines.h>
    3033#include <wtf/GetPtr.h>
     
    169172}
    170173
    171 bool JSInterfaceNameOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     174void JSInterfaceName::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     175{
     176    auto* thisObject = jsCast<JSInterfaceName*>(cell);
     177    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     178    if (thisObject->scriptExecutionContext())
     179        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     180    Base::heapSnapshot(cell, builder);
     181}
     182
     183bool JSInterfaceNameOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    172184{
    173185    UNUSED_PARAM(handle);
    174186    UNUSED_PARAM(visitor);
     187    UNUSED_PARAM(reason);
    175188    return false;
    176189}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSInterfaceName.h

    r233765 r235271  
    5353    static void visitChildren(JSCell*, JSC::SlotVisitor&);
    5454
     55    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5556protected:
    5657    JSInterfaceName(JSC::Structure*, JSDOMGlobalObject&, Ref<InterfaceName>&&);
     
    6162class JSInterfaceNameOwner : public JSC::WeakHandleOwner {
    6263public:
    63     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     64    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6465    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6566};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.cpp

    r233122 r235271  
    3131#include "JSDOMOperation.h"
    3232#include "JSDOMWrapperCache.h"
     33#include "ScriptExecutionContext.h"
     34#include "URL.h"
    3335#include <JavaScriptCore/BuiltinNames.h>
    3436#include <JavaScriptCore/FunctionPrototype.h>
     37#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3538#include <JavaScriptCore/JSCInlines.h>
    3639#include <wtf/GetPtr.h>
     
    338341}
    339342
    340 bool JSMapLikeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     343void JSMapLike::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     344{
     345    auto* thisObject = jsCast<JSMapLike*>(cell);
     346    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     347    if (thisObject->scriptExecutionContext())
     348        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     349    Base::heapSnapshot(cell, builder);
     350}
     351
     352bool JSMapLikeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    341353{
    342354    UNUSED_PARAM(handle);
    343355    UNUSED_PARAM(visitor);
     356    UNUSED_PARAM(reason);
    344357    return false;
    345358}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSMapLike.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSMapLike(JSC::Structure*, JSDOMGlobalObject&, Ref<MapLike>&&);
     
    5859class JSMapLikeOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.cpp

    r233122 r235271  
    3131#include "JSDOMOperation.h"
    3232#include "JSDOMWrapperCache.h"
     33#include "ScriptExecutionContext.h"
     34#include "URL.h"
    3335#include <JavaScriptCore/BuiltinNames.h>
    3436#include <JavaScriptCore/FunctionPrototype.h>
     37#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3538#include <JavaScriptCore/JSCInlines.h>
    3639#include <wtf/GetPtr.h>
     
    287290}
    288291
    289 bool JSReadOnlyMapLikeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     292void JSReadOnlyMapLike::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     293{
     294    auto* thisObject = jsCast<JSReadOnlyMapLike*>(cell);
     295    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     296    if (thisObject->scriptExecutionContext())
     297        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     298    Base::heapSnapshot(cell, builder);
     299}
     300
     301bool JSReadOnlyMapLikeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    290302{
    291303    UNUSED_PARAM(handle);
    292304    UNUSED_PARAM(visitor);
     305    UNUSED_PARAM(reason);
    293306    return false;
    294307}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSReadOnlyMapLike.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSReadOnlyMapLike(JSC::Structure*, JSDOMGlobalObject&, Ref<ReadOnlyMapLike>&&);
     
    5859class JSReadOnlyMapLikeOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.cpp

    r233122 r235271  
    3333#include "JSDOMWrapperCache.h"
    3434#include "JSNode.h"
     35#include "ScriptExecutionContext.h"
     36#include "URL.h"
    3537#include <JavaScriptCore/FunctionPrototype.h>
     38#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3639#include <JavaScriptCore/JSCInlines.h>
    3740#include <wtf/GetPtr.h>
     
    248251}
    249252
    250 bool JSTestActiveDOMObjectOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     253void JSTestActiveDOMObject::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     254{
     255    auto* thisObject = jsCast<JSTestActiveDOMObject*>(cell);
     256    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     257    if (thisObject->scriptExecutionContext())
     258        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     259    Base::heapSnapshot(cell, builder);
     260}
     261
     262bool JSTestActiveDOMObjectOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    251263{
    252264    UNUSED_PARAM(handle);
    253265    UNUSED_PARAM(visitor);
     266    UNUSED_PARAM(reason);
    254267    return false;
    255268}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253public:
    5354    static const unsigned StructureFlags = JSC::HasStaticPropertyTable | Base::StructureFlags;
     
    6061class JSTestActiveDOMObjectOwner : public JSC::WeakHandleOwner {
    6162public:
    62     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     63    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6364    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6465};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCEReactions.cpp

    r234636 r235271  
    3434#include "JSDOMWrapperCache.h"
    3535#include "JSTestCEReactionsStringifier.h"
     36#include "ScriptExecutionContext.h"
     37#include "URL.h"
    3638#include <JavaScriptCore/FunctionPrototype.h>
     39#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3740#include <JavaScriptCore/JSCInlines.h>
    3841#include <wtf/GetPtr.h>
     
    428431}
    429432
    430 bool JSTestCEReactionsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     433void JSTestCEReactions::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     434{
     435    auto* thisObject = jsCast<JSTestCEReactions*>(cell);
     436    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     437    if (thisObject->scriptExecutionContext())
     438        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     439    Base::heapSnapshot(cell, builder);
     440}
     441
     442bool JSTestCEReactionsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    431443{
    432444    UNUSED_PARAM(handle);
    433445    UNUSED_PARAM(visitor);
     446    UNUSED_PARAM(reason);
    434447    return false;
    435448}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCEReactions.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestCEReactions(JSC::Structure*, JSDOMGlobalObject&, Ref<TestCEReactions>&&);
     
    5859class JSTestCEReactionsOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCEReactionsStringifier.cpp

    r234636 r235271  
    3030#include "JSDOMOperation.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
     33#include "URL.h"
    3234#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3336#include <JavaScriptCore/JSCInlines.h>
    3437#include <wtf/GetPtr.h>
     
    257260}
    258261
    259 bool JSTestCEReactionsStringifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     262void JSTestCEReactionsStringifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     263{
     264    auto* thisObject = jsCast<JSTestCEReactionsStringifier*>(cell);
     265    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     266    if (thisObject->scriptExecutionContext())
     267        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     268    Base::heapSnapshot(cell, builder);
     269}
     270
     271bool JSTestCEReactionsStringifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    260272{
    261273    UNUSED_PARAM(handle);
    262274    UNUSED_PARAM(visitor);
     275    UNUSED_PARAM(reason);
    263276    return false;
    264277}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCEReactionsStringifier.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestCEReactionsStringifier(JSC::Structure*, JSDOMGlobalObject&, Ref<TestCEReactionsStringifier>&&);
     
    5859class JSTestCEReactionsStringifierOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp

    r233122 r235271  
    3737#include "JSDOMWrapperCache.h"
    3838#include "JSNode.h"
     39#include "ScriptExecutionContext.h"
     40#include "URL.h"
    3941#include <JavaScriptCore/FunctionPrototype.h>
     42#include <JavaScriptCore/HeapSnapshotBuilder.h>
    4043#include <JavaScriptCore/JSCInlines.h>
    4144#include <wtf/GetPtr.h>
     
    521524}
    522525
    523 bool JSTestCallTracerOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     526void JSTestCallTracer::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     527{
     528    auto* thisObject = jsCast<JSTestCallTracer*>(cell);
     529    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     530    if (thisObject->scriptExecutionContext())
     531        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     532    Base::heapSnapshot(cell, builder);
     533}
     534
     535bool JSTestCallTracerOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    524536{
    525537    UNUSED_PARAM(handle);
    526538    UNUSED_PARAM(visitor);
     539    UNUSED_PARAM(reason);
    527540    return false;
    528541}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.h

    r219964 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestCallTracer(JSC::Structure*, JSDOMGlobalObject&, Ref<TestCallTracer>&&);
     
    5859class JSTestCallTracerOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.cpp

    r233122 r235271  
    2626#include "JSDOMExceptionHandling.h"
    2727#include "JSDOMWrapperCache.h"
     28#include "ScriptExecutionContext.h"
    2829#include "TestClassWithJSBuiltinConstructorBuiltins.h"
     30#include "URL.h"
    2931#include <JavaScriptCore/FunctionPrototype.h>
     32#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3033#include <JavaScriptCore/JSCInlines.h>
    3134#include <wtf/GetPtr.h>
     
    161164}
    162165
    163 bool JSTestClassWithJSBuiltinConstructorOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     166void JSTestClassWithJSBuiltinConstructor::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     167{
     168    auto* thisObject = jsCast<JSTestClassWithJSBuiltinConstructor*>(cell);
     169    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     170    if (thisObject->scriptExecutionContext())
     171        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     172    Base::heapSnapshot(cell, builder);
     173}
     174
     175bool JSTestClassWithJSBuiltinConstructorOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    164176{
    165177    UNUSED_PARAM(handle);
    166178    UNUSED_PARAM(visitor);
     179    UNUSED_PARAM(reason);
    167180    return false;
    168181}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.h

    r217642 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestClassWithJSBuiltinConstructor(JSC::Structure*, JSDOMGlobalObject&, Ref<TestClassWithJSBuiltinConstructor>&&);
     
    5859class JSTestClassWithJSBuiltinConstructorOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCustomConstructorWithNoInterfaceObject.cpp

    r233122 r235271  
    2626#include "JSDOMExceptionHandling.h"
    2727#include "JSDOMWrapperCache.h"
     28#include "ScriptExecutionContext.h"
     29#include "URL.h"
    2830#include <JavaScriptCore/FunctionPrototype.h>
     31#include <JavaScriptCore/HeapSnapshotBuilder.h>
    2932#include <JavaScriptCore/JSCInlines.h>
    3033#include <wtf/GetPtr.h>
     
    159162}
    160163
    161 bool JSTestCustomConstructorWithNoInterfaceObjectOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     164void JSTestCustomConstructorWithNoInterfaceObject::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     165{
     166    auto* thisObject = jsCast<JSTestCustomConstructorWithNoInterfaceObject*>(cell);
     167    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     168    if (thisObject->scriptExecutionContext())
     169        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     170    Base::heapSnapshot(cell, builder);
     171}
     172
     173bool JSTestCustomConstructorWithNoInterfaceObjectOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    162174{
    163175    UNUSED_PARAM(handle);
    164176    UNUSED_PARAM(visitor);
     177    UNUSED_PARAM(reason);
    165178    return false;
    166179}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestCustomConstructorWithNoInterfaceObject.h

    r216198 r235271  
    4949    }
    5050
     51    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5152protected:
    5253    JSTestCustomConstructorWithNoInterfaceObject(JSC::Structure*, JSDOMGlobalObject&, Ref<TestCustomConstructorWithNoInterfaceObject>&&);
     
    5758class JSTestCustomConstructorWithNoInterfaceObjectOwner : public JSC::WeakHandleOwner {
    5859public:
    59     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     60    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6061    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6162};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestDOMJIT.cpp

    r233122 r235271  
    4141#include "JSElement.h"
    4242#include "JSNodeList.h"
     43#include "ScriptExecutionContext.h"
     44#include "URL.h"
    4345#include <JavaScriptCore/FrameTracers.h>
     46#include <JavaScriptCore/HeapSnapshotBuilder.h>
    4447#include <JavaScriptCore/JSCInlines.h>
    4548#include <wtf/GetPtr.h>
     
    12591262}
    12601263
    1261 
    1262 }
     1264void JSTestDOMJIT::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     1265{
     1266    auto* thisObject = jsCast<JSTestDOMJIT*>(cell);
     1267    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     1268    if (thisObject->scriptExecutionContext())
     1269        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     1270    Base::heapSnapshot(cell, builder);
     1271}
     1272
     1273
     1274}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestDOMJIT.h

    r230831 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253    TestDOMJIT& wrapped() const
    5354    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEnabledBySetting.cpp

    r233122 r235271  
    3030#include "JSDOMWrapperCache.h"
    3131#include "JSTestSubObj.h"
     32#include "ScriptExecutionContext.h"
    3233#include "Settings.h"
     34#include "URL.h"
    3335#include "WebCoreJSClientData.h"
    3436#include <JavaScriptCore/FunctionPrototype.h>
     37#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3538#include <JavaScriptCore/JSCInlines.h>
    3639#include <wtf/GetPtr.h>
     
    295298#endif
    296299
    297 bool JSTestEnabledBySettingOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     300void JSTestEnabledBySetting::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     301{
     302    auto* thisObject = jsCast<JSTestEnabledBySetting*>(cell);
     303    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     304    if (thisObject->scriptExecutionContext())
     305        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     306    Base::heapSnapshot(cell, builder);
     307}
     308
     309bool JSTestEnabledBySettingOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    298310{
    299311    UNUSED_PARAM(handle);
    300312    UNUSED_PARAM(visitor);
     313    UNUSED_PARAM(reason);
    301314    return false;
    302315}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEnabledBySetting.h

    r221585 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253public:
    5354    static const unsigned StructureFlags = JSC::HasStaticPropertyTable | Base::StructureFlags;
     
    6061class JSTestEnabledBySettingOwner : public JSC::WeakHandleOwner {
    6162public:
    62     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     63    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6364    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6465};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp

    r233122 r235271  
    3030#include "JSDOMExceptionHandling.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
     33#include "URL.h"
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    304307#endif
    305308
     309void JSTestEventConstructor::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     310{
     311    auto* thisObject = jsCast<JSTestEventConstructor*>(cell);
     312    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     313    if (thisObject->scriptExecutionContext())
     314        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     315    Base::heapSnapshot(cell, builder);
     316}
     317
    306318#if ENABLE(BINDING_INTEGRITY)
    307319#if PLATFORM(WIN)
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.h

    r230831 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253    TestEventConstructor& wrapped() const
    5354    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventTarget.cpp

    r233122 r235271  
    3232#include "JSDOMWrapperCache.h"
    3333#include "JSNode.h"
     34#include "ScriptExecutionContext.h"
     35#include "URL.h"
     36#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3437#include <JavaScriptCore/JSCInlines.h>
    3538#include <JavaScriptCore/PropertyNameArray.h>
     
    247250}
    248251
     252void JSTestEventTarget::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     253{
     254    auto* thisObject = jsCast<JSTestEventTarget*>(cell);
     255    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     256    if (thisObject->scriptExecutionContext())
     257        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     258    Base::heapSnapshot(cell, builder);
     259}
     260
    249261#if ENABLE(BINDING_INTEGRITY)
    250262#if PLATFORM(WIN)
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventTarget.h

    r230831 r235271  
    5454
    5555    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     56    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5657    TestEventTarget& wrapped() const
    5758    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestException.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    178181}
    179182
    180 bool JSTestExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     183void JSTestException::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     184{
     185    auto* thisObject = jsCast<JSTestException*>(cell);
     186    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     187    if (thisObject->scriptExecutionContext())
     188        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     189    Base::heapSnapshot(cell, builder);
     190}
     191
     192bool JSTestExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    181193{
    182194    UNUSED_PARAM(handle);
    183195    UNUSED_PARAM(visitor);
     196    UNUSED_PARAM(reason);
    184197    return false;
    185198}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestException.h

    r228038 r235271  
    5151
    5252    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     53    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5354protected:
    5455    JSTestException(JSC::Structure*, JSDOMGlobalObject&, Ref<TestException>&&);
     
    5960class JSTestExceptionOwner : public JSC::WeakHandleOwner {
    6061public:
    61     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     62    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6263    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6364};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp

    r233122 r235271  
    2929#include "JSDOMWrapperCache.h"
    3030#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3132#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3234#include <JavaScriptCore/JSCInlines.h>
    3335#include <wtf/GetPtr.h>
     
    184186}
    185187
    186 bool JSTestGenerateIsReachableOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     188void JSTestGenerateIsReachable::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     189{
     190    auto* thisObject = jsCast<JSTestGenerateIsReachable*>(cell);
     191    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     192    if (thisObject->scriptExecutionContext())
     193        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     194    Base::heapSnapshot(cell, builder);
     195}
     196
     197bool JSTestGenerateIsReachableOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    187198{
    188199    auto* jsTestGenerateIsReachable = jsCast<JSTestGenerateIsReachable*>(handle.slot()->asCell());
    189200    TestGenerateIsReachable* root = &jsTestGenerateIsReachable->wrapped();
     201    if (UNLIKELY(reason))
     202        *reason = "Reachable from TestGenerateIsReachable";
    190203    return visitor.containsOpaqueRoot(root);
    191204}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGenerateIsReachable.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestGenerateIsReachable(JSC::Structure*, JSDOMGlobalObject&, Ref<TestGenerateIsReachable>&&);
     
    5859class JSTestGenerateIsReachableOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp

    r233122 r235271  
    3535#include "RuntimeEnabledFeatures.h"
    3636#include "ScriptExecutionContext.h"
     37#include "URL.h"
    3738#include "WebCoreJSClientData.h"
    3839#include <JavaScriptCore/FunctionPrototype.h>
     40#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3941#include <JavaScriptCore/JSCInlines.h>
    4042#include <wtf/GetPtr.h>
     
    569571#endif
    570572
    571 bool JSTestGlobalObjectOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     573void JSTestGlobalObject::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     574{
     575    auto* thisObject = jsCast<JSTestGlobalObject*>(cell);
     576    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     577    if (thisObject->scriptExecutionContext())
     578        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     579    Base::heapSnapshot(cell, builder);
     580}
     581
     582bool JSTestGlobalObjectOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    572583{
    573584    UNUSED_PARAM(handle);
    574585    UNUSED_PARAM(visitor);
     586    UNUSED_PARAM(reason);
    575587    return false;
    576588}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.h

    r216198 r235271  
    5252
    5353    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     54    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5455public:
    5556    static const unsigned StructureFlags = JSC::HasStaticPropertyTable | Base::StructureFlags;
     
    6263class JSTestGlobalObjectOwner : public JSC::WeakHandleOwner {
    6364public:
    64     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     65    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6566    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6667};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.cpp

    r233122 r235271  
    2727#include "JSDOMExceptionHandling.h"
    2828#include "JSDOMWrapperCache.h"
     29#include "ScriptExecutionContext.h"
    2930#include "URL.h"
    3031#include <JavaScriptCore/FunctionPrototype.h>
     32#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3133#include <JavaScriptCore/JSCInlines.h>
    3234#include <JavaScriptCore/PropertyNameArray.h>
     
    247249}
    248250
    249 bool JSTestIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     251void JSTestIndexedSetterNoIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     252{
     253    auto* thisObject = jsCast<JSTestIndexedSetterNoIdentifier*>(cell);
     254    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     255    if (thisObject->scriptExecutionContext())
     256        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     257    Base::heapSnapshot(cell, builder);
     258}
     259
     260bool JSTestIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    250261{
    251262    UNUSED_PARAM(handle);
    252263    UNUSED_PARAM(visitor);
     264    UNUSED_PARAM(reason);
    253265    return false;
    254266}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestIndexedSetterNoIdentifierOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.cpp

    r233122 r235271  
    2727#include "JSDOMExceptionHandling.h"
    2828#include "JSDOMWrapperCache.h"
     29#include "ScriptExecutionContext.h"
    2930#include "URL.h"
    3031#include <JavaScriptCore/FunctionPrototype.h>
     32#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3133#include <JavaScriptCore/JSCInlines.h>
    3234#include <JavaScriptCore/PropertyNameArray.h>
     
    247249}
    248250
    249 bool JSTestIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     251void JSTestIndexedSetterThrowingException::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     252{
     253    auto* thisObject = jsCast<JSTestIndexedSetterThrowingException*>(cell);
     254    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     255    if (thisObject->scriptExecutionContext())
     256        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     257    Base::heapSnapshot(cell, builder);
     258}
     259
     260bool JSTestIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    250261{
    251262    UNUSED_PARAM(handle);
    252263    UNUSED_PARAM(visitor);
     264    UNUSED_PARAM(reason);
    253265    return false;
    254266}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestIndexedSetterThrowingExceptionOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
    3132#include "URL.h"
    3233#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3335#include <JavaScriptCore/JSCInlines.h>
    3436#include <JavaScriptCore/PropertyNameArray.h>
     
    279281}
    280282
    281 bool JSTestIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     283void JSTestIndexedSetterWithIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     284{
     285    auto* thisObject = jsCast<JSTestIndexedSetterWithIdentifier*>(cell);
     286    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     287    if (thisObject->scriptExecutionContext())
     288        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     289    Base::heapSnapshot(cell, builder);
     290}
     291
     292bool JSTestIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    282293{
    283294    UNUSED_PARAM(handle);
    284295    UNUSED_PARAM(visitor);
     296    UNUSED_PARAM(reason);
    285297    return false;
    286298}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestIndexedSetterWithIdentifierOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp

    r233122 r235271  
    3333#include "JSDOMOperation.h"
    3434#include "JSDOMWrapperCache.h"
     35#include "ScriptExecutionContext.h"
    3536#include "TestSupplemental.h"
     37#include "URL.h"
    3638#include <JavaScriptCore/FunctionPrototype.h>
     39#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3740#include <JavaScriptCore/JSCInlines.h>
    3841#include <wtf/GetPtr.h>
     
    985988#endif
    986989
    987 bool JSTestInterfaceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     990void JSTestInterface::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     991{
     992    auto* thisObject = jsCast<JSTestInterface*>(cell);
     993    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     994    if (thisObject->scriptExecutionContext())
     995        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     996    Base::heapSnapshot(cell, builder);
     997}
     998
     999bool JSTestInterfaceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    9881000{
    9891001    auto* jsTestInterface = jsCast<JSTestInterface*>(handle.slot()->asCell());
    990     if (jsTestInterface->wrapped().hasPendingActivity())
     1002    if (jsTestInterface->wrapped().hasPendingActivity()) {
     1003        if (UNLIKELY(reason))
     1004            *reason = "ActiveDOMObject with pending activity";
    9911005        return true;
     1006     }
    9921007    UNUSED_PARAM(visitor);
     1008    UNUSED_PARAM(reason);
    9931009    return false;
    9941010}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterface.h

    r219302 r235271  
    5454
    5555    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     56    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5657
    5758    // Custom attributes
     
    8485class JSTestInterfaceOwner : public JSC::WeakHandleOwner {
    8586public:
    86     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     87    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    8788    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    8889};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    178181}
    179182
    180 bool JSTestInterfaceLeadingUnderscoreOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     183void JSTestInterfaceLeadingUnderscore::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     184{
     185    auto* thisObject = jsCast<JSTestInterfaceLeadingUnderscore*>(cell);
     186    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     187    if (thisObject->scriptExecutionContext())
     188        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     189    Base::heapSnapshot(cell, builder);
     190}
     191
     192bool JSTestInterfaceLeadingUnderscoreOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    181193{
    182194    UNUSED_PARAM(handle);
    183195    UNUSED_PARAM(visitor);
     196    UNUSED_PARAM(reason);
    184197    return false;
    185198}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestInterfaceLeadingUnderscore(JSC::Structure*, JSDOMGlobalObject&, Ref<TestInterfaceLeadingUnderscore>&&);
     
    5859class JSTestInterfaceLeadingUnderscoreOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp

    r233122 r235271  
    2828#include "JSDOMOperation.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/BuiltinNames.h>
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    231234}
    232235
    233 bool JSTestIterableOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     236void JSTestIterable::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     237{
     238    auto* thisObject = jsCast<JSTestIterable*>(cell);
     239    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     240    if (thisObject->scriptExecutionContext())
     241        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     242    Base::heapSnapshot(cell, builder);
     243}
     244
     245bool JSTestIterableOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    234246{
    235247    UNUSED_PARAM(handle);
    236248    UNUSED_PARAM(visitor);
     249    UNUSED_PARAM(reason);
    237250    return false;
    238251}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestIterable.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestIterable(JSC::Structure*, JSDOMGlobalObject&, Ref<TestIterable>&&);
     
    5859class JSTestIterableOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp

    r233122 r235271  
    3030#include "JSDOMWrapperCache.h"
    3131#include "JSMediaQueryListListener.h"
     32#include "ScriptExecutionContext.h"
     33#include "URL.h"
    3234#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3336#include <JavaScriptCore/JSCInlines.h>
    3437#include <wtf/GetPtr.h>
     
    187190}
    188191
    189 bool JSTestMediaQueryListListenerOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     192void JSTestMediaQueryListListener::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     193{
     194    auto* thisObject = jsCast<JSTestMediaQueryListListener*>(cell);
     195    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     196    if (thisObject->scriptExecutionContext())
     197        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     198    Base::heapSnapshot(cell, builder);
     199}
     200
     201bool JSTestMediaQueryListListenerOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    190202{
    191203    UNUSED_PARAM(handle);
    192204    UNUSED_PARAM(visitor);
     205    UNUSED_PARAM(reason);
    193206    return false;
    194207}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestMediaQueryListListener.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestMediaQueryListListener(JSC::Structure*, JSDOMGlobalObject&, Ref<TestMediaQueryListListener>&&);
     
    5859class JSTestMediaQueryListListenerOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
    3031#include "URL.h"
    3132#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3234#include <JavaScriptCore/JSCInlines.h>
    3335#include <JavaScriptCore/PropertyNameArray.h>
     
    313315}
    314316
    315 bool JSTestNamedAndIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     317void JSTestNamedAndIndexedSetterNoIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     318{
     319    auto* thisObject = jsCast<JSTestNamedAndIndexedSetterNoIdentifier*>(cell);
     320    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     321    if (thisObject->scriptExecutionContext())
     322        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     323    Base::heapSnapshot(cell, builder);
     324}
     325
     326bool JSTestNamedAndIndexedSetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    316327{
    317328    UNUSED_PARAM(handle);
    318329    UNUSED_PARAM(visitor);
     330    UNUSED_PARAM(reason);
    319331    return false;
    320332}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedAndIndexedSetterNoIdentifierOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
    3031#include "URL.h"
    3132#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3234#include <JavaScriptCore/JSCInlines.h>
    3335#include <JavaScriptCore/PropertyNameArray.h>
     
    313315}
    314316
    315 bool JSTestNamedAndIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     317void JSTestNamedAndIndexedSetterThrowingException::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     318{
     319    auto* thisObject = jsCast<JSTestNamedAndIndexedSetterThrowingException*>(cell);
     320    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     321    if (thisObject->scriptExecutionContext())
     322        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     323    Base::heapSnapshot(cell, builder);
     324}
     325
     326bool JSTestNamedAndIndexedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    316327{
    317328    UNUSED_PARAM(handle);
    318329    UNUSED_PARAM(visitor);
     330    UNUSED_PARAM(reason);
    319331    return false;
    320332}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedAndIndexedSetterThrowingExceptionOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp

    r233122 r235271  
    3030#include "JSDOMOperation.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
    3233#include "URL.h"
    3334#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3436#include <JavaScriptCore/JSCInlines.h>
    3537#include <JavaScriptCore/PropertyNameArray.h>
     
    367369}
    368370
    369 bool JSTestNamedAndIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     371void JSTestNamedAndIndexedSetterWithIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     372{
     373    auto* thisObject = jsCast<JSTestNamedAndIndexedSetterWithIdentifier*>(cell);
     374    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     375    if (thisObject->scriptExecutionContext())
     376        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     377    Base::heapSnapshot(cell, builder);
     378}
     379
     380bool JSTestNamedAndIndexedSetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    370381{
    371382    UNUSED_PARAM(handle);
    372383    UNUSED_PARAM(visitor);
     384    UNUSED_PARAM(reason);
    373385    return false;
    374386}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedAndIndexedSetterWithIdentifierOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.cpp

    r233122 r235271  
    2929#include "JSDOMNamedConstructor.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    198201}
    199202
    200 bool JSTestNamedConstructorOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     203void JSTestNamedConstructor::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     204{
     205    auto* thisObject = jsCast<JSTestNamedConstructor*>(cell);
     206    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     207    if (thisObject->scriptExecutionContext())
     208        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     209    Base::heapSnapshot(cell, builder);
     210}
     211
     212bool JSTestNamedConstructorOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    201213{
    202214    auto* jsTestNamedConstructor = jsCast<JSTestNamedConstructor*>(handle.slot()->asCell());
    203     if (jsTestNamedConstructor->wrapped().hasPendingActivity())
     215    if (jsTestNamedConstructor->wrapped().hasPendingActivity()) {
     216        if (UNLIKELY(reason))
     217            *reason = "ActiveDOMObject with pending activity";
    204218        return true;
     219     }
    205220    UNUSED_PARAM(visitor);
     221    UNUSED_PARAM(reason);
    206222    return false;
    207223}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedConstructor.h

    r216198 r235271  
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    5252    static JSC::JSValue getNamedConstructor(JSC::VM&, JSC::JSGlobalObject*);
     53    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5354protected:
    5455    JSTestNamedConstructor(JSC::Structure*, JSDOMGlobalObject&, Ref<TestNamedConstructor>&&);
     
    5960class JSTestNamedConstructorOwner : public JSC::WeakHandleOwner {
    6061public:
    61     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     62    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6263    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6364};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    226229}
    227230
    228 bool JSTestNamedDeleterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     231void JSTestNamedDeleterNoIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     232{
     233    auto* thisObject = jsCast<JSTestNamedDeleterNoIdentifier*>(cell);
     234    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     235    if (thisObject->scriptExecutionContext())
     236        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     237    Base::heapSnapshot(cell, builder);
     238}
     239
     240bool JSTestNamedDeleterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    229241{
    230242    UNUSED_PARAM(handle);
    231243    UNUSED_PARAM(visitor);
     244    UNUSED_PARAM(reason);
    232245    return false;
    233246}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.h

    r217773 r235271  
    5555
    5656    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     57    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5758public:
    5859    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6566class JSTestNamedDeleterNoIdentifierOwner : public JSC::WeakHandleOwner {
    6667public:
    67     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     68    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6869    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6970};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    240243}
    241244
    242 bool JSTestNamedDeleterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     245void JSTestNamedDeleterThrowingException::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     246{
     247    auto* thisObject = jsCast<JSTestNamedDeleterThrowingException*>(cell);
     248    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     249    if (thisObject->scriptExecutionContext())
     250        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     251    Base::heapSnapshot(cell, builder);
     252}
     253
     254bool JSTestNamedDeleterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    243255{
    244256    UNUSED_PARAM(handle);
    245257    UNUSED_PARAM(visitor);
     258    UNUSED_PARAM(reason);
    246259    return false;
    247260}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.h

    r217773 r235271  
    5555
    5656    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     57    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5758public:
    5859    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6566class JSTestNamedDeleterThrowingExceptionOwner : public JSC::WeakHandleOwner {
    6667public:
    67     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     68    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6869    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6970};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    257260}
    258261
    259 bool JSTestNamedDeleterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     262void JSTestNamedDeleterWithIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     263{
     264    auto* thisObject = jsCast<JSTestNamedDeleterWithIdentifier*>(cell);
     265    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     266    if (thisObject->scriptExecutionContext())
     267        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     268    Base::heapSnapshot(cell, builder);
     269}
     270
     271bool JSTestNamedDeleterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    260272{
    261273    UNUSED_PARAM(handle);
    262274    UNUSED_PARAM(visitor);
     275    UNUSED_PARAM(reason);
    263276    return false;
    264277}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.h

    r217773 r235271  
    5555
    5656    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     57    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5758public:
    5859    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6566class JSTestNamedDeleterWithIdentifierOwner : public JSC::WeakHandleOwner {
    6667public:
    67     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     68    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6869    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6970};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
    3031#include "URL.h"
    3132#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3234#include <JavaScriptCore/JSCInlines.h>
    3335#include <JavaScriptCore/PropertyNameArray.h>
     
    244246}
    245247
    246 bool JSTestNamedDeleterWithIndexedGetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     248void JSTestNamedDeleterWithIndexedGetter::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     249{
     250    auto* thisObject = jsCast<JSTestNamedDeleterWithIndexedGetter*>(cell);
     251    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     252    if (thisObject->scriptExecutionContext())
     253        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     254    Base::heapSnapshot(cell, builder);
     255}
     256
     257bool JSTestNamedDeleterWithIndexedGetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    247258{
    248259    UNUSED_PARAM(handle);
    249260    UNUSED_PARAM(visitor);
     261    UNUSED_PARAM(reason);
    250262    return false;
    251263}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.h

    r217773 r235271  
    5555
    5656    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     57    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5758public:
    5859    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6566class JSTestNamedDeleterWithIndexedGetterOwner : public JSC::WeakHandleOwner {
    6667public:
    67     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     68    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6869    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6970};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterCallWith.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    205208}
    206209
    207 bool JSTestNamedGetterCallWithOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     210void JSTestNamedGetterCallWith::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     211{
     212    auto* thisObject = jsCast<JSTestNamedGetterCallWith*>(cell);
     213    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     214    if (thisObject->scriptExecutionContext())
     215        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     216    Base::heapSnapshot(cell, builder);
     217}
     218
     219bool JSTestNamedGetterCallWithOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    208220{
    209221    UNUSED_PARAM(handle);
    210222    UNUSED_PARAM(visitor);
     223    UNUSED_PARAM(reason);
    211224    return false;
    212225}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterCallWith.h

    r218967 r235271  
    5353
    5454    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     55    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5556public:
    5657    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6364class JSTestNamedGetterCallWithOwner : public JSC::WeakHandleOwner {
    6465public:
    65     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     66    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6667    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6768};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    205208}
    206209
    207 bool JSTestNamedGetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     210void JSTestNamedGetterNoIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     211{
     212    auto* thisObject = jsCast<JSTestNamedGetterNoIdentifier*>(cell);
     213    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     214    if (thisObject->scriptExecutionContext())
     215        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     216    Base::heapSnapshot(cell, builder);
     217}
     218
     219bool JSTestNamedGetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    208220{
    209221    UNUSED_PARAM(handle);
    210222    UNUSED_PARAM(visitor);
     223    UNUSED_PARAM(reason);
    211224    return false;
    212225}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.h

    r218967 r235271  
    5353
    5454    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     55    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5556public:
    5657    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6364class JSTestNamedGetterNoIdentifierOwner : public JSC::WeakHandleOwner {
    6465public:
    65     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     66    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6667    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6768};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    233236}
    234237
    235 bool JSTestNamedGetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     238void JSTestNamedGetterWithIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     239{
     240    auto* thisObject = jsCast<JSTestNamedGetterWithIdentifier*>(cell);
     241    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     242    if (thisObject->scriptExecutionContext())
     243        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     244    Base::heapSnapshot(cell, builder);
     245}
     246
     247bool JSTestNamedGetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    236248{
    237249    UNUSED_PARAM(handle);
    238250    UNUSED_PARAM(visitor);
     251    UNUSED_PARAM(reason);
    239252    return false;
    240253}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.h

    r218967 r235271  
    5353
    5454    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     55    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5556public:
    5657    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6364class JSTestNamedGetterWithIdentifierOwner : public JSC::WeakHandleOwner {
    6465public:
    65     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     66    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6667    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6768};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    267270}
    268271
    269 bool JSTestNamedSetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     272void JSTestNamedSetterNoIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     273{
     274    auto* thisObject = jsCast<JSTestNamedSetterNoIdentifier*>(cell);
     275    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     276    if (thisObject->scriptExecutionContext())
     277        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     278    Base::heapSnapshot(cell, builder);
     279}
     280
     281bool JSTestNamedSetterNoIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    270282{
    271283    UNUSED_PARAM(handle);
    272284    UNUSED_PARAM(visitor);
     285    UNUSED_PARAM(reason);
    273286    return false;
    274287}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterNoIdentifierOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    267270}
    268271
    269 bool JSTestNamedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     272void JSTestNamedSetterThrowingException::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     273{
     274    auto* thisObject = jsCast<JSTestNamedSetterThrowingException*>(cell);
     275    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     276    if (thisObject->scriptExecutionContext())
     277        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     278    Base::heapSnapshot(cell, builder);
     279}
     280
     281bool JSTestNamedSetterThrowingExceptionOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    270282{
    271283    UNUSED_PARAM(handle);
    272284    UNUSED_PARAM(visitor);
     285    UNUSED_PARAM(reason);
    273286    return false;
    274287}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterThrowingException.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterThrowingExceptionOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    298301}
    299302
    300 bool JSTestNamedSetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     303void JSTestNamedSetterWithIdentifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     304{
     305    auto* thisObject = jsCast<JSTestNamedSetterWithIdentifier*>(cell);
     306    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     307    if (thisObject->scriptExecutionContext())
     308        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     309    Base::heapSnapshot(cell, builder);
     310}
     311
     312bool JSTestNamedSetterWithIdentifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    301313{
    302314    UNUSED_PARAM(handle);
    303315    UNUSED_PARAM(visitor);
     316    UNUSED_PARAM(reason);
    304317    return false;
    305318}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterWithIdentifierOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp

    r233122 r235271  
    3030#include "JSDOMOperation.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
    3233#include "URL.h"
    3334#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3436#include <JavaScriptCore/JSCInlines.h>
    3537#include <JavaScriptCore/PropertyNameArray.h>
     
    341343}
    342344
    343 bool JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     345void JSTestNamedSetterWithIndexedGetter::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     346{
     347    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetter*>(cell);
     348    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     349    if (thisObject->scriptExecutionContext())
     350        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     351    Base::heapSnapshot(cell, builder);
     352}
     353
     354bool JSTestNamedSetterWithIndexedGetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    344355{
    345356    UNUSED_PARAM(handle);
    346357    UNUSED_PARAM(visitor);
     358    UNUSED_PARAM(reason);
    347359    return false;
    348360}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.h

    r219622 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterWithIndexedGetterOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp

    r233122 r235271  
    3030#include "JSDOMOperation.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
    3233#include "URL.h"
    3334#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3436#include <JavaScriptCore/JSCInlines.h>
    3537#include <JavaScriptCore/PropertyNameArray.h>
     
    391393}
    392394
    393 bool JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     395void JSTestNamedSetterWithIndexedGetterAndSetter::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     396{
     397    auto* thisObject = jsCast<JSTestNamedSetterWithIndexedGetterAndSetter*>(cell);
     398    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     399    if (thisObject->scriptExecutionContext())
     400        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     401    Base::heapSnapshot(cell, builder);
     402}
     403
     404bool JSTestNamedSetterWithIndexedGetterAndSetterOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    394405{
    395406    UNUSED_PARAM(handle);
    396407    UNUSED_PARAM(visitor);
     408    UNUSED_PARAM(reason);
    397409    return false;
    398410}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.h

    r219622 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterWithIndexedGetterAndSetterOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.cpp

    r233122 r235271  
    2828#include "JSDOMExceptionHandling.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    254257}
    255258
    256 bool JSTestNamedSetterWithOverrideBuiltinsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     259void JSTestNamedSetterWithOverrideBuiltins::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     260{
     261    auto* thisObject = jsCast<JSTestNamedSetterWithOverrideBuiltins*>(cell);
     262    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     263    if (thisObject->scriptExecutionContext())
     264        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     265    Base::heapSnapshot(cell, builder);
     266}
     267
     268bool JSTestNamedSetterWithOverrideBuiltinsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    257269{
    258270    UNUSED_PARAM(handle);
    259271    UNUSED_PARAM(visitor);
     272    UNUSED_PARAM(reason);
    260273    return false;
    261274}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithOverrideBuiltins.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpure | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterWithOverrideBuiltinsOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.cpp

    r233122 r235271  
    3030#include "JSDOMOperation.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
     33#include "URL.h"
    3234#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3336#include <JavaScriptCore/JSCInlines.h>
    3437#include <wtf/GetPtr.h>
     
    336339}
    337340
    338 bool JSTestNamedSetterWithUnforgablePropertiesOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     341void JSTestNamedSetterWithUnforgableProperties::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     342{
     343    auto* thisObject = jsCast<JSTestNamedSetterWithUnforgableProperties*>(cell);
     344    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     345    if (thisObject->scriptExecutionContext())
     346        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     347    Base::heapSnapshot(cell, builder);
     348}
     349
     350bool JSTestNamedSetterWithUnforgablePropertiesOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    339351{
    340352    UNUSED_PARAM(handle);
    341353    UNUSED_PARAM(visitor);
     354    UNUSED_PARAM(reason);
    342355    return false;
    343356}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithUnforgableProperties.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::HasStaticPropertyTable | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterWithUnforgablePropertiesOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.cpp

    r233122 r235271  
    3030#include "JSDOMOperation.h"
    3131#include "JSDOMWrapperCache.h"
     32#include "ScriptExecutionContext.h"
     33#include "URL.h"
    3234#include <JavaScriptCore/FunctionPrototype.h>
     35#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3336#include <JavaScriptCore/JSCInlines.h>
    3437#include <wtf/GetPtr.h>
     
    323326}
    324327
    325 bool JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     328void JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     329{
     330    auto* thisObject = jsCast<JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins*>(cell);
     331    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     332    if (thisObject->scriptExecutionContext())
     333        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     334    Base::heapSnapshot(cell, builder);
     335}
     336
     337bool JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    326338{
    327339    UNUSED_PARAM(handle);
    328340    UNUSED_PARAM(visitor);
     341    UNUSED_PARAM(reason);
    329342    return false;
    330343}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltins.h

    r217773 r235271  
    5656
    5757    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859public:
    5960    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpure | JSC::HasStaticPropertyTable | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6667class JSTestNamedSetterWithUnforgablePropertiesAndOverrideBuiltinsOwner : public JSC::WeakHandleOwner {
    6768public:
    68     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     69    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6970    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7071};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp

    r233122 r235271  
    3535#include "RuntimeEnabledFeatures.h"
    3636#include "ScriptExecutionContext.h"
     37#include "URL.h"
    3738#include <JavaScriptCore/BuiltinNames.h>
     39#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3840#include <JavaScriptCore/JSCInlines.h>
    3941#include <JavaScriptCore/ObjectConstructor.h>
     
    413415}
    414416
     417void JSTestNode::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     418{
     419    auto* thisObject = jsCast<JSTestNode*>(cell);
     420    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     421    if (thisObject->scriptExecutionContext())
     422        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     423    Base::heapSnapshot(cell, builder);
     424}
     425
    415426#if ENABLE(BINDING_INTEGRITY)
    416427#if PLATFORM(WIN)
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.h

    r230831 r235271  
    5050    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    5151    static JSC::JSObject* serialize(JSC::ExecState&, JSTestNode& thisObject, JSDOMGlobalObject&, JSC::ThrowScope&);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253    TestNode& wrapped() const
    5354    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp

    r233122 r235271  
    8383#include <JavaScriptCore/BuiltinNames.h>
    8484#include <JavaScriptCore/FunctionPrototype.h>
     85#include <JavaScriptCore/HeapSnapshotBuilder.h>
    8586#include <JavaScriptCore/IteratorOperations.h>
    8687#include <JavaScriptCore/JSArray.h>
     
    83908391}
    83918392
    8392 bool JSTestObjOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     8393void JSTestObj::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     8394{
     8395    auto* thisObject = jsCast<JSTestObj*>(cell);
     8396    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     8397    if (thisObject->scriptExecutionContext())
     8398        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     8399    Base::heapSnapshot(cell, builder);
     8400}
     8401
     8402bool JSTestObjOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    83938403{
    83948404    UNUSED_PARAM(handle);
    83958405    UNUSED_PARAM(visitor);
     8406    UNUSED_PARAM(reason);
    83968407    return false;
    83978408}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.h

    r231839 r235271  
    6363    static void visitChildren(JSCell*, JSC::SlotVisitor&);
    6464
     65    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    6566
    6667    // Custom attributes
     
    8586class JSTestObjOwner : public JSC::WeakHandleOwner {
    8687public:
    87     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     88    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    8889    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    8990};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp

    r233122 r235271  
    3232#include "JSDOMExceptionHandling.h"
    3333#include "JSDOMWrapperCache.h"
     34#include "ScriptExecutionContext.h"
     35#include "URL.h"
    3436#include <JavaScriptCore/FunctionPrototype.h>
     37#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3538#include <JavaScriptCore/JSCInlines.h>
    3639#include <wtf/GetPtr.h>
     
    250253}
    251254
    252 bool JSTestOverloadedConstructorsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     255void JSTestOverloadedConstructors::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     256{
     257    auto* thisObject = jsCast<JSTestOverloadedConstructors*>(cell);
     258    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     259    if (thisObject->scriptExecutionContext())
     260        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     261    Base::heapSnapshot(cell, builder);
     262}
     263
     264bool JSTestOverloadedConstructorsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    253265{
    254266    UNUSED_PARAM(handle);
    255267    UNUSED_PARAM(visitor);
     268    UNUSED_PARAM(reason);
    256269    return false;
    257270}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestOverloadedConstructors(JSC::Structure*, JSDOMGlobalObject&, Ref<TestOverloadedConstructors>&&);
     
    5859class JSTestOverloadedConstructorsOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.cpp

    r233122 r235271  
    2929#include "JSDOMExceptionHandling.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/IteratorOperations.h>
    3336#include <JavaScriptCore/JSArray.h>
     
    206209}
    207210
    208 bool JSTestOverloadedConstructorsWithSequenceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     211void JSTestOverloadedConstructorsWithSequence::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     212{
     213    auto* thisObject = jsCast<JSTestOverloadedConstructorsWithSequence*>(cell);
     214    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     215    if (thisObject->scriptExecutionContext())
     216        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     217    Base::heapSnapshot(cell, builder);
     218}
     219
     220bool JSTestOverloadedConstructorsWithSequenceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    209221{
    210222    UNUSED_PARAM(handle);
    211223    UNUSED_PARAM(visitor);
     224    UNUSED_PARAM(reason);
    212225    return false;
    213226}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestOverloadedConstructorsWithSequence(JSC::Structure*, JSDOMGlobalObject&, Ref<TestOverloadedConstructorsWithSequence>&&);
     
    5859class JSTestOverloadedConstructorsWithSequenceOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverrideBuiltins.cpp

    r233122 r235271  
    3232#include "JSDOMWrapperCache.h"
    3333#include "JSNode.h"
     34#include "ScriptExecutionContext.h"
     35#include "URL.h"
    3436#include <JavaScriptCore/FunctionPrototype.h>
     37#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3538#include <JavaScriptCore/JSCInlines.h>
    3639#include <wtf/GetPtr.h>
     
    236239}
    237240
    238 bool JSTestOverrideBuiltinsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     241void JSTestOverrideBuiltins::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     242{
     243    auto* thisObject = jsCast<JSTestOverrideBuiltins*>(cell);
     244    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     245    if (thisObject->scriptExecutionContext())
     246        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     247    Base::heapSnapshot(cell, builder);
     248}
     249
     250bool JSTestOverrideBuiltinsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    239251{
    240252    UNUSED_PARAM(handle);
    241253    UNUSED_PARAM(visitor);
     254    UNUSED_PARAM(reason);
    242255    return false;
    243256}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverrideBuiltins.h

    r217773 r235271  
    5353
    5454    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     55    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5556public:
    5657    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpure | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | Base::StructureFlags;
     
    6364class JSTestOverrideBuiltinsOwner : public JSC::WeakHandleOwner {
    6465public:
    65     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     66    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6667    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6768};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestPluginInterface.cpp

    r233122 r235271  
    2727#include "JSDOMWrapperCache.h"
    2828#include "JSPluginElementFunctions.h"
     29#include "ScriptExecutionContext.h"
     30#include "URL.h"
    2931#include <JavaScriptCore/FunctionPrototype.h>
     32#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3033#include <JavaScriptCore/JSCInlines.h>
    3134#include <wtf/GetPtr.h>
     
    209212}
    210213
    211 bool JSTestPluginInterfaceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     214void JSTestPluginInterface::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     215{
     216    auto* thisObject = jsCast<JSTestPluginInterface*>(cell);
     217    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     218    if (thisObject->scriptExecutionContext())
     219        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     220    Base::heapSnapshot(cell, builder);
     221}
     222
     223bool JSTestPluginInterfaceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    212224{
    213225    UNUSED_PARAM(handle);
    214226    UNUSED_PARAM(visitor);
     227    UNUSED_PARAM(reason);
    215228    return false;
    216229}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestPluginInterface.h

    r231839 r235271  
    5757
    5858    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     59    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5960public:
    6061    static const unsigned StructureFlags = JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetCallData | JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
     
    6768class JSTestPluginInterfaceOwner : public JSC::WeakHandleOwner {
    6869public:
    69     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     70    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    7071    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    7172};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp

    r233122 r235271  
    3434#include "JSDOMGlobalObject.h"
    3535#include "JSDOMWrapperCache.h"
     36#include "ScriptExecutionContext.h"
     37#include "URL.h"
     38#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3639#include <JavaScriptCore/JSCInlines.h>
    3740#include <wtf/GetPtr.h>
     
    286289}
    287290
     291void JSTestPromiseRejectionEvent::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     292{
     293    auto* thisObject = jsCast<JSTestPromiseRejectionEvent*>(cell);
     294    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     295    if (thisObject->scriptExecutionContext())
     296        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     297    Base::heapSnapshot(cell, builder);
     298}
     299
    288300#if ENABLE(BINDING_INTEGRITY)
    289301#if PLATFORM(WIN)
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestPromiseRejectionEvent.h

    r230831 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253    TestPromiseRejectionEvent& wrapped() const
    5354    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerialization.cpp

    r233122 r235271  
    3636#include "JSTestSerializationIndirectInheritance.h"
    3737#include "JSTestSerializationInheritFinal.h"
     38#include "ScriptExecutionContext.h"
     39#include "URL.h"
    3840#include <JavaScriptCore/FunctionPrototype.h>
     41#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3942#include <JavaScriptCore/JSCInlines.h>
    4043#include <JavaScriptCore/ObjectConstructor.h>
     
    543546}
    544547
    545 bool JSTestSerializationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     548void JSTestSerialization::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     549{
     550    auto* thisObject = jsCast<JSTestSerialization*>(cell);
     551    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     552    if (thisObject->scriptExecutionContext())
     553        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     554    Base::heapSnapshot(cell, builder);
     555}
     556
     557bool JSTestSerializationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    546558{
    547559    UNUSED_PARAM(handle);
    548560    UNUSED_PARAM(visitor);
     561    UNUSED_PARAM(reason);
    549562    return false;
    550563}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerialization.h

    r218342 r235271  
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    5252    static JSC::JSObject* serialize(JSC::ExecState&, JSTestSerialization& thisObject, JSDOMGlobalObject&, JSC::ThrowScope&);
     53    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5354protected:
    5455    JSTestSerialization(JSC::Structure*, JSDOMGlobalObject&, Ref<TestSerialization>&&);
     
    5960class JSTestSerializationOwner : public JSC::WeakHandleOwner {
    6061public:
    61     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     62    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6263    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6364};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.cpp

    r233122 r235271  
    2626#include "JSDOMExceptionHandling.h"
    2727#include "JSDOMWrapperCache.h"
     28#include "ScriptExecutionContext.h"
     29#include "URL.h"
     30#include <JavaScriptCore/HeapSnapshotBuilder.h>
    2831#include <JavaScriptCore/JSCInlines.h>
    2932#include <wtf/GetPtr.h>
     
    147150}
    148151
     152void JSTestSerializationIndirectInheritance::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     153{
     154    auto* thisObject = jsCast<JSTestSerializationIndirectInheritance*>(cell);
     155    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     156    if (thisObject->scriptExecutionContext())
     157        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     158    Base::heapSnapshot(cell, builder);
     159}
     160
    149161
    150162}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializationIndirectInheritance.h

    r230831 r235271  
    4949
    5050    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     51    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5152    TestSerializationIndirectInheritance& wrapped() const
    5253    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializationInherit.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <JavaScriptCore/ObjectConstructor.h>
     
    222225}
    223226
    224 
    225 }
     227void JSTestSerializationInherit::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     228{
     229    auto* thisObject = jsCast<JSTestSerializationInherit*>(cell);
     230    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     231    if (thisObject->scriptExecutionContext())
     232        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     233    Base::heapSnapshot(cell, builder);
     234}
     235
     236
     237}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializationInherit.h

    r230831 r235271  
    5050    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    5151    static JSC::JSObject* serialize(JSC::ExecState&, JSTestSerializationInherit& thisObject, JSDOMGlobalObject&, JSC::ThrowScope&);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253    TestSerializationInherit& wrapped() const
    5354    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializationInheritFinal.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <JavaScriptCore/ObjectConstructor.h>
     
    256259}
    257260
    258 
    259 }
     261void JSTestSerializationInheritFinal::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     262{
     263    auto* thisObject = jsCast<JSTestSerializationInheritFinal*>(cell);
     264    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     265    if (thisObject->scriptExecutionContext())
     266        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     267    Base::heapSnapshot(cell, builder);
     268}
     269
     270
     271}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializationInheritFinal.h

    r230831 r235271  
    5050    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
    5151    static JSC::JSObject* serialize(JSC::ExecState&, JSTestSerializationInheritFinal& thisObject, JSDOMGlobalObject&, JSC::ThrowScope&);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253    TestSerializationInheritFinal& wrapped() const
    5354    {
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp

    r233122 r235271  
    3636#include "JSDOMWrapperCache.h"
    3737#include "JSMessagePort.h"
     38#include "ScriptExecutionContext.h"
    3839#include "SerializedScriptValue.h"
     40#include "URL.h"
    3941#include <JavaScriptCore/FunctionPrototype.h>
     42#include <JavaScriptCore/HeapSnapshotBuilder.h>
    4043#include <JavaScriptCore/JSArray.h>
    4144#include <JavaScriptCore/JSCInlines.h>
     
    346349}
    347350
    348 bool JSTestSerializedScriptValueInterfaceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     351void JSTestSerializedScriptValueInterface::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     352{
     353    auto* thisObject = jsCast<JSTestSerializedScriptValueInterface*>(cell);
     354    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     355    if (thisObject->scriptExecutionContext())
     356        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     357    Base::heapSnapshot(cell, builder);
     358}
     359
     360bool JSTestSerializedScriptValueInterfaceOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    349361{
    350362    UNUSED_PARAM(handle);
    351363    UNUSED_PARAM(visitor);
     364    UNUSED_PARAM(reason);
    352365    return false;
    353366}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.h

    r216198 r235271  
    5656    static void visitChildren(JSCell*, JSC::SlotVisitor&);
    5757
     58    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5859protected:
    5960    JSTestSerializedScriptValueInterface(JSC::Structure*, JSDOMGlobalObject&, Ref<TestSerializedScriptValueInterface>&&);
     
    6465class JSTestSerializedScriptValueInterfaceOwner : public JSC::WeakHandleOwner {
    6566public:
    66     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     67    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6768    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6869};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifier.cpp

    r233122 r235271  
    2828#include "JSDOMOperation.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    180183}
    181184
    182 bool JSTestStringifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     185void JSTestStringifier::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     186{
     187    auto* thisObject = jsCast<JSTestStringifier*>(cell);
     188    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     189    if (thisObject->scriptExecutionContext())
     190        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     191    Base::heapSnapshot(cell, builder);
     192}
     193
     194bool JSTestStringifierOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    183195{
    184196    UNUSED_PARAM(handle);
    185197    UNUSED_PARAM(visitor);
     198    UNUSED_PARAM(reason);
    186199    return false;
    187200}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifier.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifier(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifier>&&);
     
    5859class JSTestStringifierOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.cpp

    r233122 r235271  
    2828#include "JSDOMOperation.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    180183}
    181184
    182 bool JSTestStringifierAnonymousOperationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     185void JSTestStringifierAnonymousOperation::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     186{
     187    auto* thisObject = jsCast<JSTestStringifierAnonymousOperation*>(cell);
     188    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     189    if (thisObject->scriptExecutionContext())
     190        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     191    Base::heapSnapshot(cell, builder);
     192}
     193
     194bool JSTestStringifierAnonymousOperationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    183195{
    184196    UNUSED_PARAM(handle);
    185197    UNUSED_PARAM(visitor);
     198    UNUSED_PARAM(reason);
    186199    return false;
    187200}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifierAnonymousOperation(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifierAnonymousOperation>&&);
     
    5859class JSTestStringifierAnonymousOperationOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierNamedOperation.cpp

    r233122 r235271  
    2828#include "JSDOMOperation.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    195198}
    196199
    197 bool JSTestStringifierNamedOperationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     200void JSTestStringifierNamedOperation::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     201{
     202    auto* thisObject = jsCast<JSTestStringifierNamedOperation*>(cell);
     203    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     204    if (thisObject->scriptExecutionContext())
     205        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     206    Base::heapSnapshot(cell, builder);
     207}
     208
     209bool JSTestStringifierNamedOperationOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    198210{
    199211    UNUSED_PARAM(handle);
    200212    UNUSED_PARAM(visitor);
     213    UNUSED_PARAM(reason);
    201214    return false;
    202215}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierNamedOperation.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifierNamedOperation(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifierNamedOperation>&&);
     
    5859class JSTestStringifierNamedOperationOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.cpp

    r233122 r235271  
    2828#include "JSDOMOperation.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    195198}
    196199
    197 bool JSTestStringifierOperationImplementedAsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     200void JSTestStringifierOperationImplementedAs::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     201{
     202    auto* thisObject = jsCast<JSTestStringifierOperationImplementedAs*>(cell);
     203    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     204    if (thisObject->scriptExecutionContext())
     205        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     206    Base::heapSnapshot(cell, builder);
     207}
     208
     209bool JSTestStringifierOperationImplementedAsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    198210{
    199211    UNUSED_PARAM(handle);
    200212    UNUSED_PARAM(visitor);
     213    UNUSED_PARAM(reason);
    201214    return false;
    202215}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifierOperationImplementedAs(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifierOperationImplementedAs>&&);
     
    5859class JSTestStringifierOperationImplementedAsOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.cpp

    r233122 r235271  
    2828#include "JSDOMOperation.h"
    2929#include "JSDOMWrapperCache.h"
     30#include "ScriptExecutionContext.h"
     31#include "URL.h"
    3032#include <JavaScriptCore/FunctionPrototype.h>
     33#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3134#include <JavaScriptCore/JSCInlines.h>
    3235#include <wtf/GetPtr.h>
     
    180183}
    181184
    182 bool JSTestStringifierOperationNamedToStringOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     185void JSTestStringifierOperationNamedToString::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     186{
     187    auto* thisObject = jsCast<JSTestStringifierOperationNamedToString*>(cell);
     188    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     189    if (thisObject->scriptExecutionContext())
     190        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     191    Base::heapSnapshot(cell, builder);
     192}
     193
     194bool JSTestStringifierOperationNamedToStringOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    183195{
    184196    UNUSED_PARAM(handle);
    185197    UNUSED_PARAM(visitor);
     198    UNUSED_PARAM(reason);
    186199    return false;
    187200}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifierOperationNamedToString(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifierOperationNamedToString>&&);
     
    5859class JSTestStringifierOperationNamedToStringOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    202205}
    203206
    204 bool JSTestStringifierReadOnlyAttributeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     207void JSTestStringifierReadOnlyAttribute::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     208{
     209    auto* thisObject = jsCast<JSTestStringifierReadOnlyAttribute*>(cell);
     210    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     211    if (thisObject->scriptExecutionContext())
     212        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     213    Base::heapSnapshot(cell, builder);
     214}
     215
     216bool JSTestStringifierReadOnlyAttributeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    205217{
    206218    UNUSED_PARAM(handle);
    207219    UNUSED_PARAM(visitor);
     220    UNUSED_PARAM(reason);
    208221    return false;
    209222}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifierReadOnlyAttribute(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifierReadOnlyAttribute>&&);
     
    5859class JSTestStringifierReadOnlyAttributeOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.cpp

    r233122 r235271  
    2929#include "JSDOMOperation.h"
    3030#include "JSDOMWrapperCache.h"
     31#include "ScriptExecutionContext.h"
     32#include "URL.h"
    3133#include <JavaScriptCore/FunctionPrototype.h>
     34#include <JavaScriptCore/HeapSnapshotBuilder.h>
    3235#include <JavaScriptCore/JSCInlines.h>
    3336#include <wtf/GetPtr.h>
     
    220223}
    221224
    222 bool JSTestStringifierReadWriteAttributeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     225void JSTestStringifierReadWriteAttribute::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     226{
     227    auto* thisObject = jsCast<JSTestStringifierReadWriteAttribute*>(cell);
     228    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     229    if (thisObject->scriptExecutionContext())
     230        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     231    Base::heapSnapshot(cell, builder);
     232}
     233
     234bool JSTestStringifierReadWriteAttributeOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    223235{
    224236    UNUSED_PARAM(handle);
    225237    UNUSED_PARAM(visitor);
     238    UNUSED_PARAM(reason);
    226239    return false;
    227240}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.h

    r218789 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253protected:
    5354    JSTestStringifierReadWriteAttribute(JSC::Structure*, JSDOMGlobalObject&, Ref<TestStringifierReadWriteAttribute>&&);
     
    5859class JSTestStringifierReadWriteAttributeOwner : public JSC::WeakHandleOwner {
    5960public:
    60     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     61    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6162    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6263};
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp

    r233122 r235271  
    4444#include "JSTestEventTarget.h"
    4545#include "JSTestSubObj.h"
     46#include "ScriptExecutionContext.h"
    4647#include "SerializedScriptValue.h"
     48#include "URL.h"
    4749#include <JavaScriptCore/FunctionPrototype.h>
     50#include <JavaScriptCore/HeapSnapshotBuilder.h>
    4851#include <JavaScriptCore/JSArray.h>
    4952#include <JavaScriptCore/JSCInlines.h>
     
    742745}
    743746
    744 bool JSTestTypedefsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor)
     747void JSTestTypedefs::heapSnapshot(JSCell* cell, HeapSnapshotBuilder& builder)
     748{
     749    auto* thisObject = jsCast<JSTestTypedefs*>(cell);
     750    builder.setWrappedObjectForCell(cell, &thisObject->wrapped());
     751    if (thisObject->scriptExecutionContext())
     752        builder.setLabelForCell(cell, String::format("url %s", thisObject->scriptExecutionContext()->url().string().utf8().data()));
     753    Base::heapSnapshot(cell, builder);
     754}
     755
     756bool JSTestTypedefsOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor, const char** reason)
    745757{
    746758    UNUSED_PARAM(handle);
    747759    UNUSED_PARAM(visitor);
     760    UNUSED_PARAM(reason);
    748761    return false;
    749762}
  • TabularUnified trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.h

    r216198 r235271  
    5050
    5151    static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
     52    static void heapSnapshot(JSCell*, JSC::HeapSnapshotBuilder&);
    5253public:
    5354    static const unsigned StructureFlags = JSC::HasStaticPropertyTable | Base::StructureFlags;
     
    6061class JSTestTypedefsOwner : public JSC::WeakHandleOwner {
    6162public:
    62     virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&);
     63    virtual bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::SlotVisitor&, const char**);
    6364    virtual void finalize(JSC::Handle<JSC::Unknown>, void* context);
    6465};
  • TabularUnified trunk/Source/WebCore/dom/Document.idl

    r231849 r235271  
    3636    ConstructorCallWith=Document,
    3737    CustomToJSObject,
     38    CustomHeapSnapshot,
    3839    DOMJIT,
    3940    ExportMacro=WEBCORE_EXPORT,
  • TabularUnified trunk/Source/WebCore/page/DOMWindow.idl

    r235050 r235271  
    3434    CustomGetOwnPropertySlot,
    3535    CustomGetPrototype,
     36    CustomHeapSnapshot,
    3637    CustomPreventExtensions,
    3738    CustomProxyToJSObject,
  • TabularUnified trunk/Source/WebInspectorUI/ChangeLog

    r235257 r235271  
     12018-08-23  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add support for dumping GC heap snapshots, and a viewer
     4        https://bugs.webkit.org/show_bug.cgi?id=186416
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Make a way to dump information about the GC heap that is useful for looking for leaked
     9        or abandoned objects. This dump is obtained (on Apple platforms) via:
     10            notifyutil -p com.apple.WebKit.dumpGCHeap
     11        which writes a JSON file to /tmp which can then be loaded into the viewer in Tools/GCHeapInspector.
     12
     13        This leverages the heap snapshot used by Web Inspector, adding an alternate format for
     14        the snapshot JSON that adds additional data about objects and why they are GC roots.
     15
     16        The generated bindings code is changed to include the output root reason from isReachableFromOpaqueRoots(),
     17        and to implement heapSnapshot() which provides the address of the wrapped object. A new IDL attribute,
     18        CustomHeapSnapshot, is used to allow custom heapSnapshot() implementations for classes like JSDocument
     19        that need to decorate the heap snapshot cell data with things like the document URL.
     20
     21        GCController registers a notifyutil callback which gathers the debug heap snapshot, and dumps it
     22        to a file in /tmp. The file path is printed out to the system log.
     23
     24        * UserInterface/Workers/HeapSnapshot/HeapSnapshot.js:
     25        (HeapSnapshot):
     26
    1272018-08-23  Brian Burg  <bburg@apple.com>
    228
  • TabularUnified trunk/Source/WebInspectorUI/UserInterface/Workers/HeapSnapshot/HeapSnapshot.js

    r230831 r235271  
    8383        snapshotDataString = null;
    8484
    85         let {version, nodes, nodeClassNames, edges, edgeTypes, edgeNames} = json;
     85        let {version, type, nodes, nodeClassNames, edges, edgeTypes, edgeNames} = json;
    8686        console.assert(version === 1, "Expect JavaScriptCore Heap Snapshot version 1");
     87        console.assert(!type || type === "Inspector", "Expect an Inspector Heap Snapshot");
    8788
    8889        this._nodes = nodes;
  • TabularUnified trunk/Tools/ChangeLog

    r235259 r235271  
     12018-08-23  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add support for dumping GC heap snapshots, and a viewer
     4        https://bugs.webkit.org/show_bug.cgi?id=186416
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        Add a viewer for GC heap snapshots. A snapshot JSON file can be dragged into this
     9        page for inspection (or set via the 'filename' URL parameter).
     10
     11        For now, this page shows all objects, all roots, and the shortest path from a root
     12        to all HTMLDocuments and Windows.
     13
     14        * GCHeapInspector/gc-heap-inspector.html: Added.
     15        * GCHeapInspector/heap-analysis/HeapSnapshot.js: Copied from Source/WebInspectorUI/UserInterface/Workers/HeapSnapshot/HeapSnapshot.js.
     16        * GCHeapInspector/script/interface.js: Added.
     17
    1182018-08-23  Alex Christensen  <achristensen@webkit.org>
    219
  • TabularUnified trunk/Tools/GCHeapInspector/heap-analysis/HeapSnapshot.js

    r235269 r235271  
    3131
    3232// nodes
    33 // [<0:id>, <1:size>, <2:classNameTableIndex>, <3:internal>]
    34 const nodeFieldCount = 4;
     33// [<0:id>, <1:size>, <2:classNameTableIndex>, <3:internal>, <4:labelIndex>, <5:address>, <6:wrapped address>]
     34let nodeFieldCount = 7;
    3535const nodeIdOffset = 0;
    3636const nodeSizeOffset = 1;
    3737const nodeClassNameOffset = 2;
    3838const nodeInternalOffset = 3;
     39const nodeLabelOffset = 4;
     40const nodeAddressOffset = 5;
     41const nodeWrappedAddressOffset = 6;
    3942
    4043// edges
     
    4548const edgeTypeOffset = 2;
    4649const edgeDataOffset = 3;
     50
     51// roots
     52// [<0:id>, <1:labelIndex>]
     53let rootFieldCount = 3;
     54const rootIdOffset = 0;
     55const rootLabelOffset = 1;
     56const reachabilityReasonOffset = 2;
    4757
    4858// Other constants.
     
    8393        snapshotDataString = null;
    8494
    85         let {version, nodes, nodeClassNames, edges, edgeTypes, edgeNames} = json;
     95        let {version, type, nodes, nodeClassNames, edges, edgeTypes, edgeNames, roots, labels} = json;
    8696        console.assert(version === 1, "Expect JavaScriptCore Heap Snapshot version 1");
     97        console.assert(type === "GCDebugging", "Expect a GCDebugging-type snapshot");
    8798
    8899        this._nodes = nodes;
    89100        this._nodeCount = nodes.length / nodeFieldCount;
     101
     102        this._roots = roots;
     103        this._rootCount = roots.length / rootFieldCount;
    90104
    91105        this._edges = edges;
     
    95109        this._edgeNamesTable = edgeNames;
    96110        this._nodeClassNamesTable = nodeClassNames;
     111        this._labelsTable = labels;
    97112
    98113        this._totalSize = 0;
     
    108123        }
    109124
     125        this._rootIdentifierToReasons = new Map; // <node identifier> => Set of root reasons
     126        for (let rootIndex = 0; rootIndex < roots.length; rootIndex += rootFieldCount) {
     127            let rootOrdinal = rootIndex / rootFieldCount;
     128            let rootIdentifier = roots[rootIndex + rootIdOffset];
     129            let rootReasonIndex = roots[rootIndex + rootLabelOffset];
     130            let rootReachabilityIndex = roots[rootIndex + reachabilityReasonOffset];
     131
     132            let existingReasons = this._rootIdentifierToReasons.get(rootIdentifier);
     133            if (existingReasons) {
     134                existingReasons.add(rootReasonIndex);
     135                existingReasons.add(rootReachabilityIndex);
     136            } else
     137                this._rootIdentifierToReasons.set(rootIdentifier, new Set([rootReasonIndex, rootReachabilityIndex]));
     138        }
     139
    110140        // FIXME: Replace toIdentifier and fromIdentifier in edges with nodeIndex to reduce hash lookups?
    111141
     
    137167        this._categories = categories;
    138168    }
     169
     170    get proxyObjectId() { return this._proxyObjectId; }
     171    get identifier() { return this._identifier; }
     172    get title() { return this._title; }
     173    get totalSize() { return this._totalSize; }
     174    get totalObjectCount() { return this._totalObjectCount; }
     175    get liveSize() { return this._liveSize; }
     176    get categories() { return this._categories; }
     177    get invalid() { return this._proxyObjectId === 0; }
    139178
    140179    // Static
     
    264303        // node is either a gcRoot or only reachable via Internal nodes.
    265304
    266         let paths = this._gcRootPathes(nodeIdentifier);
     305        let paths = this._gcRootPaths(nodeIdentifier);
    267306        if (!paths.length)
    268307            return [];
     
    288327            return this.serializeEdge(component.edge);
    289328        });
     329    }
     330   
     331    rootNodes()
     332    {
     333        let rootNodeIndexSet = new Set;
     334
     335        // Identifiers can occur multiple times in the roots list.
     336        for (let rootIndex = 0; rootIndex < this._roots.length; rootIndex += rootFieldCount) {
     337            let rootOrdinal = rootIndex / rootFieldCount;
     338            let rootIdentifier = this._roots[rootIndex + rootIdOffset];
     339
     340            let toNodeOrdinal = this._nodeIdentifierToOrdinal.get(rootIdentifier);
     341            let toNodeIndex = toNodeOrdinal * nodeFieldCount;
     342
     343            rootNodeIndexSet.add(toNodeIndex);
     344        }
     345
     346        return Array.from(rootNodeIndexSet.values()).map(this.serializeNode, this);
     347    }
     348   
     349    reasonNamesForRoot(rootIdentifier)
     350    {
     351        let reasonIndexes = this._rootIdentifierToReasons.get(rootIdentifier);
     352        if (!reasonIndexes)
     353            return [];
     354        return Array.from(reasonIndexes).map(this.labelForIndex, this).filter(a => a != 0)
    290355    }
    291356
     
    408473    serializeNode(nodeIndex)
    409474    {
    410         console.assert((nodeIndex % nodeFieldCount) === 0, "Invalid nodeIndex to serialize");
     475        console.assert((nodeIndex % nodeFieldCount) === 0, "Invalid nodeIndex to serialize: " + nodeIndex);
    411476
    412477        let nodeIdentifier = this._nodes[nodeIndex + nodeIdOffset];
     
    419484        let dominatorNodeIdentifier = this._nodes[dominatorNodeIndex + nodeIdOffset];
    420485
    421         return {
     486        let result = {
    422487            id: nodeIdentifier,
    423488            className: this._nodeClassNamesTable[this._nodes[nodeIndex + nodeClassNameOffset]],
     
    426491            internal: this._nodes[nodeIndex + nodeInternalOffset] ? true : false,
    427492            gcRoot: this._nodeOrdinalIsGCRoot[nodeOrdinal] ? true : false,
     493            markedRoot : this._rootIdentifierToReasons.has(nodeIdentifier),
    428494            dead: this._nodeOrdinalIsDead[nodeOrdinal] ? true : false,
     495            address: this._nodes[nodeIndex + nodeAddressOffset],
     496            label: this._labelsTable[this._nodes[nodeIndex + nodeLabelOffset]],
    429497            dominatorNodeIdentifier,
    430498            hasChildren,
    431499        };
     500
     501        let wrappedAddr = this._nodes[nodeIndex + nodeWrappedAddressOffset];
     502        if (wrappedAddr !== "0x0")
     503            result.wrappedAddress = wrappedAddr;
     504       
     505        return result;
     506    }
     507
     508    labelForIndex(index)
     509    {
     510        return this._labelsTable[index];
    432511    }
    433512
     
    714793    }
    715794
    716     _gcRootPathes(nodeIdentifier)
     795    _gcRootPaths(nodeIdentifier)
    717796    {
    718797        let targetNodeOrdinal = this._nodeIdentifierToOrdinal.get(nodeIdentifier);
     
    751830                let fromNodeOrdinal = this._incomingNodes[incomingEdgeIndex];
    752831                let fromNodeIndex = fromNodeOrdinal * nodeFieldCount;
    753                 let fromNodeIsInternal = this._nodes[fromNodeIndex + nodeInternalOffset];
    754                 if (fromNodeIsInternal)
    755                     continue;
     832                // let fromNodeIsInternal = this._nodes[fromNodeIndex + nodeInternalOffset];
     833                // if (fromNodeIsInternal)
     834                //     continue;
    756835
    757836                let edgeIndex = this._incomingEdges[incomingEdgeIndex];
     
    769848    }
    770849};
    771 
    772 HeapSnapshotDiff = class HeapSnapshotDiff
    773 {
    774     constructor(objectId, snapshot1, snapshot2)
    775     {
    776         this._objectId = objectId;
    777 
    778         this._snapshot1 = snapshot1;
    779         this._snapshot2 = snapshot2;
    780 
    781         this._totalSize = 0;
    782         this._addedNodeIdentifiers = new Set;
    783 
    784         let known = new Map;
    785         for (let nodeIndex = 0; nodeIndex < this._snapshot1._nodes.length; nodeIndex += nodeFieldCount) {
    786             let nodeIdentifier = this._snapshot1._nodes[nodeIndex + nodeIdOffset];
    787             known.set(nodeIdentifier, nodeIndex);
    788         }
    789 
    790         for (let nodeIndex = 0; nodeIndex < this._snapshot2._nodes.length; nodeIndex += nodeFieldCount) {
    791             let nodeIdentifier = this._snapshot2._nodes[nodeIndex + nodeIdOffset];
    792             let existed = known.delete(nodeIdentifier);
    793             if (!existed) {
    794                 this._addedNodeIdentifiers.add(nodeIdentifier);
    795                 this._totalSize += this._snapshot2._nodes[nodeIndex + nodeSizeOffset];
    796             }
    797         }
    798 
    799         let {liveSize, categories} = HeapSnapshot.updateCategoriesAndMetadata(this._snapshot2, (nodeIdentifier) => this._addedNodeIdentifiers.has(nodeIdentifier));
    800         this._categories = categories;
    801     }
    802 
    803     // Worker Methods
    804 
    805     allocationBucketCounts(bucketSizes)
    806     {
    807         return HeapSnapshot.allocationBucketCounts(this._snapshot2, bucketSizes, (nodeIdentifier) => this._addedNodeIdentifiers.has(nodeIdentifier));
    808     }
    809 
    810     instancesWithClassName(className)
    811     {
    812         return HeapSnapshot.instancesWithClassName(this._snapshot2, className, (nodeIdentifier) => this._addedNodeIdentifiers.has(nodeIdentifier));
    813     }
    814 
    815     update()
    816     {
    817         return HeapSnapshot.updateCategoriesAndMetadata(this._snapshot2, (nodeIdentifier) => this._addedNodeIdentifiers.has(nodeIdentifier));
    818     }
    819 
    820     nodeWithIdentifier(nodeIdentifier) { return this._snapshot2.nodeWithIdentifier(nodeIdentifier); }
    821     shortestGCRootPath(nodeIdentifier) { return this._snapshot2.shortestGCRootPath(nodeIdentifier); }
    822     dominatedNodes(nodeIdentifier) { return this._snapshot2.dominatedNodes(nodeIdentifier); }
    823     retainedNodes(nodeIdentifier) { return this._snapshot2.retainedNodes(nodeIdentifier); }
    824     retainers(nodeIdentifier) { return this._snapshot2.retainers(nodeIdentifier); }
    825 
    826     // Public
    827 
    828     serialize()
    829     {
    830         return {
    831             snapshot1: this._snapshot1.serialize(),
    832             snapshot2: this._snapshot2.serialize(),
    833             totalSize: this._totalSize,
    834             totalObjectCount: this._addedNodeIdentifiers.size,
    835             categories: this._categories,
    836         };
    837     }
    838 };
Note: See TracChangeset for help on using the changeset viewer.