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.
Location:
trunk/Source/JavaScriptCore/bytecompiler
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r127987 r128096  
    273273    , m_codeBlock(codeBlock)
    274274    , m_thisRegister(CallFrame::thisArgumentOffset())
     275    , m_emptyValueRegister(0)
    275276    , m_finallyDepth(0)
    276277    , m_dynamicScopeDepth(0)
     
    354355    , m_codeBlock(codeBlock)
    355356    , m_activationRegister(0)
     357    , m_emptyValueRegister(0)
    356358    , m_finallyDepth(0)
    357359    , m_dynamicScopeDepth(0)
     
    387389    }
    388390
    389     // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments'
    390     // object, if created.
    391391    if (m_codeBlock->needsFullScopeChain() || functionBody->usesArguments()) {
    392392        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
     
    527527    , m_codeBlock(codeBlock)
    528528    , m_thisRegister(CallFrame::thisArgumentOffset())
     529    , m_emptyValueRegister(0)
    529530    , m_finallyDepth(0)
    530531    , m_dynamicScopeDepth(0)
     
    11121113}
    11131114
     1115// We can't hash JSValue(), so we use a dedicated data member to cache it.
     1116RegisterID* BytecodeGenerator::addConstantEmptyValue()
     1117{
     1118    if (!m_emptyValueRegister) {
     1119        int index = m_nextConstantOffset;
     1120        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
     1121        ++m_nextConstantOffset;
     1122        m_codeBlock->addConstant(JSValue());
     1123        m_emptyValueRegister = &m_constantPoolRegisters[index];
     1124    }
     1125
     1126    return m_emptyValueRegister;
     1127}
     1128
    11141129RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
    11151130{
     1131    if (!v)
     1132        return addConstantEmptyValue();
     1133
    11161134    int index = m_nextConstantOffset;
    1117 
    11181135    JSValueMap::AddResult result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
    11191136    if (result.isNewEntry) {
    11201137        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
    11211138        ++m_nextConstantOffset;
    1122         m_codeBlock->addConstant(JSValue(v));
     1139        m_codeBlock->addConstant(v);
    11231140    } else
    11241141        index = result.iterator->second;
    1125 
    11261142    return &m_constantPoolRegisters[index];
    11271143}
     
    20472063        emitOpcode(op_tear_off_activation);
    20482064        instructions().append(m_activationRegister->index());
    2049         instructions().append(m_codeBlock->argumentsRegister());
    2050     } else if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !m_codeBlock->isStrictMode()) {
     2065    }
     2066
     2067    if (m_codeBlock->usesArguments() && m_codeBlock->numParameters() != 1 && !m_codeBlock->isStrictMode()) {
    20512068        emitOpcode(op_tear_off_arguments);
    20522069        instructions().append(m_codeBlock->argumentsRegister());
     2070        instructions().append(m_activationRegister ? m_activationRegister->index() : emitLoad(0, JSValue())->index());
    20532071    }
    20542072
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r127987 r128096  
    638638        unsigned addConstant(const Identifier&);
    639639        RegisterID* addConstantValue(JSValue);
     640        RegisterID* addConstantEmptyValue();
    640641        unsigned addRegExp(RegExp*);
    641642
     
    714715        RegisterID m_calleeRegister;
    715716        RegisterID* m_activationRegister;
     717        RegisterID* m_emptyValueRegister;
    716718        SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
    717719        SegmentedVector<RegisterID, 32> m_calleeRegisters;
Note: See TracChangeset for help on using the changeset viewer.