Ignore:
Timestamp:
Jul 24, 2013, 9:01:45 PM (12 years ago)
Author:
[email protected]
Message:

fourthTier: get rid of op_call_put_result
https://bugs.webkit.org/show_bug.cgi?id=117047

Reviewed by Gavin Barraclough.

Work in progress. This still makes like 20 tests crash.

op_call_put_result is an oddball. Its semantics are that it takes the return
value of a call instruction, which is set aside in regT0/regT1, and places them
into some stack slot. This is weird since there is an implicit contract with the
preceding bytecode instruction, and it's even weirder since it means that it
doesn't make sense to jump to it; for example OSR exit from the preceding call
instruction must make sure to jump over the op_call_put_result.

So this patch gets rid of op_call_put_result:

  • In bytecode, all calls return a value and we always allocate a temporary for that value even if it isn't used.
  • The LLInt does the return value saving as part of dispatchAfterCall().
  • The JIT and DFG do the return value saving as part of normal code generation. The DFG already did the right thing.
  • DFG->JIT OSR exit in the case of inlining will make the return PC's point at the CallLinkInfo::callReturnLocation, rather than the machine PC associated with the op_call_put_result instruction.
  • Tons of code gets removed. The DFG had to track whether or not a call had a return value in a bunch of places. It had to track the fact that we would exit to after the op_call_put_result. It was a mess. That mess is now gone.
  • bytecode/CallLinkStatus.cpp:

(JSC::CallLinkStatus::computeFromLLInt):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::printCallOp):
(JSC::CodeBlock::dumpArrayProfiling):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):

  • bytecode/CodeBlock.h:
  • bytecode/Opcode.h:

(JSC):
(JSC::padOpcodeName):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitCall):
(JSC::BytecodeGenerator::emitCallVarargs):
(JSC::BytecodeGenerator::emitConstruct):

  • bytecompiler/NodesCodegen.cpp:

(JSC::NewExprNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::ByteCodeParser):
(ByteCodeParser):
(JSC::DFG::ByteCodeParser::currentCodeOrigin):
(JSC::DFG::ByteCodeParser::addCall):
(JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
(JSC::DFG::ByteCodeParser::getPrediction):
(JSC::DFG::ByteCodeParser::handleCall):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::handleMinMax):
(JSC::DFG::ByteCodeParser::handleIntrinsic):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGOSRExitCompiler.cpp:
  • dfg/DFGOSRExitCompilerCommon.cpp:

(JSC::DFG::reifyInlinedCallFrames):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • jit/JIT.h:

(JIT):

  • jit/JITCall.cpp:

(JSC::JIT::emitPutCallResult):
(JSC::JIT::compileLoadVarargs):
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):
(JSC::JIT::emit_op_call):
(JSC):
(JSC::JIT::emit_op_call_eval):
(JSC::JIT::emit_op_call_varargs):
(JSC::JIT::emit_op_construct):
(JSC::JIT::emitSlow_op_call):
(JSC::JIT::emitSlow_op_call_eval):
(JSC::JIT::emitSlow_op_call_varargs):
(JSC::JIT::emitSlow_op_construct):

  • jit/JITCall32_64.cpp:

(JSC::JIT::emitPutCallResult):
(JSC::JIT::compileLoadVarargs):
(JSC::JIT::compileCallEval):
(JSC::JIT::compileCallEvalSlowCase):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):

  • jit/JITOpcodes.cpp:

(JSC):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::genericCall):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LowLevelInterpreter.cpp:

(JSC::CLoop::execute):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
File:
1 edited

Legend:

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

    r148696 r153200  
    5252namespace JSC {
    5353
    54 void JIT::emit_op_call_put_result(Instruction* instruction)
     54void JIT::emitPutCallResult(Instruction* instruction)
    5555{
    5656    int dst = instruction[1].u.operand;
    5757    emitValueProfilingSite();
    5858    emitPutVirtualRegister(dst);
    59     if (canBeOptimizedOrInlined())
    60         killLastResultRegister(); // Make lastResultRegister tracking simpler in the DFG.
     59    if (canBeOptimizedOrInlined()) {
     60        // Make lastResultRegister tracking simpler in the DFG. This is needed because
     61        // the DFG may have the SetLocal corresponding to this Call's return value in
     62        // a different basic block, if inlining happened. The DFG isn't smart enough to
     63        // track the baseline JIT's last result register across basic blocks.
     64        killLastResultRegister();
     65    }
    6166}
    6267
    6368void JIT::compileLoadVarargs(Instruction* instruction)
    6469{
    65     int thisValue = instruction[2].u.operand;
    66     int arguments = instruction[3].u.operand;
    67     int firstFreeRegister = instruction[4].u.operand;
     70    int thisValue = instruction[3].u.operand;
     71    int arguments = instruction[4].u.operand;
     72    int firstFreeRegister = instruction[5].u.operand;
    6873
    6974    killLastResultRegister();
     
    125130}
    126131
    127 void JIT::compileCallEval()
     132void JIT::compileCallEval(Instruction* instruction)
    128133{
    129134    JITStubCall stubCall(this, cti_op_call_eval); // Initializes ScopeChain; ReturnPC; CodeBlock.
     
    133138
    134139    sampleCodeBlock(m_codeBlock);
    135 }
    136 
    137 void JIT::compileCallEvalSlowCase(Vector<SlowCaseEntry>::iterator& iter)
     140   
     141    emitPutCallResult(instruction);
     142}
     143
     144void JIT::compileCallEvalSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter)
    138145{
    139146    linkSlowCase(iter);
     
    143150
    144151    sampleCodeBlock(m_codeBlock);
     152   
     153    emitPutCallResult(instruction);
    145154}
    146155
    147156void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
    148157{
    149     int callee = instruction[1].u.operand;
     158    int callee = instruction[2].u.operand;
    150159
    151160    /* Caller always:
     
    166175        compileLoadVarargs(instruction);
    167176    else {
    168         int argCount = instruction[2].u.operand;
    169         int registerOffset = instruction[3].u.operand;
     177        int argCount = instruction[3].u.operand;
     178        int registerOffset = instruction[4].u.operand;
    170179
    171180        if (opcodeID == op_call && shouldEmitProfiling()) {
     
    173182            Jump done = emitJumpIfNotJSCell(regT0);
    174183            loadPtr(Address(regT0, JSCell::structureOffset()), regT0);
    175             storePtr(regT0, instruction[5].u.arrayProfile->addressOfLastSeenStructure());
     184            storePtr(regT0, instruction[6].u.arrayProfile->addressOfLastSeenStructure());
    176185            done.link(this);
    177186        }
     
    189198
    190199    if (opcodeID == op_call_eval) {
    191         compileCallEval();
     200        compileCallEval(instruction);
    192201        return;
    193202    }
     
    210219
    211220    sampleCodeBlock(m_codeBlock);
    212 }
    213 
    214 void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction*, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex)
     221   
     222    emitPutCallResult(instruction);
     223}
     224
     225void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex)
    215226{
    216227    if (opcodeID == op_call_eval) {
    217         compileCallEvalSlowCase(iter);
     228        compileCallEvalSlowCase(instruction, iter);
    218229        return;
    219230    }
     
    224235
    225236    sampleCodeBlock(m_codeBlock);
     237   
     238    emitPutCallResult(instruction);
    226239}
    227240
     
    272285}
    273286
     287void JIT::emit_op_call(Instruction* currentInstruction)
     288{
     289    compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
     290}
     291
     292void JIT::emit_op_call_eval(Instruction* currentInstruction)
     293{
     294    compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex);
     295}
     296
     297void JIT::emit_op_call_varargs(Instruction* currentInstruction)
     298{
     299    compileOpCall(op_call_varargs, currentInstruction, m_callLinkInfoIndex++);
     300}
     301
     302void JIT::emit_op_construct(Instruction* currentInstruction)
     303{
     304    compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
     305}
     306
     307void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     308{
     309    compileOpCallSlowCase(op_call, currentInstruction, iter, m_callLinkInfoIndex++);
     310}
     311
     312void JIT::emitSlow_op_call_eval(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     313{
     314    compileOpCallSlowCase(op_call_eval, currentInstruction, iter, m_callLinkInfoIndex);
     315}
     316 
     317void JIT::emitSlow_op_call_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     318{
     319    compileOpCallSlowCase(op_call_varargs, currentInstruction, iter, m_callLinkInfoIndex++);
     320}
     321
     322void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     323{
     324    compileOpCallSlowCase(op_construct, currentInstruction, iter, m_callLinkInfoIndex++);
     325}
     326
    274327} // namespace JSC
    275328
Note: See TracChangeset for help on using the changeset viewer.