Bug 117140 - ASSERTION FAILED: m_isCheckingArgumentTypes || m_canExit in JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution.
Summary: ASSERTION FAILED: m_isCheckingArgumentTypes || m_canExit in JSC::DFG::Specula...
Status: RESOLVED WORKSFORME
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks: 116980
  Show dependency treegraph
 
Reported: 2013-06-03 04:43 PDT by Renata Hodovan
Modified: 2014-09-08 04:24 PDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Renata Hodovan 2013-06-03 04:43:33 PDT
The test fails in debug webkit:

function test() {
    for (var blockAlign = blockAlign; "\n" + blockAlign; -blockAlign) {
        blockAlign = "typeof new Boolean(-1)";
    }
    new blockAlign();
}

test();


Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00000000007fb8e5 in WTFCrash () at /home/reni/Data/REPOS/webkit_sec/Source/WTF/wtf/Assertions.cpp:339
339	    *(int *)(uintptr_t)0xbbadbeef = 0;
(gdb) bt
#0  0x00000000007fb8e5 in WTFCrash () at /home/reni/Data/REPOS/webkit_sec/Source/WTF/wtf/Assertions.cpp:339
#1  0x00000000005d774e in JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution (this=0x7fffffffa820, kind=JSC::Uncountable, jsValueRegs=..., node=0x0)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:308
#2  0x0000000000605a0d in JSC::DFG::SpeculativeJIT::fillSpeculateCell (this=0x7fffffffa820, edge=...)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:1186
#3  0x00000000005f2eb9 in JSC::DFG::SpeculateCellOperand::gpr (this=0x7fffffff6a00)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:2780
#4  0x00000000005f2d98 in JSC::DFG::SpeculateCellOperand::SpeculateCellOperand (this=0x7fffffff6a00, jit=0x7fffffffa820, edge=..., 
    mode=JSC::DFG::AutomaticOperandSpeculation) at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:2755
#5  0x00000000005e36cc in JSC::DFG::SpeculativeJIT::compileMakeRope (this=0x7fffffffa820, node=0x7fffb20f0620)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:3168
#6  0x000000000060b1d1 in JSC::DFG::SpeculativeJIT::compile (this=0x7fffffffa820, node=0x7fffb20f0620)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:2170
#7  0x00000000005dcf59 in JSC::DFG::SpeculativeJIT::compile (this=0x7fffffffa820, block=...)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:1795
#8  0x00000000005dd666 in JSC::DFG::SpeculativeJIT::compile (this=0x7fffffffa820)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:1913
#9  0x00000000005ac2ea in JSC::DFG::JITCompiler::compileBody (this=0x7fffffffb450, speculative=...)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp:108
#10 0x00000000005ad503 in JSC::DFG::JITCompiler::compileFunction (this=0x7fffffffb450, entry=..., entryWithArityCheck=...)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp:302
#11 0x000000000059ac1e in JSC::DFG::compile (compileMode=JSC::DFG::CompileFunction, exec=0x7fffb21c20a0, codeBlock=0xf42e30, jitCode=..., 
    jitCodeWithArityCheck=0x7fffb217fdc0, osrEntryBytecodeIndex=9) at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGDriver.cpp:164
#12 0x000000000059a424 in JSC::DFG::tryCompileFunction (exec=0x7fffb21c20a0, codeBlock=0xf42e30, jitCode=..., jitCodeWithArityCheck=..., bytecodeIndex=9)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/dfg/DFGDriver.cpp:182
#13 0x00000000007355af in JSC::jitCompileFunctionIfAppropriate (exec=0x7fffb21c20a0, codeBlock=..., jitCode=..., jitCodeWithArityCheck=..., 
---Type <return> to continue, or q <return> to quit---
    jitType=JSC::JITCode::DFGJIT, bytecodeIndex=9, effort=JSC::JITCompilationCanFail)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/jit/JITDriver.h:95
#14 0x00000000007358a1 in JSC::prepareFunctionForExecution (exec=0x7fffb21c20a0, codeBlock=..., jitCode=..., jitCodeWithArityCheck=..., 
    jitType=JSC::JITCode::DFGJIT, bytecodeIndex=9, kind=JSC::CodeForCall)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/runtime/ExecutionHarness.h:68
#15 0x0000000000733c40 in JSC::FunctionExecutable::compileForCallInternal (this=0x7fffb217fd70, exec=0x7fffb21c20a0, scope=0x7ffff7f5f970, 
    jitType=JSC::JITCode::DFGJIT, bytecodeIndex=9) at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/runtime/Executable.cpp:539
#16 0x0000000000733441 in JSC::FunctionExecutable::compileOptimizedForCall (this=0x7fffb217fd70, exec=0x7fffb21c20a0, scope=0x7ffff7f5f970, bytecodeIndex=9)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/runtime/Executable.cpp:464
#17 0x000000000048430c in JSC::FunctionExecutable::compileOptimizedFor (this=0x7fffb217fd70, exec=0x7fffb21c20a0, scope=0x7ffff7f5f970, bytecodeIndex=9, 
    kind=JSC::CodeForCall) at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/runtime/Executable.h:679
#18 0x000000000047e87c in JSC::FunctionCodeBlock::compileOptimized (this=0xf51be0, exec=0x7fffb21c20a0, scope=0x7ffff7f5f970, bytecodeIndex=9)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/bytecode/CodeBlock.cpp:2843
#19 0x0000000000677f24 in JSC::cti_optimize (args=0x7fffffffccd0) at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/jit/JITStubs.cpp:1964
#20 0x00000000006750f9 in JSC::tryCacheGetByID (callFrame=0x7fffb21c20a0, codeBlock=0x7ffff7f5f970, returnAddress=..., baseValue=..., propertyName=..., 
    slot=..., stubInfo=0x7fff00000009) at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/jit/JITStubs.cpp:1068
#21 0x00007fffb21c2058 in ?? ()
#22 0x00007fff00000009 in ?? ()
#23 0x00007ffff7f7f530 in ?? ()
#24 0x00000000006483c7 in JSC::JSStack::installTrapsAfterFrame (this=0xa88d8b4810244c89, frame=0x48fffffeb88d8b48)
    at /home/reni/Data/REPOS/webkit_sec/Source/JavaScriptCore/interpreter/JSStackInlines.h:212
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Comment 1 Oliver Hunt 2013-06-03 11:13:52 PDT
function f() {for (var a =a; "\n" + a; -a) a="foo"; return a; } f()


We end up with what looks bizarre to me:
	MakeRope(KnownString:@12<String>, KnownString:@8<String>, JS|PureInt, bc#16)

Fil, does the above no make any sense?
Comment 2 Filip Pizlo 2013-06-03 11:42:35 PDT
(In reply to comment #1)
> function f() {for (var a =a; "\n" + a; -a) a="foo"; return a; } f()
> 
> 
> We end up with what looks bizarre to me:
>     MakeRope(KnownString:@12<String>, KnownString:@8<String>, JS|PureInt, bc#16)
> 
> Fil, does the above no make any sense?

Why is that bizarre?  It's a MakeRope node.  And it takes two strings.  What's the big deal?
Comment 3 Oliver Hunt 2013-06-03 11:46:46 PDT
(In reply to comment #2)
> (In reply to comment #1)
> > function f() {for (var a =a; "\n" + a; -a) a="foo"; return a; } f()
> > 
> > 
> > We end up with what looks bizarre to me:
> >     MakeRope(KnownString:@12<String>, KnownString:@8<String>, JS|PureInt, bc#16)
> > 
> > Fil, does the above no make any sense?
> 
> Why is that bizarre?  It's a MakeRope node.  And it takes two strings.  What's the big deal?

The PureInt bit
Comment 4 Filip Pizlo 2013-06-03 11:48:00 PDT
(In reply to comment #3)
> (In reply to comment #2)
> > (In reply to comment #1)
> > > function f() {for (var a =a; "\n" + a; -a) a="foo"; return a; } f()
> > > 
> > > 
> > > We end up with what looks bizarre to me:
> > >     MakeRope(KnownString:@12<String>, KnownString:@8<String>, JS|PureInt, bc#16)
> > > 
> > > Fil, does the above no make any sense?
> > 
> > Why is that bizarre?  It's a MakeRope node.  And it takes two strings.  What's the big deal?
> 
> The PureInt bit

MakeRope is dead, therefore it isn't used as a number, therefore the flags indicate PureInt.
Comment 5 Oliver Hunt 2013-06-03 12:01:56 PDT
Here the final dump prior to codegen:

Graph after optimization:
DFG for f#ECftdW:[0x106809800->0x1017ffd70, DFGFunctionCall]:
  Fixpoint state: FixpointConverged; Form: ThreadedCPS; Unification state: GloballyUnified; Ref count state: ExactRefCount
Block #0 (bc#0):  (OSR target)
  Predecessors:
  Phi Nodes:
  vars before: arg0:(Top, TOP, TOP, TOP) : r0:(None, 0:<empty>, [], []) r1:(None, 0:<empty>, [], [])
  var links: arg0:@0 : r0:- r1:-
   0:  skipped  < 0:->	SetArgument(arg0(a), bc#0)
   1:           < 2:1>	JSConstant(JS|UseAsOther, $2 = Undefined, bc#0)
   2:           < 1:->	SetLocal(@1<Other>, NodeExitsForward, r0(B~), bc#0)  predicting StringOther
   3:           < 2:2>	JSConstant(JS|UseAsOther, $0 = String: 
, bc#1)
  19:           <!0:->	Phantom(String:@3<String>, MustGen, bc#1)
  20:           <!1:1>	ToPrimitive(@1<Other>, JS|MustGen|Clobbers|PureInt, bc#1)
  21:           <!1:1>	ToString(@20<Other>, JS|MustGen|MightClobber|PureInt, bc#1)
   4:           < 1:1>	MakeRope(KnownString:@3<String>, KnownString:@21<String>, JS|PureInt, bc#1)
   5:  skipped  < 0:->	MovHint(@4<String>, r1(C~<String>), bc#1)
   6:           <!0:->	Branch(@4<String>, MustGen|CanExit, T:#1, F:#2, bc#6)
  vars after: arg0:(Top, TOP, TOP, TOP) : r0:(Other, 0:<empty>, [], [], Undefined) r1:(String, 1:NonArray, [0x1011efde0(string)], [0x1011efde0(string)])
  var links: arg0:@0 : r0:@2 r1:@5
Block #1 (bc#10):  (OSR target)
  Predecessors: #0 #1
  Phi Nodes:
  vars before: arg0:(Other, 0:<empty>, [], [], Undefined) : r0:(String, 1:NonArray, [0x1011efde0(string)], [0x1011efde0(string)], String: foo) r1:(None, 0:<empty>, [], [])
  var links: arg0:- : r0:- r1:-
   8:           < 4:1>	JSConstant(JS|UseAsOther, $1 = String: foo, bc#10)
   9:           < 1:->	SetLocal(@8<String>, NodeExitsForward, r0(B~), bc#10)  predicting StringOther
  10:           <!0:2>	ArithNegate(Check:Int32:@8<String>, Number|MustGen|PureInt|MayOverflow|CanExit, bc#13)
  11:  skipped  < 0:->	MovHint(@10<Int32>, r1(E~<Int32>), bc#13)
  12:           < 2:2>	JSConstant(JS|UseAsOther, $0 = String: 
, bc#16)
  22:           <!0:->	Phantom(String:@12<String>, MustGen, bc#16)
  23:           <!0:->	Phantom(String:@8<String>, MustGen, bc#16)
  13:           < 1:1>	MakeRope(KnownString:@12<String>, KnownString:@8<String>, JS|PureInt, bc#16)
  14:  skipped  < 0:->	MovHint(@13<String>, r1(F~<String>), bc#16)
  15:           <!0:->	Branch(@13<String>, MustGen|CanExit, T:#1, F:#2, bc#21)
  vars after: arg0:(None, 0:<empty>, [], []) : r0:(None, 0:<empty>, [], []) r1:(String, 1:NonArray, [0x1011efde0(string)], [0x1011efde0(string)])
  var links: arg0:- : r0:@9 r1:@14
Block #2 (bc#24): 
  Predecessors: #0 #1
  Phi Nodes: @25<1>->(@9, @2)
  vars before: arg0:(None, 0:<empty>, [], []) : r0:(Other, 0:<empty>, [], [], Undefined) r1:(None, 0:<empty>, [], [])
  var links: arg0:- : r0:@24 r1:-
  24:           <!0:->	PhantomLocal(@25, MustGen, r0(B~), bc#24)  predicting StringOther
  16:           < 1:1>	JSConstant(JS|UseAsOther, $2 = Undefined, bc#24)
  17:           <!0:->	Return(@16, MustGen, bc#24)
  vars after: arg0:(None, 0:<empty>, [], []) : r0:(None, 0:<empty>, [], []) r1:(None, 0:<empty>, [], [])
  var links: arg0:- : r0:@24 r1:-



The assertion fires trying to compile node 13 when loading op2, an edge pointing to node 8 (a string) but the edge claims its register format is JSInteger.  I don't understand how.why the makes sense - the assertion implies that it is unexpected.
Comment 6 Oliver Hunt 2013-06-03 12:22:35 PDT
<rdar://problem/14049853>
Comment 7 Filip Pizlo 2013-06-03 14:23:12 PDT
(In reply to comment #5)
> Here the final dump prior to codegen:
> 
> Graph after optimization:
> DFG for f#ECftdW:[0x106809800->0x1017ffd70, DFGFunctionCall]:
>   Fixpoint state: FixpointConverged; Form: ThreadedCPS; Unification state: GloballyUnified; Ref count state: ExactRefCount
> Block #0 (bc#0):  (OSR target)
>   Predecessors:
>   Phi Nodes:
>   vars before: arg0:(Top, TOP, TOP, TOP) : r0:(None, 0:<empty>, [], []) r1:(None, 0:<empty>, [], [])
>   var links: arg0:@0 : r0:- r1:-
>    0:  skipped  < 0:->    SetArgument(arg0(a), bc#0)
>    1:           < 2:1>    JSConstant(JS|UseAsOther, $2 = Undefined, bc#0)
>    2:           < 1:->    SetLocal(@1<Other>, NodeExitsForward, r0(B~), bc#0)  predicting StringOther
>    3:           < 2:2>    JSConstant(JS|UseAsOther, $0 = String: 
> , bc#1)
>   19:           <!0:->    Phantom(String:@3<String>, MustGen, bc#1)
>   20:           <!1:1>    ToPrimitive(@1<Other>, JS|MustGen|Clobbers|PureInt, bc#1)
>   21:           <!1:1>    ToString(@20<Other>, JS|MustGen|MightClobber|PureInt, bc#1)
>    4:           < 1:1>    MakeRope(KnownString:@3<String>, KnownString:@21<String>, JS|PureInt, bc#1)
>    5:  skipped  < 0:->    MovHint(@4<String>, r1(C~<String>), bc#1)
>    6:           <!0:->    Branch(@4<String>, MustGen|CanExit, T:#1, F:#2, bc#6)
>   vars after: arg0:(Top, TOP, TOP, TOP) : r0:(Other, 0:<empty>, [], [], Undefined) r1:(String, 1:NonArray, [0x1011efde0(string)], [0x1011efde0(string)])
>   var links: arg0:@0 : r0:@2 r1:@5
> Block #1 (bc#10):  (OSR target)
>   Predecessors: #0 #1
>   Phi Nodes:
>   vars before: arg0:(Other, 0:<empty>, [], [], Undefined) : r0:(String, 1:NonArray, [0x1011efde0(string)], [0x1011efde0(string)], String: foo) r1:(None, 0:<empty>, [], [])
>   var links: arg0:- : r0:- r1:-
>    8:           < 4:1>    JSConstant(JS|UseAsOther, $1 = String: foo, bc#10)
>    9:           < 1:->    SetLocal(@8<String>, NodeExitsForward, r0(B~), bc#10)  predicting StringOther
>   10:           <!0:2>    ArithNegate(Check:Int32:@8<String>, Number|MustGen|PureInt|MayOverflow|CanExit, bc#13)
>   11:  skipped  < 0:->    MovHint(@10<Int32>, r1(E~<Int32>), bc#13)
>   12:           < 2:2>    JSConstant(JS|UseAsOther, $0 = String: 
> , bc#16)
>   22:           <!0:->    Phantom(String:@12<String>, MustGen, bc#16)
>   23:           <!0:->    Phantom(String:@8<String>, MustGen, bc#16)
>   13:           < 1:1>    MakeRope(KnownString:@12<String>, KnownString:@8<String>, JS|PureInt, bc#16)
>   14:  skipped  < 0:->    MovHint(@13<String>, r1(F~<String>), bc#16)
>   15:           <!0:->    Branch(@13<String>, MustGen|CanExit, T:#1, F:#2, bc#21)
>   vars after: arg0:(None, 0:<empty>, [], []) : r0:(None, 0:<empty>, [], []) r1:(String, 1:NonArray, [0x1011efde0(string)], [0x1011efde0(string)])
>   var links: arg0:- : r0:@9 r1:@14
> Block #2 (bc#24): 
>   Predecessors: #0 #1
>   Phi Nodes: @25<1>->(@9, @2)
>   vars before: arg0:(None, 0:<empty>, [], []) : r0:(Other, 0:<empty>, [], [], Undefined) r1:(None, 0:<empty>, [], [])
>   var links: arg0:- : r0:@24 r1:-
>   24:           <!0:->    PhantomLocal(@25, MustGen, r0(B~), bc#24)  predicting StringOther
>   16:           < 1:1>    JSConstant(JS|UseAsOther, $2 = Undefined, bc#24)
>   17:           <!0:->    Return(@16, MustGen, bc#24)
>   vars after: arg0:(None, 0:<empty>, [], []) : r0:(None, 0:<empty>, [], []) r1:(None, 0:<empty>, [], [])
>   var links: arg0:- : r0:@24 r1:-
> 
> 
> 
> The assertion fires trying to compile node 13 when loading op2, an edge pointing to node 8 (a string) but the edge claims its register format is JSInteger.  I don't understand how.why the makes sense - the assertion implies that it is unexpected.

This is a harmless debug-only assertion.  We should get rid of that assertion at some point.

The DFG backend didn't realize that it unconditionally exited at node @10.  That's not really a bug.  In a release build, the backend will generate some bad code after the unconditional exit.  We don't care what code we generate after unconditional exits.

This assertion does systematically fire in code generated after unconditional exits.

We can either get rid of the assertion, or try to modify the DFG to know when it unconditionally exited.  I don't like the latter since it would be a lot of work just to silence an assertion.
Comment 8 Renata Hodovan 2014-09-08 04:24:43 PDT
The crash isn't reproducible anymore.