WebKit Bugzilla
Attachment 348589 Details for
Bug 186269
: Make it possible to track unbalanced ref()/deref()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186269-20180830202658.patch (text/plain), 301.66 KB, created by
Simon Fraser (smfr)
on 2018-08-30 20:26:59 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2018-08-30 20:26:59 PDT
Size:
301.66 KB
patch
obsolete
>Subversion Revision: 235487 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 67fb7a581308744628f15805f7fb6de02e116bfa..5d1ad4c3f6b61704e27ce94415a41c03055b3fb6 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,93 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ In code which isn't able to pair ref() and deref(), UntrackedRefToken is used to indicate >+ that these references are not tracked. Many such sites could be easily fixed to track references, >+ which can be done incrementally as necessary to investigate leaks. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind the #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * API/JSContextRef.cpp: >+ (JSContextGroupRelease): >+ (JSGlobalContextRelease): >+ * API/JSObjectRef.cpp: >+ (JSClassRelease): >+ * API/JSScriptRef.cpp: >+ * API/JSStringRef.cpp: >+ (JSStringRelease): >+ * API/JSWeakPrivate.cpp: >+ (JSWeakRelease): >+ * bytecode/UnlinkedFunctionExecutable.cpp: >+ * bytecode/Watchpoint.cpp: >+ (JSC::InlineWatchpointSet::freeFat): >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::BytecodeGenerator::popLexicalScopeInternal): >+ (JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration): >+ (JSC::BytecodeGenerator::emitPopWithScope): >+ * bytecompiler/Label.h: >+ (JSC::Label::ref): >+ (JSC::Label::deref): >+ * bytecompiler/LabelScope.h: >+ (JSC::LabelScope::ref): >+ (JSC::LabelScope::deref): >+ * bytecompiler/RegisterID.h: >+ (JSC::RegisterID::ref): >+ (JSC::RegisterID::deref): >+ * dfg/DFGLazyJSValue.cpp: >+ (JSC::DFG::LazyJSValue::emit const): >+ * heap/MarkingConstraint.cpp: >+ (JSC::MarkingConstraint::execute): >+ (JSC::MarkingConstraint::doParallelWork): >+ * inspector/JSJavaScriptCallFrame.cpp: >+ (Inspector::JSJavaScriptCallFrame::releaseImpl): >+ * inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm: >+ (Inspector::RemoteConnectionToTarget::setup): >+ (Inspector::RemoteConnectionToTarget::close): >+ (Inspector::RemoteConnectionToTarget::sendMessageToTarget): >+ * inspector/remote/cocoa/RemoteInspectorXPCConnection.mm: >+ (Inspector::RemoteInspectorXPCConnection::handleEvent): >+ * jit/JITStubRoutine.h: >+ (JSC::JITStubRoutine::ref): >+ (JSC::JITStubRoutine::deref): >+ * jsc.cpp: >+ (runJSC): >+ * parser/SourceProviderCacheItem.h: >+ (JSC::SourceProviderCacheItem::~SourceProviderCacheItem): >+ * runtime/ArrayPrototype.cpp: >+ * runtime/HasOwnPropertyCache.h: >+ (JSC::HasOwnPropertyCache::Entry::offsetOfImpl): >+ (JSC::HasOwnPropertyCache::Entry::Entry): >+ (JSC::HasOwnPropertyCache::Entry::~Entry): >+ (JSC::HasOwnPropertyCache::Entry::operator=): >+ (JSC::HasOwnPropertyCache::get): >+ (JSC::HasOwnPropertyCache::tryAdd): >+ * runtime/PropertyMapHashTable.h: >+ (JSC::PropertyTable::remove): >+ * runtime/PropertyTable.cpp: >+ (JSC::PropertyTable::~PropertyTable): >+ > 2018-08-29 Commit Queue <commit-queue@webkit.org> > > Unreviewed, rolling out r235432 and r235436. >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index 165c56ece927544259e49ba02e49cbba412dbe62..116f1247a9f00aae125a6d648f63ef957a3976ed 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,98 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ In code which isn't able to pair ref() and deref(), UntrackedRefToken is used to indicate >+ that these references are not tracked. Many such sites could be easily fixed to track references, >+ which can be done incrementally as necessary to investigate leaks. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind the #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * WTF.xcodeproj/project.pbxproj: >+ * wtf/CMakeLists.txt: >+ * wtf/DeferrableRefCounted.h: >+ (WTF::DeferrableRefCountedBase::ref const): >+ (WTF::DeferrableRefCountedBase::derefBase const): >+ (WTF::DeferrableRefCounted::deref const): >+ * wtf/JSONValues.h: >+ * wtf/Ref.h: >+ (WTF::adopted): >+ (WTF::Ref::~Ref): >+ (WTF::Ref::Ref): >+ (WTF::Ref::token const): >+ (WTF::Ref::setToken): >+ (WTF::U>::swap): >+ (WTF::adoptRef): >+ * wtf/RefCounted.h: >+ (WTF::RefCountedBase::ref const): >+ (WTF::RefCountedBase::derefBase const): >+ (WTF::adopted): >+ (WTF::RefCounted::deref const): >+ * wtf/RefCounter.h: >+ (WTF::RefCounter<T>::Count::ref): >+ (WTF::RefCounter<T>::Count::deref): >+ * wtf/RefPtr.h: >+ (WTF::refIfNotNull): >+ (WTF::derefIfNotNull): >+ (WTF::RefPtr::RefPtr): >+ (WTF::RefPtr::~RefPtr): >+ (WTF::RefPtr::releaseNonNull): >+ (WTF::RefPtr::releaseConstNonNull): >+ (WTF::RefPtr::token const): >+ (WTF::RefPtr::setToken): >+ (WTF::U>::RefPtr): >+ (WTF::=): >+ (WTF::U>::swap): >+ (WTF::adoptRef): >+ * wtf/RefTracker.cpp: Added. >+ (WTF::RefTracker::nextRefTrackingToken): >+ (WTF::RefTracker::RefTracker): >+ (WTF::RefTracker::~RefTracker): >+ (WTF::RefTracker::dumpRemainingReferences const): >+ (WTF::RefTracker::trackRef): >+ (WTF::RefTracker::trackDeref): >+ * wtf/RefTracker.h: Copied from Tools/TestWebKitAPI/Tests/WTF/RefLogger.h. >+ * wtf/RefTracking.h: Copied from Tools/TestWebKitAPI/Tests/WTF/RefLogger.h. >+ (WTF::RefTrackingToken::RefTrackingToken): >+ (WTF::RefTrackingToken::value const): >+ * wtf/SizeLimits.cpp: >+ * wtf/ThreadSafeRefCounted.h: >+ (WTF::ThreadSafeRefCountedBase::ref const): >+ (WTF::ThreadSafeRefCountedBase::derefBase const): >+ (WTF::ThreadSafeRefCounted::deref const): >+ * wtf/ThreadingPthreads.cpp: >+ (WTF::Thread::destructTLS): >+ * wtf/WTFAssertions.cpp: >+ * wtf/text/StringImpl.cpp: >+ (WTF::StringImpl::~StringImpl): >+ * wtf/text/StringImpl.h: >+ (WTF::StringImpl::ref): >+ (WTF::StringImpl::deref): >+ * wtf/text/WTFString.h: >+ * wtf/text/cf/StringImplCF.cpp: >+ (WTF::StringWrapperCFAllocator::deallocate): >+ > 2018-08-29 David Kilzer <ddkilzer@apple.com> > > Rename wtf/text/mac/StringMac.mm to wtf/text/cococa/StringCococa.mm >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index d0d34b33c0e32b75f81560fea4503da5ba060426..0da728360c7f49a841128776ef5d85969aa20049 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,321 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ In code which isn't able to pair ref() and deref(), UntrackedRefToken is used to indicate >+ that these references are not tracked. Many such sites could be easily fixed to track references, >+ which can be done incrementally as necessary to investigate leaks. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind the #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * Modules/applepay/ApplePaySession.h: >+ * Modules/encryptedmedia/MediaKeySession.h: >+ * Modules/encryptedmedia/legacy/WebKitMediaKeySession.h: >+ * Modules/indexeddb/IDBDatabase.h: >+ * Modules/indexeddb/IDBIndex.cpp: >+ (WebCore::IDBIndex::ref): >+ (WebCore::IDBIndex::deref): >+ * Modules/indexeddb/IDBIndex.h: >+ * Modules/indexeddb/IDBObjectStore.cpp: >+ (WebCore::IDBObjectStore::ref): >+ (WebCore::IDBObjectStore::deref): >+ * Modules/indexeddb/IDBObjectStore.h: >+ * Modules/indexeddb/IDBRequest.h: >+ * Modules/indexeddb/IDBTransaction.h: >+ * Modules/indexeddb/client/IDBConnectionProxy.cpp: >+ (WebCore::IDBClient::IDBConnectionProxy::ref): >+ (WebCore::IDBClient::IDBConnectionProxy::deref): >+ * Modules/indexeddb/client/IDBConnectionProxy.h: >+ * Modules/indexeddb/client/IDBConnectionToServerDelegate.h: >+ * Modules/indexeddb/server/IDBConnectionToClientDelegate.h: >+ * Modules/indexeddb/shared/InProcessIDBServer.h: >+ * Modules/mediasession/MediaRemoteControls.h: >+ * Modules/mediasource/MediaSource.h: >+ * Modules/mediasource/SourceBuffer.h: >+ * Modules/mediasource/SourceBufferList.h: >+ * Modules/mediastream/MediaDevices.h: >+ * Modules/mediastream/MediaStream.h: >+ * Modules/mediastream/MediaStreamTrack.h: >+ * Modules/mediastream/RTCDTMFSender.h: >+ * Modules/mediastream/RTCDataChannel.h: >+ * Modules/mediastream/RTCPeerConnection.h: >+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h: >+ (WebCore::LibWebRTCMediaEndpoint::Release const): >+ * Modules/notifications/Notification.h: >+ * Modules/paymentrequest/PaymentRequest.h: >+ * Modules/speech/SpeechSynthesisUtterance.h: >+ * Modules/webaudio/AudioBufferSourceNode.cpp: >+ (WebCore::AudioBufferSourceNode::setPannerNode): >+ (WebCore::AudioBufferSourceNode::clearPannerNode): >+ * Modules/webaudio/AudioContext.cpp: >+ (WebCore::AudioContext::refNode): >+ (WebCore::AudioContext::derefNode): >+ (WebCore::AudioContext::derefUnfinishedSourceNodes): >+ * Modules/webaudio/AudioContext.h: >+ * Modules/webaudio/AudioNode.cpp: >+ (WebCore::AudioNode::refConnection): >+ (WebCore::AudioNode::derefConnection): >+ (WebCore::AudioNode::ref): >+ (WebCore::AudioNode::deref): >+ * Modules/webaudio/AudioNode.h: >+ * Modules/webaudio/AudioNodeInput.cpp: >+ (WebCore::AudioNodeInput::connect): >+ (WebCore::AudioNodeInput::disconnect): >+ * Modules/webaudio/MediaElementAudioSourceNode.cpp: >+ (WebCore::MediaElementAudioSourceNode::unlock): >+ * Modules/webaudio/OfflineAudioDestinationNode.cpp: >+ (WebCore::OfflineAudioDestinationNode::offlineRender): >+ * Modules/webaudio/ScriptProcessorNode.cpp: >+ (WebCore::ScriptProcessorNode::process): >+ * Modules/webdatabase/SQLCallbackWrapper.h: >+ (WebCore::SQLCallbackWrapper::clear): >+ * Modules/websockets/ThreadableWebSocketChannel.h: >+ (WebCore::ThreadableWebSocketChannel::ref): >+ (WebCore::ThreadableWebSocketChannel::deref): >+ * Modules/websockets/WebSocket.cpp: >+ (WebCore::WebSocket::connect): >+ * Modules/websockets/WebSocket.h: >+ * Modules/websockets/WebSocketChannel.cpp: >+ (WebCore::WebSocketChannel::didCloseSocketStream): >+ (WebCore::WebSocketChannel::didFinishLoading): >+ (WebCore::WebSocketChannel::didFail): >+ * Modules/websockets/WebSocketChannel.h: >+ * Modules/websockets/WorkerThreadableWebSocketChannel.h: >+ * Modules/webvr/VRDisplay.h: >+ * animation/WebAnimation.h: >+ * bridge/NP_jsobject.cpp: >+ (JSC::jsDeallocate): >+ * bridge/objc/WebScriptObject.mm: >+ (-[WebScriptObject _setOriginRootObject:andRootObject:]): >+ (-[WebScriptObject dealloc]): >+ * css/CSSComputedStyleDeclaration.cpp: >+ (WebCore::CSSComputedStyleDeclaration::ref): >+ (WebCore::CSSComputedStyleDeclaration::deref): >+ * css/CSSComputedStyleDeclaration.h: >+ * css/CSSDefaultStyleSheets.cpp: >+ (WebCore::CSSDefaultStyleSheets::loadFullDefaultStyle): >+ * css/CSSFontFace.h: >+ * css/CSSFontFaceSet.h: >+ * css/CSSImageGeneratorValue.cpp: >+ (WebCore::CSSImageGeneratorValue::removeClient): >+ * css/CSSPrimitiveValue.cpp: >+ (WebCore::CSSPrimitiveValue::cleanup): >+ * css/CSSProperty.cpp: >+ * css/CSSRuleList.cpp: >+ (WebCore::StaticCSSRuleList::deref): >+ * css/CSSRuleList.h: >+ * css/CSSSegmentedFontFace.h: >+ * css/CSSSelector.h: >+ (WebCore::CSSSelector::setValue): >+ (WebCore::CSSSelector::~CSSSelector): >+ * css/CSSStyleDeclaration.h: >+ * css/CSSStyleSheet.cpp: >+ * css/CSSValue.h: >+ (WebCore::CSSValue::deref): >+ * css/DeprecatedCSSOMValue.h: >+ (WebCore::DeprecatedCSSOMValue::deref): >+ * css/FontFace.cpp: >+ (WebCore::FontFace::fontStateChanged): >+ * css/FontFace.h: >+ * css/FontFaceSet.h: >+ * css/PropertySetCSSStyleDeclaration.cpp: >+ (WebCore::PropertySetCSSStyleDeclaration::ref): >+ (WebCore::PropertySetCSSStyleDeclaration::deref): >+ (WebCore::StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration): >+ (WebCore::StyleRuleCSSStyleDeclaration::ref): >+ (WebCore::StyleRuleCSSStyleDeclaration::deref): >+ (WebCore::StyleRuleCSSStyleDeclaration::reattach): >+ * css/PropertySetCSSStyleDeclaration.h: >+ * css/RuleSet.h: >+ * css/StyleProperties.cpp: >+ (WebCore::ImmutableStyleProperties::~ImmutableStyleProperties): >+ * css/StyleProperties.h: >+ (WebCore::StylePropertiesBase::deref): >+ * css/StyleRule.h: >+ (WebCore::StyleRuleBase::deref): >+ * dom/AbortSignal.h: >+ * dom/ActiveDOMObject.h: >+ (WebCore::ActiveDOMObject::unsetPendingActivity): >+ * dom/DOMImplementation.h: >+ (WebCore::DOMImplementation::ref): >+ (WebCore::DOMImplementation::deref): >+ * dom/DataTransferItemList.h: >+ (WebCore::DataTransferItemList::ref): >+ (WebCore::DataTransferItemList::deref): >+ * dom/DatasetDOMStringMap.cpp: >+ (WebCore::DatasetDOMStringMap::ref): >+ (WebCore::DatasetDOMStringMap::deref): >+ * dom/DatasetDOMStringMap.h: >+ * dom/Document.cpp: >+ (WebCore::m_identifier): >+ (WebCore::Document::~Document): >+ (WebCore::Document::referencingNodeCount const): >+ * dom/Document.h: >+ (WebCore::Document::referencingNodeCount const): Deleted. >+ * dom/ElementData.cpp: >+ * dom/ElementData.h: >+ (WebCore::ElementData::deref): >+ * dom/ElementRareData.cpp: >+ * dom/EventTarget.h: >+ (WebCore::EventTarget::ref): >+ (WebCore::EventTarget::deref): >+ * dom/MessagePort.cpp: >+ (WebCore::MessagePort::ref const): >+ (WebCore::MessagePort::deref const): >+ * dom/MessagePort.h: >+ * dom/NamedNodeMap.cpp: >+ (WebCore::NamedNodeMap::ref): >+ (WebCore::NamedNodeMap::deref): >+ * dom/NamedNodeMap.h: >+ * dom/Node.cpp: >+ (WebCore::Node::refEventTarget): >+ (WebCore::Node::derefEventTarget): >+ * dom/Node.h: >+ (WebCore::Node::refTracker const): >+ (WebCore::Node::refTracker): >+ (WebCore::adopted): >+ (WebCore::Node::ref): >+ (WebCore::Node::deref): >+ * dom/ScriptElement.cpp: >+ (WebCore::ScriptElement::ref): >+ (WebCore::ScriptElement::deref): >+ * dom/ScriptElement.h: >+ * dom/ScriptExecutionContext.h: >+ (WebCore::ScriptExecutionContext::ref): >+ (WebCore::ScriptExecutionContext::deref): >+ * dom/SpaceSplitString.h: >+ (WebCore::SpaceSplitStringData::ref): >+ (WebCore::SpaceSplitStringData::deref): >+ * fileapi/FileReader.h: >+ * html/CanvasBase.h: >+ * html/DOMTokenList.h: >+ (WebCore::DOMTokenList::ref): >+ (WebCore::DOMTokenList::deref): >+ * html/FormAssociatedElement.h: >+ (WebCore::FormAssociatedElement::ref): >+ (WebCore::FormAssociatedElement::deref): >+ * html/FormController.cpp: >+ (WebCore::FormElementKey::~FormElementKey): >+ (WebCore::FormElementKey::operator=): >+ (WebCore::FormElementKey::ref const): >+ (WebCore::FormElementKey::deref const): >+ * html/HTMLCanvasElement.h: >+ * html/HTMLFormControlElement.h: >+ * html/HTMLMediaElement.cpp: >+ (WebCore::HTMLMediaElement::HTMLMediaElement): >+ (WebCore::HTMLMediaElement::~HTMLMediaElement): >+ * html/HTMLObjectElement.h: >+ * html/MediaController.h: >+ * html/OffscreenCanvas.h: >+ * html/canvas/CanvasRenderingContext.cpp: >+ (WebCore::CanvasRenderingContext::ref): >+ (WebCore::CanvasRenderingContext::deref): >+ * html/canvas/CanvasRenderingContext.h: >+ * html/canvas/WebGLExtension.h: >+ (WebCore::WebGLExtension::ref): >+ (WebCore::WebGLExtension::deref): >+ * html/track/TextTrack.h: >+ * html/track/TextTrackCue.h: >+ * html/track/TrackListBase.h: >+ * loader/DocumentThreadableLoader.h: >+ * loader/ThreadableLoader.h: >+ (WebCore::ThreadableLoader::ref): >+ (WebCore::ThreadableLoader::deref): >+ * loader/WorkerThreadableLoader.h: >+ * loader/appcache/DOMApplicationCache.h: >+ * page/AbstractDOMWindow.h: >+ * page/EventSource.h: >+ * page/Frame.cpp: >+ (WebCore::Frame::selfOnlyDeref): >+ * page/Performance.h: >+ * page/VisualViewport.h: >+ * platform/Length.cpp: >+ (WebCore::Length::ref const): >+ (WebCore::Length::deref const): >+ * platform/Length.h: >+ (WebCore::Length::operator=): >+ (WebCore::Length::~Length): >+ * platform/ScrollableArea.cpp: >+ * platform/graphics/Color.cpp: >+ (WebCore::Color::operator=): >+ * platform/graphics/Color.h: >+ (WebCore::Color::~Color): >+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm: >+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::supportsType): >+ * platform/graphics/cg/ImageDecoderCG.cpp: >+ (WebCore::sharedBufferRelease): >+ * platform/graphics/metal/GPUBufferMetal.mm: >+ (WebCore::GPUBuffer::GPUBuffer): >+ * platform/mediastream/RealtimeOutgoingAudioSource.h: >+ * platform/mediastream/RealtimeOutgoingVideoSource.h: >+ * platform/network/AuthenticationClient.h: >+ (WebCore::AuthenticationClient::ref): >+ (WebCore::AuthenticationClient::deref): >+ * platform/network/DataURLDecoder.cpp: >+ (WebCore::DataURLDecoder::DecodingResultDispatcher::timerFired): >+ * platform/network/ResourceHandle.h: >+ * platform/network/cf/SocketStreamHandleImplCFNet.cpp: >+ (WebCore::SocketStreamHandleImpl::releaseSocketStreamHandle): >+ * platform/text/BidiContext.cpp: >+ * rendering/FloatingObjects.cpp: >+ * rendering/InlineFlowBox.cpp: >+ * rendering/RenderBox.cpp: >+ * rendering/RenderObject.cpp: >+ (WebCore::RenderObject::destroy): >+ * rendering/RenderWidget.h: >+ (WebCore::RenderWidget::ref): >+ (WebCore::RenderWidget::deref): >+ * rendering/RootInlineBox.cpp: >+ * rendering/style/RenderStyle.cpp: >+ * rendering/style/StyleRareInheritedData.cpp: >+ * testing/MockContentFilterSettings.h: >+ (WebCore::MockContentFilterSettings::ref): >+ (WebCore::MockContentFilterSettings::deref): >+ * testing/MockCredentialsMessenger.cpp: >+ (WebCore::MockCredentialsMessenger::ref): >+ (WebCore::MockCredentialsMessenger::deref): >+ * testing/MockCredentialsMessenger.h: >+ * testing/MockPaymentCoordinator.h: >+ * workers/AbstractWorker.h: >+ * workers/WorkerGlobalScope.h: >+ * workers/WorkerMessagingProxy.cpp: >+ (WebCore::WorkerMessagingProxy::workerGlobalScopeDestroyedInternal): >+ * workers/service/ServiceWorker.h: >+ * workers/service/ServiceWorkerContainer.cpp: >+ (WebCore::ServiceWorkerContainer::refEventTarget): >+ (WebCore::ServiceWorkerContainer::derefEventTarget): >+ * workers/service/ServiceWorkerContainer.h: >+ * workers/service/ServiceWorkerJobClient.h: >+ * workers/service/ServiceWorkerRegistration.h: >+ * xml/XMLHttpRequest.h: >+ * xml/XMLHttpRequestUpload.h: >+ * xml/XPathGrammar.cpp: >+ * xml/XPathGrammar.y: >+ * xml/parser/XMLDocumentParser.cpp: >+ (WebCore::XMLDocumentParser::popCurrentNode): >+ (WebCore::XMLDocumentParser::clearCurrentNodeStack): >+ > 2018-08-29 Daniel Bates <dabates@apple.com> > > REGRESSION (r226138): WebCore::subdivide() may return an empty vector; Web process can crash when performing find in Epiphany >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 439ed38a61be4d855abb1d77e74f1c6d6dbff62d..d42dc95759c9b02f20811416103452e318561229 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,84 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ In code which isn't able to pair ref() and deref(), UntrackedRefToken is used to indicate >+ that these references are not tracked. Many such sites could be easily fixed to track references, >+ which can be done incrementally as necessary to investigate leaks. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind the #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * Platform/IPC/mac/ConnectionMac.mm: >+ (IPC::Connection::open): >+ * Shared/API/APIObject.h: >+ * Shared/API/c/WKType.cpp: >+ (WKRelease): >+ * Shared/Cocoa/APIObject.mm: >+ (API::Object::ref): >+ (API::Object::deref): >+ * Shared/ShareableResource.cpp: >+ (WebKit::shareableResourceDeallocate): >+ (WebKit::ShareableResource::wrapInSharedBuffer): >+ * Shared/cg/ShareableBitmapCG.cpp: >+ (WebKit::ShareableBitmap::releaseBitmapContextData): >+ (WebKit::ShareableBitmap::releaseDataProviderData): >+ * StorageProcess/IndexedDB/WebIDBConnectionToClient.h: >+ * UIProcess/API/C/mac/WKContextPrivateMac.mm: >+ (WKContextGetInfoForInstalledPlugIns): >+ * UIProcess/Launcher/mac/ProcessLauncherMac.mm: >+ (WebKit::ProcessLauncher::launchProcess): >+ * UIProcess/Notifications/WebNotificationManagerProxy.cpp: >+ (WebKit::WebNotificationManagerProxy::refWebContextSupplement): >+ (WebKit::WebNotificationManagerProxy::derefWebContextSupplement): >+ * UIProcess/Notifications/WebNotificationManagerProxy.h: >+ * UIProcess/WebContextSupplement.h: >+ (WebKit::WebContextSupplement::ref): >+ (WebKit::WebContextSupplement::deref): >+ * UIProcess/WebCookieManagerProxy.cpp: >+ (WebKit::WebCookieManagerProxy::refWebContextSupplement): >+ (WebKit::WebCookieManagerProxy::derefWebContextSupplement): >+ * UIProcess/WebCookieManagerProxy.h: >+ * UIProcess/WebGeolocationManagerProxy.cpp: >+ (WebKit::WebGeolocationManagerProxy::refWebContextSupplement): >+ (WebKit::WebGeolocationManagerProxy::derefWebContextSupplement): >+ * UIProcess/WebGeolocationManagerProxy.h: >+ * UIProcess/WebMediaSessionFocusManager.cpp: >+ (WebKit::WebMediaSessionFocusManager::refWebContextSupplement): >+ (WebKit::WebMediaSessionFocusManager::derefWebContextSupplement): >+ * UIProcess/WebMediaSessionFocusManager.h: >+ * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h: >+ * WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp: >+ (WebKit::releaseSharedBuffer): >+ * WebProcess/Plugins/PDF/PDFPlugin.mm: >+ (WebKit::jsPDFDocFinalize): >+ * WebProcess/Plugins/PluginView.cpp: >+ (WebKit::PluginView::unprotectPluginFromDestruction): >+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: >+ (WebKit::WebFrameLoaderClient::frameLoaderDestroyed): >+ * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: >+ (WebKit::TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition): >+ > 2018-08-29 Chris Dumez <cdumez@apple.com> > > Crash under WebKit: WTF::Function<void ()>::CallableWrapper<WebKit::ResourceLoadStatisticsMemoryStore::removeDataRecords(WTF::CompletionHandler<void ()>&&)::$_1>::call() >diff --git a/Source/WebKitLegacy/ios/ChangeLog b/Source/WebKitLegacy/ios/ChangeLog >index 565a20d46224ab47eec5e87089ac2c3b3bc50d3d..396eeb12b73b3acf8f824c98058d6e509a285858 100644 >--- a/Source/WebKitLegacy/ios/ChangeLog >+++ b/Source/WebKitLegacy/ios/ChangeLog >@@ -1,3 +1,37 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ In code which isn't able to pair ref() and deref(), UntrackedRefToken is used to indicate >+ that these references are not tracked. Many such sites could be easily fixed to track references, >+ which can be done incrementally as necessary to investigate leaks. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind the #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * WebCoreSupport/WebGeolocation.mm: >+ (-[WebGeolocation dealloc]): >+ > 2018-08-24 Ryosuke Niwa <rniwa@webkit.org> > > Pass in IsComposed flag to Event constructors >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index 276c53751f0ba0c89608f6b88f10faae7049553f..2ac2f35d43527a7ad1201677926e1ca5aa0d7bd8 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,93 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind an #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * DOM/DOM.mm: >+ (-[DOMNodeFilter dealloc]): >+ * DOM/DOMBlob.mm: >+ (-[DOMBlob dealloc]): >+ * DOM/DOMCSSRule.mm: >+ (-[DOMCSSRule dealloc]): >+ * DOM/DOMCSSRuleList.mm: >+ (-[DOMCSSRuleList dealloc]): >+ * DOM/DOMCSSStyleDeclaration.mm: >+ (-[DOMCSSStyleDeclaration dealloc]): >+ * DOM/DOMCSSValue.mm: >+ (-[DOMCSSValue dealloc]): >+ * DOM/DOMCounter.mm: >+ (-[DOMCounter dealloc]): >+ * DOM/DOMEvent.mm: >+ (-[DOMEvent dealloc]): >+ * DOM/DOMFileList.mm: >+ (-[DOMFileList dealloc]): >+ * DOM/DOMHTMLCollection.mm: >+ (-[DOMHTMLCollection dealloc]): >+ * DOM/DOMHTMLOptionsCollection.mm: >+ (-[DOMHTMLOptionsCollection dealloc]): >+ * DOM/DOMImplementation.mm: >+ (-[DOMImplementation dealloc]): >+ * DOM/DOMMediaError.mm: >+ (-[DOMMediaError dealloc]): >+ * DOM/DOMMediaList.mm: >+ (-[DOMMediaList dealloc]): >+ * DOM/DOMNamedNodeMap.mm: >+ (-[DOMNamedNodeMap dealloc]): >+ * DOM/DOMNode.mm: >+ (-[DOMNode dealloc]): >+ * DOM/DOMNodeIterator.mm: >+ (-[DOMNodeIterator dealloc]): >+ * DOM/DOMNodeList.mm: >+ (-[DOMNodeList dealloc]): >+ * DOM/DOMRGBColor.mm: >+ (-[DOMRGBColor dealloc]): >+ * DOM/DOMRange.mm: >+ (-[DOMRange dealloc]): >+ * DOM/DOMRect.mm: >+ (-[DOMRect dealloc]): >+ * DOM/DOMStyleSheet.mm: >+ (-[DOMStyleSheet dealloc]): >+ * DOM/DOMStyleSheetList.mm: >+ (-[DOMStyleSheetList dealloc]): >+ * DOM/DOMTimeRanges.mm: >+ (-[DOMTimeRanges dealloc]): >+ * DOM/DOMTokenList.mm: >+ (-[DOMTokenList dealloc]): >+ * DOM/DOMTreeWalker.mm: >+ (-[DOMTreeWalker dealloc]): >+ * DOM/DOMXPath.mm: >+ (-[DOMNativeXPathNSResolver dealloc]): >+ * DOM/DOMXPathExpression.mm: >+ (-[DOMXPathExpression dealloc]): >+ * DOM/DOMXPathResult.mm: >+ (-[DOMXPathResult dealloc]): >+ * History/WebBackForwardList.mm: >+ (-[WebBackForwardList dealloc]): >+ * WebCoreSupport/WebSecurityOrigin.mm: >+ (-[WebSecurityOrigin dealloc]): >+ > 2018-08-29 Youenn Fablet <youenn@apple.com> > > Remove WebRTC legacy API implementation >diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp >index f3c0fd1c7e06d343002c14e3ecaa30643d272ad7..450378ed06fdc75048f9d594bfffd8a2b9636357 100644 >--- a/Source/JavaScriptCore/API/JSContextRef.cpp >+++ b/Source/JavaScriptCore/API/JSContextRef.cpp >@@ -81,7 +81,7 @@ void JSContextGroupRelease(JSContextGroupRef group) > VM& vm = *toJS(group); > > JSLockHolder locker(&vm); >- vm.deref(); >+ vm.deref(UntrackedRefToken()); > } > > static bool internalScriptTimeoutCallback(ExecState* exec, void* callbackPtr, void* callbackData) >@@ -179,7 +179,7 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx) > bool protectCountIsZero = vm.heap.unprotect(vm.vmEntryGlobalObject(exec)); > if (protectCountIsZero) > vm.heap.reportAbandonedObjectGraph(); >- vm.deref(); >+ vm.deref(UntrackedRefToken()); > } > > JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) >diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp >index 694d185fd50850250c27b014742940875e4dd2f6..2193e5452bdffc40cd9e3e0ebe8a8601a5b46d9e 100644 >--- a/Source/JavaScriptCore/API/JSObjectRef.cpp >+++ b/Source/JavaScriptCore/API/JSObjectRef.cpp >@@ -79,7 +79,7 @@ JSClassRef JSClassRetain(JSClassRef jsClass) > > void JSClassRelease(JSClassRef jsClass) > { >- jsClass->deref(); >+ jsClass->deref(UntrackedRefToken()); > } > > JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data) >diff --git a/Source/JavaScriptCore/API/JSScriptRef.cpp b/Source/JavaScriptCore/API/JSScriptRef.cpp >index 33f59a36334171b14556c6be3348f6c12012f172..60d327aad6adf9c16d9d3b4289c74197b2a7d098 100644 >--- a/Source/JavaScriptCore/API/JSScriptRef.cpp >+++ b/Source/JavaScriptCore/API/JSScriptRef.cpp >@@ -139,7 +139,7 @@ void JSScriptRetain(JSScriptRef script) > void JSScriptRelease(JSScriptRef script) > { > JSLockHolder locker(&script->vm()); >- script->deref(); >+ script->deref(UntrackedRefToken()); > } > > JSValueRef JSScriptEvaluate(JSContextRef context, JSScriptRef script, JSValueRef thisValueRef, JSValueRef* exception) >diff --git a/Source/JavaScriptCore/API/JSStringRef.cpp b/Source/JavaScriptCore/API/JSStringRef.cpp >index 909540481da914d8ea19c649bcbe178a269af0b0..4b036713cbddbe6ddcf50015eb58c1a596abefe3 100644 >--- a/Source/JavaScriptCore/API/JSStringRef.cpp >+++ b/Source/JavaScriptCore/API/JSStringRef.cpp >@@ -73,7 +73,7 @@ JSStringRef JSStringRetain(JSStringRef string) > > void JSStringRelease(JSStringRef string) > { >- string->deref(); >+ string->deref(UntrackedRefToken()); > } > > size_t JSStringGetLength(JSStringRef string) >diff --git a/Source/JavaScriptCore/API/JSWeakPrivate.cpp b/Source/JavaScriptCore/API/JSWeakPrivate.cpp >index 246649f59e3d04c4de5609bcfa44ee1d7c03b33e..c04011f849f672c9b21438df20cbefe475361ee4 100644 >--- a/Source/JavaScriptCore/API/JSWeakPrivate.cpp >+++ b/Source/JavaScriptCore/API/JSWeakPrivate.cpp >@@ -60,7 +60,7 @@ void JSWeakRelease(JSContextGroupRef contextGroup, JSWeakRef weakRef) > { > VM* vm = toJS(contextGroup); > JSLockHolder locker(vm); >- weakRef->deref(); >+ weakRef->deref(UntrackedRefToken()); > } > > JSObjectRef JSWeakGetObject(JSWeakRef weakRef) >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >index e540a240d8f3b9ac7259f010cd2e345d34015391..b668aa1a4bf9ed2f83995df761a277aa0444be43 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >+++ b/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp >@@ -42,7 +42,9 @@ > > namespace JSC { > >+#if !ENABLE(REF_TRACKING) > static_assert(sizeof(UnlinkedFunctionExecutable) <= 160, "UnlinkedFunctionExecutable should fit in a 160-byte cell. If you increase the size of this class, consider making a size class that perfectly fits it."); >+#endif > > const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) }; > >diff --git a/Source/JavaScriptCore/bytecode/Watchpoint.cpp b/Source/JavaScriptCore/bytecode/Watchpoint.cpp >index 7fa56167bf2045f4c8c33ee155e0ab60a4c36b6d..3683d58028a585acb632bc5445cd0fa4a43e765c 100644 >--- a/Source/JavaScriptCore/bytecode/Watchpoint.cpp >+++ b/Source/JavaScriptCore/bytecode/Watchpoint.cpp >@@ -175,7 +175,7 @@ WatchpointSet* InlineWatchpointSet::inflateSlow() > void InlineWatchpointSet::freeFat() > { > ASSERT(isFat()); >- fat()->deref(); >+ fat()->deref(UntrackedRefToken()); > } > > DeferredWatchpointFire::DeferredWatchpointFire(VM& vm) >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >index 00afc9f96c2a95c17735f1634cbe70576cac3d17..932a1d8e8f8148f5e756b334f74ddc4df7accdaf 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -2287,14 +2287,14 @@ void BytecodeGenerator::popLexicalScopeInternal(VariableEnvironment& environment > VarOffset offset = symbolTableEntry.varOffset(); > ASSERT(offset.isStack()); > RegisterID* local = ®isterFor(offset.stackOffset()); >- local->deref(); >+ local->deref(UntrackedRefToken()); > } > > if (hasCapturedVariables) { > RELEASE_ASSERT(stackEntry.m_scope); > emitPopScope(scopeRegister(), stackEntry.m_scope); > popLocalControlFlowScope(); >- stackEntry.m_scope->deref(); >+ stackEntry.m_scope->deref(UntrackedRefToken()); > } > > m_TDZStack.removeLast(); >@@ -2367,7 +2367,7 @@ void BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration(VariableEnvir > RELEASE_ASSERT(!entry.isNull()); > RegisterID* transitionValue = pair.first; > emitPutToScope(loopScope, variableForLocalEntry(identifier, entry, loopSymbolTable->index(), true), transitionValue, DoNotThrowIfNotFound, InitializationMode::NotInitialization); >- transitionValue->deref(); >+ transitionValue->deref(UntrackedRefToken()); > } > } > } >@@ -3835,7 +3835,7 @@ void BytecodeGenerator::emitPopWithScope() > emitPopScope(scopeRegister(), scopeRegister()); > popLocalControlFlowScope(); > auto stackEntry = m_lexicalScopeStack.takeLast(); >- stackEntry.m_scope->deref(); >+ stackEntry.m_scope->deref(UntrackedRefToken()); > RELEASE_ASSERT(stackEntry.m_isWithScope); > } > >diff --git a/Source/JavaScriptCore/bytecompiler/Label.h b/Source/JavaScriptCore/bytecompiler/Label.h >index 3e2d297f23d105c15984011a0f55a33574df053a..934548087ca3b64130613a80f9dd2034dc98a0c9 100644 >--- a/Source/JavaScriptCore/bytecompiler/Label.h >+++ b/Source/JavaScriptCore/bytecompiler/Label.h >@@ -54,8 +54,12 @@ namespace JSC { > return m_location - opcode; > } > >- void ref() { ++m_refCount; } >- void deref() >+ RefTrackingToken ref() >+ { >+ ++m_refCount; >+ return UntrackedRefToken(); >+ } >+ void deref(RefTrackingToken) > { > --m_refCount; > ASSERT(m_refCount >= 0); >diff --git a/Source/JavaScriptCore/bytecompiler/LabelScope.h b/Source/JavaScriptCore/bytecompiler/LabelScope.h >index a94bf05ada4688aa0d2a8adb8f2d8607ef34ccbd..36a25547cf18ce1a429d308ad965e098ad47c03c 100644 >--- a/Source/JavaScriptCore/bytecompiler/LabelScope.h >+++ b/Source/JavaScriptCore/bytecompiler/LabelScope.h >@@ -56,8 +56,12 @@ public: > const Identifier* name() const { return m_name; } > int scopeDepth() const { return m_scopeDepth; } > >- void ref() { ++m_refCount; } >- void deref() >+ RefTrackingToken ref() >+ { >+ ++m_refCount; >+ return UntrackedRefToken(); >+ } >+ void deref(RefTrackingToken) > { > --m_refCount; > ASSERT(m_refCount >= 0); >diff --git a/Source/JavaScriptCore/bytecompiler/RegisterID.h b/Source/JavaScriptCore/bytecompiler/RegisterID.h >index cc80f5eb8913562ad25cd6f7aad1c5bffd8a03b7..8c64bddaa2744fb47adbc774485260b46746ccb2 100644 >--- a/Source/JavaScriptCore/bytecompiler/RegisterID.h >+++ b/Source/JavaScriptCore/bytecompiler/RegisterID.h >@@ -97,12 +97,13 @@ namespace JSC { > return m_isTemporary; > } > >- void ref() >+ RefTrackingToken ref() > { > ++m_refCount; >+ return UntrackedRefToken(); > } > >- void deref() >+ void deref(RefTrackingToken) > { > --m_refCount; > ASSERT(m_refCount >= 0); >diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp >index 43bead62ff9be10d6e1af1617a97d96e091281e6..de51986b59dbc012470261f0010fd734766732c2 100644 >--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp >+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp >@@ -235,7 +235,7 @@ void LazyJSValue::emit(CCallHelpers& jit, JSValueRegs result) const > codeBlock->addConstant(realValue); > > if (thisValue.m_kind == NewStringImpl) >- thisValue.u.stringImpl->deref(); >+ thisValue.u.stringImpl->deref(UntrackedRefToken()); > > linkBuffer.patch(label, realValue.asCell()); > }); >diff --git a/Source/JavaScriptCore/heap/MarkingConstraint.cpp b/Source/JavaScriptCore/heap/MarkingConstraint.cpp >index 3bab7679c553cd3ec3e4c814ecea4d8c6c4299bb..bdcad0b4caf221e5e4ec46809d0c9a50c225422b 100644 >--- a/Source/JavaScriptCore/heap/MarkingConstraint.cpp >+++ b/Source/JavaScriptCore/heap/MarkingConstraint.cpp >@@ -31,7 +31,7 @@ > > namespace JSC { > >-static constexpr bool verboseMarkingConstraint = false; >+static constexpr bool verboseMarkingConstraint = true; > > MarkingConstraint::MarkingConstraint(CString abbreviatedName, CString name, ConstraintVolatility volatility, ConstraintConcurrency concurrency, ConstraintParallelism parallelism) > : m_abbreviatedName(abbreviatedName) >@@ -57,7 +57,7 @@ void MarkingConstraint::execute(SlotVisitor& visitor) > executeImpl(visitor); > m_lastVisitCount += visitCounter.visitCount(); > if (verboseMarkingConstraint && visitCounter.visitCount()) >- dataLog("(", abbreviatedName(), " visited ", visitCounter.visitCount(), " in execute)"); >+ dataLog("(", name(), " visited ", visitCounter.visitCount(), " in execute)"); > } > > double MarkingConstraint::quickWorkEstimate(SlotVisitor&) >@@ -86,7 +86,7 @@ void MarkingConstraint::doParallelWork(SlotVisitor& visitor, SharedTask<void(Slo > VisitCounter visitCounter(visitor); > task.run(visitor); > if (verboseMarkingConstraint && visitCounter.visitCount()) >- dataLog("(", abbreviatedName(), " visited ", visitCounter.visitCount(), " in doParallelWork)"); >+ dataLog("(", name(), " visited ", visitCounter.visitCount(), " in doParallelWork)"); > { > auto locker = holdLock(m_lock); > m_lastVisitCount += visitCounter.visitCount(); >diff --git a/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp b/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp >index bf976a617cdfcb020349dcb53361a3e88a5d3e8e..7bdf0cde41fa13c7fa6c781a6ce82d74be5395a4 100644 >--- a/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp >+++ b/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp >@@ -65,7 +65,7 @@ void JSJavaScriptCallFrame::destroy(JSC::JSCell* cell) > void JSJavaScriptCallFrame::releaseImpl() > { > if (auto impl = std::exchange(m_impl, nullptr)) >- impl->deref(); >+ impl->deref(UntrackedRefToken()); > } > > JSJavaScriptCallFrame::~JSJavaScriptCallFrame() >diff --git a/Source/JavaScriptCore/inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm b/Source/JavaScriptCore/inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm >index 3e894136b36932e722074bda44926e863cbfa562..e624a4fb91ce43bf53b5931e4eba18e0bcda26f5 100644 >--- a/Source/JavaScriptCore/inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm >+++ b/Source/JavaScriptCore/inspector/remote/cocoa/RemoteConnectionToTargetCocoa.mm >@@ -183,7 +183,7 @@ bool RemoteConnectionToTarget::setup(bool isAutomaticInspection, bool automatica > RemoteInspector::singleton().updateTargetListing(targetIdentifier); > } > } >- deref(); >+ deref(UntrackedRefToken()); > }); > > return true; >@@ -213,7 +213,7 @@ void RemoteConnectionToTarget::close() > RemoteInspector::singleton().updateTargetListing(targetIdentifier); > } > } >- deref(); >+ deref(UntrackedRefToken()); > }); > } > >@@ -232,7 +232,7 @@ void RemoteConnectionToTarget::sendMessageToTarget(NSString *message) > > target->dispatchMessageFromRemote(message); > } >- deref(); >+ deref(UntrackedRefToken()); > }); > } > >diff --git a/Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorXPCConnection.mm b/Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorXPCConnection.mm >index 753ac4a8cc0d9bd30ed588fba8ca30a782966cd2..b0796f85c3a9ae839f5690a6e592915c75b7da92 100644 >--- a/Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorXPCConnection.mm >+++ b/Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorXPCConnection.mm >@@ -139,7 +139,7 @@ void RemoteInspectorXPCConnection::handleEvent(xpc_object_t object) > if (object == XPC_ERROR_CONNECTION_INVALID) { > // This is the last event we will ever receive from the connection. > // This balances the ref() in the constructor. >- deref(); >+ deref(UntrackedRefToken()); > } > return; > } >diff --git a/Source/JavaScriptCore/jit/JITStubRoutine.h b/Source/JavaScriptCore/jit/JITStubRoutine.h >index 33d2a3673d7a6a4b5b9d32a5ceacc51cb972a121..4b33bae0ba3e4940466c0d8442fc1ee16c051d24 100644 >--- a/Source/JavaScriptCore/jit/JITStubRoutine.h >+++ b/Source/JavaScriptCore/jit/JITStubRoutine.h >@@ -78,12 +78,13 @@ public: > return result; > } > >- void ref() >+ RefTrackingToken ref() > { > m_refCount++; >+ return UntrackedRefToken(); > } > >- void deref() >+ void deref(RefTrackingToken) > { > if (--m_refCount) > return; >diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp >index dd709da14c02333e7b0c9b5dc5d1881c80726c2e..ba2b95c20b38e66563ed9a2f7ec50ffe5eb68abb 100644 >--- a/Source/JavaScriptCore/jsc.cpp >+++ b/Source/JavaScriptCore/jsc.cpp >@@ -2730,7 +2730,7 @@ int runJSC(CommandLine options, bool isWorker, const Func& func) > JSLockHolder locker(vm); > // This is needed because we don't want the worker's main > // thread to die before its compilation threads finish. >- vm.deref(); >+ vm.deref(UntrackedRefToken()); > } > > return result; >diff --git a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h >index d0644d2df17195ad7e24b5cb5c3725ac821660f4..4dfbdd0c7f85b0131a30fcd62d3da42b01e4faab 100644 >--- a/Source/JavaScriptCore/parser/SourceProviderCacheItem.h >+++ b/Source/JavaScriptCore/parser/SourceProviderCacheItem.h >@@ -109,7 +109,7 @@ private: > inline SourceProviderCacheItem::~SourceProviderCacheItem() > { > for (unsigned i = 0; i < usedVariablesCount; ++i) >- m_variables[i]->deref(); >+ m_variables[i]->deref(UntrackedRefToken()); > } > > inline std::unique_ptr<SourceProviderCacheItem> SourceProviderCacheItem::create(const SourceProviderCacheItemCreationParameters& parameters) >diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp >index cbf3d724db60962f7f66e2d012e2425013f27f21..0e8ee0763481ebc5712451a9a6b34406b925b5b6 100644 >--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp >@@ -241,13 +241,13 @@ static ALWAYS_INLINE std::pair<SpeciesConstructResult, JSObject*> speciesConstru > if (constructor.isConstructor(vm)) { > JSObject* constructorObject = jsCast<JSObject*>(constructor); > if (exec->lexicalGlobalObject() != constructorObject->globalObject(vm)) >- return std::make_pair(SpeciesConstructResult::FastPath, nullptr);; >+ return std::make_pair(SpeciesConstructResult::FastPath, nullptr); > } > if (constructor.isObject()) { > constructor = constructor.get(exec, vm.propertyNames->speciesSymbol); > RETURN_IF_EXCEPTION(scope, exceptionResult()); > if (constructor.isNull()) >- return std::make_pair(SpeciesConstructResult::FastPath, nullptr);; >+ return std::make_pair(SpeciesConstructResult::FastPath, nullptr); > } > } else { > // If isArray is false, return ? ArrayCreate(length). >diff --git a/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h b/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >index adadc89ab84cf1f73960aaee64856ada97c2b380..90d4771067f34a27b96ec697fe2a3fafedf40eef 100644 >--- a/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >+++ b/Source/JavaScriptCore/runtime/HasOwnPropertyCache.h >@@ -39,12 +39,54 @@ public: > > struct Entry { > static ptrdiff_t offsetOfStructureID() { return OBJECT_OFFSETOF(Entry, structureID); } >- static ptrdiff_t offsetOfImpl() { return OBJECT_OFFSETOF(Entry, impl); } >+ static ptrdiff_t offsetOfImpl() { return OBJECT_OFFSETOF(Entry, stringImpl); } > static ptrdiff_t offsetOfResult() { return OBJECT_OFFSETOF(Entry, result); } > >- RefPtr<UniquedStringImpl> impl; >+ UniquedStringImpl* stringImpl; > StructureID structureID { 0 }; > bool result { false }; >+ >+ Entry(UniquedStringImpl* impl = nullptr, StructureID structID = 0, bool res = false) >+ : stringImpl(impl) >+ , structureID(structID) >+ , result(res) >+ { >+ if (stringImpl) >+ stringImpl->ref(); >+ } >+ >+ ~Entry() >+ { >+ if (stringImpl) >+ stringImpl->deref(UntrackedRefToken()); >+ } >+ >+ Entry(const Entry& other) >+ : stringImpl(other.stringImpl) >+ , structureID(other.structureID) >+ , result(other.result) >+ { >+ if (stringImpl) >+ stringImpl->ref(); >+ } >+ >+ Entry& operator=(const Entry& other) >+ { >+ if (&other == this) >+ return *this; >+ >+ structureID = other.structureID; >+ result = other.result; >+ >+ if (stringImpl) >+ stringImpl->deref(UntrackedRefToken()); >+ >+ stringImpl = other.stringImpl; >+ if (stringImpl) >+ stringImpl->ref(); >+ >+ return *this; >+ } > }; > > HasOwnPropertyCache() = delete; >@@ -74,7 +116,7 @@ public: > StructureID id = structure->id(); > uint32_t index = HasOwnPropertyCache::hash(id, impl) & mask; > Entry& entry = bitwise_cast<Entry*>(this)[index]; >- if (entry.structureID == id && entry.impl.get() == impl) >+ if (entry.structureID == id && entry.stringImpl == impl) > return entry.result; > return std::nullopt; > } >@@ -105,7 +147,7 @@ public: > UniquedStringImpl* impl = propName.uid(); > StructureID id = structure->id(); > uint32_t index = HasOwnPropertyCache::hash(id, impl) & mask; >- bitwise_cast<Entry*>(this)[index] = Entry { RefPtr<UniquedStringImpl>(impl), id, result }; >+ bitwise_cast<Entry*>(this)[index] = Entry(impl, id, result); > } > } > >diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h >index 27edadc47ccd864ab01f5c3950dcf18828888058..b55ce5656c3d426c58987ca9d452e51ad9b25bb6 100644 >--- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h >+++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h >@@ -396,7 +396,7 @@ inline void PropertyTable::remove(const find_iterator& iter) > // Replace this one element with the deleted sentinel. Also clear out > // the entry so we can iterate all the entries as needed. > m_index[iter.second] = deletedEntryIndex(); >- iter.first->key->deref(); >+ iter.first->key->deref(UntrackedRefToken()); > iter.first->key = PROPERTY_MAP_DELETED_ENTRY_KEY; > > ASSERT(m_keyCount >= 1); >diff --git a/Source/JavaScriptCore/runtime/PropertyTable.cpp b/Source/JavaScriptCore/runtime/PropertyTable.cpp >index 59ec41c49ae82f47f6986806dd6143944a42b5d6..fa5db9a34f238ab7606a8af855f9dc62cce72dd2 100644 >--- a/Source/JavaScriptCore/runtime/PropertyTable.cpp >+++ b/Source/JavaScriptCore/runtime/PropertyTable.cpp >@@ -119,7 +119,7 @@ PropertyTable::~PropertyTable() > { > iterator end = this->end(); > for (iterator iter = begin(); iter != end; ++iter) >- iter->key->deref(); >+ iter->key->deref(UntrackedRefToken()); > > fastFree(m_index); > } >diff --git a/Source/WTF/WTF.xcodeproj/project.pbxproj b/Source/WTF/WTF.xcodeproj/project.pbxproj >index a19a6cce7c17ca091e7d1727b02dd71e98f8ccff..f1fe5775a07f68d9e400b5f7e2c8a010cc49beac 100644 >--- a/Source/WTF/WTF.xcodeproj/project.pbxproj >+++ b/Source/WTF/WTF.xcodeproj/project.pbxproj >@@ -32,6 +32,7 @@ > 0F66B2901DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F66B2861DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp */; }; > 0F66B2921DC97BAB004A1D3F /* WallTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F66B2881DC97BAB004A1D3F /* WallTime.cpp */; }; > 0F7075F51FBF53CD00489AF0 /* TimingScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7075F41FBF537A00489AF0 /* TimingScope.cpp */; }; >+ 0F77584620C502F200AB5A51 /* RefTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F77584520C502F100AB5A51 /* RefTracker.cpp */; }; > 0F7C5FB61D885CF20044F5E2 /* FastBitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7C5FB51D885CF20044F5E2 /* FastBitVector.cpp */; }; > 0F824A681B7443A0002E345D /* ParkingLot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F824A641B7443A0002E345D /* ParkingLot.cpp */; }; > 0F8E85DB1FD485B000691889 /* CountingLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8E85DA1FD485B000691889 /* CountingLock.cpp */; }; >@@ -201,6 +202,7 @@ > 0F4570421BE5B58F0062A629 /* Dominators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dominators.h; sourceTree = "<group>"; }; > 0F4570441BE834410062A629 /* BubbleSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BubbleSort.h; sourceTree = "<group>"; }; > 0F4D8C711FC1E7CE001D32AC /* SinglyLinkedListWithTail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SinglyLinkedListWithTail.h; sourceTree = "<group>"; }; >+ 0F55CEB021376F2100A9FFA3 /* RefTracking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RefTracking.h; sourceTree = "<group>"; }; > 0F5BF1651F2317830029D91D /* NaturalLoops.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NaturalLoops.h; sourceTree = "<group>"; }; > 0F5BF1741F23D49A0029D91D /* Gigacage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Gigacage.cpp; sourceTree = "<group>"; }; > 0F5BF1751F23D49A0029D91D /* Gigacage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Gigacage.h; sourceTree = "<group>"; }; >@@ -220,6 +222,8 @@ > 0F7075F31FBF537A00489AF0 /* TimingScope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TimingScope.h; sourceTree = "<group>"; }; > 0F7075F41FBF537A00489AF0 /* TimingScope.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TimingScope.cpp; sourceTree = "<group>"; }; > 0F725CAB1C50461600AD943A /* RangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RangeSet.h; sourceTree = "<group>"; }; >+ 0F77584520C502F100AB5A51 /* RefTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefTracker.cpp; sourceTree = "<group>"; }; >+ 0F77584720C502FE00AB5A51 /* RefTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefTracker.h; sourceTree = "<group>"; }; > 0F79C7C31E73511800EB34D1 /* FastTLS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastTLS.h; sourceTree = "<group>"; }; > 0F7C5FB51D885CF20044F5E2 /* FastBitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastBitVector.cpp; sourceTree = "<group>"; }; > 0F7EB85B1FA8FF4100F1ABCB /* IsoMalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IsoMalloc.h; sourceTree = "<group>"; }; >@@ -1049,6 +1053,9 @@ > A8A47302151A825B004123FF /* RefCountedLeakCounter.h */, > 86F46F5F1A2840EE00CCBF22 /* RefCounter.h */, > A8A47303151A825B004123FF /* RefPtr.h */, >+ 0F77584520C502F100AB5A51 /* RefTracker.cpp */, >+ 0F77584720C502FE00AB5A51 /* RefTracker.h */, >+ 0F55CEB021376F2100A9FFA3 /* RefTracking.h */, > A8A47305151A825B004123FF /* RetainPtr.h */, > 2CDED0F118115C85004DBA70 /* RunLoop.cpp */, > 2CDED0F218115C85004DBA70 /* RunLoop.h */, >@@ -1539,6 +1546,7 @@ > A8A47414151A825B004123FF /* RandomNumber.cpp in Sources */, > 0FEC3C5E1F368A9700F59B6C /* ReadWriteLock.cpp in Sources */, > A8A4741A151A825B004123FF /* RefCountedLeakCounter.cpp in Sources */, >+ 0F77584620C502F200AB5A51 /* RefTracker.cpp in Sources */, > 2CDED0F318115C85004DBA70 /* RunLoop.cpp in Sources */, > 2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */, > 1469419316EAAF6D0024E146 /* RunLoopTimerCF.cpp in Sources */, >diff --git a/Source/WTF/wtf/CMakeLists.txt b/Source/WTF/wtf/CMakeLists.txt >index 9adb55543d013fea9af5a7aae49432f95f3240f2..2332bee51413a0c55a47c1d18a7f2006a3edf02f 100644 >--- a/Source/WTF/wtf/CMakeLists.txt >+++ b/Source/WTF/wtf/CMakeLists.txt >@@ -187,6 +187,8 @@ set(WTF_PUBLIC_HEADERS > RefCountedLeakCounter.h > RefCounter.h > RefPtr.h >+ RefTracker.h >+ RefTracking.h > RetainPtr.h > RunLoop.h > RunLoopTimer.h >diff --git a/Source/WTF/wtf/DeferrableRefCounted.h b/Source/WTF/wtf/DeferrableRefCounted.h >index 796481a33cf3632a8bba9ac54cbf96e619383a99..26fd45d7e726fb42ceb075ad98769070efefcf5d 100644 >--- a/Source/WTF/wtf/DeferrableRefCounted.h >+++ b/Source/WTF/wtf/DeferrableRefCounted.h >@@ -42,9 +42,10 @@ class DeferrableRefCountedBase { > static const unsigned normalIncrement = 2; > > public: >- void ref() const >+ RefTrackingToken ref() const > { > m_refCount += normalIncrement; >+ return UntrackedRefToken(); > } > > bool hasOneRef() const >@@ -72,7 +73,7 @@ protected: > { > } > >- bool derefBase() const >+ bool derefBase(RefTrackingToken) const > { > m_refCount -= normalIncrement; > return !m_refCount; >@@ -96,9 +97,9 @@ template<typename T> > class DeferrableRefCounted : public DeferrableRefCountedBase { > WTF_MAKE_NONCOPYABLE(DeferrableRefCounted); WTF_MAKE_FAST_ALLOCATED; > public: >- void deref() const >+ void deref(RefTrackingToken token) const > { >- if (derefBase()) >+ if (derefBase(token)) > delete static_cast<const T*>(this); > } > >diff --git a/Source/WTF/wtf/JSONValues.h b/Source/WTF/wtf/JSONValues.h >index 7f2c8e2ccd4fb85dea5348aab685cfd27319c915..cec752f2743ba3af09375b72f71536d64cd5be47 100644 >--- a/Source/WTF/wtf/JSONValues.h >+++ b/Source/WTF/wtf/JSONValues.h >@@ -64,7 +64,7 @@ public: > break; > case Type::String: > if (m_value.string) >- m_value.string->deref(); >+ m_value.string->deref(UntrackedRefToken()); > break; > case Type::Object: > case Type::Array: >diff --git a/Source/WTF/wtf/Ref.h b/Source/WTF/wtf/Ref.h >index 3b3158dfb6efd4060728f4a7e015e3fa77fa5fe7..0e44c9bfea5304d22e20384bc47861fffeaf2bf5 100644 >--- a/Source/WTF/wtf/Ref.h >+++ b/Source/WTF/wtf/Ref.h >@@ -30,6 +30,7 @@ > #include <wtf/DumbPtrTraits.h> > #include <wtf/Forward.h> > #include <wtf/GetPtr.h> >+#include <wtf/RefTracking.h> > #include <wtf/StdLibExtras.h> > #include <wtf/TypeCasts.h> > >@@ -41,7 +42,9 @@ extern "C" int __asan_address_is_poisoned(void const volatile *addr); > > namespace WTF { > >-inline void adopted(const void*) { } >+typedef unsigned RefToken; >+ >+inline RefTrackingToken adopted(const void*) { return UntrackedRefToken(); } > > template<typename T, typename PtrTraits> class Ref; > template<typename T, typename PtrTraits = DumbPtrTraits<T>> Ref<T, PtrTraits> adoptRef(T&); >@@ -57,14 +60,23 @@ public: > if (__asan_address_is_poisoned(this)) > __asan_unpoison_memory_region(this, sizeof(*this)); > #endif >- if (m_ptr) >- PtrTraits::unwrap(m_ptr)->deref(); >+ if (m_ptr) { >+#if ENABLE(REF_TRACKING) >+ PtrTraits::unwrap(m_ptr)->deref(m_token); >+#else >+ PtrTraits::unwrap(m_ptr)->deref(UntrackedRefToken()); >+#endif >+ } > } > > Ref(T& object) > : m_ptr(&object) > { >+#if ENABLE(REF_TRACKING) >+ m_token = object.ref(); >+#else > object.ref(); >+#endif > } > > // Use copyRef() instead. >@@ -73,6 +85,9 @@ public: > > Ref(Ref&& other) > : m_ptr(&other.leakRef()) >+#if ENABLE(REF_TRACKING) >+ , m_token(other.token()) >+#endif > { > ASSERT(m_ptr); > } >@@ -80,6 +95,9 @@ public: > template<typename X, typename Y> > Ref(Ref<X, Y>&& other) > : m_ptr(&other.leakRef()) >+#if ENABLE(REF_TRACKING) >+ , m_token(other.token()) >+#endif > { > ASSERT(m_ptr); > } >@@ -139,17 +157,34 @@ public: > return result; > } > >+#if ENABLE(REF_TRACKING) >+ RefTrackingToken token() const { return m_token; } >+ void setToken(RefTrackingToken token) { m_token = token; } >+#endif >+ > private: > friend Ref adoptRef<T>(T&); > template<typename X, typename Y> friend class Ref; > > enum AdoptTag { Adopt }; >- Ref(T& object, AdoptTag) >+ >+#if ENABLE(REF_TRACKING) >+ Ref(T& object, AdoptTag, RefTrackingToken token) > : m_ptr(&object) >+ , m_token(token) > { > } >+#else >+ Ref(T& object, AdoptTag, RefTrackingToken) >+ : m_ptr(&object) >+ { >+ } >+#endif > > typename PtrTraits::StorageType m_ptr; >+#if ENABLE(REF_TRACKING) >+ RefTrackingToken m_token; >+#endif > }; > > template<typename T, typename U> Ref<T, U> adoptRef(T&); >@@ -193,6 +228,9 @@ template<typename X, typename Y> > inline void Ref<T, U>::swap(Ref<X, Y>& other) > { > U::swap(m_ptr, other.m_ptr); >+#if ENABLE(REF_TRACKING) >+ std::swap(m_token, other.m_token); >+#endif > } > > template<typename T, typename U, typename X, typename Y, typename = std::enable_if_t<!std::is_same<U, DumbPtrTraits<T>>::value || !std::is_same<Y, DumbPtrTraits<X>>::value>> >@@ -246,8 +284,13 @@ struct IsSmartPtr<Ref<T, U>> { > template<typename T, typename U> > inline Ref<T, U> adoptRef(T& reference) > { >+#if ENABLE(REF_TRACKING) >+ return Ref<T, U>(reference, Ref<T, U>::Adopt, adopted(&reference)); >+#else > adopted(&reference); > return Ref<T, U>(reference, Ref<T, U>::Adopt); >+#endif >+ > } > > template<typename T> >diff --git a/Source/WTF/wtf/RefCounted.h b/Source/WTF/wtf/RefCounted.h >index 13762e07aef4388569502be23649087085bf6ac6..a8fc442c301c0656771df22263e0c041ceec643b 100644 >--- a/Source/WTF/wtf/RefCounted.h >+++ b/Source/WTF/wtf/RefCounted.h >@@ -23,6 +23,7 @@ > #include <wtf/Assertions.h> > #include <wtf/FastMalloc.h> > #include <wtf/Noncopyable.h> >+#include <wtf/Ref.h> > > namespace WTF { > >@@ -37,13 +38,14 @@ namespace WTF { > // generated by the compiler (technique called template hoisting). > class RefCountedBase { > public: >- void ref() const >+ RefTrackingToken ref() const > { > #if CHECK_REF_COUNTED_LIFECYCLE > ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun); > ASSERT(!m_adoptionIsRequired); > #endif > ++m_refCount; >+ return UntrackedRefToken(); > } > > bool hasOneRef() const >@@ -87,7 +89,7 @@ protected: > } > > // Returns whether the pointer should be freed or not. >- bool derefBase() const >+ bool derefBase(RefTrackingToken) const > { > #if CHECK_REF_COUNTED_LIFECYCLE > ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun); >@@ -116,7 +118,7 @@ protected: > private: > > #if CHECK_REF_COUNTED_LIFECYCLE >- friend void adopted(RefCountedBase*); >+ friend RefTrackingToken adopted(RefCountedBase*); > #endif > > mutable unsigned m_refCount; >@@ -127,21 +129,22 @@ private: > }; > > #if CHECK_REF_COUNTED_LIFECYCLE >-inline void adopted(RefCountedBase* object) >+inline RefTrackingToken adopted(RefCountedBase* object) > { > if (!object) >- return; >+ return UntrackedRefToken(); > ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun); > object->m_adoptionIsRequired = false; >+ return UntrackedRefToken(); > } > #endif > > template<typename T> class RefCounted : public RefCountedBase { > WTF_MAKE_NONCOPYABLE(RefCounted); WTF_MAKE_FAST_ALLOCATED; > public: >- void deref() const >+ void deref(RefTrackingToken token) const > { >- if (derefBase()) >+ if (derefBase(token)) > delete static_cast<const T*>(this); > } > >diff --git a/Source/WTF/wtf/RefCounter.h b/Source/WTF/wtf/RefCounter.h >index 26e11f47d956012a8d2c4fb4924963e8177d4e3e..d1a3e39c37be5dc855009f5f12a77f74c14df16a 100644 >--- a/Source/WTF/wtf/RefCounter.h >+++ b/Source/WTF/wtf/RefCounter.h >@@ -42,8 +42,8 @@ class RefCounter { > class Count { > WTF_MAKE_NONCOPYABLE(Count); > public: >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > void refCounterWasDeleted(); > >@@ -84,15 +84,17 @@ private: > }; > > template<typename T> >-inline void RefCounter<T>::Count::ref() >+inline RefTrackingToken RefCounter<T>::Count::ref() > { > ++m_value; > if (m_refCounter && m_refCounter->m_valueDidChange) > m_refCounter->m_valueDidChange(RefCounterEvent::Increment); >+ >+ return UntrackedRefToken(); > } > > template<typename T> >-inline void RefCounter<T>::Count::deref() >+inline void RefCounter<T>::Count::deref(RefTrackingToken) > { > ASSERT(m_value); > >diff --git a/Source/WTF/wtf/RefPtr.h b/Source/WTF/wtf/RefPtr.h >index 522085353b8e882d1df34b1693e31988a9e658a5..8a4464ad1451f61428bb476c927af7627e35c6e3 100644 >--- a/Source/WTF/wtf/RefPtr.h >+++ b/Source/WTF/wtf/RefPtr.h >@@ -33,16 +33,18 @@ namespace WTF { > template<typename T, typename PtrTraits> class RefPtr; > template<typename T, typename PtrTraits = DumbPtrTraits<T>> RefPtr<T, PtrTraits> adoptRef(T*); > >-template<typename T> ALWAYS_INLINE void refIfNotNull(T* ptr) >+template<typename T> ALWAYS_INLINE RefTrackingToken refIfNotNull(T* ptr) > { > if (LIKELY(ptr != nullptr)) >- ptr->ref(); >+ return ptr->ref(); >+ >+ return UntrackedRefToken(); > } > >-template<typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr) >+template<typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr, RefTrackingToken token) > { > if (LIKELY(ptr != nullptr)) >- ptr->deref(); >+ ptr->deref(token); > } > > template<typename T, typename PtrTraits> >@@ -54,25 +56,93 @@ public: > > static constexpr bool isRefPtr = true; > >- ALWAYS_INLINE constexpr RefPtr() : m_ptr(nullptr) { } >- ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } >- ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(PtrTraits::unwrap(m_ptr)); } >- template<typename X, typename Y> RefPtr(const RefPtr<X, Y>& o) : m_ptr(o.get()) { refIfNotNull(PtrTraits::unwrap(m_ptr)); } >- >- ALWAYS_INLINE RefPtr(RefPtr&& o) : m_ptr(o.leakRef()) { } >- template<typename X, typename Y> RefPtr(RefPtr<X, Y>&& o) : m_ptr(o.leakRef()) { } >+ ALWAYS_INLINE constexpr RefPtr() >+ : m_ptr(nullptr) >+ { } >+ >+ ALWAYS_INLINE RefPtr(T* ptr) >+ : m_ptr(ptr) >+ { >+#if ENABLE(REF_TRACKING) >+ m_token = refIfNotNull(ptr); >+#else >+ refIfNotNull(ptr); >+#endif >+ } >+ >+ ALWAYS_INLINE RefPtr(const RefPtr& o) >+ : m_ptr(o.m_ptr) >+ { >+#if ENABLE(REF_TRACKING) >+ m_token = refIfNotNull(PtrTraits::unwrap(m_ptr)); >+#else >+ refIfNotNull(PtrTraits::unwrap(m_ptr)); >+#endif >+ } >+ >+ template<typename X, typename Y> RefPtr(const RefPtr<X, Y>& o) >+ : m_ptr(o.get()) >+ { >+#if ENABLE(REF_TRACKING) >+ m_token = >+#endif >+ refIfNotNull(PtrTraits::unwrap(m_ptr)); >+ } >+ >+ ALWAYS_INLINE RefPtr(RefPtr&& o) >+ : m_ptr(o.leakRef()) >+#if ENABLE(REF_TRACKING) >+ , m_token(o.token()) >+#endif >+ { >+ } >+ >+ template<typename X, typename Y> RefPtr(RefPtr<X, Y>&& o) >+ : m_ptr(o.leakRef()) >+#if ENABLE(REF_TRACKING) >+ , m_token(o.token()) >+#endif >+ { >+ } >+ > template<typename X, typename Y> RefPtr(Ref<X, Y>&&); > > // Hash table deleted values, which are only constructed and never copied or destroyed. > RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } > bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } > >- ALWAYS_INLINE ~RefPtr() { derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr)); } >+ ALWAYS_INLINE ~RefPtr() >+ { >+#if ENABLE(REF_TRACKING) >+ derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr), m_token); >+#else >+ derefIfNotNull(PtrTraits::exchange(m_ptr, nullptr), UntrackedRefToken); >+#endif >+ } > > T* get() const { return PtrTraits::unwrap(m_ptr); } > >- Ref<T> releaseNonNull() { ASSERT(m_ptr); Ref<T> tmp(adoptRef(*m_ptr)); m_ptr = nullptr; return tmp; } >- Ref<const T> releaseConstNonNull() { ASSERT(m_ptr); Ref<const T> tmp(adoptRef(*m_ptr)); m_ptr = nullptr; return tmp; } >+ Ref<T> releaseNonNull() >+ { >+ ASSERT(m_ptr); >+ Ref<T> tmp(adoptRef(*m_ptr)); >+ m_ptr = nullptr; >+#if ENABLE(REF_TRACKING) >+ tmp.setToken(m_token); >+#endif >+ return tmp; >+ } >+ >+ Ref<const T> releaseConstNonNull() >+ { >+ ASSERT(m_ptr); >+ Ref<const T> tmp(adoptRef(*m_ptr)); >+ m_ptr = nullptr; >+#if ENABLE(REF_TRACKING) >+ tmp.setToken(m_token); >+#endif >+ return tmp; >+ } > > T* leakRef() WARN_UNUSED_RETURN; > >@@ -102,20 +172,42 @@ public: > RefPtr copyRef() && = delete; > RefPtr copyRef() const & WARN_UNUSED_RETURN { return RefPtr(m_ptr); } > >+#if ENABLE(REF_TRACKING) >+ RefTrackingToken token() const { return m_token; } >+ void setToken(RefTrackingToken token) { m_token = token; } >+#endif >+ > private: > friend RefPtr adoptRef<T, PtrTraits>(T*); > template<typename X, typename Y> friend class RefPtr; > > enum AdoptTag { Adopt }; >- RefPtr(T* ptr, AdoptTag) : m_ptr(ptr) { } >+ >+#if ENABLE(REF_TRACKING) >+ RefPtr(T* ptr, AdoptTag, RefTrackingToken token) >+ : m_ptr(ptr) >+ , m_token(token) >+ { } >+#else >+ RefPtr(T* ptr, AdoptTag, RefTrackingToken) >+ : m_ptr(ptr) >+ { } >+#endif > > typename PtrTraits::StorageType m_ptr; >+ >+#if ENABLE(REF_TRACKING) >+ RefTrackingToken m_token; >+#endif > }; > > template<typename T, typename U> > template<typename X, typename Y> > inline RefPtr<T, U>::RefPtr(Ref<X, Y>&& reference) > : m_ptr(&reference.leakRef()) >+#if ENABLE(REF_TRACKING) >+ , m_token(reference.token()) >+#endif > { > } > >@@ -153,7 +245,11 @@ inline RefPtr<T, U>& RefPtr<T, U>::operator=(T* optr) > template<typename T, typename U> > inline RefPtr<T, U>& RefPtr<T, U>::operator=(std::nullptr_t) > { >- derefIfNotNull(U::exchange(m_ptr, nullptr)); >+#if ENABLE(REF_TRACKING) >+ derefIfNotNull(U::exchange(m_ptr, nullptr), m_token); >+#else >+ derefIfNotNull(U::exchange(m_ptr, nullptr), UntrackedRefToken); >+#endif > return *this; > } > >@@ -185,9 +281,12 @@ inline RefPtr<T, V>& RefPtr<T, V>::operator=(Ref<U>&& reference) > > template<class T, typename U> > template<typename X, typename Y> >-inline void RefPtr<T, U>::swap(RefPtr<X, Y>& o) >+inline void RefPtr<T, U>::swap(RefPtr<X, Y>& other) > { >- U::swap(m_ptr, o.m_ptr); >+ U::swap(m_ptr, other.m_ptr); >+#if ENABLE(REF_TRACKING) >+ std::swap(m_token, other.m_token); >+#endif > } > > template<typename T, typename U, typename X, typename Y, typename = std::enable_if_t<!std::is_same<U, DumbPtrTraits<T>>::value || !std::is_same<Y, DumbPtrTraits<X>>::value>> >@@ -246,8 +345,12 @@ struct IsSmartPtr<RefPtr<T, U>> { > template<typename T, typename U> > inline RefPtr<T, U> adoptRef(T* p) > { >+#if ENABLE(REF_TRACKING) >+ return RefPtr<T, U>(p, RefPtr<T, U>::Adopt, adopted(p)); >+#else > adopted(p); > return RefPtr<T, U>(p, RefPtr<T, U>::Adopt); >+#endif > } > > template<typename T> inline RefPtr<T> makeRefPtr(T* pointer) >diff --git a/Source/WTF/wtf/RefTracker.cpp b/Source/WTF/wtf/RefTracker.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..a2bf219eb7e073f1d135d54228a3f5eb3d4a75c8 >--- /dev/null >+++ b/Source/WTF/wtf/RefTracker.cpp >@@ -0,0 +1,92 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "RefTracker.h" >+ >+#if ENABLE(REF_TRACKING) >+ >+#include "StackShot.h" >+ >+namespace WTF { >+ >+const size_t maxStackSize = 512; >+ >+RefTrackingToken RefTracker::nextRefTrackingToken() >+{ >+ static unsigned tokenValue; >+ return RefTrackingToken(++tokenValue); >+} >+ >+// These need to be not inline. >+RefTracker::RefTracker() >+{ >+} >+ >+RefTracker::~RefTracker() >+{ >+} >+ >+void RefTracker::dumpRemainingReferences() const >+{ >+ for (const auto& tokenAndStack : m_refBacktraceMap) { >+ const auto& stackShot = *tokenAndStack.value; >+ >+ WTFLogAlways("Backtrace for token %u\n", tokenAndStack.key); >+ const size_t framesToSkip = 4; >+ WTFPrintBacktrace(stackShot.array() + framesToSkip, stackShot.size() - framesToSkip); >+ WTFLogAlways("\n"); >+ } >+ >+ for (const auto& stackShot : m_untrackableDerefs) { >+ WTFLogAlways("refs for the follow derefs were not tracked\n"); >+ const size_t framesToSkip = 4; >+ WTFPrintBacktrace(stackShot->array() + framesToSkip, stackShot->size() - framesToSkip); >+ WTFLogAlways("\n"); >+ } >+} >+ >+RefTrackingToken RefTracker::trackRef() >+{ >+ auto token = nextRefTrackingToken(); >+ m_refBacktraceMap.add(token.value(), std::make_unique<StackShot>(maxStackSize)); >+ return token; >+} >+ >+void RefTracker::trackDeref(RefTrackingToken token) >+{ >+ if (!token.value()) { >+ m_untrackableDerefs.append(std::make_unique<StackShot>(maxStackSize)); >+ return; >+ } >+ >+ bool removed = m_refBacktraceMap.remove(token.value()); >+ if (!removed) >+ WTFLogAlways("RefTracker::deref() passed token %u that was not tracked or already removed", token.value()); >+} >+ >+} // namespace WTF >+ >+#endif // ENABLE(REF_TRACKING) >diff --git a/Source/WTF/wtf/RefTracker.h b/Source/WTF/wtf/RefTracker.h >new file mode 100644 >index 0000000000000000000000000000000000000000..83a9e3312bc657ded4ba9bff7d6885c9ce895787 >--- /dev/null >+++ b/Source/WTF/wtf/RefTracker.h >@@ -0,0 +1,60 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include <wtf/RefTracking.h> >+ >+#if ENABLE(REF_TRACKING) >+ >+#include <wtf/HashMap.h> >+#include <wtf/Vector.h> >+ >+namespace WTF { >+ >+class StackShot; >+ >+class RefTracker { >+public: >+ WTF_EXPORT_PRIVATE RefTracker(); >+ WTF_EXPORT_PRIVATE ~RefTracker(); >+ >+ WTF_EXPORT_PRIVATE RefTrackingToken trackRef(); >+ WTF_EXPORT_PRIVATE void trackDeref(RefTrackingToken); >+ >+ WTF_EXPORT_PRIVATE void dumpRemainingReferences() const; >+ >+private: >+ static RefTrackingToken nextRefTrackingToken(); >+ >+ HashMap<RefTrackingToken::ValueType, std::unique_ptr<StackShot>> m_refBacktraceMap; >+ Vector<std::unique_ptr<StackShot>> m_untrackableDerefs; >+}; >+ >+} // namespace WTF >+ >+using WTF::RefTracker; >+ >+#endif // ENABLE(REF_TRACKING) >diff --git a/Source/WTF/wtf/RefTracking.h b/Source/WTF/wtf/RefTracking.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f9253adf5ea4d9898dc84803b5abd36f092345af >--- /dev/null >+++ b/Source/WTF/wtf/RefTracking.h >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef WTF_RefTracking_h >+#define WTF_RefTracking_h >+ >+#include <wtf/Platform.h> >+ >+#define ENABLE_REF_TRACKING 1 >+ >+namespace WTF { >+ >+class RefTrackingToken { >+friend class RefTracker; >+public: >+#if ENABLE(REF_TRACKING) >+ RefTrackingToken() = default; >+ >+protected: >+ using ValueType = unsigned; >+ >+ RefTrackingToken(ValueType value) >+ : m_value { value } >+ { >+ } >+ >+ ValueType value() const { return m_value; } >+ ValueType m_value { 0 }; >+#endif >+}; >+ >+class UntrackedRefToken : public RefTrackingToken { >+#if ENABLE(REF_TRACKING) >+public: >+ UntrackedRefToken() = default; >+#endif >+}; >+ >+} // namespace WTF >+ >+using WTF::RefTrackingToken; >+using WTF::UntrackedRefToken; >+ >+#endif // WTF_RefTracking_h >diff --git a/Source/WTF/wtf/SizeLimits.cpp b/Source/WTF/wtf/SizeLimits.cpp >index b0ad14044f3b8411686d3a1aa8eafb4dab77785c..5114ce448906333419dd8148f2622b862d38add9 100644 >--- a/Source/WTF/wtf/SizeLimits.cpp >+++ b/Source/WTF/wtf/SizeLimits.cpp >@@ -54,8 +54,10 @@ struct SameSizeAsRefCounted { > }; > #endif > >+#if !ENABLE(REF_TRACKING) > static_assert(sizeof(RefCounted<int>) == sizeof(SameSizeAsRefCounted), "RefCounted should stay small!"); > static_assert(sizeof(RefPtr<RefCounted<int>>) == sizeof(int*), "RefPtr should stay small!"); >+#endif > > #if !ASAN_ENABLED > template<typename T, unsigned inlineCapacity = 0> >diff --git a/Source/WTF/wtf/ThreadSafeRefCounted.h b/Source/WTF/wtf/ThreadSafeRefCounted.h >index c4e809ae93ab4b289bdcea2e9eaa03edad3ad7e6..f8c0e84a0f1a4e8cde21057f7b189e12d09287f0 100644 >--- a/Source/WTF/wtf/ThreadSafeRefCounted.h >+++ b/Source/WTF/wtf/ThreadSafeRefCounted.h >@@ -29,6 +29,7 @@ > #include <wtf/FastMalloc.h> > #include <wtf/MainThread.h> > #include <wtf/Noncopyable.h> >+#include <wtf/Ref.h> > > namespace WTF { > >@@ -38,9 +39,10 @@ class ThreadSafeRefCountedBase { > public: > ThreadSafeRefCountedBase() = default; > >- void ref() const >+ RefTrackingToken ref() const > { > ++m_refCount; >+ return UntrackedRefToken(); > } > > bool hasOneRef() const >@@ -55,7 +57,7 @@ public: > > protected: > // Returns whether the pointer should be freed or not. >- bool derefBase() const >+ bool derefBase(RefTrackingToken) const > { > return !--m_refCount; > } >@@ -68,9 +70,9 @@ enum class DestructionThread { Any, Main }; > > template<class T, DestructionThread destructionThread = DestructionThread::Any> class ThreadSafeRefCounted : public ThreadSafeRefCountedBase { > public: >- void deref() const >+ void deref(RefTrackingToken token) const > { >- if (!derefBase()) >+ if (!derefBase(token)) > return; > if (destructionThread == DestructionThread::Any || isMainThread()) { > delete static_cast<const T*>(this); >diff --git a/Source/WTF/wtf/ThreadingPthreads.cpp b/Source/WTF/wtf/ThreadingPthreads.cpp >index dd01c6c76ee69859c4ccd8b11c6c9a8cd1c04962..96d0dde205f37f68fa982dfd4d798be18f847070 100644 >--- a/Source/WTF/wtf/ThreadingPthreads.cpp >+++ b/Source/WTF/wtf/ThreadingPthreads.cpp >@@ -489,7 +489,7 @@ void Thread::destructTLS(void* data) > > if (thread->m_isDestroyedOnce) { > thread->didExit(); >- thread->deref(); >+ thread->deref(UntrackedRefToken()); > return; > } > >diff --git a/Source/WTF/wtf/ThreadingWin.cpp b/Source/WTF/wtf/ThreadingWin.cpp >index e1ae74ef71d018148ed13fa0ed222a4b0778beb3..93f9b6df52e524920ddb6ca48b6be47d232c86af 100644 >--- a/Source/WTF/wtf/ThreadingWin.cpp >+++ b/Source/WTF/wtf/ThreadingWin.cpp >@@ -348,7 +348,7 @@ void Thread::destructTLS(void* data) > threadMap().remove(thread->id()); > } > thread->didExit(); >- thread->deref(); >+ thread->deref(UntrackedRefToken()); > > // Fill the FLS with the non-nullptr value. While FLS destructor won't be called for that, > // non-nullptr value tells us that we already destructed Thread. This allows us to >diff --git a/Source/WTF/wtf/WTFAssertions.cpp b/Source/WTF/wtf/WTFAssertions.cpp >index 9870764cf021e1289bed1d12d8e5cf739836f910..c8f8605050131ac39543a9e7cc7fa57e2daf4063 100644 >--- a/Source/WTF/wtf/WTFAssertions.cpp >+++ b/Source/WTF/wtf/WTFAssertions.cpp >@@ -41,11 +41,13 @@ uintptr_t dummyPoison = 0; > static_assert(sizeof(Bag<DummyStruct>) == sizeof(void*), ""); > static_assert(sizeof(PoisonedBag<Poison<dummyPoison>, DummyStruct>) == sizeof(void*), ""); > >+#if !ENABLE(REF_TRACKING) > static_assert(sizeof(Ref<DummyStruct>) == sizeof(DummyStruct*), ""); > static_assert(sizeof(PoisonedRef<Poison<dummyPoison>, DummyStruct>) == sizeof(DummyStruct*), ""); > > static_assert(sizeof(RefPtr<DummyStruct>) == sizeof(DummyStruct*), ""); > static_assert(sizeof(PoisonedRefPtr<Poison<dummyPoison>, DummyStruct>) == sizeof(DummyStruct*), ""); >+#endif > > static_assert(sizeof(PoisonedUniquePtr<Poison<dummyPoison>, DummyStruct>) == sizeof(DummyStruct*), ""); > static_assert(sizeof(PoisonedUniquePtr<Poison<dummyPoison>, int[]>) == sizeof(int*), ""); >diff --git a/Source/WTF/wtf/text/StringImpl.cpp b/Source/WTF/wtf/text/StringImpl.cpp >index d50c3a3f44075218512f432c778d6d411976c2da..d3cba02ffe58c780d4fffd8cb9894a7edbc45999 100644 >--- a/Source/WTF/wtf/text/StringImpl.cpp >+++ b/Source/WTF/wtf/text/StringImpl.cpp >@@ -135,7 +135,7 @@ StringImpl::~StringImpl() > > ASSERT(ownership == BufferSubstring); > ASSERT(substringBuffer()); >- substringBuffer()->deref(); >+ substringBuffer()->deref(UntrackedRefToken()); > } > > void StringImpl::destroy(StringImpl* stringImpl) >diff --git a/Source/WTF/wtf/text/StringImpl.h b/Source/WTF/wtf/text/StringImpl.h >index 2aa0c918753b06446f0fb08ac22b71121adfbabb..ff93d03734037ee3aa64a42ca9cbe34c18c97f30 100644 >--- a/Source/WTF/wtf/text/StringImpl.h >+++ b/Source/WTF/wtf/text/StringImpl.h >@@ -320,8 +320,8 @@ public: > bool hasOneRef() const { return m_refCount == s_refCountIncrement; } > bool hasAtLeastOneRef() const { return m_refCount; } // For assertions. > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > class StaticStringImpl : private StringImplShape { > WTF_MAKE_NONCOPYABLE(StaticStringImpl); >@@ -1034,14 +1034,15 @@ inline void StringImpl::setHash(unsigned hash) const > m_hashAndFlags |= hash; // Store hash with flags in low bits. > } > >-inline void StringImpl::ref() >+inline RefTrackingToken StringImpl::ref() > { > STRING_STATS_REF_STRING(*this); > > m_refCount += s_refCountIncrement; >+ return UntrackedRefToken(); > } > >-inline void StringImpl::deref() >+inline void StringImpl::deref(RefTrackingToken) > { > STRING_STATS_DEREF_STRING(*this); > >diff --git a/Source/WTF/wtf/text/WTFString.h b/Source/WTF/wtf/text/WTFString.h >index b08be530af463f149aaa837e6fc0f72011beb344..2561a80d1f245f8e9bdb3c58d69e1273fdd83d05 100644 >--- a/Source/WTF/wtf/text/WTFString.h >+++ b/Source/WTF/wtf/text/WTFString.h >@@ -375,7 +375,9 @@ private: > RefPtr<StringImpl> m_impl; > }; > >+#if !ENABLE(REF_TRACKING) > static_assert(sizeof(String) == sizeof(void*), "String should effectively be a pointer to a StringImpl, and efficient to pass by value"); >+#endif > > inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); } > inline bool operator==(const String& a, const LChar* b) { return equal(a.impl(), b); } >diff --git a/Source/WTF/wtf/text/cf/StringImplCF.cpp b/Source/WTF/wtf/text/cf/StringImplCF.cpp >index 53f498383fac89cd004131cfbc06242561789cf9..68d2ad97ac89493ec1b72ffa3cb6600c22fd1d76 100644 >--- a/Source/WTF/wtf/text/cf/StringImplCF.cpp >+++ b/Source/WTF/wtf/text/cf/StringImplCF.cpp >@@ -82,7 +82,7 @@ namespace StringWrapperCFAllocator { > fastFree(header); > else { > if (isMainThread()) { >- underlyingString->deref(); // Balanced by call to ref in allocate above. >+ underlyingString->deref(UntrackedRefToken()); // Balanced by call to ref in allocate above. > fastFree(header); > return; > } >@@ -90,7 +90,7 @@ namespace StringWrapperCFAllocator { > callOnMainThread([header] { > StringImpl* underlyingString = *header; > ASSERT(underlyingString); >- underlyingString->deref(); // Balanced by call to ref in allocate above. >+ underlyingString->deref(UntrackedRefToken()); // Balanced by call to ref in allocate above. > fastFree(header); > }); > } >diff --git a/Source/WTF/wtf/win/WorkQueueWin.cpp b/Source/WTF/wtf/win/WorkQueueWin.cpp >index 365f188ec14bf0522fff54c55d12fc7d78fb78ec..c32d1e879576511d6d95620e226ece6c69907640 100644 >--- a/Source/WTF/wtf/win/WorkQueueWin.cpp >+++ b/Source/WTF/wtf/win/WorkQueueWin.cpp >@@ -41,7 +41,7 @@ DWORD WorkQueue::workThreadCallback(void* context) > if (queue->tryRegisterAsWorkThread()) > queue->performWorkOnRegisteredWorkThread(); > >- queue->deref(); >+ queue->deref(UntrackedRefToken()); > > return 0; > } >diff --git a/Source/WebCore/Modules/applepay/ApplePaySession.h b/Source/WebCore/Modules/applepay/ApplePaySession.h >index 70612760b110fa145d898282e63007cd78055771..a66b62a369e9276f91191afec183a97a035fab83 100644 >--- a/Source/WebCore/Modules/applepay/ApplePaySession.h >+++ b/Source/WebCore/Modules/applepay/ApplePaySession.h >@@ -107,8 +107,8 @@ private: > // EventTargetWithInlineData. > EventTargetInterface eventTargetInterface() const override { return ApplePaySessionEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > // PaymentSession > unsigned version() const override; >diff --git a/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h b/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h >index 0d1900e31bc7bd4917e826b610331ec588c95132..d77959f7da5497159e87bd9de3096ca1136312ad 100644 >--- a/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h >+++ b/Source/WebCore/Modules/encryptedmedia/MediaKeySession.h >@@ -90,8 +90,8 @@ private: > // EventTarget > EventTargetInterface eventTargetInterface() const override { return MediaKeySessionEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > // ActiveDOMObject > bool hasPendingActivity() const override; >diff --git a/Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.h b/Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.h >index 9301f09381007d6a7684ec2ba3210d305d066a7c..9ee748f3e693b569e6d78718bd405e8e1a66e878 100644 >--- a/Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.h >+++ b/Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.h >@@ -73,8 +73,8 @@ private: > void sendError(MediaKeyErrorCode, uint32_t systemCode) final; > String mediaKeysStorageDirectory() const final; > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void suspend(ReasonForSuspension) final; > void resume() final; >diff --git a/Source/WebCore/Modules/indexeddb/IDBDatabase.h b/Source/WebCore/Modules/indexeddb/IDBDatabase.h >index 76a12859101046e652b8edab4f703e0d4ad1593e..790fab9933c51942ae77eb1b856d54c9d8672c23 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBDatabase.h >+++ b/Source/WebCore/Modules/indexeddb/IDBDatabase.h >@@ -74,8 +74,8 @@ public: > // EventTarget > EventTargetInterface eventTargetInterface() const final { return IDBDatabaseEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ThreadSafeRefCounted<IDBDatabase>::ref(); } >- void derefEventTarget() final { ThreadSafeRefCounted<IDBDatabase>::deref(); } >+ RefTrackingToken refEventTarget() final { return ThreadSafeRefCounted<IDBDatabase>::ref(); } >+ void derefEventTarget(RefTrackingToken token) final { ThreadSafeRefCounted<IDBDatabase>::deref(token); } > > using ThreadSafeRefCounted<IDBDatabase>::ref; > using ThreadSafeRefCounted<IDBDatabase>::deref; >diff --git a/Source/WebCore/Modules/indexeddb/IDBIndex.cpp b/Source/WebCore/Modules/indexeddb/IDBIndex.cpp >index 9d1f83937737ae80110b020ea9983b68d803f67f..0a7011303b54162bac1fbce34e29210962713a44 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBIndex.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBIndex.cpp >@@ -365,14 +365,14 @@ void IDBIndex::markAsDeleted() > m_deleted = true; > } > >-void IDBIndex::ref() >+RefTrackingToken IDBIndex::ref() > { >- m_objectStore.ref(); >+ return m_objectStore.ref(); > } > >-void IDBIndex::deref() >+void IDBIndex::deref(RefTrackingToken token) > { >- m_objectStore.deref(); >+ m_objectStore.deref(token); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/indexeddb/IDBIndex.h b/Source/WebCore/Modules/indexeddb/IDBIndex.h >index d6488d591cac3edf0d123dd8404090bf1507f325..099dc697b08fad668fa2b226c678c3ba0e1726f8 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBIndex.h >+++ b/Source/WebCore/Modules/indexeddb/IDBIndex.h >@@ -81,8 +81,8 @@ public: > void markAsDeleted(); > bool isDeleted() const { return m_deleted; } > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > void* objectStoreAsOpaqueRoot() { return &m_objectStore; } > >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >index f08c9e52853f30b0878eeffd0db5d1702f231f10..0c18ec420a00b1b56e885c47dfcb6f10029d1e81 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp >@@ -688,14 +688,14 @@ void IDBObjectStore::renameReferencedIndex(IDBIndex& index, const String& newNam > m_referencedIndexes.set(newName, m_referencedIndexes.take(index.info().name())); > } > >-void IDBObjectStore::ref() >+RefTrackingToken IDBObjectStore::ref() > { >- m_transaction.ref(); >+ return m_transaction.ref(); > } > >-void IDBObjectStore::deref() >+void IDBObjectStore::deref(RefTrackingToken token) > { >- m_transaction.deref(); >+ m_transaction.deref(token); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >index ed60647e2077b39a97dbc4de807935ba39a1d79d..87c9a7d21b5ec4c10da94bf138598c995c02d07d 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >+++ b/Source/WebCore/Modules/indexeddb/IDBObjectStore.h >@@ -105,8 +105,8 @@ public: > > void rollbackForVersionChangeAbort(); > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > void visitReferencedIndexes(JSC::SlotVisitor&) const; > void renameReferencedIndex(IDBIndex&, const String& newName); >diff --git a/Source/WebCore/Modules/indexeddb/IDBRequest.h b/Source/WebCore/Modules/indexeddb/IDBRequest.h >index e625cd3c7fbdc8913d6d49aa340ed9bb7239b5e8..58e5b31c28987cf0dc07a8c354fa4064db0c4266 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBRequest.h >+++ b/Source/WebCore/Modules/indexeddb/IDBRequest.h >@@ -151,8 +151,8 @@ private: > void stop() final; > virtual void cancelForStop(); > >- void refEventTarget() final { RefCounted::ref(); } >- void derefEventTarget() final { RefCounted::deref(); } >+ RefTrackingToken refEventTarget() final { return RefCounted::ref(); } >+ void derefEventTarget(RefTrackingToken token) final { RefCounted::deref(token); } > void uncaughtExceptionInEventHandler() final; > > virtual bool isOpenDBRequest() const { return false; } >diff --git a/Source/WebCore/Modules/indexeddb/IDBTransaction.h b/Source/WebCore/Modules/indexeddb/IDBTransaction.h >index ecac146e5d692efea999cef1106a76b131182723..2f0dbfb55ccab233533337a834225671da0cbffd 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBTransaction.h >+++ b/Source/WebCore/Modules/indexeddb/IDBTransaction.h >@@ -82,8 +82,10 @@ public: > > EventTargetInterface eventTargetInterface() const final { return IDBTransactionEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ThreadSafeRefCounted::ref(); } >- void derefEventTarget() final { ThreadSafeRefCounted::deref(); } >+ >+ RefTrackingToken refEventTarget() final { return ThreadSafeRefCounted::ref(); } >+ void derefEventTarget(RefTrackingToken token) final { ThreadSafeRefCounted::deref(token); } >+ > using EventTarget::dispatchEvent; > void dispatchEvent(Event&) final; > >diff --git a/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp b/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp >index 15ac07e46445f43414d45f8b128666cb27c4c00c..137ebfaa0e5db0b981b26c2d1c44cf0b678aba3e 100644 >--- a/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp >+++ b/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.cpp >@@ -50,14 +50,14 @@ IDBConnectionProxy::IDBConnectionProxy(IDBConnectionToServer& connection) > ASSERT(isMainThread()); > } > >-void IDBConnectionProxy::ref() >+RefTrackingToken IDBConnectionProxy::ref() > { >- m_connectionToServer.ref(); >+ return m_connectionToServer.ref(); > } > >-void IDBConnectionProxy::deref() >+void IDBConnectionProxy::deref(RefTrackingToken token) > { >- m_connectionToServer.deref(); >+ m_connectionToServer.deref(token); > } > > Ref<IDBOpenDBRequest> IDBConnectionProxy::openDatabase(ScriptExecutionContext& context, const IDBDatabaseIdentifier& databaseIdentifier, uint64_t version) >diff --git a/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h b/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h >index 2d039bf0fa8e951ed3ad3d2a4cb5ce5926f77f25..dcde2f7aa9618baa6aba280e250d8a80cd05d619 100644 >--- a/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h >+++ b/Source/WebCore/Modules/indexeddb/client/IDBConnectionProxy.h >@@ -113,8 +113,8 @@ public: > > uint64_t serverConnectionIdentifier() const { return m_serverConnectionIdentifier; } > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > void getAllDatabaseNames(const SecurityOrigin& mainFrameOrigin, const SecurityOrigin& openingOrigin, WTF::Function<void (const Vector<String>&)>&&); > >diff --git a/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h b/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h >index f217926ae06913ada8c3083e61fb2acefd8341e1..2718f678ec9d632e84e5dea539b76d81b7866617 100644 >--- a/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h >+++ b/Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h >@@ -88,8 +88,8 @@ public: > > virtual void getAllDatabaseNames(const SecurityOriginData& mainFrameOrigin, const SecurityOriginData& openingOrigin, uint64_t callbackID) = 0; > >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > }; > > } // namespace IDBClient >diff --git a/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h b/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h >index 479742a9da94e8548d72a2d64eb48594fab5fb47..073599ab54f61d56ad3807b7cbcb51014e6ae909 100644 >--- a/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h >+++ b/Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h >@@ -72,8 +72,8 @@ public: > > virtual void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) = 0; > >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > }; > > } // namespace IDBServer >diff --git a/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h b/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h >index 473ea5b172afe7ea4781abac0b41d0f7088f3e5a..580738c44383929ba8c4e99d5f7f20addcbb202a 100644 >--- a/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h >+++ b/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h >@@ -109,8 +109,8 @@ public: > void notifyOpenDBRequestBlocked(const IDBResourceIdentifier& requestIdentifier, uint64_t oldVersion, uint64_t newVersion) final; > void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final; > >- void ref() override { RefCounted<InProcessIDBServer>::ref(); } >- void deref() override { RefCounted<InProcessIDBServer>::deref(); } >+ RefTrackingToken ref() override { return RefCounted<InProcessIDBServer>::ref(); } >+ void deref(RefTrackingToken token) override { RefCounted<InProcessIDBServer>::deref(token); } > > void prepareForAccessToTemporaryFile(const String&) override { } > void accessToTemporaryFileComplete(const String& path) override; >diff --git a/Source/WebCore/Modules/mediasession/MediaRemoteControls.h b/Source/WebCore/Modules/mediasession/MediaRemoteControls.h >index cf24dea09e41e9ef0532628b0925d852ca9f7f84..8a3bce85d85af45d14504f710de3a6d0d9161a6c 100644 >--- a/Source/WebCore/Modules/mediasession/MediaRemoteControls.h >+++ b/Source/WebCore/Modules/mediasession/MediaRemoteControls.h >@@ -67,8 +67,8 @@ private: > > MediaSession* m_session { nullptr }; > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/mediasource/MediaSource.h b/Source/WebCore/Modules/mediasource/MediaSource.h >index eca269ea9969b88f412af2471c31b6df770761d0..5017bbdd62ece3312166856badbbc03d7e0bb235 100644 >--- a/Source/WebCore/Modules/mediasource/MediaSource.h >+++ b/Source/WebCore/Modules/mediasource/MediaSource.h >@@ -117,8 +117,8 @@ private: > void setPrivateAndOpen(Ref<MediaSourcePrivate>&&) final; > void seekToTime(const MediaTime&) final; > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > EventTargetInterface eventTargetInterface() const final; > > URLRegistry& registry() const final; >diff --git a/Source/WebCore/Modules/mediasource/SourceBuffer.h b/Source/WebCore/Modules/mediasource/SourceBuffer.h >index aae7a7d36de80e73f2ef094d516018d043be258d..d72e0854e17ae9104bbfb46d09819e6ea8385b0f 100644 >--- a/Source/WebCore/Modules/mediasource/SourceBuffer.h >+++ b/Source/WebCore/Modules/mediasource/SourceBuffer.h >@@ -121,8 +121,8 @@ public: > private: > SourceBuffer(Ref<SourceBufferPrivate>&&, MediaSource*); > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void suspend(ReasonForSuspension) final; > void resume() final; >diff --git a/Source/WebCore/Modules/mediasource/SourceBufferList.h b/Source/WebCore/Modules/mediasource/SourceBufferList.h >index 073198dc732990575719078583154b8d1eaaa5d9..821b0153a7bb04c26310c2da09bf71c193ae2475 100644 >--- a/Source/WebCore/Modules/mediasource/SourceBufferList.h >+++ b/Source/WebCore/Modules/mediasource/SourceBufferList.h >@@ -74,8 +74,8 @@ private: > > void scheduleEvent(const AtomicString&); > >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > bool canSuspendForDocumentSuspension() const final; > void suspend(ReasonForSuspension) final; >diff --git a/Source/WebCore/Modules/mediastream/MediaDevices.h b/Source/WebCore/Modules/mediastream/MediaDevices.h >index 072ba15d496e3a6b872f109a963582d2f200d94c..a79cf1536535361ca5304f68a9d60f9612368ae7 100644 >--- a/Source/WebCore/Modules/mediastream/MediaDevices.h >+++ b/Source/WebCore/Modules/mediastream/MediaDevices.h >@@ -98,8 +98,8 @@ private: > // EventTargetWithInlineData. > EventTargetInterface eventTargetInterface() const final { return MediaDevicesEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > Timer m_scheduledEventTimer; > UserMediaClient::DeviceChangeObserverToken m_deviceChangeToken; >diff --git a/Source/WebCore/Modules/mediastream/MediaStream.h b/Source/WebCore/Modules/mediastream/MediaStream.h >index 1c1ae11b80e00b573c33ec24c3945115866ea455..dfb82acfdaa5880e4b89599c26ce6f1f8740944c 100644 >--- a/Source/WebCore/Modules/mediastream/MediaStream.h >+++ b/Source/WebCore/Modules/mediastream/MediaStream.h >@@ -122,8 +122,8 @@ protected: > private: > > // EventTarget >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > // MediaStreamTrack::Observer > void trackDidEnd() final; >diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h >index 47ab0cd1e372230cd5a92eba67617d422fbefee7..377f527152b28b9ffab6ae85c42eb10ce6d7b70b 100644 >--- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h >+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h >@@ -159,8 +159,8 @@ private: > bool canSuspendForDocumentSuspension() const final; > > // EventTarget >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > EventTargetInterface eventTargetInterface() const final { return MediaStreamTrackEventTargetInterfaceType; } > > // MediaStreamTrackPrivate::Observer >diff --git a/Source/WebCore/Modules/mediastream/RTCDTMFSender.h b/Source/WebCore/Modules/mediastream/RTCDTMFSender.h >index 00fce07c95229ae88505b6116cb6681f03881f8d..7b4a18d0747bf7e4616e05ec25048e41a7e0e497 100644 >--- a/Source/WebCore/Modules/mediastream/RTCDTMFSender.h >+++ b/Source/WebCore/Modules/mediastream/RTCDTMFSender.h >@@ -62,8 +62,8 @@ private: > EventTargetInterface eventTargetInterface() const final { return RTCDTMFSenderEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void didPlayTone(const String&); > >diff --git a/Source/WebCore/Modules/mediastream/RTCDataChannel.h b/Source/WebCore/Modules/mediastream/RTCDataChannel.h >index 620adb4348c6462bebd7b5efe5e643a0a36ae6db..1a9127bd14dc1083f8260e5e2dec22e93a6422a9 100644 >--- a/Source/WebCore/Modules/mediastream/RTCDataChannel.h >+++ b/Source/WebCore/Modules/mediastream/RTCDataChannel.h >@@ -85,8 +85,8 @@ private: > EventTargetInterface eventTargetInterface() const final { return RTCDataChannelEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return m_scriptExecutionContext; } > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > ExceptionOr<void> sendRawData(const char* data, size_t length); > >diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h >index 427bf223eb8e419c39b2b5ef145dfa6d108d1de7..72b66cd6385d9ab92a2ce2aa5a5d6962b6ee2900 100644 >--- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h >+++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h >@@ -177,8 +177,8 @@ private: > void applyRotationForOutgoingVideoSources() { m_backend->applyRotationForOutgoingVideoSources(); } > > // EventTarget implementation. >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > void dispatchEvent(Event&) final; > > // ActiveDOMObject >diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h >index 52331681bf78fa267b5d1db0de4e21a263cf3659..3fd79f3e253f92572ea12507d54dcc7ff11f2c30 100644 >--- a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h >+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h >@@ -137,7 +137,7 @@ private: > rtc::RefCountReleaseStatus Release() const > { > auto result = refCount() - 1; >- deref(); >+ deref(UntrackedRefToken()); > return result ? rtc::RefCountReleaseStatus::kOtherRefsRemained > : rtc::RefCountReleaseStatus::kDroppedLastRef; > } >diff --git a/Source/WebCore/Modules/notifications/Notification.h b/Source/WebCore/Modules/notifications/Notification.h >index ff0dc54daf1e50238afa35f13289e5b83e2b2b9c..86490e585108cbef408f5d1bd501867f7a82ed4c 100644 >--- a/Source/WebCore/Modules/notifications/Notification.h >+++ b/Source/WebCore/Modules/notifications/Notification.h >@@ -100,8 +100,8 @@ private: > bool canSuspendForDocumentSuspension() const final; > void stop() final; > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > String m_title; > Direction m_direction; >diff --git a/Source/WebCore/Modules/paymentrequest/PaymentRequest.h b/Source/WebCore/Modules/paymentrequest/PaymentRequest.h >index 7457ad7382dac8efe05fa7251a77e4c1d0b42fa5..95e0b30d86e2e124d666b82f01be76fabbdd46c7 100644 >--- a/Source/WebCore/Modules/paymentrequest/PaymentRequest.h >+++ b/Source/WebCore/Modules/paymentrequest/PaymentRequest.h >@@ -118,8 +118,8 @@ private: > // EventTarget > EventTargetInterface eventTargetInterface() const final { return PaymentRequestEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > PaymentOptions m_options; > PaymentDetailsInit m_details; >diff --git a/Source/WebCore/Modules/speech/SpeechSynthesisUtterance.h b/Source/WebCore/Modules/speech/SpeechSynthesisUtterance.h >index 8c24f77d379ceadcd2688ae55b12c72c9f006e02..5c6c443152060465f964c5064d6e39bb4ea343a5 100644 >--- a/Source/WebCore/Modules/speech/SpeechSynthesisUtterance.h >+++ b/Source/WebCore/Modules/speech/SpeechSynthesisUtterance.h >@@ -72,8 +72,8 @@ private: > > ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } > EventTargetInterface eventTargetInterface() const final { return SpeechSynthesisUtteranceEventTargetInterfaceType; } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > RefPtr<PlatformSpeechSynthesisUtterance> m_platformUtterance; > RefPtr<SpeechSynthesisVoice> m_voice; >diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp >index fbd2b63cf774c31d2b3be9a10575ec5266df22d0..82a3490b813bbe09824cf39a98d6db4296b0ed25 100644 >--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp >+++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp >@@ -556,9 +556,9 @@ void AudioBufferSourceNode::setPannerNode(PannerNode* pannerNode) > { > if (m_pannerNode != pannerNode && !hasFinished()) { > if (pannerNode) >- pannerNode->ref(AudioNode::RefTypeConnection); >+ pannerNode->refConnection(); > if (m_pannerNode) >- m_pannerNode->deref(AudioNode::RefTypeConnection); >+ m_pannerNode->derefConnection(); > > m_pannerNode = pannerNode; > } >@@ -567,7 +567,7 @@ void AudioBufferSourceNode::setPannerNode(PannerNode* pannerNode) > void AudioBufferSourceNode::clearPannerNode() > { > if (m_pannerNode) { >- m_pannerNode->deref(AudioNode::RefTypeConnection); >+ m_pannerNode->derefConnection(); > m_pannerNode = nullptr; > } > } >diff --git a/Source/WebCore/Modules/webaudio/AudioContext.cpp b/Source/WebCore/Modules/webaudio/AudioContext.cpp >index fbd2815cfb38049ef654e75037f6afd264291073..433194b08ce815f3b0ab20757bfc21d39dc991cf 100644 >--- a/Source/WebCore/Modules/webaudio/AudioContext.cpp >+++ b/Source/WebCore/Modules/webaudio/AudioContext.cpp >@@ -668,7 +668,7 @@ void AudioContext::refNode(AudioNode& node) > ASSERT(isMainThread()); > AutoLocker locker(*this); > >- node.ref(AudioNode::RefTypeConnection); >+ node.refConnection(); > m_referencedNodes.append(&node); > } > >@@ -676,7 +676,7 @@ void AudioContext::derefNode(AudioNode& node) > { > ASSERT(isGraphOwner()); > >- node.deref(AudioNode::RefTypeConnection); >+ node.derefConnection(); > > ASSERT(m_referencedNodes.contains(&node)); > m_referencedNodes.removeFirst(&node); >@@ -686,7 +686,7 @@ void AudioContext::derefUnfinishedSourceNodes() > { > ASSERT(isMainThread() && isAudioThreadFinished()); > for (auto& node : m_referencedNodes) >- node->deref(AudioNode::RefTypeConnection); >+ node->derefConnection(); > > m_referencedNodes.clear(); > } >diff --git a/Source/WebCore/Modules/webaudio/AudioContext.h b/Source/WebCore/Modules/webaudio/AudioContext.h >index 760a4e7114f74758223add1fb0f856d6e85d30ce..71dcdeb732a3ffcdf1fed8a8bc62dc49f4217e3b 100644 >--- a/Source/WebCore/Modules/webaudio/AudioContext.h >+++ b/Source/WebCore/Modules/webaudio/AudioContext.h >@@ -328,8 +328,8 @@ private: > void visibilityStateChanged() final; > > // EventTarget >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > void handleDirtyAudioSummingJunctions(); > void handleDirtyAudioNodeOutputs(); >diff --git a/Source/WebCore/Modules/webaudio/AudioNode.cpp b/Source/WebCore/Modules/webaudio/AudioNode.cpp >index ad1351f44aeef347c3edb0d5da5be17113e797fa..d504422ab8ef22e0da23a8cd5ba1b319a4cb22c0 100644 >--- a/Source/WebCore/Modules/webaudio/AudioNode.cpp >+++ b/Source/WebCore/Modules/webaudio/AudioNode.cpp >@@ -389,31 +389,21 @@ void AudioNode::disableOutputsIfNecessary() > } > } > >-void AudioNode::ref(RefType refType) >+void AudioNode::refConnection() > { >- switch (refType) { >- case RefTypeNormal: >- ++m_normalRefCount; >- break; >- case RefTypeConnection: >- ++m_connectionRefCount; >- break; >- default: >- ASSERT_NOT_REACHED(); >- } >+ ++m_connectionRefCount; > > #if DEBUG_AUDIONODE_REFERENCES >- fprintf(stderr, "%p: %d: AudioNode::ref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount); >+ fprintf(stderr, "%p: %d: AudioNode::refConnection() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); > #endif > > // See the disabling code in finishDeref() below. This handles the case where a node > // is being re-connected after being used at least once and disconnected. > // In this case, we need to re-enable. >- if (refType == RefTypeConnection) >- enableOutputsIfNecessary(); >+ enableOutputsIfNecessary(); > } > >-void AudioNode::deref(RefType refType) >+void AudioNode::derefConnection() > { > // The actually work for deref happens completely within the audio context's graph lock. > // In the case of the audio thread, we must use a tryLock to avoid glitches. >@@ -430,14 +420,13 @@ void AudioNode::deref(RefType refType) > > if (hasLock) { > // This is where the real deref work happens. >- finishDeref(refType); >+ finishDeref(RefTypeConnection); > > if (mustReleaseLock) > context().unlock(); > } else { > // We were unable to get the lock, so put this in a list to finish up later. > ASSERT(context().isAudioThread()); >- ASSERT(refType == RefTypeConnection); > context().addDeferredFinishDeref(this); > } > >@@ -448,6 +437,49 @@ void AudioNode::deref(RefType refType) > context().deleteMarkedNodes(); > } > >+RefTrackingToken AudioNode::ref() >+{ >+ ++m_normalRefCount; >+ >+#if DEBUG_AUDIONODE_REFERENCES >+ fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); >+#endif >+ >+ return UntrackedRefToken(); >+} >+ >+void AudioNode::deref(RefTrackingToken) >+{ >+ // The actually work for deref happens completely within the audio context's graph lock. >+ // In the case of the audio thread, we must use a tryLock to avoid glitches. >+ bool hasLock = false; >+ bool mustReleaseLock = false; >+ >+ if (context().isAudioThread()) { >+ // Real-time audio thread must not contend lock (to avoid glitches). >+ hasLock = context().tryLock(mustReleaseLock); >+ } else { >+ context().lock(mustReleaseLock); >+ hasLock = true; >+ } >+ >+ if (hasLock) { >+ // This is where the real deref work happens. >+ finishDeref(RefTypeNormal); >+ >+ if (mustReleaseLock) >+ context().unlock(); >+ } else { >+ ASSERT_NOT_REACHED(); >+ } >+ >+ // Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here. >+ // We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive >+ // because AudioNodes keep a reference to the context. >+ if (context().isAudioThreadFinished()) >+ context().deleteMarkedNodes(); >+} >+ > void AudioNode::finishDeref(RefType refType) > { > ASSERT(context().isGraphOwner()); >diff --git a/Source/WebCore/Modules/webaudio/AudioNode.h b/Source/WebCore/Modules/webaudio/AudioNode.h >index 30a5f814452b9a39e8652f7f214f51c33899ce1f..593a0c8767122a845bc957186fba737463a22877 100644 >--- a/Source/WebCore/Modules/webaudio/AudioNode.h >+++ b/Source/WebCore/Modules/webaudio/AudioNode.h >@@ -93,8 +93,11 @@ public: > enum RefType { RefTypeNormal, RefTypeConnection }; > > // Can be called from main thread or context's audio thread. >- void ref(RefType refType = RefTypeNormal); >- void deref(RefType refType = RefTypeNormal); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); >+ >+ void refConnection(); >+ void derefConnection(); > > // Can be called from main thread or context's audio thread. It must be called while the context's graph lock is held. > void finishDeref(RefType refType); >@@ -214,8 +217,8 @@ private: > static int s_nodeCount[NodeTypeEnd]; > #endif > >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > protected: > unsigned m_channelCount; >diff --git a/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp b/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp >index ccaa51d822e0c85563e9e2fd5df1360b4eacff7b..2b7e2934203d2f60d83b35cc8db68902c4fcf88f 100644 >--- a/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp >+++ b/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp >@@ -59,7 +59,7 @@ void AudioNodeInput::connect(AudioNodeOutput* output) > changedOutputs(); > > // Sombody has just connected to us, so count it as a reference. >- node()->ref(AudioNode::RefTypeConnection); >+ node()->refConnection(); > } > > void AudioNodeInput::disconnect(AudioNodeOutput* output) >@@ -74,14 +74,14 @@ void AudioNodeInput::disconnect(AudioNodeOutput* output) > if (m_outputs.remove(output)) { > changedOutputs(); > output->removeInput(this); >- node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted. >+ node()->derefConnection(); // Note: it's important to return immediately after all deref() calls since the node may be deleted. > return; > } > > // Otherwise, try to disconnect from disabled connections. > if (m_disabledOutputs.remove(output)) { > output->removeInput(this); >- node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted. >+ node()->derefConnection(); // Note: it's important to return immediately after all deref() calls since the node may be deleted. > return; > } > >diff --git a/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp b/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp >index 576554da6743219e7008d90965562a57311f6434..9fd945a50a59bcb21b7e927b03f07e43742cb3bf 100644 >--- a/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp >+++ b/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp >@@ -166,7 +166,7 @@ void MediaElementAudioSourceNode::lock() > void MediaElementAudioSourceNode::unlock() > { > m_processMutex.unlock(); >- deref(); >+ deref(UntrackedRefToken()); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp b/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp >index e995b0865870679f7a6bf9a21ac28e1df3e31434..0c458324f2f7a11951d8dc88f9145bce33395781 100644 >--- a/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp >+++ b/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp >@@ -135,7 +135,7 @@ void OfflineAudioDestinationNode::offlineRender() > // Our work is done. Let the AudioContext know. > callOnMainThread([this] { > notifyComplete(); >- deref(); >+ deref(UntrackedRefToken()); > }); > } > >diff --git a/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp b/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp >index 88ae04abbe39e51734ebb017e20f261fbb041e56..e54cc70490ab76fc0ba34cfa91b2ae3102cf7790 100644 >--- a/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp >+++ b/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp >@@ -196,7 +196,7 @@ void ScriptProcessorNode::process(size_t framesToProcess) > fireProcessEvent(); > > // De-reference to match the ref() call in process(). >- deref(); >+ deref(UntrackedRefToken()); > }); > } > >diff --git a/Source/WebCore/Modules/webdatabase/SQLCallbackWrapper.h b/Source/WebCore/Modules/webdatabase/SQLCallbackWrapper.h >index d0d128096bab0a6a0f7c2dbf103c22d40839ff0a..38153ebf712d2f2c68b9adf804900a569506f0e9 100644 >--- a/Source/WebCore/Modules/webdatabase/SQLCallbackWrapper.h >+++ b/Source/WebCore/Modules/webdatabase/SQLCallbackWrapper.h >@@ -75,8 +75,8 @@ public: > ScriptExecutionContext::Task::CleanupTask, > [callback, scriptExecutionContextPtr] (ScriptExecutionContext& context) { > ASSERT_UNUSED(context, &context == scriptExecutionContextPtr && context.isContextThread()); >- callback->deref(); >- scriptExecutionContextPtr->deref(); >+ callback->deref(UntrackedRefToken()); >+ scriptExecutionContextPtr->deref(UntrackedRefToken()); > } > }); > } >diff --git a/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h b/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h >index ca406af4c6f52251f9f6cca8c45d443abb8d9857..53d89698e3ebd48e5bab789f877fdcb8159cb696 100644 >--- a/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h >+++ b/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h >@@ -32,6 +32,7 @@ > > #include <wtf/Forward.h> > #include <wtf/Noncopyable.h> >+#include <wtf/RefTracking.h> > > namespace JSC { > class ArrayBuffer; >@@ -73,13 +74,13 @@ public: > virtual void suspend() = 0; > virtual void resume() = 0; > >- void ref() { refThreadableWebSocketChannel(); } >- void deref() { derefThreadableWebSocketChannel(); } >+ RefTrackingToken ref() { return refThreadableWebSocketChannel(); } >+ void deref(RefTrackingToken token) { derefThreadableWebSocketChannel(token); } > > protected: > virtual ~ThreadableWebSocketChannel() = default; >- virtual void refThreadableWebSocketChannel() = 0; >- virtual void derefThreadableWebSocketChannel() = 0; >+ virtual RefTrackingToken refThreadableWebSocketChannel() = 0; >+ virtual void derefThreadableWebSocketChannel(RefTrackingToken) = 0; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/websockets/WebSocket.cpp b/Source/WebCore/Modules/websockets/WebSocket.cpp >index 58536213b5c7ab639d55e6c70f71d16996a0cdd7..6d6785550a478d052b9a8753ec1b06b711bf3daa 100644 >--- a/Source/WebCore/Modules/websockets/WebSocket.cpp >+++ b/Source/WebCore/Modules/websockets/WebSocket.cpp >@@ -300,7 +300,7 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr > WebThreadRun(^{ > dispatchOrQueueErrorEvent(); > stop(); >- deref(); >+ deref(UntrackedRefToken()); > }); > }); > #else >diff --git a/Source/WebCore/Modules/websockets/WebSocket.h b/Source/WebCore/Modules/websockets/WebSocket.h >index 90121f70d30880c2a02f96580ae05728fb8bddc8..c5d430c77eb2cef96dac8b990bae1cc037dfb8f4 100644 >--- a/Source/WebCore/Modules/websockets/WebSocket.h >+++ b/Source/WebCore/Modules/websockets/WebSocket.h >@@ -113,8 +113,8 @@ private: > > EventTargetInterface eventTargetInterface() const final; > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void didConnect() final; > void didReceiveMessage(const String& message) final; >diff --git a/Source/WebCore/Modules/websockets/WebSocketChannel.cpp b/Source/WebCore/Modules/websockets/WebSocketChannel.cpp >index 8147f0d4bc5267ea3a199d6b32941f635d0d812a..f4495ffa0cd60d95ac4c30626c2eb126d2e828db 100644 >--- a/Source/WebCore/Modules/websockets/WebSocketChannel.cpp >+++ b/Source/WebCore/Modules/websockets/WebSocketChannel.cpp >@@ -306,7 +306,7 @@ void WebSocketChannel::didCloseSocketStream(SocketStreamHandle& handle) > if (client) > client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandshake ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient::ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason); > } >- deref(); >+ deref(UntrackedRefToken()); > } > > void WebSocketChannel::didReceiveSocketStreamData(SocketStreamHandle& handle, const char* data, size_t length) >@@ -392,7 +392,7 @@ void WebSocketChannel::didFinishLoading() > ASSERT(m_blobLoaderStatus == BlobLoaderStarted); > m_blobLoaderStatus = BlobLoaderFinished; > processOutgoingFrameQueue(); >- deref(); >+ deref(UntrackedRefToken()); > } > > void WebSocketChannel::didFail(int errorCode) >@@ -403,7 +403,7 @@ void WebSocketChannel::didFail(int errorCode) > m_blobLoader = nullptr; > m_blobLoaderStatus = BlobLoaderFailed; > fail("Failed to load Blob: error code = " + String::number(errorCode)); // FIXME: Generate human-friendly reason message. >- deref(); >+ deref(UntrackedRefToken()); > } > > bool WebSocketChannel::appendToBuffer(const char* data, size_t len) >diff --git a/Source/WebCore/Modules/websockets/WebSocketChannel.h b/Source/WebCore/Modules/websockets/WebSocketChannel.h >index 1131ea611f9523a720fc5404253cd709c0b82a0d..5ce79552d6bc27117a5a1a0b41e7e0ed3576b3d5 100644 >--- a/Source/WebCore/Modules/websockets/WebSocketChannel.h >+++ b/Source/WebCore/Modules/websockets/WebSocketChannel.h >@@ -124,8 +124,8 @@ public: > using RefCounted<WebSocketChannel>::deref; > > protected: >- void refThreadableWebSocketChannel() override { ref(); } >- void derefThreadableWebSocketChannel() override { deref(); } >+ RefTrackingToken refThreadableWebSocketChannel() override { return ref(); } >+ void derefThreadableWebSocketChannel(RefTrackingToken token) override { deref(token); } > > private: > WEBCORE_EXPORT WebSocketChannel(Document&, WebSocketChannelClient&, SocketProvider&); >diff --git a/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h b/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h >index 812f8a02d30a1683ce94684f871020e6bbb99d18..f15f41f950af546a4c98db12276370832f33693b 100644 >--- a/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h >+++ b/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h >@@ -109,8 +109,8 @@ public: > using RefCounted<WorkerThreadableWebSocketChannel>::deref; > > protected: >- void refThreadableWebSocketChannel() override { ref(); } >- void derefThreadableWebSocketChannel() override { deref(); } >+ RefTrackingToken refThreadableWebSocketChannel() override { return ref(); } >+ void derefThreadableWebSocketChannel(RefTrackingToken token) override { deref(token); } > > private: > // Bridge for Peer. Running on the worker thread. >diff --git a/Source/WebCore/Modules/webvr/VRDisplay.h b/Source/WebCore/Modules/webvr/VRDisplay.h >index 2f8ea8c267a06e7ee9c99db7e4eccc6d5ea62c6c..a1666582dcf36c50d2265035221c8d744f4862d7 100644 >--- a/Source/WebCore/Modules/webvr/VRDisplay.h >+++ b/Source/WebCore/Modules/webvr/VRDisplay.h >@@ -97,8 +97,8 @@ private: > // EventTarget > EventTargetInterface eventTargetInterface() const override { return VRDisplayEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > // ActiveDOMObject > bool hasPendingActivity() const override; >diff --git a/Source/WebCore/animation/WebAnimation.h b/Source/WebCore/animation/WebAnimation.h >index f026e31d1b0d345d6b56eac065e042d0a4e4f439..7031bcf54d444f662efdcdaad81820134d0299c0 100644 >--- a/Source/WebCore/animation/WebAnimation.h >+++ b/Source/WebCore/animation/WebAnimation.h >@@ -186,8 +186,8 @@ private: > > // EventTarget > EventTargetInterface eventTargetInterface() const final { return WebAnimationEventTargetInterfaceType; } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } > }; > >diff --git a/Source/WebCore/bridge/NP_jsobject.cpp b/Source/WebCore/bridge/NP_jsobject.cpp >index d9458c516ba73716172b9c51de03e81d4adfec6d..adb76abbf9c0ae78f35f839c104dbb16687cdc7b 100644 >--- a/Source/WebCore/bridge/NP_jsobject.cpp >+++ b/Source/WebCore/bridge/NP_jsobject.cpp >@@ -131,7 +131,7 @@ static void jsDeallocate(NPObject* npObj) > } > > if (obj->rootObject) >- obj->rootObject->deref(); >+ obj->rootObject->deref(UntrackedRefToken()); > > free(obj); > } >diff --git a/Source/WebCore/bridge/objc/WebScriptObject.mm b/Source/WebCore/bridge/objc/WebScriptObject.mm >index 02b84283ed39b1412da0c0133a02739a0b642334..cc5ded1e498907a85a7b186d7187381c4cf41b55 100644 >--- a/Source/WebCore/bridge/objc/WebScriptObject.mm >+++ b/Source/WebCore/bridge/objc/WebScriptObject.mm >@@ -216,10 +216,10 @@ - (void)_setOriginRootObject:(RefPtr<RootObject>&&)originRootObject andRootObjec > _private->rootObject->gcUnprotect(_private->imp); > > if (_private->rootObject) >- _private->rootObject->deref(); >+ _private->rootObject->deref(UntrackedRefToken()); > > if (_private->originRootObject) >- _private->originRootObject->deref(); >+ _private->originRootObject->deref(UntrackedRefToken()); > > _private->rootObject = rootObject.leakRef(); > _private->originRootObject = originRootObject.leakRef(); >@@ -308,10 +308,10 @@ - (void)dealloc > _private->rootObject->gcUnprotect(_private->imp); > > if (_private->rootObject) >- _private->rootObject->deref(); >+ _private->rootObject->deref(UntrackedRefToken()); > > if (_private->originRootObject) >- _private->originRootObject->deref(); >+ _private->originRootObject->deref(UntrackedRefToken()); > > [_private release]; > >diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp >index db9c6d79e087651443f074b6a0800a0f8a3e526c..ecbd00eae6ff0e6bff6e87f3c10802856856af8b 100644 >--- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp >+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp >@@ -1671,12 +1671,13 @@ CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(Element& element, bool > > CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() = default; > >-void CSSComputedStyleDeclaration::ref() >+RefTrackingToken CSSComputedStyleDeclaration::ref() > { > ++m_refCount; >+ return UntrackedRefToken(); > } > >-void CSSComputedStyleDeclaration::deref() >+void CSSComputedStyleDeclaration::deref(RefTrackingToken) > { > ASSERT(m_refCount); > if (!--m_refCount) >diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.h b/Source/WebCore/css/CSSComputedStyleDeclaration.h >index bdf343272a6aa41b76e31d2a19ff711772367f73..2caa07570ce4bb37f9c4edfe273493665f4d627c 100644 >--- a/Source/WebCore/css/CSSComputedStyleDeclaration.h >+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.h >@@ -109,8 +109,8 @@ public: > } > virtual ~CSSComputedStyleDeclaration(); > >- WEBCORE_EXPORT void ref() final; >- WEBCORE_EXPORT void deref() final; >+ WEBCORE_EXPORT RefTrackingToken ref() final; >+ WEBCORE_EXPORT void deref(RefTrackingToken) final; > > String getPropertyValue(CSSPropertyID) const; > >diff --git a/Source/WebCore/css/CSSDefaultStyleSheets.cpp b/Source/WebCore/css/CSSDefaultStyleSheets.cpp >index 582b930f7c44dd574b0495c3af5cfef0646d5078..855e659e9c2ca8c6fe4526579de7ccad8d3281de 100644 >--- a/Source/WebCore/css/CSSDefaultStyleSheets.cpp >+++ b/Source/WebCore/css/CSSDefaultStyleSheets.cpp >@@ -146,7 +146,7 @@ void CSSDefaultStyleSheets::loadFullDefaultStyle() > ASSERT(defaultStyle); > ASSERT(defaultPrintStyle == defaultStyle); > delete defaultStyle; >- simpleDefaultStyleSheet->deref(); >+ simpleDefaultStyleSheet->deref(UntrackedRefToken()); > simpleDefaultStyleSheet = nullptr; > } else { > ASSERT(!defaultStyle); >diff --git a/Source/WebCore/css/CSSFontFace.h b/Source/WebCore/css/CSSFontFace.h >index bd7fc22d3f97c4f766822cbeba95ffcd711a7c18..72cd18fa609fcecc47ba47dbffdae6ef285c9c9b 100644 >--- a/Source/WebCore/css/CSSFontFace.h >+++ b/Source/WebCore/css/CSSFontFace.h >@@ -123,8 +123,8 @@ public: > virtual void fontLoaded(CSSFontFace&) { } > virtual void fontStateChanged(CSSFontFace&, Status /*oldState*/, Status /*newState*/) { } > virtual void fontPropertyChanged(CSSFontFace&, CSSValueList* /*oldFamilies*/ = nullptr) { } >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > }; > > // Pending => Loading => TimedOut >diff --git a/Source/WebCore/css/CSSFontFaceSet.h b/Source/WebCore/css/CSSFontFaceSet.h >index 337feab4b158f36585dacfd9987ace3556f37b27..1733d274572bf4775a80556491c73f533e9d5e40 100644 >--- a/Source/WebCore/css/CSSFontFaceSet.h >+++ b/Source/WebCore/css/CSSFontFaceSet.h >@@ -78,8 +78,8 @@ public: > ExceptionOr<Vector<std::reference_wrapper<CSSFontFace>>> matchingFacesExcludingPreinstalledFonts(const String& font, const String& text); > > // CSSFontFace::Client needs to be able to be held in a RefPtr. >- void ref() final { RefCounted::ref(); } >- void deref() final { RefCounted::deref(); } >+ RefTrackingToken ref() final { return RefCounted::ref(); } >+ void deref(RefTrackingToken token) final { RefCounted::deref(token); } > > private: > CSSFontFaceSet(CSSFontSelector*); >diff --git a/Source/WebCore/css/CSSImageGeneratorValue.cpp b/Source/WebCore/css/CSSImageGeneratorValue.cpp >index 7a8e19f230f4a200a52b51158302e1cdce55fc6e..cc3eb586762fc7c3b439d4a5761939218d755b43 100644 >--- a/Source/WebCore/css/CSSImageGeneratorValue.cpp >+++ b/Source/WebCore/css/CSSImageGeneratorValue.cpp >@@ -90,7 +90,7 @@ void CSSImageGeneratorValue::removeClient(RenderElement& renderer) > } > > if (m_clients.isEmpty()) >- deref(); >+ deref(UntrackedRefToken()); > } > > GeneratedImage* CSSImageGeneratorValue::cachedImageForSize(FloatSize size) >diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp >index c60d1b4e1ba9564d156b4f79f8484662631628af..ce4e1a9820528a545930469a50b947aefccdd895 100644 >--- a/Source/WebCore/css/CSSPrimitiveValue.cpp >+++ b/Source/WebCore/css/CSSPrimitiveValue.cpp >@@ -491,36 +491,36 @@ void CSSPrimitiveValue::cleanup() > case CSS_ATTR: > case CSS_COUNTER_NAME: > if (m_value.string) >- m_value.string->deref(); >+ m_value.string->deref(UntrackedRefToken()); > break; > case CSS_DIMENSION: > case CSS_COUNTER: >- m_value.counter->deref(); >+ m_value.counter->deref(UntrackedRefToken()); > break; > case CSS_RECT: >- m_value.rect->deref(); >+ m_value.rect->deref(UntrackedRefToken()); > break; > case CSS_QUAD: >- m_value.quad->deref(); >+ m_value.quad->deref(UntrackedRefToken()); > break; > case CSS_PAIR: >- m_value.pair->deref(); >+ m_value.pair->deref(UntrackedRefToken()); > break; > #if ENABLE(DASHBOARD_SUPPORT) > case CSS_DASHBOARD_REGION: > if (m_value.region) >- m_value.region->deref(); >+ m_value.region->deref(UntrackedRefToken()); > break; > #endif > case CSS_CALC: >- m_value.calc->deref(); >+ m_value.calc->deref(UntrackedRefToken()); > break; > case CSS_CALC_PERCENTAGE_WITH_NUMBER: > case CSS_CALC_PERCENTAGE_WITH_LENGTH: > ASSERT_NOT_REACHED(); > break; > case CSS_SHAPE: >- m_value.shape->deref(); >+ m_value.shape->deref(UntrackedRefToken()); > break; > case CSS_FONT_FAMILY: > ASSERT(m_value.fontFamily); >diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp >index 0e6a799909db305841bcfe4403f2deb3ba2b66fd..cf15853ab7ae0b035dd967010fb910eb4ed48968 100644 >--- a/Source/WebCore/css/CSSProperty.cpp >+++ b/Source/WebCore/css/CSSProperty.cpp >@@ -33,7 +33,9 @@ struct SameSizeAsCSSProperty { > void* value; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small); >+#endif > > CSSPropertyID StylePropertyMetadata::shorthandID() const > { >diff --git a/Source/WebCore/css/CSSRuleList.cpp b/Source/WebCore/css/CSSRuleList.cpp >index a040109169892f373526a0d0be5e4163fc1d6ef8..6275eff86f572a61c0f5324ad043f833cd5d190e 100644 >--- a/Source/WebCore/css/CSSRuleList.cpp >+++ b/Source/WebCore/css/CSSRuleList.cpp >@@ -37,7 +37,7 @@ StaticCSSRuleList::StaticCSSRuleList() > > StaticCSSRuleList::~StaticCSSRuleList() = default; > >-void StaticCSSRuleList::deref() >+void StaticCSSRuleList::deref(RefTrackingToken) > { > ASSERT(m_refCount); > if (!--m_refCount) >diff --git a/Source/WebCore/css/CSSRuleList.h b/Source/WebCore/css/CSSRuleList.h >index 35a0925feb6f3cdab740d9ef2d7a0dd6f07d3eac..b292bcb053541805780657cfb4d359f54e4055ec 100644 >--- a/Source/WebCore/css/CSSRuleList.h >+++ b/Source/WebCore/css/CSSRuleList.h >@@ -34,8 +34,8 @@ class CSSRuleList { > public: > virtual ~CSSRuleList(); > >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > > virtual unsigned length() const = 0; > virtual CSSRule* item(unsigned index) const = 0; >@@ -50,8 +50,8 @@ class StaticCSSRuleList final : public CSSRuleList { > public: > static Ref<StaticCSSRuleList> create() { return adoptRef(*new StaticCSSRuleList); } > >- void ref() final { ++m_refCount; } >- void deref() final; >+ RefTrackingToken ref() final { ++m_refCount; return UntrackedRefToken(); } >+ void deref(RefTrackingToken) final; > > Vector<RefPtr<CSSRule>>& rules() { return m_rules; } > >@@ -77,8 +77,8 @@ public: > { > } > >- void ref() final { m_rule.ref(); } >- void deref() final { m_rule.deref(); } >+ RefTrackingToken ref() final { m_rule.ref(); return UntrackedRefToken(); } >+ void deref(RefTrackingToken) final { m_rule.deref(UntrackedRefToken()); } > > private: > unsigned length() const final { return m_rule.length(); } >diff --git a/Source/WebCore/css/CSSSegmentedFontFace.h b/Source/WebCore/css/CSSSegmentedFontFace.h >index f66e7339320aababc3048eaf011680d420f9936c..686e7d7099e96eb945d3c143d0084f3bfc73b951 100644 >--- a/Source/WebCore/css/CSSSegmentedFontFace.h >+++ b/Source/WebCore/css/CSSSegmentedFontFace.h >@@ -53,8 +53,8 @@ public: > Vector<Ref<CSSFontFace>, 1>& constituentFaces() { return m_fontFaces; } > > // CSSFontFace::Client needs to be able to be held in a RefPtr. >- void ref() final { RefCounted<CSSSegmentedFontFace>::ref(); } >- void deref() final { RefCounted<CSSSegmentedFontFace>::deref(); } >+ RefTrackingToken ref() final { return RefCounted<CSSSegmentedFontFace>::ref(); } >+ void deref(RefTrackingToken token) final { RefCounted<CSSSegmentedFontFace>::deref(token); } > > private: > CSSSegmentedFontFace(); >diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h >index a6a1bd96d635f450c2f4f376bbfabaa8cb4ae3c2..077ff5b14fe12077f5363786151d260bf9e0a7c8 100644 >--- a/Source/WebCore/css/CSSSelector.h >+++ b/Source/WebCore/css/CSSSelector.h >@@ -464,7 +464,7 @@ inline void CSSSelector::setValue(const AtomicString& value, bool matchLowerCase > // Need to do ref counting manually for the union. > if (!m_hasRareData) { > if (m_data.m_value) >- m_data.m_value->deref(); >+ m_data.m_value->deref(UntrackedRefToken()); > m_data.m_value = value.impl(); > m_data.m_value->ref(); > return; >@@ -528,19 +528,19 @@ inline CSSSelector::~CSSSelector() > m_destructorHasBeenCalled = true; > #endif > if (m_hasRareData) { >- m_data.m_rareData->deref(); >+ m_data.m_rareData->deref(UntrackedRefToken()); > m_data.m_rareData = nullptr; > m_hasRareData = false; > } else if (m_hasNameWithCase) { >- m_data.m_nameWithCase->deref(); >+ m_data.m_nameWithCase->deref(UntrackedRefToken()); > m_data.m_nameWithCase = nullptr; > m_hasNameWithCase = false; > } else if (match() == Tag) { >- m_data.m_tagQName->deref(); >+ m_data.m_tagQName->deref(UntrackedRefToken()); > m_data.m_tagQName = nullptr; > m_match = Unknown; > } else if (m_data.m_value) { >- m_data.m_value->deref(); >+ m_data.m_value->deref(UntrackedRefToken()); > m_data.m_value = nullptr; > } > } >diff --git a/Source/WebCore/css/CSSStyleDeclaration.h b/Source/WebCore/css/CSSStyleDeclaration.h >index b18c9ce327499acd052ae28f08357cdf74029f98..17008db606cad841a7e475eb60d5e5fc686570d1 100644 >--- a/Source/WebCore/css/CSSStyleDeclaration.h >+++ b/Source/WebCore/css/CSSStyleDeclaration.h >@@ -43,8 +43,8 @@ class CSSStyleDeclaration : public ScriptWrappable { > public: > virtual ~CSSStyleDeclaration() = default; > >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > > virtual StyledElement* parentElement() const { return nullptr; } > virtual CSSRule* parentRule() const = 0; >diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp >index 1ecc5ba3708792fa637f16b12cd73e11efb04a62..ca20330f4eefd1ec6c978ff5b0db661905ac590e 100644 >--- a/Source/WebCore/css/CSSStyleSheet.cpp >+++ b/Source/WebCore/css/CSSStyleSheet.cpp >@@ -45,8 +45,8 @@ public: > StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { } > > private: >- void ref() final { m_styleSheet->ref(); } >- void deref() final { m_styleSheet->deref(); } >+ RefTrackingToken ref() final { m_styleSheet->ref(); return UntrackedRefToken(); } >+ void deref(RefTrackingToken) final { m_styleSheet->deref(UntrackedRefToken()); } > > unsigned length() const final { return m_styleSheet->length(); } > CSSRule* item(unsigned index) const final { return m_styleSheet->item(index); } >diff --git a/Source/WebCore/css/CSSValue.h b/Source/WebCore/css/CSSValue.h >index d44b0750bfae02d9c7aa9e05a9db8cab1dd95b36..feeca2beb3a1130d23dfc7bca63acc07ab701d06 100644 >--- a/Source/WebCore/css/CSSValue.h >+++ b/Source/WebCore/css/CSSValue.h >@@ -51,9 +51,9 @@ public: > > // Override RefCounted's deref() to ensure operator delete is called on > // the appropriate subclass type. >- void deref() >+ void deref(RefTrackingToken token) > { >- if (derefBase()) >+ if (derefBase(token)) > destroy(); > } > >diff --git a/Source/WebCore/css/DeprecatedCSSOMValue.h b/Source/WebCore/css/DeprecatedCSSOMValue.h >index 16bca96d0687fbccb2c7a0b518a2f81ea0e65cf1..1bd8dab21db6794b57f5141a62346ee1e8687fcb 100644 >--- a/Source/WebCore/css/DeprecatedCSSOMValue.h >+++ b/Source/WebCore/css/DeprecatedCSSOMValue.h >@@ -48,9 +48,9 @@ public: > > // Override RefCounted's deref() to ensure operator delete is called on > // the appropriate subclass type. >- void deref() >+ void deref(RefTrackingToken token) > { >- if (derefBase()) >+ if (derefBase(token)) > destroy(); > } > >diff --git a/Source/WebCore/css/FontFace.cpp b/Source/WebCore/css/FontFace.cpp >index 2eb41c9c11444d61bddf3ab142b95be384195c78..d131c8f59256e162b9569b53640d3f5c1ea40c16 100644 >--- a/Source/WebCore/css/FontFace.cpp >+++ b/Source/WebCore/css/FontFace.cpp >@@ -443,14 +443,14 @@ void FontFace::fontStateChanged(CSSFontFace& face, CSSFontFace::Status, CSSFontF > // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again. > if (!m_loadedPromise.isFulfilled()) > m_loadedPromise.resolve(*this); >- deref(); >+ deref(UntrackedRefToken()); > return; > case CSSFontFace::Status::Failure: > // FIXME: This check should not be needed, but because FontFace's are sometimes adopted after they have already > // gone through a load cycle, we can sometimes come back through here and try to resolve the promise again. > if (!m_loadedPromise.isFulfilled()) > m_loadedPromise.reject(Exception { NetworkError }); >- deref(); >+ deref(UntrackedRefToken()); > return; > case CSSFontFace::Status::Pending: > ASSERT_NOT_REACHED(); >diff --git a/Source/WebCore/css/FontFace.h b/Source/WebCore/css/FontFace.h >index 3d9a0ec1c9adaac821b67401b8796ea7cb678af6..efca00cff71ea71c72e1a98eaaa34032e8d9332a 100644 >--- a/Source/WebCore/css/FontFace.h >+++ b/Source/WebCore/css/FontFace.h >@@ -88,8 +88,8 @@ public: > > void fontStateChanged(CSSFontFace&, CSSFontFace::Status oldState, CSSFontFace::Status newState) final; > >- void ref() final { RefCounted::ref(); } >- void deref() final { RefCounted::deref(); } >+ RefTrackingToken ref() final { return RefCounted::ref(); } >+ void deref(RefTrackingToken token) final { RefCounted::deref(token); } > > private: > explicit FontFace(CSSFontSelector&); >diff --git a/Source/WebCore/css/FontFaceSet.h b/Source/WebCore/css/FontFaceSet.h >index 1c89172a8e71dd838d43ba6dd843838864ed6ec7..bc9ff4e51832f8a89f4c8e0514ce9cc89f9cbd3c 100644 >--- a/Source/WebCore/css/FontFaceSet.h >+++ b/Source/WebCore/css/FontFaceSet.h >@@ -105,8 +105,8 @@ private: > // EventTarget > EventTargetInterface eventTargetInterface() const final { return FontFaceSetEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > // Callback for ReadyPromise. > FontFaceSet& readyPromiseResolve(); >diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp >index e28b34c0d91e7785a47a78c8bc1309056ffa119c..bb2b239223b6799e8e199e8e8581a59ce3acd91d 100644 >--- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp >+++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp >@@ -129,14 +129,14 @@ PropertySetCSSStyleDeclaration* StyleAttributeMutationScope::s_currentDecl = nul > bool StyleAttributeMutationScope::s_shouldNotifyInspector = false; > bool StyleAttributeMutationScope::s_shouldDeliver = false; > >-void PropertySetCSSStyleDeclaration::ref() >+RefTrackingToken PropertySetCSSStyleDeclaration::ref() > { >- m_propertySet->ref(); >+ return m_propertySet->ref(); > } > >-void PropertySetCSSStyleDeclaration::deref() >+void PropertySetCSSStyleDeclaration::deref(RefTrackingToken token) > { >- m_propertySet->deref(); >+ m_propertySet->deref(token); > } > > unsigned PropertySetCSSStyleDeclaration::length() const >@@ -353,15 +353,16 @@ StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertie > > StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration() > { >- m_propertySet->deref(); >+ m_propertySet->deref(UntrackedRefToken()); > } > >-void StyleRuleCSSStyleDeclaration::ref() >+RefTrackingToken StyleRuleCSSStyleDeclaration::ref() > { > ++m_refCount; >+ return UntrackedRefToken(); > } > >-void StyleRuleCSSStyleDeclaration::deref() >+void StyleRuleCSSStyleDeclaration::deref(RefTrackingToken) > { > ASSERT(m_refCount); > if (!--m_refCount) >@@ -404,7 +405,7 @@ CSSParserContext StyleRuleCSSStyleDeclaration::cssParserContext() const > > void StyleRuleCSSStyleDeclaration::reattach(MutableStyleProperties& propertySet) > { >- m_propertySet->deref(); >+ m_propertySet->deref(UntrackedRefToken()); > m_propertySet = &propertySet; > m_propertySet->ref(); > } >diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h >index 5983f213edc5b0e38443758447813f351c8c0417..4724ef52b33e4d5b4c5bb842378c434e58fe6ea1 100644 >--- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h >+++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h >@@ -61,8 +61,8 @@ protected: > std::unique_ptr<HashMap<CSSValue*, WeakPtr<DeprecatedCSSOMValue>>> m_cssomValueWrappers; > > private: >- void ref() override; >- void deref() override; >+ RefTrackingToken ref() override; >+ void deref(RefTrackingToken) override; > > CSSRule* parentRule() const override { return nullptr; } > unsigned length() const final; >@@ -98,8 +98,8 @@ public: > > void clearParentRule() { m_parentRule = nullptr; } > >- void ref() final; >- void deref() final; >+ RefTrackingToken ref() final; >+ void deref(RefTrackingToken) final; > > void reattach(MutableStyleProperties&); > >diff --git a/Source/WebCore/css/RuleSet.h b/Source/WebCore/css/RuleSet.h >index ba5dc60fe34c6b7678246734d322ac2f7a02f57f..e5bef9d1309c64fd2453bc9a78f465063aa7e54c 100644 >--- a/Source/WebCore/css/RuleSet.h >+++ b/Source/WebCore/css/RuleSet.h >@@ -98,7 +98,9 @@ struct SameSizeAsRuleData { > unsigned d[4]; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small); >+#endif > > class RuleSet { > WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED; >diff --git a/Source/WebCore/css/StyleProperties.cpp b/Source/WebCore/css/StyleProperties.cpp >index 345013961a16262ad7208b3beebb8f487bfe6b6a..9158dccf40f6847a1fd22fafbe4c07a82c1128a1 100644 >--- a/Source/WebCore/css/StyleProperties.cpp >+++ b/Source/WebCore/css/StyleProperties.cpp >@@ -102,7 +102,7 @@ ImmutableStyleProperties::~ImmutableStyleProperties() > { > CSSValue** valueArray = const_cast<CSSValue**>(this->valueArray()); > for (unsigned i = 0; i < m_arraySize; ++i) >- valueArray[i]->deref(); >+ valueArray[i]->deref(UntrackedRefToken()); > } > > MutableStyleProperties::MutableStyleProperties(const StyleProperties& other) >diff --git a/Source/WebCore/css/StyleProperties.h b/Source/WebCore/css/StyleProperties.h >index a183a9cca2c563e03834beab24ebc250d20543a8..59f34a61823b4071316fe2a3d56350671c21a401 100644 >--- a/Source/WebCore/css/StyleProperties.h >+++ b/Source/WebCore/css/StyleProperties.h >@@ -51,7 +51,7 @@ class StylePropertiesBase : public RefCounted<StylePropertiesBase> { > public: > // Override RefCounted's deref() to ensure operator delete is called on > // the appropriate subclass type. >- void deref(); >+ void deref(RefTrackingToken); > > StylePropertiesType type() const { return static_cast<StylePropertiesType>(m_type); } > >@@ -305,9 +305,9 @@ inline unsigned StyleProperties::propertyCount() const > return downcast<ImmutableStyleProperties>(*this).propertyCount(); > } > >-inline void StylePropertiesBase::deref() >+inline void StylePropertiesBase::deref(RefTrackingToken token) > { >- if (!derefBase()) >+ if (!derefBase(token)) > return; > > if (is<MutableStyleProperties>(*this)) >diff --git a/Source/WebCore/css/StyleRule.h b/Source/WebCore/css/StyleRule.h >index 6807141feea71b076afa9a4a69a3cd26fc532288..e6db902944dc06c61d48b98535d886463066c97e 100644 >--- a/Source/WebCore/css/StyleRule.h >+++ b/Source/WebCore/css/StyleRule.h >@@ -77,9 +77,9 @@ public: > > Ref<StyleRuleBase> copy() const; > >- void deref() >+ void deref(RefTrackingToken token) > { >- if (derefBase()) >+ if (derefBase(token)) > destroy(); > } > >diff --git a/Source/WebCore/dom/AbortSignal.h b/Source/WebCore/dom/AbortSignal.h >index d3140acc2d8291454636a903c4be573981b1cbc1..330ed5e9adf3befce32106d9d5e1b3007ceb33e3 100644 >--- a/Source/WebCore/dom/AbortSignal.h >+++ b/Source/WebCore/dom/AbortSignal.h >@@ -50,8 +50,8 @@ private: > > EventTargetInterface eventTargetInterface() const final { return AbortSignalEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > bool m_aborted { false }; > }; >diff --git a/Source/WebCore/dom/ActiveDOMObject.h b/Source/WebCore/dom/ActiveDOMObject.h >index 360ad21489adbd5fecbb817680df4b9e8f789e74..39e3ee42282a7484b9d096c8bc680e4f41e2758b 100644 >--- a/Source/WebCore/dom/ActiveDOMObject.h >+++ b/Source/WebCore/dom/ActiveDOMObject.h >@@ -82,7 +82,7 @@ public: > { > ASSERT(m_pendingActivityCount > 0); > --m_pendingActivityCount; >- thisObject->deref(); >+ thisObject->deref(UntrackedRefToken()); > } > > template<class T> >diff --git a/Source/WebCore/dom/DOMImplementation.h b/Source/WebCore/dom/DOMImplementation.h >index a40a2f6912f1ef31a0dc9f4310c2a4ff4cd32bd9..5285e892c7289c571ea12a0d92c1f31e136ad8b8 100644 >--- a/Source/WebCore/dom/DOMImplementation.h >+++ b/Source/WebCore/dom/DOMImplementation.h >@@ -33,8 +33,8 @@ class DOMImplementation : public ScriptWrappable { > public: > explicit DOMImplementation(Document&); > >- void ref() { m_document.ref(); } >- void deref() { m_document.deref(); } >+ RefTrackingToken ref() { m_document.ref(); return UntrackedRefToken(); } >+ void deref(RefTrackingToken) { m_document.deref(UntrackedRefToken()); } > Document& document() { return m_document; } > > WEBCORE_EXPORT ExceptionOr<Ref<DocumentType>> createDocumentType(const String& qualifiedName, const String& publicId, const String& systemId); >diff --git a/Source/WebCore/dom/DataTransferItemList.h b/Source/WebCore/dom/DataTransferItemList.h >index d25359abac9b536607dd133440fe93fdd116c8a3..616889155bb178c2b9a2c3799857b567f7e68072 100644 >--- a/Source/WebCore/dom/DataTransferItemList.h >+++ b/Source/WebCore/dom/DataTransferItemList.h >@@ -51,8 +51,8 @@ public: > ~DataTransferItemList(); > > // DataTransfer owns DataTransferItemList, and DataTransfer is kept alive as long as DataTransferItemList is alive. >- void ref() { m_dataTransfer.ref(); } >- void deref() { m_dataTransfer.deref(); } >+ RefTrackingToken ref() { m_dataTransfer.ref(); return UntrackedRefToken(); } >+ void deref(RefTrackingToken) { m_dataTransfer.deref(UntrackedRefToken()); } > DataTransfer& dataTransfer() { return m_dataTransfer; } > > // DOM API >diff --git a/Source/WebCore/dom/DatasetDOMStringMap.cpp b/Source/WebCore/dom/DatasetDOMStringMap.cpp >index ec6315c960b5a77e7992b4c6d9e23af25725c015..fce0573085d3e47e6b3f0156d28a81dad77a1e9d 100644 >--- a/Source/WebCore/dom/DatasetDOMStringMap.cpp >+++ b/Source/WebCore/dom/DatasetDOMStringMap.cpp >@@ -140,14 +140,14 @@ static AtomicString convertPropertyNameToAttributeName(const String& name) > return convertPropertyNameToAttributeName<UChar>(*nameImpl); > } > >-void DatasetDOMStringMap::ref() >+RefTrackingToken DatasetDOMStringMap::ref() > { >- m_element.ref(); >+ return m_element.ref(); > } > >-void DatasetDOMStringMap::deref() >+void DatasetDOMStringMap::deref(RefTrackingToken token) > { >- m_element.deref(); >+ m_element.deref(token); > } > > bool DatasetDOMStringMap::isSupportedPropertyName(const String& propertyName) const >diff --git a/Source/WebCore/dom/DatasetDOMStringMap.h b/Source/WebCore/dom/DatasetDOMStringMap.h >index 9100db8c88ccade140eebd35a4a0e599c5ba115e..0b3a0f251662b76802b03355dfabda6fd97d1104 100644 >--- a/Source/WebCore/dom/DatasetDOMStringMap.h >+++ b/Source/WebCore/dom/DatasetDOMStringMap.h >@@ -40,8 +40,8 @@ public: > { > } > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > bool isSupportedPropertyName(const String& name) const; > Vector<String> supportedPropertyNames() const; >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index e723591a9133ca518ba0a4e512ed17fc4d74ce8e..3f2a288b3a387dea343fc1ba481ab9f4df3635ee 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -481,6 +481,8 @@ static inline int currentOrientation(Frame* frame) > return 0; > } > >+static int DocumentCount; >+ > Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsigned constructionFlags) > : ContainerNode(*this, CreateDocument) > , TreeScope(*this) >@@ -531,6 +533,8 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig > , m_orientationNotifier(currentOrientation(frame)) > , m_identifier(generateObjectIdentifier<DocumentIdentifierType>()) > { >+ WTFLogAlways("Created document %p %s (%d documents)", this, url.string().utf8().data(), ++DocumentCount); >+ > auto addResult = allDocumentsMap().add(m_identifier, this); > ASSERT_UNUSED(addResult, addResult.isNewEntry); > >@@ -582,6 +586,8 @@ Ref<Document> Document::create(Document& contextDocument) > > Document::~Document() > { >+ WTFLogAlways("Destroying document %p %s (%d documents)", this, url().string().utf8().data(), --DocumentCount); >+ > if (m_logger) > m_logger->removeObserver(*this); > >@@ -714,6 +720,11 @@ void Document::removedLastRef() > } > } > >+unsigned Document::referencingNodeCount() const >+{ >+ return m_referencingNodeCount; >+} >+ > void Document::commonTeardown() > { > if (svgExtensions()) >diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h >index 9e3c31853f123ec9bea3f690b85e17bad07675d5..6af700af3ecf9a820884fffb1a5745a75c73dfd7 100644 >--- a/Source/WebCore/dom/Document.h >+++ b/Source/WebCore/dom/Document.h >@@ -377,7 +377,7 @@ public: > } > } > >- unsigned referencingNodeCount() const { return m_referencingNodeCount; } >+ WEBCORE_EXPORT unsigned referencingNodeCount() const; > > void removedLastRef(); > >@@ -1524,8 +1524,8 @@ private: > Ref<Node> cloneNodeInternal(Document&, CloningOperation) final; > void cloneDataFromDocument(const Document&); > >- void refScriptExecutionContext() final { ref(); } >- void derefScriptExecutionContext() final { deref(); } >+ RefTrackingToken refScriptExecutionContext() final { return ref(); } >+ void derefScriptExecutionContext(RefTrackingToken token) final { deref(token); } > > // The following addMessage function is deprecated. > // Callers should try to create the ConsoleMessage themselves. >diff --git a/Source/WebCore/dom/ElementData.cpp b/Source/WebCore/dom/ElementData.cpp >index 9515305584ba41e6af47aa3944f1918bdcd2df82..01f53fe2cffe5f70da076d3ef94c9f1e8aaab2b7 100644 >--- a/Source/WebCore/dom/ElementData.cpp >+++ b/Source/WebCore/dom/ElementData.cpp >@@ -56,7 +56,9 @@ struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> { > void* refPtrs[3]; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small); >+#endif > > static size_t sizeForShareableElementDataWithAttributeCount(unsigned count) > { >diff --git a/Source/WebCore/dom/ElementData.h b/Source/WebCore/dom/ElementData.h >index f6d1eafd736b2aa826beb2b7fe054ffc2d59b653..2e0735e65d473a7a24a6e0e03db7d09632a81b1b 100644 >--- a/Source/WebCore/dom/ElementData.h >+++ b/Source/WebCore/dom/ElementData.h >@@ -80,7 +80,7 @@ class ElementData : public RefCounted<ElementData> { > public: > // Override RefCounted's deref() to ensure operator delete is called on > // the appropriate subclass type. >- void deref(); >+ void deref(RefTrackingToken); > > static const unsigned attributeNotFound = static_cast<unsigned>(-1); > >@@ -223,9 +223,9 @@ public: > AttributeVector m_attributeVector; > }; > >-inline void ElementData::deref() >+inline void ElementData::deref(RefTrackingToken token) > { >- if (!derefBase()) >+ if (!derefBase(token)) > return; > destroy(); > } >diff --git a/Source/WebCore/dom/ElementRareData.cpp b/Source/WebCore/dom/ElementRareData.cpp >index 6cfa8096d3f58407dd0a86cc73f8f7e0c360e579..93cec1a94c669764e050948e3e9a36990810e02c 100644 >--- a/Source/WebCore/dom/ElementRareData.cpp >+++ b/Source/WebCore/dom/ElementRareData.cpp >@@ -50,6 +50,8 @@ struct SameSizeAsElementRareData : NodeRareData { > > }; > >+#if !ENABLE(REF_TRACKING) > static_assert(sizeof(ElementRareData) == sizeof(SameSizeAsElementRareData), "ElementRareData should stay small"); >+#endif > > } // namespace WebCore >diff --git a/Source/WebCore/dom/EventTarget.h b/Source/WebCore/dom/EventTarget.h >index a3e9a47e916bc14430a18d776a7ac9b0f9a196f1..41a6ad0adf7fb7828418ad06bb8d0d2c6ce52a82 100644 >--- a/Source/WebCore/dom/EventTarget.h >+++ b/Source/WebCore/dom/EventTarget.h >@@ -52,8 +52,8 @@ public: > > class EventTarget : public ScriptWrappable { > public: >- void ref() { refEventTarget(); } >- void deref() { derefEventTarget(); } >+ RefTrackingToken ref() { return refEventTarget(); } >+ void deref(RefTrackingToken token) { derefEventTarget(token); } > > virtual EventTargetInterface eventTargetInterface() const = 0; > virtual ScriptExecutionContext* scriptExecutionContext() const = 0; >@@ -117,8 +117,8 @@ protected: > const EventTargetData* eventTargetData() const; > > private: >- virtual void refEventTarget() = 0; >- virtual void derefEventTarget() = 0; >+ virtual RefTrackingToken refEventTarget() = 0; >+ virtual void derefEventTarget(RefTrackingToken) = 0; > > void fireEventListeners(Event&, EventListenerVector); > >diff --git a/Source/WebCore/dom/MessagePort.cpp b/Source/WebCore/dom/MessagePort.cpp >index 188cc31febb787f94d474d1d661f187e5664499a..74be75ded3bea90340903f93a45305ea605ca117 100644 >--- a/Source/WebCore/dom/MessagePort.cpp >+++ b/Source/WebCore/dom/MessagePort.cpp >@@ -45,12 +45,13 @@ static HashMap<MessagePortIdentifier, MessagePort*>& allMessagePorts() > return map; > } > >-void MessagePort::ref() const >+RefTrackingToken MessagePort::ref() const > { > ++m_refCount; >+ return UntrackedRefToken(); > } > >-void MessagePort::deref() const >+void MessagePort::deref(RefTrackingToken) const > { > // This custom deref() function ensures that as long as the lock to allMessagePortsLock is taken, no MessagePort will be destroyed. > // This allows isExistingMessagePortLocallyReachable and notifyMessageAvailable to easily query the map and manipulate MessagePort instances. >diff --git a/Source/WebCore/dom/MessagePort.h b/Source/WebCore/dom/MessagePort.h >index 18ad62e583ceec482c182fa31bf2dfd4e9a0e828..c0088c08bd7e8753a1151432871504c1eb310483 100644 >--- a/Source/WebCore/dom/MessagePort.h >+++ b/Source/WebCore/dom/MessagePort.h >@@ -78,8 +78,8 @@ public: > const MessagePortIdentifier& identifier() const { return m_identifier; } > const MessagePortIdentifier& remoteIdentifier() const { return m_remoteIdentifier; } > >- WEBCORE_EXPORT void ref() const; >- WEBCORE_EXPORT void deref() const; >+ WEBCORE_EXPORT RefTrackingToken ref() const; >+ WEBCORE_EXPORT void deref(RefTrackingToken) const; > > // ActiveDOMObject > const char* activeDOMObjectName() const final; >@@ -93,8 +93,8 @@ public: > // EventTargetWithInlineData. > EventTargetInterface eventTargetInterface() const final { return MessagePortEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > private: > explicit MessagePort(ScriptExecutionContext&, const MessagePortIdentifier& local, const MessagePortIdentifier& remote); >diff --git a/Source/WebCore/dom/NamedNodeMap.cpp b/Source/WebCore/dom/NamedNodeMap.cpp >index 5b74a2b359884d25652fdee280af8f22670b52d0..8137089152909cdafb92fb3e16514f7918f1b844 100644 >--- a/Source/WebCore/dom/NamedNodeMap.cpp >+++ b/Source/WebCore/dom/NamedNodeMap.cpp >@@ -33,14 +33,14 @@ namespace WebCore { > > using namespace HTMLNames; > >-void NamedNodeMap::ref() >+RefTrackingToken NamedNodeMap::ref() > { >- m_element.ref(); >+ return m_element.ref(); > } > >-void NamedNodeMap::deref() >+void NamedNodeMap::deref(RefTrackingToken token) > { >- m_element.deref(); >+ m_element.deref(token); > } > > RefPtr<Attr> NamedNodeMap::getNamedItem(const AtomicString& name) const >diff --git a/Source/WebCore/dom/NamedNodeMap.h b/Source/WebCore/dom/NamedNodeMap.h >index 2cb596449980673793884a3b0a844b59d3c8c1b0..1fdf2ca39126830f7f57f11566de934fd2fa1f15 100644 >--- a/Source/WebCore/dom/NamedNodeMap.h >+++ b/Source/WebCore/dom/NamedNodeMap.h >@@ -40,8 +40,8 @@ public: > { > } > >- WEBCORE_EXPORT void ref(); >- WEBCORE_EXPORT void deref(); >+ WEBCORE_EXPORT RefTrackingToken ref(); >+ WEBCORE_EXPORT void deref(RefTrackingToken); > > WEBCORE_EXPORT unsigned length() const; > WEBCORE_EXPORT RefPtr<Attr> item(unsigned index) const; >diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp >index 2fb001a2bfd23ac5db8866219d10b53937fa9fa8..18e37bc1b6190a2d30d5e974b25199ca70724c6b 100644 >--- a/Source/WebCore/dom/Node.cpp >+++ b/Source/WebCore/dom/Node.cpp >@@ -748,14 +748,14 @@ LayoutRect Node::renderRect(bool* isReplaced) > return LayoutRect(); > } > >-void Node::refEventTarget() >+RefTrackingToken Node::refEventTarget() > { >- ref(); >+ return ref(); > } > >-void Node::derefEventTarget() >+void Node::derefEventTarget(RefTrackingToken token) > { >- deref(); >+ deref(token); > } > > void Node::adjustStyleValidity(Style::Validity validity, Style::InvalidationMode mode) >diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h >index 5c27f6b0679f41ac46e7828a7fad31352b5027ec..c2a2d57d2312c3e9e641f654265793a48045ca15 100644 >--- a/Source/WebCore/dom/Node.h >+++ b/Source/WebCore/dom/Node.h >@@ -36,6 +36,7 @@ > #include <wtf/IsoMalloc.h> > #include <wtf/ListHashSet.h> > #include <wtf/MainThread.h> >+#include <wtf/RefTracker.h> > > // This needs to be here because Document.h also depends on it. > #define DUMP_NODE_STATISTICS 0 >@@ -502,11 +503,17 @@ public: > // Perform the default action for an event. > virtual void defaultEventHandler(Event&); > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); >+ > bool hasOneRef() const; > int refCount() const; > >+#if ENABLE(REF_TRACKING) >+ const RefTracker& refTracker() const { return m_refTracker; } >+ RefTracker& refTracker() { return m_refTracker; } >+#endif >+ > #ifndef NDEBUG > bool m_deletionHasBegun { false }; > bool m_inRemovedLastRefFunction { false }; >@@ -648,8 +655,9 @@ private: > > WEBCORE_EXPORT void removedLastRef(); > >- void refEventTarget() final; >- void derefEventTarget() final; >+ RefTrackingToken refEventTarget() final; >+ void derefEventTarget(RefTrackingToken) final; >+ > bool isNode() const final; > > void trackForDebugging(); >@@ -678,35 +686,57 @@ private: > RenderObject* m_renderer; > NodeRareDataBase* m_rareData; > } m_data { nullptr }; >+ >+#if ENABLE(REF_TRACKING) >+ RefTracker m_refTracker; >+#endif > }; > >-#ifndef NDEBUG >-inline void adopted(Node* node) >+#if (!defined(NDEBUG) || ENABLE(REF_TRACKING)) >+inline RefTrackingToken adopted(Node* node) > { > if (!node) >- return; >+ return UntrackedRefToken(); > ASSERT(!node->m_deletionHasBegun); > ASSERT(!node->m_inRemovedLastRefFunction); >+#ifndef NDEBUG > node->m_adoptionIsRequired = false; >+#endif >+ >+#if ENABLE(REF_TRACKING) >+ return node->refTracker().trackRef(); >+#endif > } > #endif > >-ALWAYS_INLINE void Node::ref() >+ALWAYS_INLINE RefTrackingToken Node::ref() > { > ASSERT(isMainThread()); > ASSERT(!m_deletionHasBegun); > ASSERT(!m_inRemovedLastRefFunction); > ASSERT(!m_adoptionIsRequired); > ++m_refCount; >+#if ENABLE(REF_TRACKING) >+ return m_refTracker.trackRef(); >+#else >+ return UntrackedRefToken(); >+#endif > } > >-ALWAYS_INLINE void Node::deref() >+ALWAYS_INLINE void Node::deref(RefTrackingToken token) > { > ASSERT(isMainThread()); > ASSERT(m_refCount >= 0); > ASSERT(!m_deletionHasBegun); > ASSERT(!m_inRemovedLastRefFunction); > ASSERT(!m_adoptionIsRequired); >+ >+#if ENABLE(REF_TRACKING) >+ m_refTracker.trackDeref(token); >+#else >+ UNUSED_PARAM(token); >+#endif >+ > if (--m_refCount <= 0 && !parentNode()) { > #ifndef NDEBUG > m_inRemovedLastRefFunction = true; >diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp >index 488ab8e1ddba6c7dd1dbad2c98c0cdc790d287e0..185179f410424a1c4110dcea4fdd4484dbd9876d 100644 >--- a/Source/WebCore/dom/ScriptElement.cpp >+++ b/Source/WebCore/dom/ScriptElement.cpp >@@ -466,14 +466,14 @@ String ScriptElement::scriptContent() const > return TextNodeTraversal::childTextContent(m_element); > } > >-void ScriptElement::ref() >+RefTrackingToken ScriptElement::ref() > { >- m_element.ref(); >+ return m_element.ref(); > } > >-void ScriptElement::deref() >+void ScriptElement::deref(RefTrackingToken token) > { >- m_element.deref(); >+ m_element.deref(token); > } > > bool isScriptElement(Element& element) >diff --git a/Source/WebCore/dom/ScriptElement.h b/Source/WebCore/dom/ScriptElement.h >index a61dad45e9e444fa322e59822b4e8e6b1e8f6db7..c10a9ee69a90f59ccf2d18011d8e592b26dceade 100644 >--- a/Source/WebCore/dom/ScriptElement.h >+++ b/Source/WebCore/dom/ScriptElement.h >@@ -69,8 +69,8 @@ public: > enum class ScriptType { Classic, Module }; > ScriptType scriptType() const { return m_isModuleScript ? ScriptType::Module : ScriptType::Classic; } > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > protected: > ScriptElement(Element&, bool createdByParser, bool isEvaluated); >diff --git a/Source/WebCore/dom/ScriptExecutionContext.h b/Source/WebCore/dom/ScriptExecutionContext.h >index 3bdfcc80dbe6e6adad5877d1fee301127376d563..5d185ebe3012d72e10ce2a68ae1f003fb87cd7be 100644 >--- a/Source/WebCore/dom/ScriptExecutionContext.h >+++ b/Source/WebCore/dom/ScriptExecutionContext.h >@@ -157,8 +157,8 @@ public: > > virtual void didLoadResourceSynchronously(); > >- void ref() { refScriptExecutionContext(); } >- void deref() { derefScriptExecutionContext(); } >+ RefTrackingToken ref() { return refScriptExecutionContext(); } >+ void deref(RefTrackingToken token) { derefScriptExecutionContext(token); } > > class Task { > WTF_MAKE_FAST_ALLOCATED; >@@ -292,8 +292,8 @@ private: > virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) = 0; > bool dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception*, CachedScript*); > >- virtual void refScriptExecutionContext() = 0; >- virtual void derefScriptExecutionContext() = 0; >+ virtual RefTrackingToken refScriptExecutionContext() = 0; >+ virtual void derefScriptExecutionContext(RefTrackingToken) = 0; > > enum class ShouldContinue { No, Yes }; > void forEachActiveDOMObject(const Function<ShouldContinue(ActiveDOMObject&)>&) const; >diff --git a/Source/WebCore/dom/SpaceSplitString.h b/Source/WebCore/dom/SpaceSplitString.h >index 057fbfc47e8ebaae0c3a80fd2026fd7b312b0590..4a0258a1da841ba5025fb89baf79291184d0350f 100644 >--- a/Source/WebCore/dom/SpaceSplitString.h >+++ b/Source/WebCore/dom/SpaceSplitString.h >@@ -54,14 +54,15 @@ public: > return tokenArrayStart()[i]; > } > >- void ref() >+ RefTrackingToken ref() > { > ASSERT(isMainThread()); > ASSERT(m_refCount); > ++m_refCount; >+ return UntrackedRefToken(); > } > >- void deref() >+ void deref(RefTrackingToken) > { > ASSERT(isMainThread()); > ASSERT(m_refCount); >diff --git a/Source/WebCore/fileapi/FileReader.h b/Source/WebCore/fileapi/FileReader.h >index ef89f5bd6e012e5e4d058c30104439a72ef0ea6c..21bdbd0b7698c1d41f89b830e6d2f1f41251c4b1 100644 >--- a/Source/WebCore/fileapi/FileReader.h >+++ b/Source/WebCore/fileapi/FileReader.h >@@ -82,8 +82,8 @@ private: > > EventTargetInterface eventTargetInterface() const final { return FileReaderEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void didStartLoading() final; > void didReceiveData() final; >diff --git a/Source/WebCore/html/CanvasBase.h b/Source/WebCore/html/CanvasBase.h >index 5dfe29352e1534f6620c5366beb98441a1f472f7..af72d02d4c64b7e7f8daea367c6cb3b9ac1fed21 100644 >--- a/Source/WebCore/html/CanvasBase.h >+++ b/Source/WebCore/html/CanvasBase.h >@@ -53,8 +53,8 @@ class CanvasBase { > public: > virtual ~CanvasBase(); > >- virtual void refCanvasBase() = 0; >- virtual void derefCanvasBase() = 0; >+ virtual RefTrackingToken refCanvasBase() = 0; >+ virtual void derefCanvasBase(RefTrackingToken) = 0; > > virtual bool isHTMLCanvasElement() const { return false; } > virtual bool isOffscreenCanvas() const { return false; } >diff --git a/Source/WebCore/html/DOMTokenList.h b/Source/WebCore/html/DOMTokenList.h >index 3940f035eaeba02394e5a912b90c833baf4a9afb..e724596643b50300817518a22b30e72874ef7b30 100644 >--- a/Source/WebCore/html/DOMTokenList.h >+++ b/Source/WebCore/html/DOMTokenList.h >@@ -37,8 +37,8 @@ public: > > void associatedAttributeValueChanged(const AtomicString&); > >- void ref() { m_element.ref(); } >- void deref() { m_element.deref(); } >+ RefTrackingToken ref() { return m_element.ref(); } >+ void deref(RefTrackingToken token) { m_element.deref(token); } > > unsigned length() const; > const AtomicString& item(unsigned index) const; >diff --git a/Source/WebCore/html/FormAssociatedElement.h b/Source/WebCore/html/FormAssociatedElement.h >index 1275003fe097c751536f649a0aa1235cfef2d032..85600be88369447190ee0e263dd16325202ae120 100644 >--- a/Source/WebCore/html/FormAssociatedElement.h >+++ b/Source/WebCore/html/FormAssociatedElement.h >@@ -43,8 +43,8 @@ class FormAssociatedElement : public FormNamedItem { > public: > virtual ~FormAssociatedElement(); > >- void ref() { refFormAssociatedElement(); } >- void deref() { derefFormAssociatedElement(); } >+ RefTrackingToken ref() { return refFormAssociatedElement(); } >+ void deref(RefTrackingToken token) { derefFormAssociatedElement(token); } > > static HTMLFormElement* findAssociatedForm(const HTMLElement*, HTMLFormElement*); > HTMLFormElement* form() const { return m_form; } >@@ -109,8 +109,8 @@ protected: > > private: > virtual bool willValidate() const = 0; >- virtual void refFormAssociatedElement() = 0; >- virtual void derefFormAssociatedElement() = 0; >+ virtual RefTrackingToken refFormAssociatedElement() = 0; >+ virtual void derefFormAssociatedElement(RefTrackingToken) = 0; > > void resetFormAttributeTargetObserver(); > >diff --git a/Source/WebCore/html/FormController.cpp b/Source/WebCore/html/FormController.cpp >index 0f5b775bd02b3d1ce068ae035260aff154f5c22c..0df9744fa065d0ea97408c07e5b1146286a2c817 100644 >--- a/Source/WebCore/html/FormController.cpp >+++ b/Source/WebCore/html/FormController.cpp >@@ -92,8 +92,8 @@ public: > bool isHashTableDeletedValue() const { return m_name == hashTableDeletedValue(); } > > private: >- void ref() const; >- void deref() const; >+ RefTrackingToken ref() const; >+ void deref(RefTrackingToken) const; > > static AtomicStringImpl* hashTableDeletedValue() { return reinterpret_cast<AtomicStringImpl*>(-1); } > >@@ -110,7 +110,8 @@ FormElementKey::FormElementKey(AtomicStringImpl* name, AtomicStringImpl* type) > > FormElementKey::~FormElementKey() > { >- deref(); >+ // FIXME: This is weird. Normally trying to call deref() in a destructor would cause that destructor to never be called. >+ deref(UntrackedRefToken()); > } > > FormElementKey::FormElementKey(const FormElementKey& other) >@@ -123,26 +124,27 @@ FormElementKey::FormElementKey(const FormElementKey& other) > FormElementKey& FormElementKey::operator=(const FormElementKey& other) > { > other.ref(); >- deref(); >+ deref(UntrackedRefToken()); > m_name = other.name(); > m_type = other.type(); > return *this; > } > >-void FormElementKey::ref() const >+RefTrackingToken FormElementKey::ref() const > { > if (name()) > name()->ref(); > if (type()) > type()->ref(); >+ return UntrackedRefToken(); > } > >-void FormElementKey::deref() const >+void FormElementKey::deref(RefTrackingToken) const > { > if (name()) >- name()->deref(); >+ name()->deref(UntrackedRefToken()); > if (type()) >- type()->deref(); >+ type()->deref(UntrackedRefToken()); > } > > inline bool operator==(const FormElementKey& a, const FormElementKey& b) >diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h >index f88d6112de29ee0e01b7648d17136dd6816470de..40c0066d2000fa7ff6f34003a1a3d5a0bd4e6d61 100644 >--- a/Source/WebCore/html/HTMLCanvasElement.h >+++ b/Source/WebCore/html/HTMLCanvasElement.h >@@ -176,8 +176,8 @@ private: > > bool isGPUBased() const; > >- void refCanvasBase() final { HTMLElement::ref(); } >- void derefCanvasBase() final { HTMLElement::deref(); } >+ RefTrackingToken refCanvasBase() final { return HTMLElement::ref(); } >+ void derefCanvasBase(RefTrackingToken token) final { HTMLElement::deref(token); } > > FloatRect m_dirtyRect; > mutable IntSize m_size; >diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h >index d876573a298b2d6ceb7de9151a81ca2d45c45e6c..d818a08ef875a89889e01c1a5d7e7fbe8e0d0a2e 100644 >--- a/Source/WebCore/html/HTMLFormControlElement.h >+++ b/Source/WebCore/html/HTMLFormControlElement.h >@@ -159,8 +159,8 @@ protected: > void didChangeForm() override; > > private: >- void refFormAssociatedElement() override { ref(); } >- void derefFormAssociatedElement() override { deref(); } >+ RefTrackingToken refFormAssociatedElement() override { return ref(); } >+ void derefFormAssociatedElement(RefTrackingToken token) override { deref(token); } > > bool matchesValidPseudoClass() const override; > bool matchesInvalidPseudoClass() const override; >diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp >index 3019e096b693d58eaa54e6af66ceab91ce5be5db..c8dfe3d42086cfeb1f0d79e6b779c82705845455 100644 >--- a/Source/WebCore/html/HTMLMediaElement.cpp >+++ b/Source/WebCore/html/HTMLMediaElement.cpp >@@ -461,6 +461,8 @@ static uint64_t nextLogIdentifier() > } > #endif > >+static int HTMLMediaElementCount; >+ > HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser) > : HTMLElement(tagName, document) > , ActiveDOMObject(&document) >@@ -516,6 +518,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum > , m_logIdentifier(nextLogIdentifier()) > #endif > { >+ WTFLogAlways("HTMLMediaElement ctor %p - count %d", this, ++HTMLMediaElementCount); > allMediaElements().add(this); > > ALWAYS_LOG(LOGIDENTIFIER); >@@ -697,6 +700,8 @@ HTMLMediaElement::~HTMLMediaElement() > > m_mediaSession = nullptr; > schedulePlaybackControlsManagerUpdate(); >+ >+ WTFLogAlways("HTMLMediaElement dtor %p - count %d", this, --HTMLMediaElementCount); > } > > static bool needsAutoplayPlayPauseEventsQuirk(const Document& document) >diff --git a/Source/WebCore/html/HTMLObjectElement.h b/Source/WebCore/html/HTMLObjectElement.h >index 82f582dfd78a9cdc17ba968799b551b20cceb99a..6bd6245496c9111a97873fb8493f36d5b22b8e31 100644 >--- a/Source/WebCore/html/HTMLObjectElement.h >+++ b/Source/WebCore/html/HTMLObjectElement.h >@@ -88,8 +88,8 @@ private: > bool shouldAllowQuickTimeClassIdQuirk(); > bool hasValidClassId(); > >- void refFormAssociatedElement() final { ref(); } >- void derefFormAssociatedElement() final { deref(); } >+ RefTrackingToken refFormAssociatedElement() final { return ref(); } >+ void derefFormAssociatedElement(RefTrackingToken token) final { deref(token); } > > FormNamedItem* asFormNamedItem() final { return this; } > HTMLObjectElement& asHTMLElement() final { return *this; } >diff --git a/Source/WebCore/html/MediaController.h b/Source/WebCore/html/MediaController.h >index 738cb5414ccc016687a0cccbe254abca4d7a17aa..95ca8e1576225d6556cdd1652dd98391f8092a94 100644 >--- a/Source/WebCore/html/MediaController.h >+++ b/Source/WebCore/html/MediaController.h >@@ -91,8 +91,8 @@ private: > void scheduleTimeupdateEvent(); > void startTimeupdateTimer(); > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > EventTargetInterface eventTargetInterface() const final { return MediaControllerEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return &m_scriptExecutionContext; }; > >diff --git a/Source/WebCore/html/OffscreenCanvas.h b/Source/WebCore/html/OffscreenCanvas.h >index c272ed6e999f8c0209b474b676a840da0e68926c..89388a05e09270c48e76787e2705ab26f61e8bb2 100644 >--- a/Source/WebCore/html/OffscreenCanvas.h >+++ b/Source/WebCore/html/OffscreenCanvas.h >@@ -87,11 +87,11 @@ private: > ScriptExecutionContext* scriptExecutionContext() const final { return CanvasBase::scriptExecutionContext(); } > > EventTargetInterface eventTargetInterface() const final { return OffscreenCanvasEventTargetInterfaceType; } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > >- void refCanvasBase() final { ref(); } >- void derefCanvasBase() final { deref(); } >+ RefTrackingToken refCanvasBase() final { return ref(); } >+ void derefCanvasBase(RefTrackingToken token) final { deref(token); } > > IntSize m_size; > }; >diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp >index c34610215e569fe7aa119ca5216a7d83e1556229..5de4a9f1b3d248d4d5a5135af92f3e5f849d26bf 100644 >--- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp >+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp >@@ -44,14 +44,14 @@ CanvasRenderingContext::CanvasRenderingContext(CanvasBase& canvas) > { > } > >-void CanvasRenderingContext::ref() >+RefTrackingToken CanvasRenderingContext::ref() > { >- m_canvas.refCanvasBase(); >+ return m_canvas.refCanvasBase(); > } > >-void CanvasRenderingContext::deref() >+void CanvasRenderingContext::deref(RefTrackingToken token) > { >- m_canvas.derefCanvasBase(); >+ m_canvas.derefCanvasBase(token); > } > > bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern) >diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h >index 81cb55d77e31805644707777a1e29956f443f658..d6ce72267cf44be230b10ec91e4c050170db6f6c 100644 >--- a/Source/WebCore/html/canvas/CanvasRenderingContext.h >+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h >@@ -46,8 +46,8 @@ class CanvasRenderingContext : public ScriptWrappable { > public: > virtual ~CanvasRenderingContext() = default; > >- void ref(); >- WEBCORE_EXPORT void deref(); >+ RefTrackingToken ref(); >+ WEBCORE_EXPORT void deref(RefTrackingToken); > > CanvasBase& canvasBase() const { return m_canvas; } > >diff --git a/Source/WebCore/html/canvas/WebGLExtension.h b/Source/WebCore/html/canvas/WebGLExtension.h >index 0f601fa82ffd826750e195042c548f49a5ffc287..f74702a7e16b4c6a3e1658c2fed1d32f99a873c7 100644 >--- a/Source/WebCore/html/canvas/WebGLExtension.h >+++ b/Source/WebCore/html/canvas/WebGLExtension.h >@@ -58,8 +58,9 @@ public: > ANGLEInstancedArraysName, > }; > >- void ref() { m_context.ref(); } >- void deref() { m_context.deref(); } >+ RefTrackingToken ref() { return m_context.ref(); } >+ void deref(RefTrackingToken token) { m_context.deref(token); } >+ > WebGLRenderingContextBase& context() { return m_context; } > > virtual ~WebGLExtension(); >diff --git a/Source/WebCore/html/track/TextTrack.h b/Source/WebCore/html/track/TextTrack.h >index a7ef715a520b28997e0f8f6b3f2c3fb24ac3493d..cab4f2850aaf5949367de08ade6c1a6d57d94b80 100644 >--- a/Source/WebCore/html/track/TextTrack.h >+++ b/Source/WebCore/html/track/TextTrack.h >@@ -156,8 +156,8 @@ protected: > private: > bool enabled() const override; > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > VTTRegionList& ensureVTTRegionList(); > RefPtr<VTTRegionList> m_regions; >diff --git a/Source/WebCore/html/track/TextTrackCue.h b/Source/WebCore/html/track/TextTrackCue.h >index cfee47d844a47d4fb15ae5436f326717354bd76b..482b95096b5354945edb38a46a7648fb76514067 100644 >--- a/Source/WebCore/html/track/TextTrackCue.h >+++ b/Source/WebCore/html/track/TextTrackCue.h >@@ -98,8 +98,8 @@ protected: > virtual void toJSON(JSON::Object&) const; > > private: >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > using EventTarget::dispatchEvent; > void dispatchEvent(Event&) final; >diff --git a/Source/WebCore/html/track/TrackListBase.h b/Source/WebCore/html/track/TrackListBase.h >index fdae3b0de185cc8cb64bf954dbbe12704f3b32ae..d555b41777d7bc99ee92e04d0aaf029d289c4df1 100644 >--- a/Source/WebCore/html/track/TrackListBase.h >+++ b/Source/WebCore/html/track/TrackListBase.h >@@ -80,8 +80,8 @@ private: > void stop() final; > > // EventTarget >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > HTMLMediaElement* m_element; > >diff --git a/Source/WebCore/loader/DocumentThreadableLoader.h b/Source/WebCore/loader/DocumentThreadableLoader.h >index 38382edf4cdd31ea21f546bd7da6481acb17eb19..2e6e9b237435fc51861f88ddc3882903dcd63cd7 100644 >--- a/Source/WebCore/loader/DocumentThreadableLoader.h >+++ b/Source/WebCore/loader/DocumentThreadableLoader.h >@@ -66,8 +66,8 @@ namespace WebCore { > using RefCounted<DocumentThreadableLoader>::deref; > > protected: >- void refThreadableLoader() override { ref(); } >- void derefThreadableLoader() override { deref(); } >+ RefTrackingToken refThreadableLoader() override { return ref(); } >+ void derefThreadableLoader(RefTrackingToken token) override { deref(token); } > > private: > enum BlockingBehavior { >diff --git a/Source/WebCore/loader/ThreadableLoader.h b/Source/WebCore/loader/ThreadableLoader.h >index 861748b7c7b5b32757889c0f1a3ce0520fddcced..031461ec1ed4d733f8868f184f11499b8d4c35b2 100644 >--- a/Source/WebCore/loader/ThreadableLoader.h >+++ b/Source/WebCore/loader/ThreadableLoader.h >@@ -77,16 +77,16 @@ namespace WebCore { > static RefPtr<ThreadableLoader> create(ScriptExecutionContext&, ThreadableLoaderClient&, ResourceRequest&&, const ThreadableLoaderOptions&, String&& referrer = String()); > > virtual void cancel() = 0; >- void ref() { refThreadableLoader(); } >- void deref() { derefThreadableLoader(); } >+ RefTrackingToken ref() { return refThreadableLoader(); } >+ void deref(RefTrackingToken token) { derefThreadableLoader(token); } > > static void logError(ScriptExecutionContext&, const ResourceError&, const String&); > > protected: > ThreadableLoader() = default; > virtual ~ThreadableLoader() = default; >- virtual void refThreadableLoader() = 0; >- virtual void derefThreadableLoader() = 0; >+ virtual RefTrackingToken refThreadableLoader() = 0; >+ virtual void derefThreadableLoader(RefTrackingToken) = 0; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/loader/WorkerThreadableLoader.h b/Source/WebCore/loader/WorkerThreadableLoader.h >index 03c1673b13f2f8b7d4b75cb41925887383f48975..741c9ca48ab6c2eaafc36ffd0859a71130b33e73 100644 >--- a/Source/WebCore/loader/WorkerThreadableLoader.h >+++ b/Source/WebCore/loader/WorkerThreadableLoader.h >@@ -64,8 +64,8 @@ namespace WebCore { > using RefCounted<WorkerThreadableLoader>::deref; > > protected: >- void refThreadableLoader() override { ref(); } >- void derefThreadableLoader() override { deref(); } >+ RefTrackingToken refThreadableLoader() override { return ref(); } >+ void derefThreadableLoader(RefTrackingToken token) override { deref(token); } > > private: > // Creates a loader on the main thread and bridges communication between >diff --git a/Source/WebCore/loader/appcache/DOMApplicationCache.h b/Source/WebCore/loader/appcache/DOMApplicationCache.h >index cf6d2a9d99f7068c06cc2f4a27111e2dcdc1e675..b77f9294e84349ebfc875b177b7cea81cb53ddee 100644 >--- a/Source/WebCore/loader/appcache/DOMApplicationCache.h >+++ b/Source/WebCore/loader/appcache/DOMApplicationCache.h >@@ -49,8 +49,8 @@ public: > private: > explicit DOMApplicationCache(Frame&); > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > EventTargetInterface eventTargetInterface() const final { return DOMApplicationCacheEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final; >diff --git a/Source/WebCore/page/AbstractDOMWindow.h b/Source/WebCore/page/AbstractDOMWindow.h >index 49917c83ae620d923ba768ed39f982b8a5b12152..a439dc4484fd1d34584e4e8bf4864e617e0876c9 100644 >--- a/Source/WebCore/page/AbstractDOMWindow.h >+++ b/Source/WebCore/page/AbstractDOMWindow.h >@@ -61,8 +61,8 @@ protected: > explicit AbstractDOMWindow(GlobalWindowIdentifier&&); > > EventTargetInterface eventTargetInterface() const final { return DOMWindowEventTargetInterfaceType; } >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > private: > GlobalWindowIdentifier m_identifier; >diff --git a/Source/WebCore/page/EventSource.h b/Source/WebCore/page/EventSource.h >index 3792a9126f1d30affe37be1c2a6dac78216a729a..47d9f03d5a2d1e5f765eef4730c059d9ac924162 100644 >--- a/Source/WebCore/page/EventSource.h >+++ b/Source/WebCore/page/EventSource.h >@@ -75,8 +75,8 @@ private: > EventTargetInterface eventTargetInterface() const final { return EventSourceEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > // ThreadableLoaderClient > void didReceiveResponse(unsigned long, const ResourceResponse&) final; >diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp >index 2b87d607105112431b39e908602647246cb7fdd7..63cd8b20407e303df3eb605f9fe4c394cbe8c254 100644 >--- a/Source/WebCore/page/Frame.cpp >+++ b/Source/WebCore/page/Frame.cpp >@@ -1138,7 +1138,7 @@ void Frame::selfOnlyDeref() > if (hasOneRef()) > dropChildren(); > >- deref(); >+ deref(UntrackedRefToken()); > } > > } // namespace WebCore >diff --git a/Source/WebCore/page/Performance.h b/Source/WebCore/page/Performance.h >index 24ab94bca295ccafb0a651a6270b287945eba991..d16fd6ecb9d87d740fd1af85015d8cddc2c3ff5f 100644 >--- a/Source/WebCore/page/Performance.h >+++ b/Source/WebCore/page/Performance.h >@@ -97,8 +97,8 @@ private: > > EventTargetInterface eventTargetInterface() const final { return PerformanceEventTargetInterfaceType; } > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > bool isResourceTimingBufferFull() const; > void resourceTimingBufferFullTimerFired(); >diff --git a/Source/WebCore/page/VisualViewport.h b/Source/WebCore/page/VisualViewport.h >index 47727d35aca5919c5abf3311508711e95b64c23d..a15446d0b99e676e2a748971a4bdc156f3490ae7 100644 >--- a/Source/WebCore/page/VisualViewport.h >+++ b/Source/WebCore/page/VisualViewport.h >@@ -58,8 +58,8 @@ public: > private: > explicit VisualViewport(Frame*); > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void enqueueResizeEvent(); > void enqueueScrollEvent(); >diff --git a/Source/WebCore/platform/Length.cpp b/Source/WebCore/platform/Length.cpp >index 2982852824b583415f6ccc63880e86e19523c4da..d9ba00e835a06ea7250fea5cd129b3fcea845f6d 100644 >--- a/Source/WebCore/platform/Length.cpp >+++ b/Source/WebCore/platform/Length.cpp >@@ -259,13 +259,14 @@ CalculationValue& Length::calculationValue() const > return calculationValues().get(m_calculationValueHandle); > } > >-void Length::ref() const >+RefTrackingToken Length::ref() const > { > ASSERT(isCalculated()); > calculationValues().ref(m_calculationValueHandle); >+ return UntrackedRefToken(); > } > >-void Length::deref() const >+void Length::deref(RefTrackingToken) const > { > ASSERT(isCalculated()); > calculationValues().deref(m_calculationValueHandle); >diff --git a/Source/WebCore/platform/Length.h b/Source/WebCore/platform/Length.h >index bf14421af35f79d7e40fd3cdf4adfc43a57cdeaf..b7820de81129f4ec64bf25c7edd3c179d2907ab7 100644 >--- a/Source/WebCore/platform/Length.h >+++ b/Source/WebCore/platform/Length.h >@@ -123,8 +123,8 @@ private: > > bool isCalculatedEqual(const Length&) const; > >- WEBCORE_EXPORT void ref() const; >- WEBCORE_EXPORT void deref() const; >+ WEBCORE_EXPORT RefTrackingToken ref() const; >+ WEBCORE_EXPORT void deref(RefTrackingToken) const; > > union { > int m_intValue; >@@ -194,7 +194,7 @@ inline Length& Length::operator=(const Length& other) > if (other.isCalculated()) > other.ref(); > if (isCalculated()) >- deref(); >+ deref(UntrackedRefToken()); > > memcpy(static_cast<void*>(this), static_cast<void*>(const_cast<Length*>(&other)), sizeof(Length)); > return *this; >@@ -206,7 +206,7 @@ inline Length& Length::operator=(Length&& other) > return *this; > > if (isCalculated()) >- deref(); >+ deref(UntrackedRefToken()); > > memcpy(static_cast<void*>(this), static_cast<void*>(&other), sizeof(Length)); > other.m_type = Auto; >@@ -216,7 +216,7 @@ inline Length& Length::operator=(Length&& other) > inline Length::~Length() > { > if (isCalculated()) >- deref(); >+ deref(UntrackedRefToken()); > } > > inline bool Length::operator==(const Length& other) const >diff --git a/Source/WebCore/platform/ScrollableArea.cpp b/Source/WebCore/platform/ScrollableArea.cpp >index 7b1d359dbc6368520c92f4cd2b23067d64660f7b..f18c6350174b72491206183c4a027aeb97e0c0d7 100644 >--- a/Source/WebCore/platform/ScrollableArea.cpp >+++ b/Source/WebCore/platform/ScrollableArea.cpp >@@ -57,7 +57,9 @@ struct SameSizeAsScrollableArea { > unsigned bitfields : 16; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(ScrollableArea) == sizeof(SameSizeAsScrollableArea), ScrollableArea_should_stay_small); >+#endif > > ScrollableArea::ScrollableArea() > : m_constrainsScrollingToContentEdge(true) >diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp >index 5ef11b08e70aa4ffc967686b44fca9bb5671c218..e475fe231b57b39fe4ef13dedfe0732f38bf2d2a 100644 >--- a/Source/WebCore/platform/graphics/Color.cpp >+++ b/Source/WebCore/platform/graphics/Color.cpp >@@ -314,7 +314,7 @@ Color& Color::operator=(const Color& other) > return *this; > > if (isExtended()) >- m_colorData.extendedColor->deref(); >+ m_colorData.extendedColor->deref(UntrackedRefToken()); > > m_colorData = other.m_colorData; > >@@ -329,7 +329,7 @@ Color& Color::operator=(Color&& other) > return *this; > > if (isExtended()) >- m_colorData.extendedColor->deref(); >+ m_colorData.extendedColor->deref(UntrackedRefToken()); > > m_colorData = other.m_colorData; > other.m_colorData.rgbaAndFlags = invalidRGBAColor; >diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h >index 66609cc2d40cf2803ee54d72457b4be8f393469d..65838264c625288d83686902d83edf84ffa5748b 100644 >--- a/Source/WebCore/platform/graphics/Color.h >+++ b/Source/WebCore/platform/graphics/Color.h >@@ -185,7 +185,7 @@ public: > ~Color() > { > if (isExtended()) >- m_colorData.extendedColor->deref(); >+ m_colorData.extendedColor->deref(UntrackedRefToken()); > } > > static Color createUnchecked(int r, int g, int b) >diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm >index 968fc5a087f311d88b239e676948949213b4cba6..9f967341dfd965bbaf7e9dfbe6ed494aadbcd5cc 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm >+++ b/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm >@@ -236,7 +236,7 @@ MediaPlayer::SupportsType MediaPlayerPrivateMediaSourceAVFObjC::supportsType(con > return MediaPlayer::IsNotSupported; > > NSString *typeString = [NSString stringWithFormat:@"%@; codecs=\"%@\"", (NSString *)parameters.type.containerType(), (NSString *)outputCodecs]; >- return [getAVURLAssetClass() isPlayableExtendedMIMEType:typeString] ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported;; >+ return [getAVURLAssetClass() isPlayableExtendedMIMEType:typeString] ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported; > } > > #pragma mark - >diff --git a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp >index 61a0369f5df165d3ec4d0b48f2da3faef078e613..a69b89d4b7a77d496020e7e483358fe78a2361e9 100644 >--- a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp >+++ b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp >@@ -30,98 +30,114 @@ > > namespace WTF { > >-template<> void refIfNotNull(cairo_t* ptr) >+template<> RefTrackingToken refIfNotNull(cairo_t* ptr) > { > if (LIKELY(ptr)) > cairo_reference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(cairo_t* ptr) >+template<> void derefIfNotNull(cairo_t* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > cairo_destroy(ptr); > } > >-template<> void refIfNotNull(cairo_surface_t* ptr) >+template<> RefTrackingToken refIfNotNull(cairo_surface_t* ptr) > { > if (LIKELY(ptr)) > cairo_surface_reference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(cairo_surface_t* ptr) >+template<> void derefIfNotNull(cairo_surface_t* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > cairo_surface_destroy(ptr); > } > >-template<> void refIfNotNull(cairo_font_face_t* ptr) >+template<> RefTrackingToken refIfNotNull(cairo_font_face_t* ptr) > { > if (LIKELY(ptr)) > cairo_font_face_reference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(cairo_font_face_t* ptr) >+template<> void derefIfNotNull(cairo_font_face_t* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > cairo_font_face_destroy(ptr); > } > >-template<> void refIfNotNull(cairo_scaled_font_t* ptr) >+template<> RefTrackingToken refIfNotNull(cairo_scaled_font_t* ptr) > { > if (LIKELY(ptr)) > cairo_scaled_font_reference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(cairo_scaled_font_t* ptr) >+template<> void derefIfNotNull(cairo_scaled_font_t* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > cairo_scaled_font_destroy(ptr); > } > >-template<> void refIfNotNull(cairo_pattern_t* ptr) >+template<> RefTrackingToken refIfNotNull(cairo_pattern_t* ptr) > { > if (LIKELY(ptr)) > cairo_pattern_reference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(cairo_pattern_t* ptr) >+template<> void derefIfNotNull(cairo_pattern_t* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > cairo_pattern_destroy(ptr); > } > >-template<> void refIfNotNull(cairo_region_t* ptr) >+template<> RefTrackingToken refIfNotNull(cairo_region_t* ptr) > { > if (LIKELY(ptr)) > cairo_region_reference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(cairo_region_t* ptr) >+template<> void derefIfNotNull(cairo_region_t* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > cairo_region_destroy(ptr); > } > > #if USE(FREETYPE) >-template<> void refIfNotNull(FcPattern* ptr) >+template<> RefTrackingToken refIfNotNull(FcPattern* ptr) > { > if (LIKELY(ptr)) > FcPatternReference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(FcPattern* ptr) >+template<> void derefIfNotNull(FcPattern* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > FcPatternDestroy(ptr); > } > >-template<> void refIfNotNull(FcConfig* ptr) >+template<> RefTrackingToken refIfNotNull(FcConfig* ptr) > { > if (LIKELY(ptr)) > FcConfigReference(ptr); >+ >+ return UntrackedRefToken(); > } > >-template<> void derefIfNotNull(FcConfig* ptr) >+template<> void derefIfNotNull(FcConfig* ptr, RefTrackingToken) > { > if (LIKELY(ptr)) > FcConfigDestroy(ptr); >diff --git a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h >index 23e8819eed1518f9c241bd4eedbf2b3325e8a13c..518b514674bfb0b54d007359cda06f0bcf644248 100644 >--- a/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h >+++ b/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h >@@ -38,30 +38,30 @@ typedef struct _FcConfig FcConfig; > > namespace WTF { > >-template<> void refIfNotNull(cairo_t* ptr); >-template<> WEBCORE_EXPORT void derefIfNotNull(cairo_t* ptr); >+template<> RefTrackingToken refIfNotNull(cairo_t* ptr); >+template<> WEBCORE_EXPORT void derefIfNotNull(cairo_t* ptr, RefTrackingToken); > >-template<> void refIfNotNull(cairo_surface_t* ptr); >-template<> WEBCORE_EXPORT void derefIfNotNull(cairo_surface_t* ptr); >+template<> RefTrackingToken refIfNotNull(cairo_surface_t* ptr); >+template<> WEBCORE_EXPORT void derefIfNotNull(cairo_surface_t* ptr, RefTrackingToken); > >-template<> void refIfNotNull(cairo_font_face_t* ptr); >-template<> void derefIfNotNull(cairo_font_face_t* ptr); >+template<> RefTrackingToken refIfNotNull(cairo_font_face_t* ptr); >+template<> void derefIfNotNull(cairo_font_face_t* ptr, RefTrackingToken); > >-template<> void refIfNotNull(cairo_scaled_font_t* ptr); >-template<> void derefIfNotNull(cairo_scaled_font_t* ptr); >+template<> RefTrackingToken refIfNotNull(cairo_scaled_font_t* ptr); >+template<> void derefIfNotNull(cairo_scaled_font_t* ptr, RefTrackingToken); > >-template<> void refIfNotNull(cairo_pattern_t*); >-template<> void derefIfNotNull(cairo_pattern_t*); >+template<> RefTrackingToken refIfNotNull(cairo_pattern_t*); >+template<> void derefIfNotNull(cairo_pattern_t*, RefTrackingToken); > >-template<> void refIfNotNull(cairo_region_t*); >-template<> void derefIfNotNull(cairo_region_t*); >+template<> RefTrackingToken refIfNotNull(cairo_region_t*); >+template<> void derefIfNotNull(cairo_region_t*, RefTrackingToken); > > #if USE(FREETYPE) >-template<> void refIfNotNull(FcPattern* ptr); >-template<> void derefIfNotNull(FcPattern* ptr); >+template<> RefTrackingToken refIfNotNull(FcPattern* ptr); >+template<> void derefIfNotNull(FcPattern* ptr, RefTrackingToken); > >-template<> void refIfNotNull(FcConfig* ptr); >-template<> void derefIfNotNull(FcConfig* ptr); >+template<> RefTrackingToken refIfNotNull(FcConfig* ptr); >+template<> void derefIfNotNull(FcConfig* ptr, RefTrackingToken); > #endif > > } // namespace WTF >diff --git a/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp b/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp >index b7d592a9c8a25d70d37f519f5137c42d3a331aee..2e4f036c250515bda4db9bcbc727053e1d8279b1 100644 >--- a/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp >+++ b/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp >@@ -139,7 +139,7 @@ size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, > void sharedBufferRelease(void* info) > { > SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info); >- sharedBuffer->deref(); >+ sharedBuffer->deref(UntrackedRefToken()); > } > #endif > >diff --git a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp >index 53625df7acf4c45d75713cee0967c13c77a4eb87..50883eb29b4c3a073023d8342111029f2114f970 100644 >--- a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp >+++ b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp >@@ -33,7 +33,7 @@ namespace WebCore { > > static void releaseCustomFontData(void* data) > { >- static_cast<SharedBuffer*>(data)->deref(); >+ static_cast<SharedBuffer*>(data)->deref(UntrackedRefToken()); > } > > FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer& buffer) >diff --git a/Source/WebCore/platform/graphics/metal/GPUBufferMetal.mm b/Source/WebCore/platform/graphics/metal/GPUBufferMetal.mm >index 4a119c7d9f4fc59e6c964d2fbea03b2753ccbbcd..eb9f88d186e9e649b2b08fc414d3d2b0b6bf18c3 100644 >--- a/Source/WebCore/platform/graphics/metal/GPUBufferMetal.mm >+++ b/Source/WebCore/platform/graphics/metal/GPUBufferMetal.mm >@@ -56,10 +56,10 @@ GPUBuffer::GPUBuffer(const GPUDevice& device, const JSC::ArrayBufferView& data) > m_contents->ref(); > ArrayBuffer* capturedContents = m_contents.get(); > m_metal = adoptNS([device.metal() newBufferWithBytesNoCopy:m_contents->data() length:pageAlignedSize options:MTLResourceOptionCPUCacheModeDefault deallocator:^(void*, NSUInteger) { >- capturedContents->deref(); >+ capturedContents->deref(UntrackedRefToken()); > }]); > if (!m_metal) { >- m_contents->deref(); >+ m_contents->deref(UntrackedRefToken()); > m_contents = nullptr; > } > } >diff --git a/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaPaintingContextCairo.cpp b/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaPaintingContextCairo.cpp >index 0c8a670e3a0a36307e3f299ecda02552fd774ed1..fde99950ff362b5b0b02994521cf5673cc326fc4 100644 >--- a/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaPaintingContextCairo.cpp >+++ b/Source/WebCore/platform/graphics/nicosia/cairo/NicosiaPaintingContextCairo.cpp >@@ -59,7 +59,7 @@ PaintingContextCairo::ForPainting::ForPainting(Buffer& buffer) > auto* userData = static_cast<std::pair<Buffer*, ForPainting*>*>(data); > > // Deref the Buffer object. >- userData->first->deref(); >+ userData->first->deref(UntrackedRefToken()); > #if !ASSERT_DISABLED > // Mark the deletion of the cairo_surface_t object associated with this > // PaintingContextCairo as complete. This way we check that the cairo_surface_t >diff --git a/Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp b/Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp >index e8270b0e97f28d52753b3671446fbaf6bddbb03f..7baaf0a3efa83d3792f7e188a3f34f446e691338 100644 >--- a/Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp >+++ b/Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp >@@ -37,7 +37,7 @@ NativeImagePtr ImageBackingStore::image() const > reinterpret_cast<unsigned char*>(const_cast<uint32_t*>(m_pixelsPtr)), > CAIRO_FORMAT_ARGB32, size().width(), size().height(), size().width() * sizeof(uint32_t))); > static cairo_user_data_key_t s_surfaceDataKey; >- cairo_surface_set_user_data(surface.get(), &s_surfaceDataKey, m_pixels.get(), [](void* data) { static_cast<SharedBuffer*>(data)->deref(); }); >+ cairo_surface_set_user_data(surface.get(), &s_surfaceDataKey, m_pixels.get(), [](void* data) { static_cast<SharedBuffer*>(data)->deref(UntrackedRefToken()); }); > > return surface; > } >diff --git a/Source/WebCore/platform/mediastream/RealtimeOutgoingAudioSource.h b/Source/WebCore/platform/mediastream/RealtimeOutgoingAudioSource.h >index ea457f7d53350afd1844ef3cf43211f8332956f4..d59a34cf9d2c0e4c2537ac8a602bd5f1a28523c3 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeOutgoingAudioSource.h >+++ b/Source/WebCore/platform/mediastream/RealtimeOutgoingAudioSource.h >@@ -79,7 +79,7 @@ private: > rtc::RefCountReleaseStatus Release() const final > { > callOnMainThread([this] { >- deref(); >+ deref(UntrackedRefToken()); > }); > return rtc::RefCountReleaseStatus::kOtherRefsRemained; > } >diff --git a/Source/WebCore/platform/mediastream/RealtimeOutgoingVideoSource.h b/Source/WebCore/platform/mediastream/RealtimeOutgoingVideoSource.h >index 548ea3f01d807e87ce11d30e6cbcdb702f9155e1..51de772dd0ecd972e17e4453b78ddc0604a174c7 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeOutgoingVideoSource.h >+++ b/Source/WebCore/platform/mediastream/RealtimeOutgoingVideoSource.h >@@ -59,7 +59,7 @@ public: > void AddRef() const final { ref(); } > rtc::RefCountReleaseStatus Release() const final > { >- deref(); >+ deref(UntrackedRefToken()); > return rtc::RefCountReleaseStatus::kOtherRefsRemained; > } > >diff --git a/Source/WebCore/platform/network/AuthenticationClient.h b/Source/WebCore/platform/network/AuthenticationClient.h >index 19f8bcd7c68ad8026229bed6eefdc43cf5cf6aff..976d5b132b951effcd2d0880ab46fe3b49f9012a 100644 >--- a/Source/WebCore/platform/network/AuthenticationClient.h >+++ b/Source/WebCore/platform/network/AuthenticationClient.h >@@ -26,6 +26,8 @@ > #ifndef AuthenticationClient_h > #define AuthenticationClient_h > >+#include <wtf/RefTracking.h> >+ > namespace WebCore { > > class AuthenticationChallenge; >@@ -39,15 +41,15 @@ public: > virtual void receivedRequestToPerformDefaultHandling(const AuthenticationChallenge&) = 0; > virtual void receivedChallengeRejection(const AuthenticationChallenge&) = 0; > >- void ref() { refAuthenticationClient(); } >- void deref() { derefAuthenticationClient(); } >+ RefTrackingToken ref() { return refAuthenticationClient(); } >+ void deref(RefTrackingToken token) { derefAuthenticationClient(token); } > > protected: > virtual ~AuthenticationClient() = default; > > private: >- virtual void refAuthenticationClient() = 0; >- virtual void derefAuthenticationClient() = 0; >+ virtual RefTrackingToken refAuthenticationClient() = 0; >+ virtual void derefAuthenticationClient(RefTrackingToken) = 0; > }; > > } >diff --git a/Source/WebCore/platform/network/DataURLDecoder.cpp b/Source/WebCore/platform/network/DataURLDecoder.cpp >index 60749ac35a84cd9de0e5c4d812677f2ef5ad597f..592257f86e545a7e52596fe8fe962ef4bb4d3544 100644 >--- a/Source/WebCore/platform/network/DataURLDecoder.cpp >+++ b/Source/WebCore/platform/network/DataURLDecoder.cpp >@@ -103,7 +103,7 @@ private: > // Ensure DecodeTask gets deleted in the main thread. > m_decodeTask = nullptr; > >- deref(); >+ deref(UntrackedRefToken()); > } > > RunLoopTimer<DecodingResultDispatcher> m_timer; >diff --git a/Source/WebCore/platform/network/ResourceHandle.h b/Source/WebCore/platform/network/ResourceHandle.h >index 90b0fda53b5ced92b87efaf7c5074edfc136c5dc..32468ec14333eaef7a626b3ee8ca488be058f748 100644 >--- a/Source/WebCore/platform/network/ResourceHandle.h >+++ b/Source/WebCore/platform/network/ResourceHandle.h >@@ -229,8 +229,8 @@ private: > bool start(); > static void platformLoadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data); > >- void refAuthenticationClient() override { ref(); } >- void derefAuthenticationClient() override { deref(); } >+ RefTrackingToken refAuthenticationClient() override { return ref(); } >+ void derefAuthenticationClient(RefTrackingToken token) override { deref(token); } > > #if PLATFORM(COCOA) || USE(CFURLCONNECTION) > enum class SchedulingBehavior { Asynchronous, Synchronous }; >diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegate.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegate.cpp >index a7b9c81eaed8f55c920430fca51ffb38a8d308d8..b61994a5f9479f4f845421ef5a09a57a118bbc87 100644 >--- a/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegate.cpp >+++ b/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegate.cpp >@@ -56,7 +56,7 @@ const void* ResourceHandleCFURLConnectionDelegate::retain(const void* clientInfo > > void ResourceHandleCFURLConnectionDelegate::release(const void* clientInfo) > { >- static_cast<ResourceHandleCFURLConnectionDelegate*>(const_cast<void*>(clientInfo))->deref(); >+ static_cast<ResourceHandleCFURLConnectionDelegate*>(const_cast<void*>(clientInfo))->deref(UntrackedRefToken()); > } > > CFURLRequestRef ResourceHandleCFURLConnectionDelegate::willSendRequestCallback(CFURLConnectionRef, CFURLRequestRef cfRequest, CFURLResponseRef originalRedirectResponse, const void* clientInfo) >diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp >index 95e7ffd5786f0baa25a49b21d29196c38bbcd584..4f4df6a04b7843e663209d37f0430755df4623ae 100644 >--- a/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp >+++ b/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp >@@ -236,7 +236,7 @@ void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFinishLoading() > auto work = [protectedThis = makeRef(*this)] () mutable { > auto& handle = protectedThis->m_handle; > if (!protectedThis->hasHandle() || !handle->client() || !handle->connection()) { >- protectedThis->m_handle->deref(); >+ protectedThis->m_handle->deref(UntrackedRefToken()); > return; > } > >@@ -247,7 +247,7 @@ void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFinishLoading() > protectedThis->m_messageQueue->kill(); > protectedThis->m_messageQueue = nullptr; > } >- protectedThis->m_handle->deref(); >+ protectedThis->m_handle->deref(UntrackedRefToken()); > }; > > if (m_messageQueue) >@@ -261,7 +261,7 @@ void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFail(CFErrorRef > auto work = [protectedThis = makeRef(*this), error = RetainPtr<CFErrorRef>(error)] () mutable { > auto& handle = protectedThis->m_handle; > if (!protectedThis->hasHandle() || !handle->client() || !handle->connection()) { >- protectedThis->m_handle->deref(); >+ protectedThis->m_handle->deref(UntrackedRefToken()); > return; > } > >@@ -272,7 +272,7 @@ void ResourceHandleCFURLConnectionDelegateWithOperationQueue::didFail(CFErrorRef > protectedThis->m_messageQueue->kill(); > protectedThis->m_messageQueue = nullptr; > } >- protectedThis->m_handle->deref(); >+ protectedThis->m_handle->deref(UntrackedRefToken()); > }; > > if (m_messageQueue) >diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp b/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp >index 9ed5aa0c9d9bf13eea31a29568a2497574e586c4..c908650bd4f36ccbd860f1e20a39410e9a59cfea 100644 >--- a/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp >+++ b/Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp >@@ -165,7 +165,7 @@ void* SocketStreamHandleImpl::retainSocketStreamHandle(void* info) > void SocketStreamHandleImpl::releaseSocketStreamHandle(void* info) > { > SocketStreamHandle* handle = static_cast<SocketStreamHandle*>(info); >- handle->deref(); >+ handle->deref(UntrackedRefToken()); > } > > CFStringRef SocketStreamHandleImpl::copyPACExecutionDescription(void*) >diff --git a/Source/WebCore/platform/network/curl/CurlDownload.h b/Source/WebCore/platform/network/curl/CurlDownload.h >index c6f5c596f243dfcd4cdee0a1b5575a410a5464b4..e464e64cd2215ae4e765bc49c45d65efe8e97701 100644 >--- a/Source/WebCore/platform/network/curl/CurlDownload.h >+++ b/Source/WebCore/platform/network/curl/CurlDownload.h >@@ -52,8 +52,8 @@ public: > CurlDownload() = default; > ~CurlDownload(); > >- void ref() override { ThreadSafeRefCounted<CurlDownload>::ref(); } >- void deref() override { ThreadSafeRefCounted<CurlDownload>::deref(); } >+ RefTrackingToken ref() override { return ThreadSafeRefCounted<CurlDownload>::ref(); } >+ void deref(RefTrackingToken token) override { ThreadSafeRefCounted<CurlDownload>::deref(token); } > > void init(CurlDownloadListener&, const URL&); > void init(CurlDownloadListener&, ResourceHandle*, const ResourceRequest&, const ResourceResponse&); >diff --git a/Source/WebCore/platform/network/curl/CurlRequest.h b/Source/WebCore/platform/network/curl/CurlRequest.h >index e4cc4a234fd03a44a136b62bdfed20b2285d143e..173d1140fbb922eb9ce4269f62d02ec5ab350991 100644 >--- a/Source/WebCore/platform/network/curl/CurlRequest.h >+++ b/Source/WebCore/platform/network/curl/CurlRequest.h >@@ -103,7 +103,7 @@ private: > CurlRequest(const ResourceRequest&, CurlRequestClient*, bool, bool, MessageQueue<Function<void()>>*); > > void retain() override { ref(); } >- void release() override { deref(); } >+ void release() override { deref(UntrackedRefToken()); } > CURL* handle() override { return m_curlHandle ? m_curlHandle->handle() : nullptr; } > > void startWithJobManager(); >diff --git a/Source/WebCore/platform/network/curl/CurlRequestClient.h b/Source/WebCore/platform/network/curl/CurlRequestClient.h >index 033b8e93a3287bc49ad55b253ca8a0be2dfea5f3..2beac17b00732235789bb547dbdf38dd7bd2b5a6 100644 >--- a/Source/WebCore/platform/network/curl/CurlRequestClient.h >+++ b/Source/WebCore/platform/network/curl/CurlRequestClient.h >@@ -36,8 +36,8 @@ class SharedBuffer; > > class CurlRequestClient { > public: >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > > virtual void curlDidSendData(CurlRequest&, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) = 0; > virtual void curlDidReceiveResponse(CurlRequest&, const CurlResponse&) = 0; >diff --git a/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp b/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp >index 6a06f19d2877683304e282b5dab785e54d4bdf23..b6c01af3f30241a83aeb5da6545ce76c7c871f08 100644 >--- a/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp >+++ b/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.cpp >@@ -49,14 +49,14 @@ CurlResourceHandleDelegate::CurlResourceHandleDelegate(ResourceHandle& handle) > > } > >-void CurlResourceHandleDelegate::ref() >+RefTrackingToken CurlResourceHandleDelegate::ref() > { >- m_handle.ref(); >+ return m_handle.ref(); > } > >-void CurlResourceHandleDelegate::deref() >+void CurlResourceHandleDelegate::deref(RefTrackingToken token) > { >- m_handle.deref(); >+ m_handle.deref(token); > } > > bool CurlResourceHandleDelegate::cancelledOrClientless() >diff --git a/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.h b/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.h >index 39b6be9320f123564ca53da369d6a17e5ba03190..9dd25c4d47c07bcc6d277b9c42ce7a0d5c432c4f 100644 >--- a/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.h >+++ b/Source/WebCore/platform/network/curl/CurlResourceHandleDelegate.h >@@ -48,8 +48,8 @@ public: > > // CurlRequestClient methods > >- void ref() final; >- void deref() final; >+ RefTrackingToken ref() final; >+ void deref(RefTrackingToken) final; > > void curlDidSendData(CurlRequest&, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) final; > void curlDidReceiveResponse(CurlRequest&, const CurlResponse&) final; >diff --git a/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp b/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp >index 248a421e41e6f7bd11cfabb8e723a11f2bd4bd01..687780b5d2d1ef457714e41b6845e9e0143b0e7c 100644 >--- a/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp >+++ b/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp >@@ -269,7 +269,7 @@ void SocketStreamHandleImpl::beginWaitingForSocketWritability() > m_writeReadySource = adoptGRef(g_pollable_output_stream_create_source(m_outputStream.get(), m_cancellable.get())); > ref(); > g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(reinterpret_cast<GCallback>(writeReadyCallback)), this, [](gpointer handle) { >- static_cast<SocketStreamHandleImpl*>(handle)->deref(); >+ static_cast<SocketStreamHandleImpl*>(handle)->deref(UntrackedRefToken()); > }); > g_source_attach(m_writeReadySource.get(), g_main_context_get_thread_default()); > } >diff --git a/Source/WebCore/platform/soup/SharedBufferSoup.cpp b/Source/WebCore/platform/soup/SharedBufferSoup.cpp >index 17ad2475e90fee349d333910c7f5f1afada15e2a..704b0d92a1e6fcba28711372e433ef0bedebbfbd 100644 >--- a/Source/WebCore/platform/soup/SharedBufferSoup.cpp >+++ b/Source/WebCore/platform/soup/SharedBufferSoup.cpp >@@ -42,7 +42,7 @@ GUniquePtr<SoupBuffer> SharedBuffer::createSoupBuffer(unsigned offset, unsigned > { > ref(); > GUniquePtr<SoupBuffer> buffer(soup_buffer_new_with_owner(data() + offset, size ? size : this->size(), this, [](void* data) { >- static_cast<SharedBuffer*>(data)->deref(); >+ static_cast<SharedBuffer*>(data)->deref(UntrackedRefToken()); > })); > return buffer; > } >diff --git a/Source/WebCore/platform/text/BidiContext.cpp b/Source/WebCore/platform/text/BidiContext.cpp >index c9f0f813bcb6366154bc04bea503c624faea01b5..20009403c8c586346bf0942a3fed2435b906ee68 100644 >--- a/Source/WebCore/platform/text/BidiContext.cpp >+++ b/Source/WebCore/platform/text/BidiContext.cpp >@@ -31,7 +31,9 @@ struct SameSizeAsBidiContext : public RefCounted<SameSizeAsBidiContext> { > void* parent; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(BidiContext) == sizeof(SameSizeAsBidiContext), BidiContext_should_stay_small); >+#endif > > inline BidiContext::BidiContext(unsigned char level, UCharDirection direction, bool override, BidiEmbeddingSource source, BidiContext* parent) > : m_level(level) >diff --git a/Source/WebCore/rendering/FloatingObjects.cpp b/Source/WebCore/rendering/FloatingObjects.cpp >index 4338bd39b532d90275556820f89a1309c5dc262d..78ba49e792f3dbd97cfedc26f8b6bfbfe5dbc5ba 100644 >--- a/Source/WebCore/rendering/FloatingObjects.cpp >+++ b/Source/WebCore/rendering/FloatingObjects.cpp >@@ -40,7 +40,9 @@ struct SameSizeAsFloatingObject { > uint32_t bitfields : 8; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject), FloatingObject_should_stay_small); >+#endif > > FloatingObject::FloatingObject(RenderBox& renderer) > : m_renderer(makeWeakPtr(renderer)) >diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp >index 2876b17a08d94521527f7311e4280402b9e1e1a7..844164e79304ed4e0e77227f9568671239559687 100644 >--- a/Source/WebCore/rendering/InlineFlowBox.cpp >+++ b/Source/WebCore/rendering/InlineFlowBox.cpp >@@ -53,7 +53,9 @@ struct SameSizeAsInlineFlowBox : public InlineBox { > void* pointers[5]; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(InlineFlowBox) == sizeof(SameSizeAsInlineFlowBox), InlineFlowBox_should_stay_small); >+#endif > > #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED > >diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp >index 5a2ef2f375888e3c103b45270eef4df0c1fb3c3a..b937dccb69600f0f83726847f10cd02bee1f1776 100644 >--- a/Source/WebCore/rendering/RenderBox.cpp >+++ b/Source/WebCore/rendering/RenderBox.cpp >@@ -88,7 +88,9 @@ struct SameSizeAsRenderBox : public RenderBoxModelObject { > void* pointers[2]; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(RenderBox) == sizeof(SameSizeAsRenderBox), RenderBox_should_stay_small); >+#endif > > using namespace HTMLNames; > >diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp >index cdb0262053bb4b7f4270f7aa2fca40af0405251d..d2015195850b682f7cc9074342d143b100c1fb53 100644 >--- a/Source/WebCore/rendering/RenderObject.cpp >+++ b/Source/WebCore/rendering/RenderObject.cpp >@@ -108,7 +108,9 @@ struct SameSizeAsRenderObject { > unsigned m_bitfields; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small); >+#endif > > DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("RenderObject")); > >@@ -1477,7 +1479,7 @@ void RenderObject::destroy() > willBeDestroyed(); > > if (is<RenderWidget>(*this)) { >- downcast<RenderWidget>(*this).deref(); >+ downcast<RenderWidget>(*this).deref(UntrackedRefToken()); > return; > } > delete this; >diff --git a/Source/WebCore/rendering/RenderWidget.h b/Source/WebCore/rendering/RenderWidget.h >index 8ae3d2c65b2d44e52600a02c7a63f734549d196c..44eb85590210e87672a85d35170925f5d8f3664f 100644 >--- a/Source/WebCore/rendering/RenderWidget.h >+++ b/Source/WebCore/rendering/RenderWidget.h >@@ -71,8 +71,8 @@ public: > > bool requiresAcceleratedCompositing() const; > >- void ref() { ++m_refCount; } >- void deref(); >+ RefTrackingToken ref() { ++m_refCount; return UntrackedRefToken(); } >+ void deref(RefTrackingToken); > > protected: > RenderWidget(HTMLFrameOwnerElement&, RenderStyle&&); >@@ -104,7 +104,7 @@ private: > unsigned m_refCount { 1 }; > }; > >-inline void RenderWidget::deref() >+inline void RenderWidget::deref(RefTrackingToken) > { > ASSERT(m_refCount); > if (!--m_refCount) >diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp >index 1999764789db57060ff241c59beda9befc9075dc..f8d45b661ac66223d37b3bc630993ced98c0faaa 100644 >--- a/Source/WebCore/rendering/RootInlineBox.cpp >+++ b/Source/WebCore/rendering/RootInlineBox.cpp >@@ -50,7 +50,9 @@ struct SameSizeAsRootInlineBox : public InlineFlowBox, public CanMakeWeakPtr<Roo > void* pointers[3]; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(RootInlineBox) == sizeof(SameSizeAsRootInlineBox), RootInlineBox_should_stay_small); >+#endif > > typedef WTF::HashMap<const RootInlineBox*, std::unique_ptr<EllipsisBox>> EllipsisBoxMap; > static EllipsisBoxMap* gEllipsisBoxMap; >diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp >index c2c4e85e947345503e2f0781db08517bef0746ad..0074d4e68b13dd01e71600db05760419c1789a5d 100644 >--- a/Source/WebCore/rendering/style/RenderStyle.cpp >+++ b/Source/WebCore/rendering/style/RenderStyle.cpp >@@ -81,7 +81,9 @@ struct SameSizeAsRenderStyle { > #endif > }; > >+#if !ENABLE(REF_TRACKING) > static_assert(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), "RenderStyle should stay small"); >+#endif > > RenderStyle& RenderStyle::defaultStyle() > { >diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp >index 5a847c83431b4390c5ef5ca0c5967b94ee693ab0..23a00a77498b113304ce9793ef750abf53f9473f 100644 >--- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp >+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp >@@ -68,7 +68,9 @@ struct GreaterThanOrSameSizeAsStyleRareInheritedData : public RefCounted<Greater > void* customPropertyDataRefs[1]; > }; > >+#if !ENABLE(REF_TRACKING) > COMPILE_ASSERT(sizeof(StyleRareInheritedData) <= sizeof(GreaterThanOrSameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack); >+#endif > > StyleRareInheritedData::StyleRareInheritedData() > : listStyleImage(RenderStyle::initialListStyleImage()) >diff --git a/Source/WebCore/testing/MockContentFilterSettings.h b/Source/WebCore/testing/MockContentFilterSettings.h >index 33d21a0efa95064b32c91d05f279ef095635e86a..b4f387e3ad8ee010ad583f9bf632691c85172d62 100644 >--- a/Source/WebCore/testing/MockContentFilterSettings.h >+++ b/Source/WebCore/testing/MockContentFilterSettings.h >@@ -51,8 +51,8 @@ public: > static const char* unblockURLHost() { return "mock-unblock"; } > > // Trick the generated bindings into thinking we're RefCounted. >- void ref() { } >- void deref() { } >+ RefTrackingToken ref() { return UntrackedRefToken(); } >+ void deref(RefTrackingToken) { } > > bool enabled() const { return m_enabled; } > WTF_EXPORT_PRIVATE void setEnabled(bool); >diff --git a/Source/WebCore/testing/MockCredentialsMessenger.cpp b/Source/WebCore/testing/MockCredentialsMessenger.cpp >index 102e33b5c5b88a81f1e2a64b7ce0fe3f55014a3f..278f344dd6d9dcb83524a949626fc62f169bff69 100644 >--- a/Source/WebCore/testing/MockCredentialsMessenger.cpp >+++ b/Source/WebCore/testing/MockCredentialsMessenger.cpp >@@ -61,14 +61,15 @@ void MockCredentialsMessenger::setAssertionReturnBundle(const BufferSource& cred > m_userHandle.append(userHandle.data(), userHandle.length()); > } > >-void MockCredentialsMessenger::ref() >+RefTrackingToken MockCredentialsMessenger::ref() > { > m_internals.ref(); >+ return UntrackedRefToken(); > } > >-void MockCredentialsMessenger::deref() >+void MockCredentialsMessenger::deref(RefTrackingToken) > { >- m_internals.deref(); >+ m_internals.deref(UntrackedRefToken()); > } > > void MockCredentialsMessenger::makeCredential(const Vector<uint8_t>&, const PublicKeyCredentialCreationOptions&, CreationCompletionHandler&& handler) >diff --git a/Source/WebCore/testing/MockCredentialsMessenger.h b/Source/WebCore/testing/MockCredentialsMessenger.h >index b4b08df4eaa0848e11191e9a86e404a2bc51182f..ca3868a3cca4a1c35d75570fc7c793a32e79b52d 100644 >--- a/Source/WebCore/testing/MockCredentialsMessenger.h >+++ b/Source/WebCore/testing/MockCredentialsMessenger.h >@@ -46,8 +46,8 @@ public: > void setCreationReturnBundle(const BufferSource& credentialId, const BufferSource& attestationObject); > void setAssertionReturnBundle(const BufferSource& credentialId, const BufferSource& authenticatorData, const BufferSource& signature, const BufferSource& userHandle); > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > > private: > void makeCredential(const Vector<uint8_t>&, const PublicKeyCredentialCreationOptions&, CreationCompletionHandler&&) final; >diff --git a/Source/WebCore/testing/MockPaymentCoordinator.h b/Source/WebCore/testing/MockPaymentCoordinator.h >index 1f7d068d1cc09ef4d5c3e5bf1609b400216317cf..4867e0021fc0c1913f2972b2708a7ee6fd78c07c 100644 >--- a/Source/WebCore/testing/MockPaymentCoordinator.h >+++ b/Source/WebCore/testing/MockPaymentCoordinator.h >@@ -51,8 +51,8 @@ public: > const ApplePayLineItem& total() const { return m_total; } > const Vector<ApplePayLineItem>& lineItems() const { return m_lineItems; } > >- void ref() const { } >- void deref() const { } >+ RefTrackingToken ref() const { return UntrackedRefToken(); } >+ void deref(RefTrackingToken) const { } > > private: > bool supportsVersion(unsigned) final; >diff --git a/Source/WebCore/workers/AbstractWorker.h b/Source/WebCore/workers/AbstractWorker.h >index 900c2cb40462a0ebe37028a375a633feaf9534f1..bb81e342d0939be763b36176ad41b3062373273c 100644 >--- a/Source/WebCore/workers/AbstractWorker.h >+++ b/Source/WebCore/workers/AbstractWorker.h >@@ -51,8 +51,8 @@ protected: > intptr_t asID() const { return reinterpret_cast<intptr_t>(this); } > > private: >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > }; > > } // namespace WebCore >diff --git a/Source/WebCore/workers/WorkerGlobalScope.h b/Source/WebCore/workers/WorkerGlobalScope.h >index 5b9a0be369c299c0fb7541078fc7656d6de79ec1..f74d226dd94a1ad6ea7c87011802b4645f1c061a 100644 >--- a/Source/WebCore/workers/WorkerGlobalScope.h >+++ b/Source/WebCore/workers/WorkerGlobalScope.h >@@ -131,11 +131,11 @@ protected: > void applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders&); > > private: >- void refScriptExecutionContext() final { ref(); } >- void derefScriptExecutionContext() final { deref(); } >+ RefTrackingToken refScriptExecutionContext() final { return ref(); } >+ void derefScriptExecutionContext(RefTrackingToken token) final { deref(token); } > >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) final; > >diff --git a/Source/WebCore/workers/WorkerMessagingProxy.cpp b/Source/WebCore/workers/WorkerMessagingProxy.cpp >index a75c0156c59e38dd999d6cec1ddeede23be187b3..5edf86b0b8ff0d168af448a0674938a6c4a04030 100644 >--- a/Source/WebCore/workers/WorkerMessagingProxy.cpp >+++ b/Source/WebCore/workers/WorkerMessagingProxy.cpp >@@ -256,7 +256,7 @@ void WorkerMessagingProxy::workerGlobalScopeDestroyedInternal() > > // This balances the original ref in construction. > if (m_mayBeDestroyed) >- deref(); >+ deref(UntrackedRefToken()); > } > > void WorkerMessagingProxy::terminateWorkerGlobalScope() >diff --git a/Source/WebCore/workers/service/ServiceWorker.h b/Source/WebCore/workers/service/ServiceWorker.h >index 9b9bcc8a22f9d767129897ec01f37b2a5521b7ed..880a512e7b6516e8c388e2112ee5733a82f1d1c9 100644 >--- a/Source/WebCore/workers/service/ServiceWorker.h >+++ b/Source/WebCore/workers/service/ServiceWorker.h >@@ -70,8 +70,8 @@ private: > > EventTargetInterface eventTargetInterface() const final; > ScriptExecutionContext* scriptExecutionContext() const final; >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > // ActiveDOMObject. > const char* activeDOMObjectName() const final; >diff --git a/Source/WebCore/workers/service/ServiceWorkerContainer.cpp b/Source/WebCore/workers/service/ServiceWorkerContainer.cpp >index 40d40dada0b18f22a8837cb9768a4a996e2e6bd2..b33b133a0a332cd9ae6123371abf97a4d0f2d7fa 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerContainer.cpp >+++ b/Source/WebCore/workers/service/ServiceWorkerContainer.cpp >@@ -71,14 +71,15 @@ ServiceWorkerContainer::~ServiceWorkerContainer() > #endif > } > >-void ServiceWorkerContainer::refEventTarget() >+RefTrackingToken ServiceWorkerContainer::refEventTarget() > { > m_navigator.ref(); >+ return UntrackedRefToken(); > } > >-void ServiceWorkerContainer::derefEventTarget() >+void ServiceWorkerContainer::derefEventTarget(RefTrackingToken) > { >- m_navigator.deref(); >+ m_navigator.deref(UntrackedRefToken()); > } > > auto ServiceWorkerContainer::ready() -> ReadyPromise& >diff --git a/Source/WebCore/workers/service/ServiceWorkerContainer.h b/Source/WebCore/workers/service/ServiceWorkerContainer.h >index 17e5681bde02d7a714231fde34e5a624c3f7d615..c2d325957b6e1977e17f711ec2b88d4a84055331 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerContainer.h >+++ b/Source/WebCore/workers/service/ServiceWorkerContainer.h >@@ -81,8 +81,8 @@ public: > > void startMessages(); > >- void ref() final { refEventTarget(); } >- void deref() final { derefEventTarget(); } >+ RefTrackingToken ref() final { return refEventTarget(); } >+ void deref(RefTrackingToken token) final { derefEventTarget(token); } > > bool isStopped() const { return m_isStopped; }; > >@@ -112,8 +112,10 @@ private: > bool canSuspendForDocumentSuspension() const final; > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } > EventTargetInterface eventTargetInterface() const final { return ServiceWorkerContainerEventTargetInterfaceType; } >- void refEventTarget() final; >- void derefEventTarget() final; >+ >+ RefTrackingToken refEventTarget() final; >+ void derefEventTarget(RefTrackingToken) final; >+ > void stop() final; > > std::unique_ptr<ReadyPromise> m_readyPromise; >diff --git a/Source/WebCore/workers/service/ServiceWorkerJobClient.h b/Source/WebCore/workers/service/ServiceWorkerJobClient.h >index 6737ecaf1ec2df1ed5fbcbec6eb398bd73f0feaa..b2dd8ccdd57039d9cb72ac53d523c6921385febd 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerJobClient.h >+++ b/Source/WebCore/workers/service/ServiceWorkerJobClient.h >@@ -54,8 +54,8 @@ public: > > virtual SWServerConnectionIdentifier connectionIdentifier() = 0; > >- virtual void ref() = 0; >- virtual void deref() = 0; >+ virtual RefTrackingToken ref() = 0; >+ virtual void deref(RefTrackingToken) = 0; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/workers/service/ServiceWorkerRegistration.h b/Source/WebCore/workers/service/ServiceWorkerRegistration.h >index d75fbc458bb60a0bdf3df20c5a19faecead2f505..7110a395ea8dee0d46ea0fde16720b90bcf0254d 100644 >--- a/Source/WebCore/workers/service/ServiceWorkerRegistration.h >+++ b/Source/WebCore/workers/service/ServiceWorkerRegistration.h >@@ -83,8 +83,8 @@ private: > > EventTargetInterface eventTargetInterface() const final; > ScriptExecutionContext* scriptExecutionContext() const final; >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > void softUpdate(); > >diff --git a/Source/WebCore/xml/XMLHttpRequest.h b/Source/WebCore/xml/XMLHttpRequest.h >index 4e8ae70bbe52ae6fe2dcd4064088ad07cf7edbb7..95a293d86e24edfcbfc3c7b6fcb46969f27f4102 100644 >--- a/Source/WebCore/xml/XMLHttpRequest.h >+++ b/Source/WebCore/xml/XMLHttpRequest.h >@@ -136,8 +136,8 @@ private: > void stop() override; > const char* activeDOMObjectName() const override; > >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ RefTrackingToken refEventTarget() override { return ref(); } >+ void derefEventTarget(RefTrackingToken token) override { deref(token); } > > Document* document() const; > SecurityOrigin* securityOrigin() const; >diff --git a/Source/WebCore/xml/XMLHttpRequestUpload.h b/Source/WebCore/xml/XMLHttpRequestUpload.h >index e9ebb58232d121f73c6b13c826576493b7c598e5..f552813d497c0e830430245202e9ddc7ed07b588 100644 >--- a/Source/WebCore/xml/XMLHttpRequestUpload.h >+++ b/Source/WebCore/xml/XMLHttpRequestUpload.h >@@ -35,15 +35,15 @@ class XMLHttpRequestUpload final : public XMLHttpRequestEventTarget { > public: > explicit XMLHttpRequestUpload(XMLHttpRequest&); > >- void ref() { m_request.ref(); } >- void deref() { m_request.deref(); } >+ RefTrackingToken ref() { m_request.ref(); return UntrackedRefToken(); } >+ void deref(RefTrackingToken) { m_request.deref(UntrackedRefToken()); } > > void dispatchThrottledProgressEvent(bool lengthComputable, unsigned long long loaded, unsigned long long total); > void dispatchProgressEvent(const AtomicString& type); > > private: >- void refEventTarget() final { ref(); } >- void derefEventTarget() final { deref(); } >+ RefTrackingToken refEventTarget() final { return ref(); } >+ void derefEventTarget(RefTrackingToken token) final { deref(token); } > > EventTargetInterface eventTargetInterface() const final { return XMLHttpRequestUploadEventTargetInterfaceType; } > ScriptExecutionContext* scriptExecutionContext() const final { return m_request.scriptExecutionContext(); } >diff --git a/Source/WebCore/xml/XPathGrammar.cpp b/Source/WebCore/xml/XPathGrammar.cpp >index 31df1c0d158a278f4c096cb2ba911f3f7b01b943..dab459cc8f28a7adb51fdc756a3dde59b28c1aef 100644 >--- a/Source/WebCore/xml/XPathGrammar.cpp >+++ b/Source/WebCore/xml/XPathGrammar.cpp >@@ -1203,32 +1203,32 @@ yydestruct (yymsg, yytype, yyvaluep, parser) > { > case 10: /* "FUNCTIONNAME" */ > #line 80 "WebCore/xml/XPathGrammar.y" >- { if ((yyvaluep->string)) (yyvaluep->string)->deref(); }; >+ { if ((yyvaluep->string)) (yyvaluep->string)->deref(UntrackedRefToken()); }; > #line 1205 "./XPathGrammar.cpp" > break; > case 11: /* "LITERAL" */ > #line 80 "WebCore/xml/XPathGrammar.y" >- { if ((yyvaluep->string)) (yyvaluep->string)->deref(); }; >+ { if ((yyvaluep->string)) (yyvaluep->string)->deref(UntrackedRefToken()); }; > #line 1210 "./XPathGrammar.cpp" > break; > case 12: /* "NAMETEST" */ > #line 80 "WebCore/xml/XPathGrammar.y" >- { if ((yyvaluep->string)) (yyvaluep->string)->deref(); }; >+ { if ((yyvaluep->string)) (yyvaluep->string)->deref(UntrackedRefToken()); }; > #line 1215 "./XPathGrammar.cpp" > break; > case 13: /* "NUMBER" */ > #line 80 "WebCore/xml/XPathGrammar.y" >- { if ((yyvaluep->string)) (yyvaluep->string)->deref(); }; >+ { if ((yyvaluep->string)) (yyvaluep->string)->deref(UntrackedRefToken()); }; > #line 1220 "./XPathGrammar.cpp" > break; > case 14: /* "NODETYPE" */ > #line 80 "WebCore/xml/XPathGrammar.y" >- { if ((yyvaluep->string)) (yyvaluep->string)->deref(); }; >+ { if ((yyvaluep->string)) (yyvaluep->string)->deref(UntrackedRefToken()); }; > #line 1225 "./XPathGrammar.cpp" > break; > case 15: /* "VARIABLEREFERENCE" */ > #line 80 "WebCore/xml/XPathGrammar.y" >- { if ((yyvaluep->string)) (yyvaluep->string)->deref(); }; >+ { if ((yyvaluep->string)) (yyvaluep->string)->deref(UntrackedRefToken()); }; > #line 1230 "./XPathGrammar.cpp" > break; > case 35: /* "Expr" */ >diff --git a/Source/WebCore/xml/XPathGrammar.y b/Source/WebCore/xml/XPathGrammar.y >index 4eb20b92a56489e0ffb6059e11afa926cba3b946..938795d1aea08996d16aed02849d7432eae10bb8 100644 >--- a/Source/WebCore/xml/XPathGrammar.y >+++ b/Source/WebCore/xml/XPathGrammar.y >@@ -77,7 +77,7 @@ using namespace XPath; > %left OR AND > > %token <string> FUNCTIONNAME LITERAL NAMETEST NUMBER NODETYPE VARIABLEREFERENCE >-%destructor { if ($$) $$->deref(); } FUNCTIONNAME LITERAL NAMETEST NUMBER NODETYPE VARIABLEREFERENCE >+%destructor { if ($$) $$->deref(UntrackedRefToken()); } FUNCTIONNAME LITERAL NAMETEST NUMBER NODETYPE VARIABLEREFERENCE > > %token <axis> AXISNAME > %type <axis> AxisSpecifier >diff --git a/Source/WebCore/xml/parser/XMLDocumentParser.cpp b/Source/WebCore/xml/parser/XMLDocumentParser.cpp >index 1f28a8eba59df1e6e21fcc875e0f490baa60885f..f77521d18ca9efee549204d93e768d5d75d9b27b 100644 >--- a/Source/WebCore/xml/parser/XMLDocumentParser.cpp >+++ b/Source/WebCore/xml/parser/XMLDocumentParser.cpp >@@ -77,7 +77,7 @@ void XMLDocumentParser::popCurrentNode() > ASSERT(m_currentNodeStack.size()); > > if (m_currentNode != document()) >- m_currentNode->deref(); >+ m_currentNode->deref(UntrackedRefToken()); > > m_currentNode = m_currentNodeStack.last(); > m_currentNodeStack.removeLast(); >@@ -86,15 +86,15 @@ void XMLDocumentParser::popCurrentNode() > void XMLDocumentParser::clearCurrentNodeStack() > { > if (m_currentNode && m_currentNode != document()) >- m_currentNode->deref(); >+ m_currentNode->deref(UntrackedRefToken()); > m_currentNode = nullptr; > m_leafTextNode = nullptr; > > if (m_currentNodeStack.size()) { // Aborted parsing. > for (size_t i = m_currentNodeStack.size() - 1; i != 0; --i) >- m_currentNodeStack[i]->deref(); >+ m_currentNodeStack[i]->deref(UntrackedRefToken()); > if (m_currentNodeStack[0] && m_currentNodeStack[0] != document()) >- m_currentNodeStack[0]->deref(); >+ m_currentNodeStack[0]->deref(UntrackedRefToken()); > m_currentNodeStack.clear(); > } > } >diff --git a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h >index fcc4d34e4d621967599f8ff90dfb3c02c4dd4bad..eb757ae8dd72731f6d50eefcd4cf31465c370cad 100644 >--- a/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h >+++ b/Source/WebKit/NetworkProcess/curl/NetworkDataTaskCurl.h >@@ -45,8 +45,8 @@ public: > > ~NetworkDataTaskCurl(); > >- void ref() override { RefCounted<NetworkDataTask>::ref(); } >- void deref() override { RefCounted<NetworkDataTask>::deref(); } >+ RefTrackingToken ref() override { return RefCounted<NetworkDataTask>::ref(); } >+ void deref(RefTrackingToken token) override { RefCounted<NetworkDataTask>::deref(token); } > > private: > enum class RequestStatus { >diff --git a/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm b/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm >index d9ce5796f5fb2e9ae580919e8de937be4ad614f6..52286d6d032ff6f3f70d3d482176c1a4bfb333c6 100644 >--- a/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm >+++ b/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm >@@ -238,7 +238,7 @@ bool Connection::open() > if (m_sendSource) > dispatch_resume(m_sendSource); > >- deref(); >+ deref(UntrackedRefToken()); > }); > > return true; >diff --git a/Source/WebKit/Shared/API/APIObject.h b/Source/WebKit/Shared/API/APIObject.h >index 1f6003ff5f4d9de4f186e7b1a3ba4ed2a12d2c70..96b82424040f79dc0d0248e1dfa27b63c2459310 100644 >--- a/Source/WebKit/Shared/API/APIObject.h >+++ b/Source/WebKit/Shared/API/APIObject.h >@@ -217,8 +217,8 @@ public: > > NSObject *wrapper() { return m_wrapper; } > >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > #endif // DELEGATE_REF_COUNTING_TO_COCOA > > static void* wrap(API::Object*); >diff --git a/Source/WebKit/Shared/API/c/WKType.cpp b/Source/WebKit/Shared/API/c/WKType.cpp >index fd20e6fff1e04f04a7e99cd55d486a4d13f9a691..f5826324339ff6c86c3c4ec59bdc40c8072367ce 100644 >--- a/Source/WebKit/Shared/API/c/WKType.cpp >+++ b/Source/WebKit/Shared/API/c/WKType.cpp >@@ -45,5 +45,5 @@ WKTypeRef WKRetain(WKTypeRef typeRef) > > void WKRelease(WKTypeRef typeRef) > { >- toImpl(typeRef)->deref(); >+ toImpl(typeRef)->deref(UntrackedRefToken()); > } >diff --git a/Source/WebKit/Shared/Cocoa/APIObject.mm b/Source/WebKit/Shared/Cocoa/APIObject.mm >index 448ffd28aca7b8f0d911d7c3c2bd744f22f847f7..838802f68b564f9159e468419fa90496b1ad551c 100644 >--- a/Source/WebKit/Shared/Cocoa/APIObject.mm >+++ b/Source/WebKit/Shared/Cocoa/APIObject.mm >@@ -93,12 +93,13 @@ static const size_t maximumExtraSpaceForAlignment = minimumObjectAlignment - ali > > namespace API { > >-void Object::ref() >+RefTrackingToken Object::ref() > { > CFRetain((__bridge CFTypeRef)wrapper()); >+ return UntrackedRefToken(); > } > >-void Object::deref() >+void Object::deref(RefTrackingToken) > { > CFRelease((__bridge CFTypeRef)wrapper()); > } >diff --git a/Source/WebKit/Shared/ShareableResource.cpp b/Source/WebKit/Shared/ShareableResource.cpp >index d147d80e5747358fc34bb3d3e4b1cdeba8c2dd1d..06b416091977eb252eab48477f55478506d60b20 100644 >--- a/Source/WebKit/Shared/ShareableResource.cpp >+++ b/Source/WebKit/Shared/ShareableResource.cpp >@@ -60,7 +60,7 @@ bool ShareableResource::Handle::decode(IPC::Decoder& decoder, Handle& handle) > #if USE(CF) > static void shareableResourceDeallocate(void *ptr, void *info) > { >- static_cast<ShareableResource*>(info)->deref(); // Balanced by ref() in createShareableResourceDeallocator() >+ static_cast<ShareableResource*>(info)->deref(UntrackedRefToken()); // Balanced by ref() in createShareableResourceDeallocator() > } > > static CFAllocatorRef createShareableResourceDeallocator(ShareableResource* resource) >@@ -89,7 +89,9 @@ RefPtr<SharedBuffer> ShareableResource::wrapInSharedBuffer() > RetainPtr<CFDataRef> cfData = adoptCF(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data()), static_cast<CFIndex>(size()), deallocator.get())); > return SharedBuffer::create(cfData.get()); > #elif USE(SOUP) >- return SharedBuffer::wrapSoupBuffer(soup_buffer_new_with_owner(data(), size(), this, [](void* data) { static_cast<ShareableResource*>(data)->deref(); })); >+ return SharedBuffer::wrapSoupBuffer(soup_buffer_new_with_owner(data(), size(), this, [](void* data) { >+ static_cast<ShareableResource*>(data)->deref(UntrackedRefToken()); >+ })); > #else > ASSERT_NOT_REACHED(); > return nullptr; >diff --git a/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp b/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp >index c7347c79e669383785d05d229e47b747c1f0ca55..c0b019e412d07ef928029d47256ddca499e8b008 100644 >--- a/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp >+++ b/Source/WebKit/Shared/cairo/ShareableBitmapCairo.cpp >@@ -92,7 +92,7 @@ RefPtr<cairo_surface_t> ShareableBitmap::createCairoSurface() > > void ShareableBitmap::releaseSurfaceData(void* typelessBitmap) > { >- static_cast<ShareableBitmap*>(typelessBitmap)->deref(); // Balanced by ref in createCairoSurface. >+ static_cast<ShareableBitmap*>(typelessBitmap)->deref(UntrackedRefToken()); // Balanced by ref in createCairoSurface. > } > > RefPtr<Image> ShareableBitmap::createImage() >diff --git a/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp b/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp >index 41b2fea32b153f3bf4fef6592e29e23542e6545f..be53ced813c772aa5b75b924d8db08dc5a464d34 100644 >--- a/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp >+++ b/Source/WebKit/Shared/cg/ShareableBitmapCG.cpp >@@ -137,14 +137,14 @@ void ShareableBitmap::releaseBitmapContextData(void* typelessBitmap, void* typel > { > ShareableBitmap* bitmap = static_cast<ShareableBitmap*>(typelessBitmap); > ASSERT_UNUSED(typelessData, bitmap->data() == typelessData); >- bitmap->deref(); // Balanced by ref in createGraphicsContext. >+ bitmap->deref(UntrackedRefToken()); // Balanced by ref in createGraphicsContext. > } > > void ShareableBitmap::releaseDataProviderData(void* typelessBitmap, const void* typelessData, size_t) > { > ShareableBitmap* bitmap = static_cast<ShareableBitmap*>(typelessBitmap); > ASSERT_UNUSED(typelessData, bitmap->data() == typelessData); >- bitmap->deref(); // Balanced by ref in createCGImage. >+ bitmap->deref(UntrackedRefToken()); // Balanced by ref in createCGImage. > } > > RefPtr<Image> ShareableBitmap::createImage() >diff --git a/Source/WebKit/StorageProcess/IndexedDB/WebIDBConnectionToClient.h b/Source/WebKit/StorageProcess/IndexedDB/WebIDBConnectionToClient.h >index 0087e8aa87c1625e3b98e9260713d72b39bec35e..9f3db14668be72d17acdf364c05882673bdc7520 100644 >--- a/Source/WebKit/StorageProcess/IndexedDB/WebIDBConnectionToClient.h >+++ b/Source/WebKit/StorageProcess/IndexedDB/WebIDBConnectionToClient.h >@@ -87,8 +87,8 @@ public: > > void didGetAllDatabaseNames(uint64_t callbackID, const Vector<String>& databaseNames) final; > >- void ref() override { RefCounted<WebIDBConnectionToClient>::ref(); } >- void deref() override { RefCounted<WebIDBConnectionToClient>::deref(); } >+ RefTrackingToken ref() override { return RefCounted<WebIDBConnectionToClient>::ref(); } >+ void deref(RefTrackingToken token) override { RefCounted<WebIDBConnectionToClient>::deref(token); } > > // Messages received from WebProcess > void deleteDatabase(const WebCore::IDBRequestData&); >diff --git a/Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm b/Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm >index aedc3d7a51b911a7cae16dd9d906b87ffa978b0c..7dde4556b44efd6895447fbb82276c84dde8daec 100644 >--- a/Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm >+++ b/Source/WebKit/UIProcess/API/C/mac/WKContextPrivateMac.mm >@@ -98,7 +98,7 @@ void WKContextGetInfoForInstalledPlugIns(WKContextRef contextRef, WKContextGetIn > dispatch_async(dispatch_get_main_queue(), ^() { > block(toAPI(array.get()), 0); > >- toImpl(contextRef)->deref(); >+ toImpl(contextRef)->deref(UntrackedRefToken()); > }); > #endif > } >diff --git a/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm b/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm >index ee0eb935a6e5c9f407205d06c344b9abfe1db08c..8ac614447f10beee85129c0a347eb6311e9c1ed6 100644 >--- a/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm >+++ b/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm >@@ -269,7 +269,7 @@ void ProcessLauncher::launchProcess() > m_xpcConnection = nullptr; > } > >- deref(); >+ deref(UntrackedRefToken()); > }); > } > >diff --git a/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp b/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp >index 7965868be04339e7849f4dd3442c64dc956e668c..8fb01a7c123d3f93c37ab6c8fc92088610d30636 100644 >--- a/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.cpp >@@ -78,14 +78,14 @@ void WebNotificationManagerProxy::processPoolDestroyed() > m_provider->removeNotificationManager(*this); > } > >-void WebNotificationManagerProxy::refWebContextSupplement() >+RefTrackingToken WebNotificationManagerProxy::refWebContextSupplement() > { >- API::Object::ref(); >+ return API::Object::ref(); > } > >-void WebNotificationManagerProxy::derefWebContextSupplement() >+void WebNotificationManagerProxy::derefWebContextSupplement(RefTrackingToken token) > { >- API::Object::deref(); >+ API::Object::deref(token); > } > > HashMap<String, bool> WebNotificationManagerProxy::notificationPermissions() >diff --git a/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h b/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h >index 542fbd9726ea9a6ab32d8357a93a3693a34a7dde..febf4bc8f1b26ba7db37e9948fcb72a581f8b6f9 100644 >--- a/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h >+++ b/Source/WebKit/UIProcess/Notifications/WebNotificationManagerProxy.h >@@ -84,8 +84,8 @@ private: > > // WebContextSupplement > void processPoolDestroyed() override; >- void refWebContextSupplement() override; >- void derefWebContextSupplement() override; >+ RefTrackingToken refWebContextSupplement() override; >+ void derefWebContextSupplement(RefTrackingToken) override; > > std::unique_ptr<API::NotificationProvider> m_provider; > // Pair comprised of web page ID and the web process's notification ID >diff --git a/Source/WebKit/UIProcess/WebContextSupplement.h b/Source/WebKit/UIProcess/WebContextSupplement.h >index 80ca3a533a1c704f231db840d91f566474de748a..9aaa1712e9ed05b4639c5de0b343e95205e3ad5d 100644 >--- a/Source/WebKit/UIProcess/WebContextSupplement.h >+++ b/Source/WebKit/UIProcess/WebContextSupplement.h >@@ -63,12 +63,12 @@ public: > WebProcessPool* processPool() const { return m_processPool; } > void clearProcessPool() { m_processPool = nullptr; } > >- void ref() { refWebContextSupplement(); } >- void deref() { derefWebContextSupplement(); } >+ RefTrackingToken ref() { return refWebContextSupplement(); } >+ void deref(RefTrackingToken token) { derefWebContextSupplement(token); } > > private: >- virtual void refWebContextSupplement() = 0; >- virtual void derefWebContextSupplement() = 0; >+ virtual RefTrackingToken refWebContextSupplement() = 0; >+ virtual void derefWebContextSupplement(RefTrackingToken) = 0; > > WebProcessPool* m_processPool; > }; >diff --git a/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp b/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp >index 0a20d854f44f21abc5a43bbd0d77c8692f8f2769..7d84af90d82e737e55f84f9e30ed4860258be04b 100644 >--- a/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/WebCookieManagerProxy.cpp >@@ -96,14 +96,14 @@ void WebCookieManagerProxy::processDidClose(NetworkProcessProxy*) > m_callbacks.invalidate(CallbackBase::Error::ProcessExited); > } > >-void WebCookieManagerProxy::refWebContextSupplement() >+RefTrackingToken WebCookieManagerProxy::refWebContextSupplement() > { >- API::Object::ref(); >+ return API::Object::ref(); > } > >-void WebCookieManagerProxy::derefWebContextSupplement() >+void WebCookieManagerProxy::derefWebContextSupplement(RefTrackingToken token) > { >- API::Object::deref(); >+ API::Object::deref(token); > } > > void WebCookieManagerProxy::getHostnamesWithCookies(PAL::SessionID sessionID, Function<void (API::Array*, CallbackBase::Error)>&& callbackFunction) >diff --git a/Source/WebKit/UIProcess/WebCookieManagerProxy.h b/Source/WebKit/UIProcess/WebCookieManagerProxy.h >index e33167a8950c168f01c032ceb9e5f8f981e51380..27ad24a58c021b41e38c49f11da9bc3aed322eb8 100644 >--- a/Source/WebKit/UIProcess/WebCookieManagerProxy.h >+++ b/Source/WebKit/UIProcess/WebCookieManagerProxy.h >@@ -121,8 +121,8 @@ private: > void processPoolDestroyed() override; > void processDidClose(WebProcessProxy*) override; > void processDidClose(NetworkProcessProxy*) override; >- void refWebContextSupplement() override; >- void derefWebContextSupplement() override; >+ RefTrackingToken refWebContextSupplement() override; >+ void derefWebContextSupplement(RefTrackingToken) override; > > // IPC::MessageReceiver > void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; >diff --git a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp >index 52b011f5dbac6cd6b7073b820546fb626e21a4d1..015710e425be513838fec93dbca6eb8aa9b92735 100644 >--- a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.cpp >@@ -76,14 +76,14 @@ void WebGeolocationManagerProxy::processDidClose(WebProcessProxy* webProcessProx > removeRequester(webProcessProxy); > } > >-void WebGeolocationManagerProxy::refWebContextSupplement() >+RefTrackingToken WebGeolocationManagerProxy::refWebContextSupplement() > { >- API::Object::ref(); >+ return API::Object::ref(); > } > >-void WebGeolocationManagerProxy::derefWebContextSupplement() >+void WebGeolocationManagerProxy::derefWebContextSupplement(RefTrackingToken token) > { >- API::Object::deref(); >+ API::Object::deref(token); > } > > void WebGeolocationManagerProxy::providerDidChangePosition(WebGeolocationPosition* position) >diff --git a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.h b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.h >index 151539207309f78f000de117d78697804541e358..4e4e86d2f881e13f339846fa443d555c8794d8da 100644 >--- a/Source/WebKit/UIProcess/WebGeolocationManagerProxy.h >+++ b/Source/WebKit/UIProcess/WebGeolocationManagerProxy.h >@@ -64,8 +64,8 @@ private: > // WebContextSupplement > void processPoolDestroyed() override; > void processDidClose(WebProcessProxy*) override; >- void refWebContextSupplement() override; >- void derefWebContextSupplement() override; >+ RefTrackingToken refWebContextSupplement() override; >+ void derefWebContextSupplement(RefTrackingToken) override; > > // IPC::MessageReceiver > void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; >diff --git a/Source/WebKit/UIProcess/WebMediaSessionFocusManager.cpp b/Source/WebKit/UIProcess/WebMediaSessionFocusManager.cpp >index 2cdcd1765299fe77649babf9de3e74e8b0f00e37..ba1cea2a5e0ed285b436c4c951b4f3306286d43b 100644 >--- a/Source/WebKit/UIProcess/WebMediaSessionFocusManager.cpp >+++ b/Source/WebKit/UIProcess/WebMediaSessionFocusManager.cpp >@@ -47,14 +47,14 @@ WebMediaSessionFocusManager::WebMediaSessionFocusManager(WebProcessPool* process > > // WebContextSupplement > >-void WebMediaSessionFocusManager::refWebContextSupplement() >+RefTrackingToken WebMediaSessionFocusManager::refWebContextSupplement() > { >- API::Object::ref(); >+ return API::Object::ref(); > } > >-void WebMediaSessionFocusManager::derefWebContextSupplement() >+void WebMediaSessionFocusManager::derefWebContextSupplement(RefTrackingToken token) > { >- API::Object::deref(); >+ API::Object::deref(token); > } > > void WebMediaSessionFocusManager::initializeClient(const WKMediaSessionFocusManagerClientBase* client) >diff --git a/Source/WebKit/UIProcess/WebMediaSessionFocusManager.h b/Source/WebKit/UIProcess/WebMediaSessionFocusManager.h >index 24c7037df6a0dd54323eba8307f401afc89e5092..16858fdc8b4029bca123d25aefbd825046b5a9eb 100644 >--- a/Source/WebKit/UIProcess/WebMediaSessionFocusManager.h >+++ b/Source/WebKit/UIProcess/WebMediaSessionFocusManager.h >@@ -58,8 +58,8 @@ private: > explicit WebMediaSessionFocusManager(WebProcessPool*); > > // WebContextSupplement >- void refWebContextSupplement() override; >- void derefWebContextSupplement() override; >+ RefTrackingToken refWebContextSupplement() override; >+ void derefWebContextSupplement(RefTrackingToken) override; > > void updatePlaybackAttribute(WKMediaSessionFocusManagerPlaybackAttribute, bool); > >diff --git a/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h b/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h >index 28c9889900d05fabb72ac4cfb33a71d08ce1ff20..f6141512f0d1b571a0c969fe4b12ac65b07ef038 100644 >--- a/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h >+++ b/Source/WebKit/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.h >@@ -76,8 +76,8 @@ public: > > void getAllDatabaseNames(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& openingOrigin, uint64_t callbackID) final; > >- void ref() override { RefCounted<WebIDBConnectionToServer>::ref(); } >- void deref() override { RefCounted<WebIDBConnectionToServer>::deref(); } >+ RefTrackingToken ref() override { return RefCounted<WebIDBConnectionToServer>::ref(); } >+ void deref(RefTrackingToken token) override { RefCounted<WebIDBConnectionToServer>::deref(token); } > > // Messages received from StorageProcess > void didDeleteDatabase(const WebCore::IDBResultData&); >diff --git a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp >index f55b6fe1fe70ebb93ea5731b91a6e9a8c6606f07..2b45b446be1005882dfd971885d01713ba897a32 100644 >--- a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp >+++ b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp >@@ -61,7 +61,7 @@ void InjectedBundlePageLoaderClient::willLoadURLRequest(WebPage& page, const Res > static void releaseSharedBuffer(unsigned char*, const void* data) > { > // Balanced by ref() in InjectedBundlePageLoaderClient::willLoadDataRequest(). >- static_cast<SharedBuffer*>(const_cast<void*>(data))->deref(); >+ static_cast<SharedBuffer*>(const_cast<void*>(data))->deref(UntrackedRefToken()); > } > > void InjectedBundlePageLoaderClient::willLoadDataRequest(WebPage& page, const ResourceRequest& request, SharedBuffer* sharedBuffer, const String& MIMEType, const String& encodingName, const URL& unreachableURL, API::Object* userData) >diff --git a/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm b/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm >index 5307e26a7637e8a69b045abb92879f3f8c6586f2..2354c9b683ea87680da791f8765f90a16b1b702c 100644 >--- a/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm >+++ b/Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm >@@ -943,7 +943,7 @@ static void jsPDFDocInitialize(JSContextRef ctx, JSObjectRef object) > static void jsPDFDocFinalize(JSObjectRef object) > { > PDFPlugin* pdfView = static_cast<PDFPlugin*>(JSObjectGetPrivate(object)); >- pdfView->deref(); >+ pdfView->deref(UntrackedRefToken()); > } > > JSValueRef PDFPlugin::jsPDFDocPrint(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) >diff --git a/Source/WebKit/WebProcess/Plugins/PluginView.cpp b/Source/WebKit/WebProcess/Plugins/PluginView.cpp >index e7b80647801cce224f3e58bf0b63ad825d9c5d15..082090590f5078395630a9a9b816d18ebf4e864e 100644 >--- a/Source/WebKit/WebProcess/Plugins/PluginView.cpp >+++ b/Source/WebKit/WebProcess/Plugins/PluginView.cpp >@@ -1653,7 +1653,7 @@ void PluginView::unprotectPluginFromDestruction() > return; > } > >- deref(); >+ deref(UntrackedRefToken()); > } > > void PluginView::didFinishLoad(WebFrame* webFrame) >diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >index 1b94bbc70ad7a814349bc87f4815bc3b4f63c0c9..d0e8e9b9ea01cb7faa4834941520d1952494ce57 100644 >--- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >+++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp >@@ -136,7 +136,7 @@ void WebFrameLoaderClient::frameLoaderDestroyed() > m_frame->invalidate(); > > // Balances explicit ref() in WebFrame::create(). >- m_frame->deref(); >+ m_frame->deref(UntrackedRefToken()); > } > > bool WebFrameLoaderClient::hasHTMLView() const >diff --git a/Source/WebKit/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp b/Source/WebKit/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp >index c2faefbb24ac455699d3094a0da1d318e97b60ff..1943b88cc7db7da92948f99602396998ec35ed68 100644 >--- a/Source/WebKit/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp >+++ b/Source/WebKit/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp >@@ -151,7 +151,7 @@ public: > > static void printJobFinished(WebPrintOperationGtkUnix* printOperation) > { >- printOperation->deref(); >+ printOperation->deref(UntrackedRefToken()); > WebProcess::singleton().enableTermination(); > } > >diff --git a/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm b/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm >index b89395a40130a139a7ff47a69239bb508abf1270..d14bccb43727b833a49b185b8a66715071a951a1 100644 >--- a/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm >+++ b/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm >@@ -390,7 +390,7 @@ void TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(W > if (!m_layerTreeStateIsFrozen) > m_layerFlushScheduler.resume(); > >- webPage->deref(); >+ webPage->deref(UntrackedRefToken()); > }); > #else > function(); >diff --git a/Source/WebKitLegacy/ios/WebCoreSupport/WebGeolocation.mm b/Source/WebKitLegacy/ios/WebCoreSupport/WebGeolocation.mm >index dac61c1f5d4ae878fc11167c8eeb5f3fe23fdc40..b5b0860b36dbd3d134858e4c2f688ea19660a755 100644 >--- a/Source/WebKitLegacy/ios/WebCoreSupport/WebGeolocation.mm >+++ b/Source/WebKitLegacy/ios/WebCoreSupport/WebGeolocation.mm >@@ -56,7 +56,7 @@ - (void)setIsAllowed:(BOOL)allowed > - (void)dealloc > { > if (_private) >- reinterpret_cast<Geolocation*>(_private)->deref(); >+ reinterpret_cast<Geolocation*>(_private)->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOM.mm b/Source/WebKitLegacy/mac/DOM/DOM.mm >index 8ebb8a0daf6345f21903d6fecb24d8f14e06c2a1..b8f2132018c3521ca5c72d39ae67d301970427e5 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOM.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOM.mm >@@ -839,7 +839,7 @@ @implementation DOMNodeFilter > - (void)dealloc > { > if (_internal) >- reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref(); >+ reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMBlob.mm b/Source/WebKitLegacy/mac/DOM/DOMBlob.mm >index 4e6edc56a63ff4ca7cf4b46ce1c7724839113c6e..5f69652d6a8b9a687ac689a8fed92dbef2618926 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMBlob.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMBlob.mm >@@ -46,7 +46,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMCSSRule.mm b/Source/WebKitLegacy/mac/DOM/DOMCSSRule.mm >index d48cb3f9229ddb2bd63dd99f091fd5bc5c652d0f..9809927aa46d42dc81f1dc25998c7838ae05cf5e 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMCSSRule.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMCSSRule.mm >@@ -49,7 +49,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMCSSRuleList.mm b/Source/WebKitLegacy/mac/DOM/DOMCSSRuleList.mm >index 8efde61f75217f12d0d57b2cc3069356d4dff9f0..fbf15400292034c63e8e169c1ba84c50b2717b8d 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMCSSRuleList.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMCSSRuleList.mm >@@ -48,7 +48,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMCSSStyleDeclaration.mm b/Source/WebKitLegacy/mac/DOM/DOMCSSStyleDeclaration.mm >index 2d9fefffc15400d98733133c8a374f1d6e938ef8..817072ae9f67cdac69a8ff56dd6bb1f1f5666831 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMCSSStyleDeclaration.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMCSSStyleDeclaration.mm >@@ -51,7 +51,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMCSSValue.mm b/Source/WebKitLegacy/mac/DOM/DOMCSSValue.mm >index 0c6e074d8f3d150500091b111dd9987c88aa738f..510badf907bc893794c53c6bed5a57703f9e4b62 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMCSSValue.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMCSSValue.mm >@@ -46,7 +46,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMCounter.mm b/Source/WebKitLegacy/mac/DOM/DOMCounter.mm >index 2d1e5657ea2d668d2005b53c4859edd9d52f8bf8..109b1adb9d3d57c1beaf9bb6461d7cc6fad71bf0 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMCounter.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMCounter.mm >@@ -46,7 +46,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMEvent.mm b/Source/WebKitLegacy/mac/DOM/DOMEvent.mm >index 60cdb6e57f5be1760f4d915d38ae4a33557517cd..a1e6e0e608a7e194d01c5b5d1989cb10217531ea 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMEvent.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMEvent.mm >@@ -48,7 +48,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMFileList.mm b/Source/WebKitLegacy/mac/DOM/DOMFileList.mm >index c0ac825b63d1f9db4e96bff0609084310c06ea06..dede2060d8de856146d2ad807c56136baa291b25 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMFileList.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMFileList.mm >@@ -47,7 +47,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMHTMLCollection.mm b/Source/WebKitLegacy/mac/DOM/DOMHTMLCollection.mm >index e344098cb48e2d390f540bc1d50e6973cc43d7f1..0d419c650f9dd241eedfea5942320865bf5e2c7d 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMHTMLCollection.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMHTMLCollection.mm >@@ -50,7 +50,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMHTMLOptionsCollection.mm b/Source/WebKitLegacy/mac/DOM/DOMHTMLOptionsCollection.mm >index f770a8a14d5a83d7695e43719ee1af4dcb664ca1..2f618255af895e349ed24d941135837b11b0195f 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMHTMLOptionsCollection.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMHTMLOptionsCollection.mm >@@ -51,7 +51,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMImplementation.mm b/Source/WebKitLegacy/mac/DOM/DOMImplementation.mm >index 732cf438bd6211eab32f46219ac189acbbc99cae..a3a5e9762402a58b12da5031976e2e3e67df899b 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMImplementation.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMImplementation.mm >@@ -53,7 +53,7 @@ - (void)dealloc > if (WebCoreObjCScheduleDeallocateOnMainThread([DOMImplementation class], self)) > return; > if (_internal) >- unwrap(*self).deref(); >+ unwrap(*self).deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMMediaError.mm b/Source/WebKitLegacy/mac/DOM/DOMMediaError.mm >index a927fb234bde0fb5d506d879135bbd0aa0b66eda..c29bb4526d866451650bc4c32dbd2e26e00c6ac3 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMMediaError.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMMediaError.mm >@@ -51,7 +51,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMMediaList.mm b/Source/WebKitLegacy/mac/DOM/DOMMediaList.mm >index 9e8167a16a44b3137b23edb1a8eed45949d27d98..61888b27dbb46ff5ab53c7476db1d88c64174bd2 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMMediaList.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMMediaList.mm >@@ -48,7 +48,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMNamedNodeMap.mm b/Source/WebKitLegacy/mac/DOM/DOMNamedNodeMap.mm >index 56819332bb6742e1efedd01e2c7533577d71e3f8..6a9e6db31819a8449d71ae2cd415e688daf5f1f1 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMNamedNodeMap.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMNamedNodeMap.mm >@@ -47,7 +47,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMNode.mm b/Source/WebKitLegacy/mac/DOM/DOMNode.mm >index 25e47846d1678ccf4280c37c278febc1b37f336f..3055f7b2e13c3b693685ed081a7d0f754e09a196 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMNode.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMNode.mm >@@ -78,7 +78,7 @@ - (void)dealloc > if (WebCoreObjCScheduleDeallocateOnMainThread([DOMNode class], self)) > return; > if (_internal) >- unwrap(*self).deref(); >+ unwrap(*self).deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMNodeIterator.mm b/Source/WebKitLegacy/mac/DOM/DOMNodeIterator.mm >index d77f27bf81d0f8672e8645be3b7972468f45057b..2474e1626207feb1cf74e72018b23fa2b376bf74 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMNodeIterator.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMNodeIterator.mm >@@ -51,7 +51,7 @@ - (void)dealloc > > if (_internal) { > [self detach]; >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > }; > [super dealloc]; > } >diff --git a/Source/WebKitLegacy/mac/DOM/DOMNodeList.mm b/Source/WebKitLegacy/mac/DOM/DOMNodeList.mm >index bc95dd60c94c4f111f9c4e2bb8e9285ad42105cf..f260e668f4f6288d50c747ad0c6b5410f2c16f60 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMNodeList.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMNodeList.mm >@@ -46,7 +46,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMRGBColor.mm b/Source/WebKitLegacy/mac/DOM/DOMRGBColor.mm >index ea66291bd7eee91037f3ad1462ba01267b1cbaaa..6ff532cef2c22e0b59b74f8e36b60ea8a5f649f0 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMRGBColor.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMRGBColor.mm >@@ -53,7 +53,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMRange.mm b/Source/WebKitLegacy/mac/DOM/DOMRange.mm >index f289b3a26e8a4f566b6724fb8d6151158bdb62e8..2a3ffe5128c6d2c44d20fce1ae19a60ac700e271 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMRange.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMRange.mm >@@ -49,7 +49,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMRect.mm b/Source/WebKitLegacy/mac/DOM/DOMRect.mm >index e054a2be38da7bbca132f94a3dfd210e15cfadb2..a620b43016bd133932b69d76be874815ec222603 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMRect.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMRect.mm >@@ -47,7 +47,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMStyleSheet.mm b/Source/WebKitLegacy/mac/DOM/DOMStyleSheet.mm >index 7a1a4a87fc6ef249acb9d07de254bdb2b0a3c933..809c9cbbeffe547da0c6ae51959c26e3bc6a4284 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMStyleSheet.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMStyleSheet.mm >@@ -51,7 +51,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMStyleSheetList.mm b/Source/WebKitLegacy/mac/DOM/DOMStyleSheetList.mm >index cda37e9b84f16507411bb4347f80677c4e11e672..52f2b8b894f3589ea39e1da2d85d1b6f645be7bb 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMStyleSheetList.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMStyleSheetList.mm >@@ -49,7 +49,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMTimeRanges.mm b/Source/WebKitLegacy/mac/DOM/DOMTimeRanges.mm >index 07a8876404fec55801f45a48a3cb03c51ab3e41d..eb8a8b68c02c38be1b3899de7095efe8264c096f 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMTimeRanges.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMTimeRanges.mm >@@ -50,7 +50,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMTokenList.mm b/Source/WebKitLegacy/mac/DOM/DOMTokenList.mm >index db8f55ce07aa64fd929a5f5f83ff0cbccdd77468..140f2326429f9a41b9b74af403c52d0b7a34c845 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMTokenList.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMTokenList.mm >@@ -47,7 +47,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMTreeWalker.mm b/Source/WebKitLegacy/mac/DOM/DOMTreeWalker.mm >index 580c56039f09f4c2c2d9038450ed14a112783be7..da236bcdfcddd2b0c15ad1399d7bea2cf946e031 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMTreeWalker.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMTreeWalker.mm >@@ -48,7 +48,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMXPath.mm b/Source/WebKitLegacy/mac/DOM/DOMXPath.mm >index cda837ac7d9229dca4bda63f368c3dfb949118d3..c0036c71385aa7ab2215e6a57ea252c04e1b16d8 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMXPath.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMXPath.mm >@@ -41,7 +41,7 @@ @implementation DOMNativeXPathNSResolver > - (void)dealloc > { > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMXPathExpression.mm b/Source/WebKitLegacy/mac/DOM/DOMXPathExpression.mm >index 13993b4d30257d16e0b84d845fa6c23a60460c6e..6c81da6407e3f44b3df450ff4e68374f09ed8aeb 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMXPathExpression.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMXPathExpression.mm >@@ -48,7 +48,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/DOM/DOMXPathResult.mm b/Source/WebKitLegacy/mac/DOM/DOMXPathResult.mm >index a1ef573f8dd2c10b686c119509a70242d7cf52af..42bc462da6a33b7fe37868cbcf52521921c89c17 100644 >--- a/Source/WebKitLegacy/mac/DOM/DOMXPathResult.mm >+++ b/Source/WebKitLegacy/mac/DOM/DOMXPathResult.mm >@@ -47,7 +47,7 @@ - (void)dealloc > return; > > if (_internal) >- IMPL->deref(); >+ IMPL->deref(UntrackedRefToken()); > [super dealloc]; > } > >diff --git a/Source/WebKitLegacy/mac/History/WebBackForwardList.mm b/Source/WebKitLegacy/mac/History/WebBackForwardList.mm >index 78e30f9fbe015291b2fbcc7fb14fc336020044f4..b4166120de262cdb0f23240a016ea8715f85821c 100644 >--- a/Source/WebKitLegacy/mac/History/WebBackForwardList.mm >+++ b/Source/WebKitLegacy/mac/History/WebBackForwardList.mm >@@ -120,7 +120,7 @@ - (void)dealloc > if (backForwardList) { > ASSERT(backForwardList->closed()); > backForwardLists().remove(backForwardList); >- backForwardList->deref(); >+ backForwardList->deref(UntrackedRefToken()); > } > > [super dealloc]; >diff --git a/Source/WebKitLegacy/mac/WebCoreSupport/WebSecurityOrigin.mm b/Source/WebKitLegacy/mac/WebCoreSupport/WebSecurityOrigin.mm >index 4e4c13dfb73ab64aee97d7a3739513ae492429fc..48228b63ccd88fb60a9d7f41c94975523dc45732 100644 >--- a/Source/WebKitLegacy/mac/WebCoreSupport/WebSecurityOrigin.mm >+++ b/Source/WebKitLegacy/mac/WebCoreSupport/WebSecurityOrigin.mm >@@ -104,7 +104,7 @@ - (BOOL)isEqual:(id)anObject > - (void)dealloc > { > if (_private) >- reinterpret_cast<SecurityOrigin*>(_private)->deref(); >+ reinterpret_cast<SecurityOrigin*>(_private)->deref(UntrackedRefToken()); > if (_applicationCacheQuotaManager) > [(NSObject *)_applicationCacheQuotaManager release]; > if (_databaseQuotaManager) >diff --git a/Source/WebKitLegacy/win/DOMCSSClasses.cpp b/Source/WebKitLegacy/win/DOMCSSClasses.cpp >index febb92ed813d185f593b1794ac9042be561b85ef..5c0318a9ddc911cde246f1f5621bc0c0b644c15d 100644 >--- a/Source/WebKitLegacy/win/DOMCSSClasses.cpp >+++ b/Source/WebKitLegacy/win/DOMCSSClasses.cpp >@@ -42,7 +42,7 @@ DOMCSSStyleDeclaration::DOMCSSStyleDeclaration(WebCore::CSSStyleDeclaration* s) > DOMCSSStyleDeclaration::~DOMCSSStyleDeclaration() > { > if (m_style) >- m_style->deref(); >+ m_style->deref(UntrackedRefToken()); > } > > IDOMCSSStyleDeclaration* DOMCSSStyleDeclaration::createInstance(WebCore::CSSStyleDeclaration* s) >diff --git a/Source/WebKitLegacy/win/DOMCoreClasses.cpp b/Source/WebKitLegacy/win/DOMCoreClasses.cpp >index 6e4016c5c8d8e5017ad84032fa5250bf349f3925..bc4dd5037c9a64af044218fab439da5e836447d6 100644 >--- a/Source/WebKitLegacy/win/DOMCoreClasses.cpp >+++ b/Source/WebKitLegacy/win/DOMCoreClasses.cpp >@@ -465,7 +465,7 @@ DOMNode::DOMNode(WebCore::Node* n) > DOMNode::~DOMNode() > { > if (m_node) >- m_node->deref(); >+ m_node->deref(UntrackedRefToken()); > } > > IDOMNode* DOMNode::createInstance(WebCore::Node* n) >@@ -568,7 +568,7 @@ DOMNodeList::DOMNodeList(WebCore::NodeList* l) > DOMNodeList::~DOMNodeList() > { > if (m_nodeList) >- m_nodeList->deref(); >+ m_nodeList->deref(UntrackedRefToken()); > } > > IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l) >diff --git a/Source/WebKitLegacy/win/Plugins/PluginView.cpp b/Source/WebKitLegacy/win/Plugins/PluginView.cpp >index d0cc45e2cbcfd5eb1497f0eecb8db1d2d8f388d5..aa103133ffa83d25c4996ea6b913a19b1a6faa33 100644 >--- a/Source/WebKitLegacy/win/Plugins/PluginView.cpp >+++ b/Source/WebKitLegacy/win/Plugins/PluginView.cpp >@@ -1158,7 +1158,7 @@ const char* PluginView::userAgentStatic() > > void PluginView::lifeSupportTimerFired() > { >- deref(); >+ deref(UntrackedRefToken()); > } > > void PluginView::keepAlive() >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 3ad6772a8a07b5ea6819e7bb50bf6e7ba66efd99..aacb00961af5c78842a8ade721b2c039204fa3c7 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,62 @@ >+2018-08-30 Simon Fraser <simon.fraser@apple.com> >+ >+ Make it possible to track unbalanced ref()/deref() >+ https://bugs.webkit.org/show_bug.cgi?id=186269 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add RefTrackingToken which simply wraps an unsigned value. This uniquely tracks one >+ call to ref(), and should passed back to deref(), allowing them to be paired. Change >+ Ref and RefPtr to store RefTrackingTokens, so that their ref()/deref() are always paired. >+ >+ All implementations of ref() now return a RefTrackingToken, and deref() take a RefTrackingToken. >+ If ENABLE_REF_TRACKING is not defined, this is just an empty class. >+ >+ In code which isn't able to pair ref() and deref(), UntrackedRefToken is used to indicate >+ that these references are not tracked. Many such sites could be easily fixed to track references, >+ which can be done incrementally as necessary to investigate leaks. >+ >+ RefTracker provides functionality to keep track of ref()/deref() pairs via these tokens. >+ >+ If you are investigating a leak of a ref-counted class, add a RefTracker member variable, >+ and have its ref() return m_refTracker.trackRef(), and its deref() call m_refTracker.trackDeref(token). >+ At some point where you expect to have released all references to an instance, but it's still alive, >+ call m_refTracker.dumpRemainingReferences(), and it will print out all of the unbalanced ref() >+ callstacks. >+ >+ This patch adds a RefTracker to Node (behind the #ifdef), so that all Elements and Documents can be tracked. >+ >+ If ENABLE_REF_TRACKING is not defined, these changes should mostly be a no-op. Define >+ ENABLE_REF_TRACKING to 1 in RefTracking.h to enable tracking. >+ >+ * DumpRenderTree/TestRunner.cpp: >+ (testRunnerObjectFinalize): >+ * TestRunnerShared/Bindings/JSWrapper.cpp: >+ (WTR::JSWrapper::finalize): >+ * TestWebKitAPI/Tests/WTF/HashMap.cpp: >+ (TestWebKitAPI::TEST): >+ * TestWebKitAPI/Tests/WTF/HashSet.cpp: >+ (TestWebKitAPI::TEST): >+ * TestWebKitAPI/Tests/WTF/MetaAllocator.cpp: >+ * TestWebKitAPI/Tests/WTF/PoisonedRef.cpp: >+ (TestWebKitAPI::PoisonedRefCheckingRefLogger::ref): >+ (TestWebKitAPI::PoisonedRefCheckingRefLogger::deref): >+ * TestWebKitAPI/Tests/WTF/PoisonedRefPtr.cpp: >+ (TestWebKitAPI::PoisonedRefPtrCheckingRefLogger::ref): >+ (TestWebKitAPI::PoisonedRefPtrCheckingRefLogger::deref): >+ * TestWebKitAPI/Tests/WTF/Ref.cpp: >+ (TestWebKitAPI::RefCheckingRefLogger::ref): >+ (TestWebKitAPI::RefCheckingRefLogger::deref): >+ * TestWebKitAPI/Tests/WTF/RefLogger.cpp: >+ (TestWebKitAPI::RefLogger::ref): >+ (TestWebKitAPI::RefLogger::deref): >+ * TestWebKitAPI/Tests/WTF/RefLogger.h: >+ * TestWebKitAPI/Tests/WTF/RefPtr.cpp: >+ (TestWebKitAPI::RefPtrCheckingRefLogger::ref): >+ (TestWebKitAPI::RefPtrCheckingRefLogger::deref): >+ * TestWebKitAPI/Tests/WTF/Threading.cpp: >+ (TestWebKitAPI::TEST): >+ > 2018-08-29 Jer Noble <jer.noble@apple.com> > > Unreviewed test gardening; NowPlayingTest API tests require High Sierra. >diff --git a/Tools/DumpRenderTree/TestRunner.cpp b/Tools/DumpRenderTree/TestRunner.cpp >index a5c0d809dc30b611cb4332fb690e6ed3ea8c3ba9..487cb71ba432ee6f0f19550abd2fbf71ab9a5ea7 100644 >--- a/Tools/DumpRenderTree/TestRunner.cpp >+++ b/Tools/DumpRenderTree/TestRunner.cpp >@@ -2061,7 +2061,7 @@ static JSValueRef runUIScriptCallback(JSContextRef context, JSObjectRef, JSObjec > static void testRunnerObjectFinalize(JSObjectRef object) > { > TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(object)); >- controller->deref(); >+ controller->deref(UntrackedRefToken()); > } > > // Object Creation >diff --git a/Tools/MiniBrowser/win/MainWindow.cpp b/Tools/MiniBrowser/win/MainWindow.cpp >index f90528c465d9c6d1cca647554de858f5cfe60a31..a22351241afa1a558207069596f57765ebb67be1 100644 >--- a/Tools/MiniBrowser/win/MainWindow.cpp >+++ b/Tools/MiniBrowser/win/MainWindow.cpp >@@ -243,7 +243,7 @@ LRESULT CALLBACK MainWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPA > break; > case WM_DESTROY: > SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); >- thisWindow->deref(); >+ thisWindow->deref(UntrackedRefToken()); > if (s_numInstances > 1) > return 0; > #if USE(CF) >diff --git a/Tools/MiniBrowser/win/WebKitLegacyBrowserWindow.cpp b/Tools/MiniBrowser/win/WebKitLegacyBrowserWindow.cpp >index d3f88ba3fb320655ebc874c52f18c8e175996f00..732a23575cb9dd23c0fc96005f5f5e8f94d794d0 100644 >--- a/Tools/MiniBrowser/win/WebKitLegacyBrowserWindow.cpp >+++ b/Tools/MiniBrowser/win/WebKitLegacyBrowserWindow.cpp >@@ -82,7 +82,7 @@ ULONG WebKitLegacyBrowserWindow::AddRef() > ULONG WebKitLegacyBrowserWindow::Release() > { > auto count = refCount(); >- deref(); >+ deref(UntrackedRefToken()); > return --count; > } > >diff --git a/Tools/TestRunnerShared/Bindings/JSWrapper.cpp b/Tools/TestRunnerShared/Bindings/JSWrapper.cpp >index 6f47c1062ee68cf254c297652f2a660feced38a4..942db487d915a68680428f6dc94aaa76fe03122f 100644 >--- a/Tools/TestRunnerShared/Bindings/JSWrapper.cpp >+++ b/Tools/TestRunnerShared/Bindings/JSWrapper.cpp >@@ -74,7 +74,7 @@ void JSWrapper::finalize(JSObjectRef object) > JSWrappable* wrappable = unwrapObject(object); > if (!wrappable) > return; >- wrappable->deref(); >+ wrappable->deref(UntrackedRefToken()); > } > > } // namespace WTR >diff --git a/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp b/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp >index 4399da82384a6dd5ebb68278bbc1ccd7d44afea3..17e0589af39ced4755d96e7364dd5ff21cb8f076 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp >@@ -674,11 +674,12 @@ TEST(WTF_HashMap, ValueIsDestructedOnRemove) > TEST(WTF_HashMap, RefPtrNotZeroedBeforeDeref) > { > struct DerefObserver { >- NEVER_INLINE void ref() >+ NEVER_INLINE RefTrackingToken ref() > { > ++count; >+ return UntrackedRefToken(); > } >- NEVER_INLINE void deref() >+ NEVER_INLINE void deref(RefTrackingToken) > { > --count; > observedBucket = bucketAddress->get(); >diff --git a/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp b/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp >index fff6b08bb834442374391eebd5eeb674b989ca44..ccdb3304ddd37e25e287385366d424332932f54c 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp >@@ -283,11 +283,12 @@ TEST(WTF_HashSet, CopyCapacityIsNotOnBoundary) > TEST(WTF_HashSet, RefPtrNotZeroedBeforeDeref) > { > struct DerefObserver { >- NEVER_INLINE void ref() >+ NEVER_INLINE RefTrackingToken ref() > { > ++count; >+ return UntrackedRefToken(); > } >- NEVER_INLINE void deref() >+ NEVER_INLINE void deref(RefTrackingToken) > { > --count; > observedBucket = bucketAddress->get(); >diff --git a/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp b/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp >index 85304003106d475319f84acab786ed678bb49b08..0d6f0800044324b4914af88ceaf9a90d35cae3f5 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/MetaAllocator.cpp >@@ -209,7 +209,7 @@ public: > EXPECT_TRUE(handle); > > notifyFree(handle->start().untaggedPtr(), handle->sizeInBytes()); >- handle->deref(); >+ handle->deref(UntrackedRefToken()); > > if (sanityCheckMode == RunSanityCheck) > sanityCheck(); >diff --git a/Tools/TestWebKitAPI/Tests/WTF/PoisonedRef.cpp b/Tools/TestWebKitAPI/Tests/WTF/PoisonedRef.cpp >index 3be228f7fceec51633c984f86465d896b55bc588..d73b41184e98ff6d73c2abcb58326e23bef98225 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/PoisonedRef.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/PoisonedRef.cpp >@@ -259,8 +259,8 @@ struct PoisonedRefCheckingRefLogger : RefLogger { > using Ref = PoisonedRef<PoisonB, PoisonedRefCheckingRefLogger>; > > PoisonedRefCheckingRefLogger(const char* name); >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > const Ref* slotToCheck { nullptr }; > }; > >@@ -273,18 +273,18 @@ PoisonedRefCheckingRefLogger::PoisonedRefCheckingRefLogger(const char* name) > { > } > >-void PoisonedRefCheckingRefLogger::ref() >+RefTrackingToken PoisonedRefCheckingRefLogger::ref() > { > if (slotToCheck) > log() << "slot=" << slotToCheck->get().name << " "; >- RefLogger::ref(); >+ return RefLogger::ref(); > } > >-void PoisonedRefCheckingRefLogger::deref() >+void PoisonedRefCheckingRefLogger::deref(RefTrackingToken token) > { > if (slotToCheck) > log() << "slot=" << slotToCheck->get().name << " "; >- RefLogger::deref(); >+ RefLogger::deref(token); > } > > DerivedPoisonedRefCheckingRefLogger::DerivedPoisonedRefCheckingRefLogger(const char* name) >diff --git a/Tools/TestWebKitAPI/Tests/WTF/PoisonedRefPtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/PoisonedRefPtr.cpp >index fb40cf649382ed7b70755bfcd7ad86d4eaf8dab0..b76354ac314ae362a0a24b3dd8f649d8c1c14b72 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/PoisonedRefPtr.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/PoisonedRefPtr.cpp >@@ -500,8 +500,8 @@ struct PoisonedRefPtrCheckingRefLogger : RefLogger { > using Ref = PoisonedRefPtr<PoisonD, PoisonedRefPtrCheckingRefLogger>; > > PoisonedRefPtrCheckingRefLogger(const char* name); >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > const Ref* slotToCheck { nullptr }; > }; > >@@ -515,18 +515,18 @@ static const char* loggerName(const PoisonedRefPtrCheckingRefLogger::Ref& pointe > return pointer ? &pointer->name : "null"; > } > >-void PoisonedRefPtrCheckingRefLogger::ref() >+RefTrackingToken PoisonedRefPtrCheckingRefLogger::ref() > { > if (slotToCheck) > log() << "slot=" << loggerName(*slotToCheck) << " "; >- RefLogger::ref(); >+ return RefLogger::ref(); > } > >-void PoisonedRefPtrCheckingRefLogger::deref() >+void PoisonedRefPtrCheckingRefLogger::deref(RefTrackingToken token) > { > if (slotToCheck) > log() << "slot=" << loggerName(*slotToCheck) << " "; >- RefLogger::deref(); >+ RefLogger::deref(token); > } > > TEST(WTF_PoisonedRefPtr, AssignBeforeDeref) >diff --git a/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp b/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp >index a5c7bd1541603bcdbc29bb7a7d21a04c1643533d..50a3159b7c19e3c45ea6ac895a7e33a76814f413 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/Ref.cpp >@@ -180,8 +180,8 @@ TEST(WTF_Ref, Swap) > > struct RefCheckingRefLogger : RefLogger { > RefCheckingRefLogger(const char* name); >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > const Ref<RefCheckingRefLogger>* slotToCheck { nullptr }; > }; > >@@ -194,18 +194,18 @@ RefCheckingRefLogger::RefCheckingRefLogger(const char* name) > { > } > >-void RefCheckingRefLogger::ref() >+RefTrackingToken RefCheckingRefLogger::ref() > { > if (slotToCheck) > log() << "slot=" << slotToCheck->get().name << " "; >- RefLogger::ref(); >+ return RefLogger::ref(); > } > >-void RefCheckingRefLogger::deref() >+void RefCheckingRefLogger::deref(RefTrackingToken token) > { > if (slotToCheck) > log() << "slot=" << slotToCheck->get().name << " "; >- RefLogger::deref(); >+ RefLogger::deref(token); > } > > DerivedRefCheckingRefLogger::DerivedRefCheckingRefLogger(const char* name) >diff --git a/Tools/TestWebKitAPI/Tests/WTF/RefLogger.cpp b/Tools/TestWebKitAPI/Tests/WTF/RefLogger.cpp >index edb2e2b4a1264dab17fd0a55d2be924b53f64029..ed2f3c912e7b088b0d654e682bdc7821b2b1f1db 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/RefLogger.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/RefLogger.cpp >@@ -33,12 +33,13 @@ RefLogger::RefLogger(const char* name) > { > } > >-void RefLogger::ref() >+RefTrackingToken RefLogger::ref() > { > log() << "ref(" << &name << ") "; >+ return UntrackedRefToken(); > } > >-void RefLogger::deref() >+void RefLogger::deref(RefTrackingToken) > { > log() << "deref(" << &name << ") "; > } >diff --git a/Tools/TestWebKitAPI/Tests/WTF/RefLogger.h b/Tools/TestWebKitAPI/Tests/WTF/RefLogger.h >index 6b412d2913a481c5cdf1edd0d1964898474283cc..d97e61fa27cd4a96caf925c90f8813c8665dd840 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/RefLogger.h >+++ b/Tools/TestWebKitAPI/Tests/WTF/RefLogger.h >@@ -26,13 +26,14 @@ > #pragma once > > #include "Logger.h" >+#include <wtf/RefTracking.h> > > namespace TestWebKitAPI { > > struct RefLogger { > RefLogger(const char* name); >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > const char& name; > }; > >diff --git a/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp b/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp >index 1ceb07ff275b96f0807a0044cd474d5b7b17e5ba..eb68bcb57287a4af727119ce97c7160a4f38b3f6 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/RefPtr.cpp >@@ -444,8 +444,8 @@ TEST(WTF_RefPtr, Const) > > struct RefPtrCheckingRefLogger : RefLogger { > RefPtrCheckingRefLogger(const char* name); >- void ref(); >- void deref(); >+ RefTrackingToken ref(); >+ void deref(RefTrackingToken); > const RefPtr<RefPtrCheckingRefLogger>* slotToCheck { nullptr }; > }; > >@@ -459,18 +459,18 @@ static const char* loggerName(const RefPtr<RefPtrCheckingRefLogger>& pointer) > return pointer ? &pointer->name : "null"; > } > >-void RefPtrCheckingRefLogger::ref() >+RefTrackingToken RefPtrCheckingRefLogger::ref() > { > if (slotToCheck) > log() << "slot=" << loggerName(*slotToCheck) << " "; >- RefLogger::ref(); >+ return RefLogger::ref(); > } > >-void RefPtrCheckingRefLogger::deref() >+void RefPtrCheckingRefLogger::deref(RefTrackingToken token) > { > if (slotToCheck) > log() << "slot=" << loggerName(*slotToCheck) << " "; >- RefLogger::deref(); >+ RefLogger::deref(token); > } > > TEST(WTF_RefPtr, AssignBeforeDeref) >diff --git a/Tools/TestWebKitAPI/Tests/WTF/Threading.cpp b/Tools/TestWebKitAPI/Tests/WTF/Threading.cpp >index 3468d15096c528b28f947e73f80913f00adadb2f..0c25c1e8c77a79bee199807efce0b7daa3a76b5e 100644 >--- a/Tools/TestWebKitAPI/Tests/WTF/Threading.cpp >+++ b/Tools/TestWebKitAPI/Tests/WTF/Threading.cpp >@@ -59,8 +59,8 @@ TEST(WTF, ThreadingThreadIdentity) > EXPECT_TRUE(thread1 != &Thread::current()); > EXPECT_TRUE(thread2 != &Thread::current()); > EXPECT_TRUE(thread1 != thread2); >- thread1->deref(); >- thread2->deref(); >+ thread1->deref(UntrackedRefToken()); >+ thread2->deref(UntrackedRefToken()); > })->waitForCompletion(); > } > #endif // USE(PTHREADS)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186269
:
341904
|
348580
|
348584
|
348586
|
348588
|
348589
|
348592
|
348595
|
348596
|
348605
|
348606
|
348608
|
348610
|
348613
|
348614
|
348632
|
348640