[webkit-changes] [WebKit/WebKit] 09d85c: [cocoa] Explicitly check the file extension for we...

Justin Michaud noreply at github.com
Wed May 15 17:25:25 PDT 2024


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 09d85cb271e93516c5f1e8bd00898394683772c3
      https://github.com/WebKit/WebKit/commit/09d85cb271e93516c5f1e8bd00898394683772c3
  Author: Matthew Finkel <sysrqb at apple.com>
  Date:   2024-05-15 (Wed, 15 May 2024)

  Changed paths:
    M Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm

  Log Message:
  -----------
  [cocoa] Explicitly check the file extension for webarchives when deciding quarantine
https://bugs.webkit.org/show_bug.cgi?id=271793
rdar://123902597

Reviewed by Brent Fulgham and Sihui Liu.

Currently we only check the string suffix to see if the requested file path is
a webarchive, but this isn't sufficient because the file extension isn't
guaranteed to be at the end of the string. This patch parses the string as a
file URL and then checks the file extension.

* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::isQuarantinedAndNotUserApproved):

Originally-landed-as: 272448.832 at safari-7618-branch (61f821826ece). rdar://128085972
Canonical link: https://commits.webkit.org/278838@main


  Commit: ea17d49efaade98f0f494de085a44bff77d5be07
      https://github.com/WebKit/WebKit/commit/ea17d49efaade98f0f494de085a44bff77d5be07
  Author: Charlie Wolfe <charliew at apple.com>
  Date:   2024-05-15 (Wed, 15 May 2024)

  Changed paths:
    A LayoutTests/ipc/validate-media-constraint-expected.txt
    A LayoutTests/ipc/validate-media-constraint.html
    M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in

  Log Message:
  -----------
  Add IPC validation for `WebCore::MediaConstraint`
https://bugs.webkit.org/show_bug.cgi?id=271816
rdar://125343106

Reviewed by Pascoe.

* LayoutTests/ipc/validate-media-constraint-expected.txt: Added.
* LayoutTests/ipc/validate-media-constraint.html: Added.
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:

Originally-landed-as: 272448.817 at safari-7618-branch (a734205bc9a9). rdar://128087364
Canonical link: https://commits.webkit.org/278839@main


  Commit: 475e0f544b6f8c97cf9506650cf144cb124d375c
      https://github.com/WebKit/WebKit/commit/475e0f544b6f8c97cf9506650cf144cb124d375c
  Author: Charlie Wolfe <charliew at apple.com>
  Date:   2024-05-15 (Wed, 15 May 2024)

  Changed paths:
    A LayoutTests/ipc/dirty-region-overflow-expected.txt
    A LayoutTests/ipc/dirty-region-overflow.html
    M Source/WebCore/platform/graphics/Region.cpp
    M Source/WebCore/platform/graphics/Region.h
    M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in

  Log Message:
  -----------
  Add IPC validation for `WebCore::Region::Shape`
https://bugs.webkit.org/show_bug.cgi?id=271741
rdar://125348548

Reviewed by Matt Woodrow.

* LayoutTests/ipc/dirty-region-overflow-expected.txt: Added.
* LayoutTests/ipc/dirty-region-overflow.html: Added.
* Source/WebCore/platform/graphics/Region.cpp:
(WebCore::Region::Shape::isValid const):
* Source/WebCore/platform/graphics/Region.h:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:

Originally-landed-as: 272448.816 at safari-7618-branch (63e5787d715c). rdar://128087353
Canonical link: https://commits.webkit.org/278840@main


  Commit: ab0d7793f15cf087af2e8d0f1508152881a2187b
      https://github.com/WebKit/WebKit/commit/ab0d7793f15cf087af2e8d0f1508152881a2187b
  Author: Kimmo Kinnunen <kkinnunen at apple.com>
  Date:   2024-05-15 (Wed, 15 May 2024)

  Changed paths:
    M Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp
    M Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.h
    M Tools/TestWebKitAPI/Tests/WebCore/cocoa/TestGraphicsContextGLCocoa.mm

  Log Message:
  -----------
  GraphicsContextGLANGLE does not validate clearBuffers value length
https://bugs.webkit.org/show_bug.cgi?id=271634
rdar://125222153

Reviewed by Dan Glastonbury.

Avoid passing too long or small arrays as GL_clearBuffer*v values.

* Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp:
(WebCore::GraphicsContextGLANGLE::clearBufferiv):
(WebCore::GraphicsContextGLANGLE::clearBufferuiv):
(WebCore::GraphicsContextGLANGLE::clearBufferfv):
(WebCore::GraphicsContextGLANGLE::validateClearBufferv):
* Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.h:
* Tools/TestWebKitAPI/Tests/WebCore/cocoa/TestGraphicsContextGLCocoa.mm:
(TestWebKitAPI::TEST_F):

Originally-landed-as: 272448.803 at safari-7618-branch (89ee93bd2ea4). rdar://128087675
Canonical link: https://commits.webkit.org/278841@main


  Commit: d7a70fb281247e8baeba6030d69b58b2126b022a
      https://github.com/WebKit/WebKit/commit/d7a70fb281247e8baeba6030d69b58b2126b022a
  Author: Justin Michaud <justin at justinmichaud.com>
  Date:   2024-05-15 (Wed, 15 May 2024)

  Changed paths:
    A JSTests/stress/get-by-val-hoist-above-structure-2.js
    A JSTests/stress/get-by-val-hoist-above-structure.js
    M LayoutTests/platform/mac/TestExpectations
    M Source/JavaScriptCore/dfg/DFGBasicBlock.h
    M Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
    M Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.cpp
    M Source/JavaScriptCore/dfg/DFGInPlaceAbstractState.h

  Log Message:
  -----------
  DFG Constant Folding phase can see inconsistent view of world, causing LICM to miscompile
https://bugs.webkit.org/show_bug.cgi?id=271435
rdar://124506508

Reviewed by Yusuke Suzuki.

Consider the following example:

============================================================================================================
FIRST SLEEP (before performCFA)

     D at 80:< 10:->	JSConstant(JS|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, Final, Weak:Object: 0x13a0e8140 with butterfly 0x0(base=0xfffffffffffffff8) (Structure %AJ:Object), StructureID: 40640, bc#0, ExitValid)

     D at 126:<!0:->	FilterGetByStatus(Check:Untyped:D at 80, MustGen, (Simple, <id='uid:(x)', [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){x:0, toJSON:1}, NonArray, Proto:0x1180348d8]], [], offset = 0>, seenInJIT = true), W:SideState, bc#112, ExitValid)
     D at 128:<!0:->	CheckStructure(Cell:D at 80, MustGen, [%AJ:Object], R:JSCell_structureID, Exits, bc#112, ExitValid)
     D at 133:<!0:->	FilterGetByStatus(Check:Untyped:D at 80, MustGen, (Simple, <id='uid:(toJSON),cell:(String (atomic),8Bit:(1),length:(6): toJSON, StructureID: 16976)', [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){x:0, toJSON:1}, NonArray, Proto:0x1180348d8]], [], offset = 1>, seenInJIT = true), W:SideState, bc#118, ExitValid)
     D at 136:< 4:->	GetByOffset(KnownCell:D at 80, KnownCell:D at 80, JS|PureNum|NeedsNaNOrInfinity|UseAsOther|ReallyWantsInt, BoolInt32, id6{toJSON}, 1, R:NamedProperties(6), bc#118, ExitValid)  predicting BoolInt32
     D at 138:<!0:->	Check(Check:Int32:D at 136, MustGen, Exits, bc#118, exit: bc#124, ExitValid)
     D at 140:<!0:->	Branch(Boolean:D at 35, MustGen, T:#9/w:10.000000, F:#12/w:10.000000, W:SideState, bc#124, ExitValid)

     D at 4:< 1:->	GetButterfly(Cell:D at 104, Storage|PureInt, R:JSObject_butterfly, bc#127, ExitValid)
     D at 1:<!1:->	CheckInBounds(Int32:D at 136, KnownInt32:D at 151, JS|MustGen|PureInt, Int32, Exits, bc#127, ExitValid)
     D at 143:< 3:->	GetByVal(KnownCell:D at 104, Int32:Kill:D at 136, Check:Untyped:Kill:D at 4, Check:Untyped:Kill:D at 1, JS|VarArgs|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, StringIdent, Contiguous+OriginalCopyOnWriteArray+InBoundsSaneChain+AsIs+Read, R:Butterfly_publicLength,IndexedContiguousProperties, Exits, bc#127, ExitValid)  predicting StringIdent

     %AJ:Object                                  = 0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){x:0, toJSON:1}, NonArray, Proto:0x1180348d8]

Execution:
     AI GetByOffset D at 136 AI says (BoolInt32, Int32: 0, none:StructuresAreClobbered) base: (Final, NonArray, [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){x:0, toJSON:1}, NonArray, Proto:0x1180348d8]], Object: 0x13a0e8140 with butterfly 0x0(base=0xfffffffffffffff8) (Structure 0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){x:0, toJSON:1}, NonArray, Proto:0x1180348d8]), StructureID: 40640, 1:StructuresAreWatched) state StructuresAreWatched
     AI CheckInBounds D at 1 AI says left Int32:D at 136 is Int32: 0

SECOND SLEEP (after performCFA, before performConstantFolding)

Note that the jsconstant has a structure transition at this point.

     D at 80:< 10:->	JSConstant(JS|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, Final, Weak:Object: 0x13a0e8140 with butterfly 0x8014002388(base=0x8014002380) (Structure %AR:Object), StructureID: 40976, bc#0, ExitValid)

     D at 126:<!0:->	FilterGetByStatus(Check:Untyped:D at 80, MustGen, (Simple, <id='uid:(x)', [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){toJSON:1, x:0}, NonArray, Proto:0x1180348d8]], [], offset = 0>, seenInJIT = true), W:SideState, bc#112, ExitValid)
     D at 128:<!0:->	CheckStructure(Cell:D at 80, MustGen, [%AR:Object], R:JSCell_structureID, Exits, bc#112, ExitValid)
     D at 133:<!0:->	FilterGetByStatus(Check:Untyped:D at 80, MustGen, (Simple, <id='uid:(toJSON),cell:(String (atomic),8Bit:(1),length:(6): toJSON, StructureID: 16976)', [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){toJSON:1, x:0}, NonArray, Proto:0x1180348d8]], [], offset = 1>, seenInJIT = true), W:SideState, bc#118, ExitValid)
     D at 136:< 4:->	GetByOffset(KnownCell:D at 80, KnownCell:D at 80, JS|PureNum|NeedsNaNOrInfinity|UseAsOther|ReallyWantsInt, BoolInt32, id6{toJSON}, 1, R:NamedProperties(6), bc#118, ExitValid)  predicting BoolInt32

     D at 4:< 1:->	GetButterfly(Cell:D at 104, Storage|PureInt, R:JSObject_butterfly, bc#127, ExitValid)
     D at 1:<!1:->	CheckInBounds(Int32:D at 136, KnownInt32:D at 151, JS|MustGen|PureInt, Int32, Exits, bc#127, ExitValid)
     D at 143:< 3:->	GetByVal(KnownCell:D at 104, Int32:Kill:D at 136, Check:Untyped:Kill:D at 4, Check:Untyped:Kill:D at 1, JS|VarArgs|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, StringIdent, Contiguous+OriginalCopyOnWriteArray+InBoundsSaneChain+AsIs+Read, R:Butterfly_publicLength,IndexedContiguousProperties, Exits, bc#127, ExitValid)  predicting StringIdent

     %AR:Object                                  = 0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){toJSON:1, x:0}, NonArray, Proto:0x1180348d8]
     %B6:Object                                  = 0x30000a010:[0xa010/40976, Object, (2/2, 1/4){y:64, toJSON:1, x:0}, NonArray, Proto:0x1180348d8, Leaf (Watched)]

Execution:
     AI GetByOffset D at 136 AI says (HeapTop, TOP, TOP, none:StructuresAreClobbered) base: (Final, NonArray, [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){toJSON:1, x:0}, NonArray, Proto:0x1180348d8]], Object: 0x13a0e8140 with butterfly 0x8014002388(base=0x8014002360) (Structure 0x30000a010:[0xa010/40976, Object, (2/2, 1/4){y:64, toJSON:1, x:0}, NonArray, Proto:0x1180348d8, Leaf (Watched)]), StructureID: 40976, 1:StructuresAreWatched) state StructuresAreWatched
     GetByOffset D at 136 AI says (HeapTop, TOP, TOP, 1:StructuresAreWatched)
     CheckInBounds D at 1 AI says left Int32:D at 136 is Int32: 0
     AI GetByOffset D at 136 AI says (HeapTop, TOP, TOP, none:StructuresAreClobbered) base: (Final, NonArray, [0x300009ec0:[0x9ec0/40640, Object, (2/2, 0/0){toJSON:1, x:0}, NonArray, Proto:0x1180348d8]], Object: 0x13a0e8140 with butterfly 0x8014002388(base=0x8014002360) (Structure 0x30000a010:[0xa010/40976, Object, (2/2, 1/4){y:64, toJSON:1, x:0}, NonArray, Proto:0x1180348d8, Leaf (Watched)]), StructureID: 40976, 1:StructuresAreWatched) state StructuresAreWatched

SLEEP DONE
============================================================================================================

The constant folding phase chooses to fold the CheckInBounds, but not the GetByOffset. At this point, this is still correct (although sub-optimal).

1) Why does AI disagree in these two places?

The constant folding phase doesn't re-run AI. It runs it from top to bottom on certain blocks only.
In this example, The CheckInBounds AI proof is read directly from the block, but the GetByOffset
has its value computed.

1) Why can the JSConstant's structure change without triggering a watchpoint?

The constant remains constant. We never used the fact that that it had a certain
structure anywhere, our proofs stem from the fact that we have a CheckStructure.

1) Why does the re-run AI pass in performConstantFolding not predict the GetByOffset to be constant?

The structure change causes GetPropertyConcurrently to fail to get the value concurrently.
We must assume that it is always safe to produce a more conservative result in this phase.

Note though that if the phase returned the same value as the first time around, that would still have been
correct! The answer to this question didn't change, we just lost the ability to compute it.

============================================================================================================
Why this is a problem

This is a classic example of a broad class of bugs affecting the JIT. Different passes can see different values as the mutator
changes the object graph, even for the same pass. Normally this is fine, because the compiler is always narrowing its assumptions.

Specifically, with each pass we assume more and more detailed things about the code, and guard against these assumptions
being wrong either with watchpoints or runtime checks.

In this example, we see that we CheckStructure. Then, as a result, we can elide nodes that are dominated by that check (like the
GetByOffset or the CheckInBounds). As long as we never loosen that assumption again, we are fine.

In this example, our CFA pass assumes that the GetByOffset is constant. The Constant Folding phase then assumes sometimes that it is constant,
and sometimes that it is not. This puts us in opposition to another principle, that is the idea that we should always
be able to answer any question asked of us conservatively and be safe. Up until this point, both of these ideas are holding true.

Unfortunately, we also need LICM. LICM needs to run after many assumptions have already been made, and it dramatically loosens
assumptions. In this example, LICM comes along and hoists the GetByVal(GetByOffset()) above the CheckStructure.

If we had indeed constant folded the GetByOffset too, we would be fine to do.

We should always be able to avoid constant folding safely.

LICM should be able to hoist constant values safely.

============================================================================================================
How to fix this generally

1) If AI says something is constant, just make it constant then.

This is the simplest solution, and should just work. This makes sure that what AI says is true, even if LICM moves stuff around.

This would require some re-work of the AI phase though.

1) LCIM should see that this isn't safe to move

The effects here are super specific. If LICM asked the question "If I move this, is this still safe to execute?" it would
have answered "no" in this case (without the structure check). Of course, if we hadn't removed the CheckInBounds, the answer
would be "yes," which is also fine.

One could imagine that this analysis would be pretty difficult.

1) Always run the constant folder on each block.

```
// This method is evil - it causes a huge maintenance headache and there is a gross amount of
// code devoted to it. It would be much nicer to just always run the constant folder on each
// block. But, the last time we did it, it was a 1% SunSpider regression:
// https://bugs.webkit.org/show_bug.cgi?id=133947
// So, we should probably keep this method.
void setShouldTryConstantFolding(bool tryConstantFolding) { m_shouldTryConstantFolding = tryConstantFolding; }
```

This would fix the issue though, as a failure to prove something at any point in time would not permit
that proof to be used later on.

This patch chooses the third option.

This appears to be perf-neutral on modern hardware on JS2/3 and SP2/3.

* JSTests/stress/get-by-val-hoist-above-structure.js: Added.
(opt):
(createObjectOfS1):
(createObjectOfS2):
(main):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):

Originally-landed-as: 272448.796 at safari-7618-branch (8d5ba1eecf30). rdar://128088091
Canonical link: https://commits.webkit.org/278842@main


Compare: https://github.com/WebKit/WebKit/compare/0d0caf957971...d7a70fb28124

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


More information about the webkit-changes mailing list