Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: c7f7a508727420ada216e981d0c7d6fd99a199f7
      
https://github.com/WebKit/WebKit/commit/c7f7a508727420ada216e981d0c7d6fd99a199f7
  Author: Geoffrey Garen <[email protected]>
  Date:   2025-12-18 (Thu, 18 Dec 2025)

  Changed paths:
    M Source/WTF/WTF.xcodeproj/project.pbxproj
    M Source/WTF/wtf/CMakeLists.txt
    M Source/WTF/wtf/Forward.h
    A Source/WTF/wtf/InlineWeakPtr.h
    A Source/WTF/wtf/InlineWeakRef.h
    A Source/WTF/wtf/RefCountedWithInlineWeakPtr.h
    M Source/WTF/wtf/TZoneMalloc.h
    A Source/WTF/wtf/UniquelyOwned.h
    A Source/WTF/wtf/UniquelyOwnedPtr.h
    M Source/WTF/wtf/text/TextStream.h
    M Source/WebCore/SaferCPPExpectations/NoUncountedMemberCheckerExpectations
    M Source/WebCore/SaferCPPExpectations/RefCntblBaseVirtualDtorExpectations
    M Source/WebCore/SaferCPPExpectations/UncheckedCallArgsCheckerExpectations
    M Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations
    M Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations
    M Source/WebCore/page/EventHandler.h
    M Source/WebCore/rendering/LayerAncestorClippingStack.h
    M Source/WebCore/rendering/RenderFragmentedFlow.h
    M Source/WebCore/rendering/RenderLayer.cpp
    M Source/WebCore/rendering/RenderLayer.h
    M Source/WebCore/rendering/RenderLayerBacking.cpp
    M Source/WebCore/rendering/RenderLayerBacking.h
    M Source/WebCore/rendering/RenderLayerCompositor.cpp
    M Source/WebCore/rendering/RenderLayerCompositor.h
    M Source/WebCore/rendering/RenderLayerFilters.cpp
    M Source/WebCore/rendering/RenderLayerFilters.h
    M Source/WebCore/rendering/RenderLayerModelObject.cpp
    M Source/WebCore/rendering/RenderLayerModelObject.h
    M Source/WebCore/rendering/RenderMarquee.cpp
    M Source/WebCore/rendering/RenderMarquee.h
    M Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceContainer.cpp
    M Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceContainer.h
    M Tools/TestWebKitAPI/Tests/WTF/CheckedPtr.cpp
    M Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp
    M Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp
    M Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp

  Log Message:
  -----------
  Introduce UniquelyOwned and InlineWeakPtr and use them in RenderLayer
https://bugs.webkit.org/show_bug.cgi?id=304082
<rdar://problem/166403158>

Reviewed by Ryosuke Niwa.

Example usage:

class T : public UniquelyOwned<T> {
public:
    UniquelyOwnedPtr<T> create() { return adoptUniquelyOwned(new T); }

private:
    T() { }
};

class Owner {
    UniquelyOwnedPtr<T> m_t;
};

class X {
    // Data members must be weak
    InlineWeakPtr<T> m_t1;
    InlineWeakRef<T> m_t2;
};

void X::f()
{
    // Locals must be Checked
    if (CheckedPtr checkedT1 = m_t1)
        checkedT1->g();
    ChekckedRef { m_t2 }->g();

    // CheckedPtrs in the heap are also OK, but only if they're temporary,
    // and out of scope before ~T().
    Vector<CheckedPtr<T>> tmpVector;
    HashSet<CheckedPtr<T>> tmpHashSet;
}

This patch is neutral on Speedometer, MotionMark, and Membuster.

Chris tried diligently to adopt existing smart pointers in RenderLayer data
members, but it didn't work out:

    * SingleThreadWeakPtr is a performance regression

    * CheckedPtr crashes because our pointers outlive their pointees

    * Clearing pointers eagerly to prevent CheckedPtr crashes is a performance
    regression

Solution: InlineWeakPtr. InlineWeakPtr is a counter directly inside the object.

InlineWeakPtr is always faster than SingleThreadWeakPtr because it doesn't
require allocation or double-indirection.

InlineWeakPtr is sometimes smaller and sometimes larger than
SingleThreadWeakPtr:
    * It's 24 bytes smaller when the pointee is live
    * It's equal in size when the pointee and all pointers are dead
    * It's sizeof(T) - 16 bytes larger when the pointee is dead but a
    pointer is still live.

So InlineWeakPtr is always faster, and requires some thoughtfulness about
pointee lifetime and size.

InlineWeakPtr depends internally on reference counting
(RefCountedWithInlineWeakPtr), but we want to maintain the clarity that
RenderLayer is a single-owner object. So this patch also introduces 
UniquelyOwned
and UniquelyOwnedPtr, which indicate and enforce single ownership explicitly.

UniquelyOwned also improves the safety of CheckedPtr by eliminating
    * the window of time after scribbling and before crashing during which
    pointers borrowed before scribbling might still UAF
    * the whacky macro that must be included in all subclasses

I designed UniquelyOwned and RefCountedWithInlineWeakPtr to be useable in many
more places, including thread-safe places -- but this patch doesn't take those
steps yet.

* Source/WTF/WTF.xcodeproj/project.pbxproj:
* Source/WTF/wtf/CMakeLists.txt:
* Source/WTF/wtf/Forward.h:
* Source/WTF/wtf/InlineWeakPtr.h: InlineWeakPtr is basically a copy of
RefPtr<T>, except that it calls weakRef() / weakDeref() instead of ref() / deref
(), and it checks for a non-zero refCount() before returning T*.

* Source/WTF/wtf/InlineWeakRef.h: Just like WeakRef<T>, for use in cases where
we want to verify memory safety but writing code to handle null would be absurd.

* Source/WTF/wtf/RefCountedWithInlineWeakPtr.h: The key insight of
RefCountedWithInlineWeakPtr is that the refcount gives us total control over
destruction, so we get a much tighter interface for checking validity of weak
pointers and CheckedPtrs.

* Source/WebCore/SaferCPPExpectations/NoUncountedMemberCheckerExpectations:
* Source/WebCore/SaferCPPExpectations/RefCntblBaseVirtualDtorExpectations:
* Source/WebCore/SaferCPPExpectations/UncheckedCallArgsCheckerExpectations:
* Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations:
* Source/WebCore/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations:
Updated expectations to copy RenderLayer CheckedPtr skips to RefCounted skips,
since UniquelyOwned is internally backed by refcounting.

* Source/WebCore/rendering/RenderLayer.h: Replace CanMakeSingleThreadWeakPtr<T>,
CanMakeCheckedPtr<T>, and WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR with
UniquelyOwned<T>. Yay!

* Source/WebCore/rendering/RenderMarquee.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceContainer.cpp:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceContainer.h:
Adopt InlineWeakPtr now that RenderLayer requires it.

* Tools/TestWebKitAPI/Tests/WTF/CheckedPtr.cpp:
* Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp:
* Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp:
* Tools/TestWebKitAPI/Tests/WTF/ListHashSet.cpp: Some API tests for new
CheckedPtr and InlineWeakPtr usage.

Canonical link: https://commits.webkit.org/304729@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to