Changeset 38322 in webkit for trunk/JavaScriptCore/bytecompiler


Ignore:
Timestamp:
Nov 11, 2008, 4:32:38 PM (17 years ago)
Author:
[email protected]
Message:

2008-11-11 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.


Fixed https://bugs.webkit.org/show_bug.cgi?id=22174
Simplified op_call by nixing its responsibility for moving the value of
"this" into the first argument slot.

Instead, the caller emits an explicit load or mov instruction, or relies
on implicit knowledge that "this" is already in the first argument slot.
As a result, two operands to op_call are gone: firstArg and thisVal.


SunSpider and v8 tests show no change in bytecode or CTI.

  • VM/CTI.cpp: (JSC::CTI::compileOpCallSetupArgs): (JSC::CTI::compileOpCallEvalSetupArgs): (JSC::CTI::compileOpConstructSetupArgs): Split apart these three versions of setting up arguments to op_call, because they're more different than they are the same -- even more so with this patch.

(JSC::CTI::compileOpCall): Updated for the fact that op_construct doesn't
match op_call anymore.

(JSC::CTI::privateCompileMainPass):
(JSC::CTI::privateCompileSlowCases): Merged a few call cases. Updated
for changes mentioned above.

  • VM/CTI.h:
  • VM/CodeBlock.cpp: (JSC::CodeBlock::dump): Updated for new bytecode format of call / construct.
  • VM/Machine.cpp: (JSC::Machine::callEval): Updated for new bytecode format of call / construct.

(JSC::Machine::dumpCallFrame):
(JSC::Machine::dumpRegisters): Simplified these debugging functions,
taking advantage of the new call frame layout.

(JSC::Machine::execute): Fixed up the eval version of execute to be
friendlier to calls in the new format.

(JSC::Machine::privateExecute): Implemented the new call format in
bytecode.

(JSC::Machine::cti_op_call_NotJSFunction):
(JSC::Machine::cti_op_construct_JSConstruct):
(JSC::Machine::cti_op_construct_NotJSConstruct):
(JSC::Machine::cti_op_call_eval): Updated CTI helpers to match the new
call format.


Fixed a latent bug in stack overflow checking that is now hit because
the register layout has changed a bit -- namely: when throwing a stack
overflow exception inside an op_call helper, we need to account for the
fact that the current call frame is only half-constructed, and use the
parent call frame instead.

  • VM/Machine.h:
  • bytecompiler/CodeGenerator.cpp: (JSC::CodeGenerator::emitCall): (JSC::CodeGenerator::emitCallEval): (JSC::CodeGenerator::emitConstruct):
  • bytecompiler/CodeGenerator.h: Updated codegen to match the new call format.
  • parser/Nodes.cpp: (JSC::EvalFunctionCallNode::emitCode): (JSC::FunctionCallValueNode::emitCode): (JSC::FunctionCallResolveNode::emitCode): (JSC::FunctionCallBracketNode::emitCode): (JSC::FunctionCallDotNode::emitCode):
  • parser/Nodes.h: (JSC::ScopeNode::neededConstants): ditto

2008-11-10 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.


Updated a test after fixing https://bugs.webkit.org/show_bug.cgi?id=22174
Simplified op_call by nixing its responsibility for moving the value of
"this" into the first argument slot.

  • fast/js/global-recursion-on-full-stack-expected.txt: This test passes a little differently now, because the register layout has changed. Specifically, the stack overflow now happens in the call to f() instead of the initiation of the <script> tag, so it is caught, and it does not log an exception to the console.
Location:
trunk/JavaScriptCore/bytecompiler
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecompiler/CodeGenerator.cpp

    r38298 r38322  
    12201220}
    12211221
    1222 RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    1223 {
    1224     return emitCall(op_call, dst, func, base, argumentsNode, divot, startOffset, endOffset);
    1225 }
    1226 
    1227 RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    1228 {
    1229     return emitCall(op_call_eval, dst, func, base, argumentsNode, divot, startOffset, endOffset);
    1230 }
    1231 
    1232 RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1222RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1223{
     1224    return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
     1225}
     1226
     1227RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1228{
     1229    return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
     1230}
     1231
     1232RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    12331233{
    12341234    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
    12351235    ASSERT(func->refCount());
    1236     ASSERT(!base || base->refCount());
    12371236   
    12381237    // Generate code for arguments.
    12391238    Vector<RefPtr<RegisterID>, 16> argv;
    1240     argv.append(newTemporary()); // reserve space for "this"
     1239    argv.append(thisRegister);
    12411240    for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
    12421241        argv.append(newTemporary());
     
    12561255    emitExpressionInfo(divot, startOffset, endOffset);
    12571256    m_codeBlock->callLinkInfos.append(CallLinkInfo());
     1257
     1258    // Emit call.
    12581259    emitOpcode(opcodeID);
    1259     instructions().append(dst->index());
    1260     instructions().append(func->index());
    1261     instructions().append(base ? base->index() : missingThisObjectMarker()); // We encode the "this" value in the instruction stream, to avoid an explicit instruction for copying or loading it.
    1262     instructions().append(argv[0]->index()); // argv
    1263     instructions().append(argv.size()); // argc
     1260    instructions().append(dst->index()); // dst
     1261    instructions().append(func->index()); // func
     1262    instructions().append(argv.size()); // argCount
    12641263    instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
    12651264
     
    13201319    emitExpressionInfo(divot, startOffset, endOffset);
    13211320    m_codeBlock->callLinkInfos.append(CallLinkInfo());
     1321
    13221322    emitOpcode(op_construct);
    1323     instructions().append(dst->index());
    1324     instructions().append(func->index());
    1325     instructions().append(funcProto->index());
    1326     instructions().append(argv[0]->index()); // argv
    1327     instructions().append(argv.size()); // argc
     1323    instructions().append(dst->index()); // dst
     1324    instructions().append(func->index()); // func
     1325    instructions().append(argv.size()); // argCount
    13281326    instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
     1327    instructions().append(funcProto->index()); // proto
     1328    instructions().append(argv[0]->index()); // thisRegister
    13291329
    13301330    emitOpcode(op_construct_verify);
  • trunk/JavaScriptCore/bytecompiler/CodeGenerator.h

    r38247 r38322  
    274274        RegisterID* emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value);
    275275
    276         RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    277         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
     276        RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
     277        RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    278278
    279279        RegisterID* emitReturn(RegisterID* src);
     
    346346        typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap;
    347347
    348         RegisterID* emitCall(OpcodeID, RegisterID*, RegisterID*, RegisterID*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
     348        RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
    349349       
    350350        RegisterID* newRegister();
Note: See TracChangeset for help on using the changeset viewer.