Ignore:
Timestamp:
Sep 10, 2012, 1:23:50 PM (13 years ago)
Author:
[email protected]
Message:

Refactored op_tear_off* to support activations that don't allocate space for 'arguments'
https://bugs.webkit.org/show_bug.cgi?id=96231

Reviewed by Gavin Barraclough.

This is a step toward smaller activations.

As a side-effect, this patch eliminates a load and branch from the hot path
of activation tear-off by moving it to the cold path of arguments tear-off. Our
optimizing assumptions are that activations are common and that reifying the
arguments object is less common.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dump):

  • bytecode/Opcode.h:

(JSC::padOpcodeName): Updated for new opcode lengths.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::addConstantValue): Added support for JSValue()
in the bytecode, which we use when we have 'arguments' but no activation.

(JSC::BytecodeGenerator::emitReturn): Always emit tear_off_arguments
if we've allocated the arguments registers. This allows tear_off_activation
not to worry about the arguments object anymore.

Also, pass the activation and arguments values directly to these opcodes
instead of requiring the opcodes to infer the values through special
registers. This gives us more flexibility to move or eliminate registers.

  • dfg/DFGArgumentsSimplificationPhase.cpp:

(JSC::DFG::ArgumentsSimplificationPhase::run):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGNode.h:

(Node): Updated for new opcode lengths.

  • dfg/DFGOperations.cpp: Activation tear-off doesn't worry about the

arguments object anymore. If 'arguments' is in use and reified, it's
responsible for aliasing back to the activation object in tear_off_arguments.

  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):
(SpeculativeJIT):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile): Don't pass the arguments object to
activation tear-off; do pass the activation object to arguments tear-off.

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute): Ditto.

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_tear_off_activation):
(JSC::JIT::emit_op_tear_off_arguments):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_tear_off_activation):
(JSC::JIT::emit_op_tear_off_arguments):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm: Same change in a few more execution engines.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r127810 r128096  
    11661166}
    11671167
    1168 void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activationCell, int32_t unmodifiedArgumentsRegister)
     1168void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activationCell)
    11691169{
    11701170    JSGlobalData& globalData = exec->globalData();
    11711171    NativeCallFrameTracer tracer(&globalData, exec);
    1172     if (!activationCell) {
    1173         if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister).jsValue()) {
    1174             if (!exec->codeBlock()->isStrictMode())
    1175                 asArguments(v)->tearOff(exec);
    1176         }
     1172    jsCast<JSActivation*>(activationCell)->tearOff(exec->globalData());
     1173}
     1174
     1175void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
     1176{
     1177    ASSERT(exec->codeBlock()->usesArguments());
     1178    if (activationCell) {
     1179        jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec->globalData(), jsCast<JSActivation*>(activationCell));
    11771180        return;
    11781181    }
    1179     JSActivation* activation = jsCast<JSActivation*>(activationCell);
    1180     activation->tearOff(exec->globalData());
    1181     if (JSValue v = exec->uncheckedR(unmodifiedArgumentsRegister).jsValue())
    1182         asArguments(v)->didTearOffActivation(exec->globalData(), activation);
    1183 }
    1184 
    1185 
    1186 void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell)
    1187 {
    1188     ASSERT(exec->codeBlock()->usesArguments());
    1189     ASSERT(!exec->codeBlock()->needsFullScopeChain());
    1190     asArguments(argumentsCell)->tearOff(exec);
     1182    jsCast<Arguments*>(argumentsCell)->tearOff(exec);
    11911183}
    11921184
    11931185void DFG_OPERATION operationTearOffInlinedArguments(
    1194     ExecState* exec, JSCell* argumentsCell, InlineCallFrame* inlineCallFrame)
    1195 {
    1196     // This should only be called when the inline code block uses arguments but does not
    1197     // need a full scope chain. We could assert it, except that the assertion would be
    1198     // rather expensive and may cause side effects that would greatly diverge debug-mode
    1199     // behavior from release-mode behavior, since getting the code block of an inline
    1200     // call frame implies call frame reification.
    1201     asArguments(argumentsCell)->tearOff(exec, inlineCallFrame);
     1186    ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
     1187{
     1188    ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
     1189    jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
    12021190}
    12031191
Note: See TracChangeset for help on using the changeset viewer.