Bug 172957 - We should not claim that SpecEmpty is filtered out of cell checks on 64 bit platforms
Summary: We should not claim that SpecEmpty is filtered out of cell checks on 64 bit p...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: Safari 10
Hardware: Mac macOS 10.12
: P2 Normal
Assignee: Saam Barati
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2017-06-05 21:48 PDT by zhunkibatu
Modified: 2017-06-12 14:01 PDT (History)
14 users (show)

See Also:


Attachments
crash log (92.85 KB, text/plain)
2017-06-06 17:25 PDT, Alexey Proskuryakov
no flags Details
WIP (11.67 KB, patch)
2017-06-07 20:56 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (23.85 KB, patch)
2017-06-08 13:22 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (28.92 KB, patch)
2017-06-08 13:39 PDT, Saam Barati
buildbot: commit-queue-
Details | Formatted Diff | Diff
patch (33.44 KB, patch)
2017-06-08 15:44 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
patch (32.61 KB, patch)
2017-06-08 16:30 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
patch (32.60 KB, patch)
2017-06-08 16:51 PDT, Saam Barati
fpizlo: review-
Details | Formatted Diff | Diff
patch (32.47 KB, patch)
2017-06-11 14:03 PDT, Saam Barati
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description zhunkibatu 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);
}
Comment 1 Alexey Proskuryakov 2017-06-06 17:25:28 PDT
Created attachment 312144 [details]
crash log
Comment 2 Alexey Proskuryakov 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
Comment 3 Radar WebKit Bug Importer 2017-06-06 17:26:26 PDT
<rdar://problem/32602704>
Comment 4 Saam Barati 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
Comment 5 Filip Pizlo 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.
Comment 6 Saam Barati 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.
Comment 7 Saam Barati 2017-06-07 20:56:13 PDT
Created attachment 312274 [details]
WIP

still a bunch of assertion failures, I need to audit more code
Comment 8 Saam Barati 2017-06-08 13:22:49 PDT
Created attachment 312337 [details]
WIP
Comment 9 Saam Barati 2017-06-08 13:39:33 PDT
Created attachment 312338 [details]
WIP
Comment 10 Saam Barati 2017-06-08 13:58:25 PDT
Might be all that's needed
Comment 11 Saam Barati 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
Comment 12 Build Bot 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
Comment 13 Saam Barati 2017-06-08 15:44:42 PDT
Created attachment 312357 [details]
patch
Comment 14 Saam Barati 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.
Comment 15 Saam Barati 2017-06-08 16:30:07 PDT
Created attachment 312359 [details]
patch
Comment 16 Saam Barati 2017-06-08 16:51:38 PDT
Created attachment 312361 [details]
patch
Comment 17 Saam Barati 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.
Comment 18 Saam Barati 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.
Comment 19 Filip Pizlo 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.
Comment 20 Saam Barati 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.
Comment 21 WebKit Commit Bot 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>
Comment 22 WebKit Commit Bot 2017-06-12 14:01:57 PDT
All reviewed patches have been landed.  Closing bug.