Bug 122597

Summary: [sh4] JavascriptCore freezes in a loop when DFG is enabled.
Product: WebKit Reporter: yannick.poirier
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Severity: Normal CC: jbriance
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   

Description yannick.poirier 2013-10-10 07:08:36 PDT
JavascriptCore freezes in a loop when DFG is enabled.

Minimal code to reproduce it:

var args = [];
for (var i = 0; i < 2000; i++ ) {
    var result = "test" in args ? 1 : 0;
Comment 1 Julien Brianceau 2013-11-02 15:02:11 PDT
Thanks for this reduced test case. FYI, I see the same issue with the js/dfg-arguments-out-of-bounds LayoutTest, and this seems to be a sh4 specific issue, as I cannot reproduce it with the traditional ARM port.

The operationInOptimize generates an endless loop in this case for sh4, looking like this:

  // The following jump comes from the repatchBuffer.relink(stubInfo.hotPathBegin.jumpAtOffset(0), CodeLocationLabel(stubRoutine->code().code())) call in tryRepatchIn function from jit/Repatch.cpp

  0x436841d8: 0xd35c  MOV.L @(92, PC), R3     // R3=0x000001e2
  0x436841da: 0x0323  BRAF R3                 // jumping to 0x436843c0 (stubRoutine->code().code())
  0x436841dc: 0x0009  NOP

  // The stubRoutine code

  // failureCases.append(stubJit.branchPtr(
  //     MacroAssembler::NotEqual,
  //     MacroAssembler::Address(baseGPR, JSCell::structureOffset()),
  //     MacroAssembler::TrustedImmPtr(structure)));
  0x436843c0: 0x6302  MOV.L @R0, R3           // @R0 is Address(baseGPR, JSCell::structureOffset())
  0x436843c2: 0xdb05  MOV.L @(5, PC), R11     // R11=0x434fe1d8
  0x436843c4: 0x33b0  CMP/EQ R11, R3
  0x436843c6: 0x8902  BT 2                    // jumping to 0x436843ce if R11==R3
  0x436843c8: 0xdd04  MOV.L @(4, PC), R13     // R13=0xfffffece
  0x436843ca: 0x0d23  BRAF R13                // jumping to 0x4368429c
  0x436843cc: 0x0009  NOP

  // stubJit.move(MacroAssembler::TrustedImm32(wasFound), resultGPR);
  0x436843ce: 0xe100  MOV #0, R1              // wasFound=0, resultGPR is R1

  // success = stubJit.jump() (in emitRestoreScratch)
  0x436843d0: 0xd303  MOV.L @(3, PC), R3      // R3=0xfffffe02
  0x436843d2: 0x0323  BRAF R3                 // jumping back to 0x436841d8
  0x436843d4: 0x0009  NOP

This is definitely an issue for sh4 port, I'll try to have a look.
Comment 2 Julien Brianceau 2013-11-03 07:32:02 PST
I get it. After comparing what was going on in x86 32-bit port compared to the sh4 one, the sh4 port should refactor its patchableJump() to return the label after the jump, like other ports (x86, arm, mips..).

A quick "dummy" fix for this issue: in tryRepatchIn function from jit/Repatch.cpp file,

        PolymorphicAccessStructureList* polymorphicStructureList;
        int listIndex;
    #if CPU(SH4)
        CodeLocationLabel successLabel = stubInfo.hotPathBegin.labelAtOffset(6);
        CodeLocationLabel successLabel = stubInfo.hotPathBegin;
        CodeLocationLabel slowCaseLabel;

I'll try to do the refactor tomorrow to submit a clean fix for this.
Comment 3 Julien Brianceau 2013-11-04 03:19:26 PST
I've created a new bug to refactor sh4 jumps: https://bugs.webkit.org/show_bug.cgi?id=122597, I'll submit a patch in it soon.

*** This bug has been marked as a duplicate of bug 123734 ***
Comment 4 Julien Brianceau 2013-11-04 03:20:53 PST
The real bug entry to refactor sh4 jumps: https://bugs.webkit.org/show_bug.cgi?id=123734