Ignore:
Timestamp:
Dec 12, 2016, 1:46:45 PM (9 years ago)
Author:
[email protected]
Message:

REGRESSION(r209653): speedometer crashes making virtual slow path tailcalls
https://bugs.webkit.org/show_bug.cgi?id=165748

Reviewed by Filip Pizlo.

JSTests:

New regression test.

  • stress/regress-165748.js: Added.

(sum1):
(sum2):
(sum3):
(sum4):
(sum5):
(sum6):
(tailCaller):
(test):

Source/JavaScriptCore:

The virtual slow path for tailcalls always passes arguments on the stack.
The fix here is to link to the stack argument entrypoint instead of a register
argument entrypoint.

While fixing this bug, I found that we weren't clearing the code origin when
shuffling the call frame for a register argument tailcall.

Also rolling back in r209653, r209654, r209663, and r209673.

  • jit/CallFrameShuffler.cpp:

(JSC::CallFrameShuffler::prepareAny):

  • jit/ThunkGenerators.cpp:

(JSC::virtualThunkFor):

Source/WTF:

Rolling back in r209653, r209654, r209663, and r209673.

  • wtf/Platform.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JITCall.cpp

    r209678 r209725  
    9292
    9393    addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), regT1, stackPointerRegister);
     94    incrementCounter(this, VM::BaselineCaller);
     95    incrementCounter(this, VM::CallVarargs);
    9496}
    9597
     
    99101    storePtr(callFrameRegister, Address(regT1, CallFrame::callerFrameOffset()));
    100102
     103    incrementCounter(this, VM::BaselineCaller);
     104    incrementCounter(this, VM::CallEval);
     105
    101106    addPtr(TrustedImm32(stackPointerOffsetFor(m_codeBlock) * sizeof(Register)), callFrameRegister, stackPointerRegister);
    102107    checkStackPointerAlignment();
     
    114119{
    115120    CallLinkInfo* info = m_codeBlock->addCallLinkInfo();
    116     info->setUpCall(CallLinkInfo::Call, CodeOrigin(m_bytecodeOffset), regT0);
     121    info->setUpCall(CallLinkInfo::Call, StackArgs, CodeOrigin(m_bytecodeOffset), regT0);
    117122
    118123    linkSlowCase(iter);
     
    155160
    156161    CallLinkInfo* info = nullptr;
     162    ArgumentsLocation argumentsLocation = StackArgs;
     163
    157164    if (opcodeID != op_call_eval)
    158165        info = m_codeBlock->addCallLinkInfo();
     
    160167        compileSetupVarargsFrame(opcodeID, instruction, info);
    161168    else {
    162         int argCount = instruction[3].u.operand;
     169        unsigned argCount = instruction[3].u.unsignedValue;
    163170        int registerOffset = -instruction[4].u.operand;
    164171
     
    172179   
    173180        addPtr(TrustedImm32(registerOffset * sizeof(Register) + sizeof(CallerFrameAndPC)), callFrameRegister, stackPointerRegister);
     181        if (argumentsLocation != StackArgs) {
     182            move(TrustedImm32(argCount), argumentRegisterForArgumentCount());
     183            unsigned registerArgs = std::min(argCount, NUMBER_OF_JS_FUNCTION_ARGUMENT_REGISTERS);
     184            for (unsigned arg = 0; arg < registerArgs; arg++)
     185                load64(Address(stackPointerRegister, (CallFrameSlot::thisArgument + arg) * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)), argumentRegisterForFunctionArgument(arg));
     186        }
    174187        store32(TrustedImm32(argCount), Address(stackPointerRegister, CallFrameSlot::argumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset - sizeof(CallerFrameAndPC)));
    175188    } // SP holds newCallFrame + sizeof(CallerFrameAndPC), with ArgumentCount initialized.
     189
     190    incrementCounter(this, VM::BaselineCaller);
    176191   
    177192    uint32_t bytecodeOffset = instruction - m_codeBlock->instructions().begin();
     
    179194    store32(TrustedImm32(locationBits), Address(callFrameRegister, CallFrameSlot::argumentCount * static_cast<int>(sizeof(Register)) + TagOffset));
    180195
    181     emitGetVirtualRegister(callee, regT0); // regT0 holds callee.
    182     store64(regT0, Address(stackPointerRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
     196    GPRReg calleeRegister = argumentRegisterForCallee();
     197
     198    emitGetVirtualRegister(callee, calleeRegister);
     199    store64(calleeRegister, Address(stackPointerRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register)) - sizeof(CallerFrameAndPC)));
    183200
    184201    if (opcodeID == op_call_eval) {
     
    188205
    189206    DataLabelPtr addressOfLinkedFunctionCheck;
    190     Jump slowCase = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, TrustedImmPtr(0));
     207    Jump slowCase = branchPtrWithPatch(NotEqual, calleeRegister, addressOfLinkedFunctionCheck, TrustedImmPtr(0));
    191208    addSlowCase(slowCase);
    192209
    193210    ASSERT(m_callCompilationInfo.size() == callLinkInfoIndex);
    194     info->setUpCall(CallLinkInfo::callTypeFor(opcodeID), CodeOrigin(m_bytecodeOffset), regT0);
     211    info->setUpCall(CallLinkInfo::callTypeFor(opcodeID), argumentsLocation, CodeOrigin(m_bytecodeOffset), calleeRegister);
    195212    m_callCompilationInfo.append(CallCompilationInfo());
    196213    m_callCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
     
    198215
    199216    if (opcodeID == op_tail_call) {
     217        incrementCounter(this, VM::TailCall);
     218
    200219        CallFrameShuffleData shuffleData;
    201220        shuffleData.tagTypeNumber = GPRInfo::tagTypeNumberRegister;
     
    210229        }
    211230        shuffleData.callee =
    212             ValueRecovery::inGPR(regT0, DataFormatJS);
     231            ValueRecovery::inGPR(calleeRegister, DataFormatJS);
    213232        shuffleData.setupCalleeSaveRegisters(m_codeBlock);
    214233        info->setFrameShuffleData(shuffleData);
     
    247266        emitRestoreCalleeSaves();
    248267
    249     move(TrustedImmPtr(m_callCompilationInfo[callLinkInfoIndex].callLinkInfo), regT2);
    250 
    251     m_callCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_vm->getCTIStub(linkCallThunkGenerator).code());
     268    CallLinkInfo* callLinkInfo = m_callCompilationInfo[callLinkInfoIndex].callLinkInfo;
     269    move(TrustedImmPtr(callLinkInfo), nonArgGPR0);
     270
     271    m_callCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_vm->getJITCallThunkEntryStub(linkCallThunkGenerator).entryFor(callLinkInfo->argumentsLocation()));
    252272
    253273    if (opcodeID == op_tail_call || opcodeID == op_tail_call_varargs) {
Note: See TracChangeset for help on using the changeset viewer.