RESOLVED FIXED 172957
We should not claim that SpecEmpty is filtered out of cell checks on 64 bit platforms
https://bugs.webkit.org/show_bug.cgi?id=172957
Summary We should not claim that SpecEmpty is filtered out of cell checks on 64 bit p...
zhunkibatu
Reported 2017-06-05 21:48:43 PDT
the following sample can crash safari 10.1. class A { }; class B extends A { constructor(a, b) { var f = () => b ? this : {}; if (a) { var val = f() == super(); } else { super(); var val = f(); } } }; for (var i=0; i < 10000; i++) { try { new B(true, true); } catch (e) { } var a = new B(false, true); var c = new B(true, false); }
Attachments
crash log (92.85 KB, text/plain)
2017-06-06 17:25 PDT, Alexey Proskuryakov
no flags
WIP (11.67 KB, patch)
2017-06-07 20:56 PDT, Saam Barati
no flags
WIP (23.85 KB, patch)
2017-06-08 13:22 PDT, Saam Barati
no flags
WIP (28.92 KB, patch)
2017-06-08 13:39 PDT, Saam Barati
buildbot: commit-queue-
patch (33.44 KB, patch)
2017-06-08 15:44 PDT, Saam Barati
no flags
patch (32.61 KB, patch)
2017-06-08 16:30 PDT, Saam Barati
no flags
patch (32.60 KB, patch)
2017-06-08 16:51 PDT, Saam Barati
fpizlo: review-
patch (32.47 KB, patch)
2017-06-11 14:03 PDT, Saam Barati
no flags
Alexey Proskuryakov
Comment 1 2017-06-06 17:25:28 PDT
Created attachment 312144 [details] crash log
Alexey Proskuryakov
Comment 2 2017-06-06 17:26:12 PDT
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 ??? 0x00004e19b5e03ca6 0 + 85872332520614 1 com.apple.JavaScriptCore 0x00007fff9877bca0 llint_entry + 27522 2 com.apple.JavaScriptCore 0x00007fff98774f3b vmEntryToJavaScript + 299 3 com.apple.JavaScriptCore 0x00007fff9865017e JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 158 4 com.apple.JavaScriptCore 0x00007fff9861dd38 JSC::Interpreter::executeProgram(JSC::SourceCode const&, JSC::ExecState*, JSC::JSObject*) + 15192 5 com.apple.JavaScriptCore 0x00007fff982e3f31 JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 337 6 com.apple.WebCore 0x00007fff9db351c9 WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&, WebCore::ExceptionDetails*) + 313
Radar WebKit Bug Importer
Comment 3 2017-06-06 17:26:26 PDT
Saam Barati
Comment 4 2017-06-07 13:18:05 PDT
This bug is really interesting. We have code like this: ``` block#1: n: GetClosureVar(..., |this|) // this will load empty JSValue() SetLocal(Cell:@n, locFoo) // Cell check succeeds because JSValue() looks like a cell Branch(#2, #3) Block#3: x: GetLocal(locFoo) y: CheckNotEmpty(@x) ``` However, AI will think that @x is a cell, hence not empty, and we'll crash because we eliminate node @y
Filip Pizlo
Comment 5 2017-06-07 13:20:41 PDT
(In reply to Saam Barati from comment #4) > This bug is really interesting. We have code like this: > > ``` > block#1: > n: GetClosureVar(..., |this|) // this will load empty JSValue() > SetLocal(Cell:@n, locFoo) // Cell check succeeds because JSValue() looks > like a cell > Branch(#2, #3) > > Block#3: > x: GetLocal(locFoo) > y: CheckNotEmpty(@x) > ``` > > However, AI will think that @x is a cell, hence not empty, and we'll crash > because we eliminate node @y Sounds like AI should model cell checks as admitting empty on 64-bit.
Saam Barati
Comment 6 2017-06-07 13:46:28 PDT
(In reply to Filip Pizlo from comment #5) > (In reply to Saam Barati from comment #4) > > This bug is really interesting. We have code like this: > > > > ``` > > block#1: > > n: GetClosureVar(..., |this|) // this will load empty JSValue() > > SetLocal(Cell:@n, locFoo) // Cell check succeeds because JSValue() looks > > like a cell > > Branch(#2, #3) > > > > Block#3: > > x: GetLocal(locFoo) > > y: CheckNotEmpty(@x) > > ``` > > > > However, AI will think that @x is a cell, hence not empty, and we'll crash > > because we eliminate node @y > > Sounds like AI should model cell checks as admitting empty on 64-bit. I was thinking of either doing this, or we can change the value representation for TDZ sentinel.
Saam Barati
Comment 7 2017-06-07 20:56:13 PDT
Created attachment 312274 [details] WIP still a bunch of assertion failures, I need to audit more code
Saam Barati
Comment 8 2017-06-08 13:22:49 PDT
Saam Barati
Comment 9 2017-06-08 13:39:33 PDT
Saam Barati
Comment 10 2017-06-08 13:58:25 PDT
Might be all that's needed
Saam Barati
Comment 11 2017-06-08 14:05:14 PDT
(In reply to Saam Barati from comment #10) > Might be all that's needed it passes release JSC tests
Build Bot
Comment 12 2017-06-08 14:44:47 PDT
Comment on attachment 312338 [details] WIP Attachment 312338 [details] did not pass jsc-ews (mac): Output: http://webkit-queues.webkit.org/results/3895910 New failing tests: jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout-no-llint jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout-no-llint jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/arrowfunction-tdz.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout-no-llint jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout-dfg-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout-no-llint jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout-ftl-eager-no-cjit jsc-layout-tests.yaml/js/script-tests/arrowfunction-supercall.js.layout jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-name.js.layout jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout-no-llint jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout-no-ftl jsc-layout-tests.yaml/js/script-tests/arrowfunction-superproperty.js.layout-no-llint jsc-layout-tests.yaml/js/script-tests/class-syntax-extends.js.layout-no-cjit jsc-layout-tests.yaml/js/script-tests/class-syntax-super.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout-ftl-no-cjit jsc-layout-tests.yaml/js/script-tests/class-constructor-return.js.layout-no-llint
Saam Barati
Comment 13 2017-06-08 15:44:42 PDT
Saam Barati
Comment 14 2017-06-08 16:24:38 PDT
Comment on attachment 312357 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=312357&action=review > Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:134 > + WTFReportBacktrace(); oops, this should be removed.
Saam Barati
Comment 15 2017-06-08 16:30:07 PDT
Saam Barati
Comment 16 2017-06-08 16:51:38 PDT
Saam Barati
Comment 17 2017-06-08 17:12:31 PDT
Comment on attachment 312361 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=312361&action=review > Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:13447 > + FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecSymbol, isNotSymbol(cell)); We can go either way for all these various speculateX functions. They all do lowCell prior to being called, so we're guaranteed that ~SpecCell is not in the set. However, we could leave this code as is (this is how the DFG writes many of its speculation checks). This would leave these functions open to folks doing their own manual checks that haven't updated AI state.
Saam Barati
Comment 18 2017-06-08 17:15:33 PDT
Comment on attachment 312361 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=312361&action=review >> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:13447 >> + FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecSymbol, isNotSymbol(cell)); > > We can go either way for all these various speculateX functions. They all do lowCell prior to being called, so we're guaranteed that ~SpecCell is not in the set. However, we could leave this code as is (this is how the DFG writes many of its speculation checks). This would leave these functions open to folks doing their own manual checks that haven't updated AI state. Alternatively, we could assert against the current state of things. So if folks started using this in the way described above, they'd hit the assert, and be forced to write the more general version.
Filip Pizlo
Comment 19 2017-06-09 16:50:36 PDT
Comment on attachment 312361 [details] patch View in context: https://bugs.webkit.org/attachment.cgi?id=312361&action=review I think it's correct, but I think there are two style goofs: - The cellCheckTypePassthrough is not specific to the DFG - it's just how cell checks work everywhere, including LLInt, Baseline, and JSValue. I think it should be defined in SpeculatedType.h and follow the same naming convention as everything else (so SpecCellBlahBlah). - There seem to be places where you don't use this type constant and instead you introduce #if's. You should probably use the constant you introduced. > Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:63 > +// When doing a cell check, this is the type that passes through > +static constexpr SpeculatedType cellCheckTypePassthrough = is64Bit() ? SpecCellOrEmpty : SpecCell; > + I think this should be SpecCellCheck, defined in SpeculatedType.h. Even JSValue's isCell() has this issue, so it's not DFG-specific. I'd call it SpecCellCheck, but I'm also OK with SpecCellChekTypePassthrough, or whatever. Shorter names are better IMO, but I don't care too much. I care more about this not being DFG-specific, and being named SpecBlah like all the other SpeculatedType constants. > Source/JavaScriptCore/dfg/DFGUseKind.h:120 > +#if USE(JSVALUE64) > + return SpecCellOrEmpty; > +#else > + return SpecCell; > +#endif Shouldn't this use SpecCellCheck, or whatever it ends up being called? > Source/JavaScriptCore/dfg/DFGUseKind.h:128 > +#if USE(JSVALUE64) > + return SpecCellOrEmpty | SpecOther; > +#else > return SpecCell | SpecOther; > +#endif Ditto. > Source/JavaScriptCore/dfg/DFGUseKind.h:171 > +#if USE(JSVALUE64) > + return ~SpecCellOrEmpty; > +#else > return ~SpecCell; > +#endif Ditto. >>> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:13447 >>> + FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecSymbol, isNotSymbol(cell)); >> >> We can go either way for all these various speculateX functions. They all do lowCell prior to being called, so we're guaranteed that ~SpecCell is not in the set. However, we could leave this code as is (this is how the DFG writes many of its speculation checks). This would leave these functions open to folks doing their own manual checks that haven't updated AI state. > > Alternatively, we could assert against the current state of things. So if folks started using this in the way described above, they'd hit the assert, and be forced to write the more general version. I guess speculateSymbol was modeled after speculateString.
Saam Barati
Comment 20 2017-06-11 14:03:07 PDT
Created attachment 312617 [details] patch Addressed Fil's comments. I also like the name "SpecCellCheck", and decided to use that.
WebKit Commit Bot
Comment 21 2017-06-12 14:01:55 PDT
Comment on attachment 312617 [details] patch Clearing flags on attachment: 312617 Committed r218137: <http://trac.webkit.org/changeset/218137>
WebKit Commit Bot
Comment 22 2017-06-12 14:01:57 PDT
All reviewed patches have been landed. Closing bug.
Note You need to log in before you can comment on or make changes to this bug.