[webkit-changes] [WebKit/WebKit] 31319e: Difference in semantics between jsTypeStringForVal...
Justin Michaud
noreply at github.com
Thu May 16 09:26:32 PDT 2024
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 31319e7a0b96c61cd61e17377adc648e4b8b5692
https://github.com/WebKit/WebKit/commit/31319e7a0b96c61cd61e17377adc648e4b8b5692
Author: Justin Michaud <justin at justinmichaud.com>
Date: 2024-05-16 (Thu, 16 May 2024)
Changed paths:
A JSTests/stress/getter-setter-ai.js
M Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
M Source/JavaScriptCore/runtime/Operations.cpp
Log Message:
-----------
Difference in semantics between jsTypeStringForValueWithConcurrency and buildTypeOf
https://bugs.webkit.org/show_bug.cgi?id=270659
rdar://124116542
Reviewed by Yusuke Suzuki.
Consider the given test case:
Object1: 0x30000bba0 %DL (should never getByOffset p3 of this, it is a GetterSetter)
Object2: 0x30000bc10 %DS (p3 is fine)
Before LICM:
32 0 40: D at 26:<!0:-> FilterGetByStatus(Check:Untyped:D at 7, MustGen, (Simple, <id='uid:(p1)', [0x30000bc10:[0xbc10/48144, Function, (0/0, 3/4){p1:64, p2:65, p3:66}, NonArray, Proto:0x11706ddc8, Leaf (Watched)], 0x30000bba0:[0xbba0/48032, Function, (0/0, 3/4){p1:64, p2:65, p3:66}, NonArray, Proto:0x11706ddc8, Leaf (Watched)]], [], offset = 64>, seenInJIT = true), W:SideState, bc#4, ExitValid)
33 0 40: D at 15:<!0:-> AssertNotEmpty(Check:Untyped:D at 7, MustGen, W:SideState, Exits, bc#4, ExitValid)
34 0 40: D at 28:<!0:-> CheckStructure(Cell:D at 7, MustGen, [%DS:Function, %DL:Function], R:JSCell_structureID, Exits, bc#4, ExitValid)
35 0 40: D at 29:< 2:-> GetButterfly(Cell:D at 7, Storage|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, Other, R:JSObject_butterfly, bc#4, ExitValid)
36 0 40: D at 30:< 1:-> GetByOffset(Check:Untyped:D at 29, KnownCell:D at 7, JS|PureInt, Int32, id0{p1}, 64, R:NamedProperties(0), bc#4, ExitValid) predicting Int32
... branching
6 7 40: D at 87:<!0:-> FilterGetByStatus(Check:Untyped:D at 7, MustGen, (Simple, <id='uid:(p3)', [0x30000bc10:[0xbc10/48144, Function, (0/0, 3/4){p1:64, p2:65, p3:66}, NonArray, Proto:0x11706ddc8, Leaf (Watched)]], [], offset = 66>, seenInJIT = true), W:SideState, bc#45, ExitValid)
7 7 40: D at 89:<!0:-> CheckStructure(Cell:D at 7, MustGen, [%DS:Function], R:JSCell_structureID, Exits, bc#45, ExitValid)
8 7 40: D at 91:< 2:-> GetByOffset(Check:Untyped:D at 29, KnownCell:D at 7, JS|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, BoolInt32, id3{p3}, 66, R:NamedProperties(3), bc#45, ExitValid) predicting BoolInt32
11 7 40: D at 94:< 2:-> TypeOf(Check:Untyped:Kill:D at 91, JS|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, StringIdent, Exits, bc#51, ExitValid)
Note that we never get p3 of DL
After LICM blind hoist:
34 0 41: D at 28:<!0:-> CheckStructure(Cell:D at 7, MustGen, [%DS:Function, %DL:Function], R:JSCell_structureID, Exits, bc#4, ExitValid)
35 0 41: D at 29:< 2:-> GetButterfly(Cell:D at 7, Storage|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, Other, R:JSObject_butterfly, bc#4, ExitValid)
36 0 41: D at 30:< 1:-> GetByOffset(Check:Untyped:D at 29, KnownCell:D at 7, JS|PureInt, Int32, id0{p1}, 64, R:NamedProperties(0), bc#4, ExitValid) predicting Int32
44 0 41: D at 48:<!0:-> CheckIsConstant(Cell:D at 7, MustGen, <0x13908f140, Function>, object1#B5FU55/<nogen>:[0x13909da00], Exits, bc#25, exit: bc#17, ExitValid, WasHoisted)
45 0 41: D at 91:< 2:-> GetByOffset(Check:Untyped:D at 29, KnownCell:D at 7, JS|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, BoolInt32, id3{p3}, 66, R:NamedProperties(3), bc#45, exit: bc#17, ExitValid) predicting BoolInt32
46 0 41: D at 94:< 2:-> TypeOf(Check:Untyped:Kill:D at 91, JS|PureNum|NeedsNegZero|NeedsNaNOrInfinity|UseAsOther, StringIdent, Exits, bc#51, exit: bc#17, ExitValid, WasHoisted)
The GetByOffset is hoisted without its guarding CheckStructure, and it accesses p3 unexpectedly. SafeToExecute says it is
safe because it won't crash or produce a malformed JSValue. Honestly, fair.
This patch fixes the semantic difference between AI and runtime for GetterSetter objects.
Stopping the GetterSetter from being hoisted may be too costly and restrictive, and it
doesn't get leaked anyway.
The string result (which was [object] but is now [symbol]) doesn't really matter, it should
never leak to user code anyway. Even if it does, it is just a string.
* JSTests/stress/getter-setter-ai.js: Added.
(opt):
(watchP3.cache):
(watchP3):
(main.let.object1):
(main.let.object2):
(main):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/runtime/Operations.cpp:
(JSC::jsTypeStringForValueWithConcurrency):
Originally-landed-as: 272448.708 at safari-7618-branch (b42cc4168b71). rdar://128089110
Canonical link: https://commits.webkit.org/278868@main
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