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/interpreter/Interpreter.cpp

    r127958 r128096  
    44764476    }
    44774477    DEFINE_OPCODE(op_tear_off_activation) {
    4478         /* tear_off_activation activation(r) arguments(r)
     4478        /* tear_off_activation activation(r)
    44794479
    44804480           Copy locals and named parameters from the register file to the heap.
    4481            Point the bindings in 'activation' and 'arguments' to this new backing
    4482            store. (Note that 'arguments' may not have been created. If created,
    4483            'arguments' already holds a copy of any extra / unnamed parameters.)
     4481           Point the bindings in 'activation' to this new backing store.
    44844482
    44854483           This opcode appears before op_ret in functions that require full scope chains.
     
    44874485
    44884486        int activation = vPC[1].u.operand;
    4489         int arguments = vPC[2].u.operand;
    44904487        ASSERT(codeBlock->needsFullScopeChain());
    44914488        JSValue activationValue = callFrame->r(activation).jsValue();
    4492         if (activationValue) {
     4489        if (activationValue)
    44934490            asActivation(activationValue)->tearOff(*globalData);
    44944491
    4495             if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue())
    4496                 asArguments(argumentsValue)->didTearOffActivation(*globalData, asActivation(activationValue));
    4497         } else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
    4498             if (!codeBlock->isStrictMode())
    4499                 asArguments(argumentsValue)->tearOff(callFrame);
    4500         }
    4501 
    45024492        vPC += OPCODE_LENGTH(op_tear_off_activation);
    45034493        NEXT_INSTRUCTION();
    45044494    }
    45054495    DEFINE_OPCODE(op_tear_off_arguments) {
    4506         /* tear_off_arguments arguments(r)
     4496        /* tear_off_arguments arguments(r) activation(r)
    45074497
    45084498           Copy named parameters from the register file to the heap. Point the
    4509            bindings in 'arguments' to this new backing store. (Note that
    4510            'arguments' may not have been created. If created, 'arguments' already
    4511            holds a copy of any extra / unnamed parameters.)
     4499           bindings in 'arguments' to this new backing store. (If 'activation'
     4500           was also copied to the heap, 'arguments' will point to its storage.)
    45124501
    45134502           This opcode appears before op_ret in functions that don't require full
     
    45154504        */
    45164505
    4517         int src1 = vPC[1].u.operand;
    4518         ASSERT(!codeBlock->needsFullScopeChain() && codeBlock->ownerExecutable()->usesArguments());
    4519 
    4520         if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src1)).jsValue())
    4521             asArguments(arguments)->tearOff(callFrame);
     4506        int arguments = vPC[1].u.operand;
     4507        int activation = vPC[2].u.operand;
     4508        ASSERT(codeBlock->usesArguments());
     4509        if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
     4510            if (JSValue activationValue = callFrame->r(activation).jsValue())
     4511                asArguments(argumentsValue)->didTearOffActivation(callFrame->globalData(), asActivation(activationValue));
     4512            else
     4513                asArguments(argumentsValue)->tearOff(callFrame);
     4514        }
    45224515
    45234516        vPC += OPCODE_LENGTH(op_tear_off_arguments);
Note: See TracChangeset for help on using the changeset viewer.