Changeset 38322 in webkit for trunk/JavaScriptCore/parser


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/parser
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r38249 r38322  
    586586RegisterID* EvalFunctionCallNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    587587{
    588     RefPtr<RegisterID> base = generator.tempDestination(dst);
    589     RefPtr<RegisterID> func = generator.newTemporary();
    590     generator.emitResolveWithBase(base.get(), func.get(), generator.propertyNames().eval);
    591     return generator.emitCallEval(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
     588    RefPtr<RegisterID> func = generator.tempDestination(dst);
     589    RefPtr<RegisterID> thisRegister = generator.newTemporary();
     590    generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
     591    return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    592592}
    593593
     
    608608{
    609609    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
    610     return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), divot(), startOffset(), endOffset());
     610    RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
     611    return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    611612}
    612613
     
    625626RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    626627{
    627     if (RefPtr<RegisterID> local = generator.registerFor(m_ident))
    628         return generator.emitCall(generator.finalDestination(dst), local.get(), 0, m_args.get(), divot(), startOffset(), endOffset());
     628    if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
     629        RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
     630        return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     631    }
    629632
    630633    int index = 0;
     
    633636    if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
    634637        RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
    635         return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), divot(), startOffset(), endOffset());
    636     }
    637 
    638     RefPtr<RegisterID> base = generator.tempDestination(dst);
    639     RefPtr<RegisterID> func = generator.newTemporary();
     638        RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
     639        return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
     640    }
     641
     642    RefPtr<RegisterID> func = generator.tempDestination(dst);
     643    RefPtr<RegisterID> thisRegister = generator.newTemporary();
    640644    int identifierStart = divot() - startOffset();
    641645    generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
    642     generator.emitResolveFunction(base.get(), func.get(), m_ident);
    643     return generator.emitCall(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
     646    generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
     647    return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    644648}
    645649
     
    663667    RegisterID* property = generator.emitNode(m_subscript.get());
    664668    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    665     RefPtr<RegisterID> function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
    666     return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
     669    RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
     670    RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
     671    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    667672}
    668673
     
    684689    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
    685690    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    686     RefPtr<RegisterID> function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
    687     return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), divot(), startOffset(), endOffset());
     691    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
     692    RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
     693    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
    688694}
    689695
  • trunk/JavaScriptCore/parser/Nodes.h

    r38298 r38322  
    20792079        int neededConstants()
    20802080        {
    2081             // We may need 1 more constant than the count given by the parser,
    2082             // because of the various uses of jsUndefined().
    2083             return m_numConstants + 1;
     2081            // We may need 2 more constants than the count given by the parser,
     2082            // because of the various uses of jsUndefined() and jsNull().
     2083            return m_numConstants + 2;
    20842084        }
    20852085
Note: See TracChangeset for help on using the changeset viewer.