Changeset 44030 in webkit for trunk/JavaScriptCore/bytecode


Ignore:
Timestamp:
May 21, 2009, 7:34:41 PM (16 years ago)
Author:
[email protected]
Message:

2009-05-21 Gavin Barraclough <[email protected]>

Reviewed by Darin Adler.
Addition of MacroAssemblerCodeRef.h rubber stamped by Geoff Garen.

Refactor JIT code-handle objects. The representation of generated code is currently
a bit of a mess. We have a class JITCode which wraps the pointer to a block of
generated code, but this object does not reference the executable pool meaning that
external events (the pool being derefed) could make the pointer become invalid.
To overcome this both the JIT and Yarr implement further (and similar) objects to
wrap the code pointer with a RefPtr to the pool. To add to the mire, as well as the
CodeBlock containing a handle onto the code the FunctionBodyNode also contains a
copy of the code pointer which is used almost (but not entirely) uniquely to access
the JIT code for a function.

Rationalization of all this:

  • Add a new type 'MacroAssembler::CodeRef' as a handle for a block of JIT generated code.
  • Change the JIT & Yarr to internally handle code using CodeRefs.
  • Move the CodeRef (formerly anow defunct JITCodeRef) from CodeBlock to its owner node.
  • Remove the (now) redundant code pointer from FunctionBodyNode.

While tidying this up I've made the PatchBuffer return code in new allocations using a CodeRef,
and have enforced an interface that the PatchBuffer will always be used, and 'finalizeCode()' or
'finalizeCodeAddendum()' will always be called exactly once on the PatchBuffer to complete code generation.

This gives us a potentially useful hook ('PatchBuffer::performFinalization()') at the end of generation,
which may have a number of uses. It may be helpful should we wish to switch our generation
model to allow RW/RX exclusive memory, and it may be useful on non-cache-coherent platforms to
give us an oportunity to cache flush as necessary.

No performance impact.

  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToTrampoline): (JSC::AbstractMacroAssembler::CodeRef::CodeRef): (JSC::AbstractMacroAssembler::CodeRef::trampolineAt): (JSC::AbstractMacroAssembler::PatchBuffer::PatchBuffer): (JSC::AbstractMacroAssembler::PatchBuffer::~PatchBuffer): (JSC::AbstractMacroAssembler::PatchBuffer::link): (JSC::AbstractMacroAssembler::PatchBuffer::linkTailRecursive): (JSC::AbstractMacroAssembler::PatchBuffer::patch): (JSC::AbstractMacroAssembler::PatchBuffer::complete): (JSC::AbstractMacroAssembler::PatchBuffer::finalize): (JSC::AbstractMacroAssembler::PatchBuffer::entry):
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::CodeBlock): (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): (JSC::CodeBlock::setJITCode):
  • bytecode/CodeBlock.h: (JSC::CodeBlock::getBytecodeIndex): (JSC::CodeBlock::executablePool):
  • interpreter/CallFrameClosure.h:
  • interpreter/Interpreter.cpp: (JSC::Interpreter::execute): (JSC::Interpreter::prepareForRepeatCall):
  • jit/JIT.cpp: (JSC::JIT::privateCompile): (JSC::JIT::privateCompileCTIMachineTrampolines): (JSC::JIT::linkCall):
  • jit/JIT.h:
  • jit/JITCode.h: (JSC::JITCode::JITCode): (JSC::JITCode::operator bool): (JSC::JITCode::addressForCall): (JSC::JITCode::offsetOf): (JSC::JITCode::execute): (JSC::JITCode::size): (JSC::JITCode::executablePool): (JSC::JITCode::HostFunction):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::privateCompilePutByIdTransition): (JSC::JIT::privateCompilePatchGetArrayLength): (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
  • jit/JITStubs.cpp: (JSC::JITStubs::cti_vm_dontLazyLinkCall): (JSC::JITStubs::cti_vm_lazyLinkCall):
  • parser/Nodes.cpp: (JSC::ProgramNode::generateJITCode): (JSC::EvalNode::generateJITCode): (JSC::FunctionBodyNode::FunctionBodyNode): (JSC::FunctionBodyNode::createNativeThunk): (JSC::FunctionBodyNode::generateJITCode):
  • parser/Nodes.h: (JSC::ScopeNode::generatedJITCode): (JSC::ScopeNode::getExecutablePool): (JSC::ScopeNode::setJITCode): (JSC::ProgramNode::jitCode): (JSC::EvalNode::jitCode): (JSC::FunctionBodyNode::jitCode):
  • runtime/RegExp.cpp: (JSC::RegExp::match):
  • yarr/RegexJIT.cpp: (JSC::Yarr::RegexGenerator::compile): (JSC::Yarr::jitCompileRegex): (JSC::Yarr::executeRegex):
  • yarr/RegexJIT.h: (JSC::Yarr::RegexCodeBlock::RegexCodeBlock): (JSC::Yarr::RegexCodeBlock::pcreFallback): (JSC::Yarr::RegexCodeBlock::setFallback): (JSC::Yarr::RegexCodeBlock::operator bool): (JSC::Yarr::RegexCodeBlock::set): (JSC::Yarr::RegexCodeBlock::execute):
Location:
trunk/JavaScriptCore/bytecode
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r43839 r44030  
    14641464#if ENABLE(JIT)
    14651465            JIT::compile(m_globalData, &newCodeBlock);
    1466             ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);
     1466            ASSERT(newFunctionBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size());
    14671467#endif
    14681468
     
    14851485#if ENABLE(JIT)
    14861486            JIT::compile(m_globalData, &newCodeBlock);
    1487             ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);
     1487            ASSERT(newEvalBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size());
    14881488#endif
    14891489
     
    16791679
    16801680#if ENABLE(JIT)
    1681 void CodeBlock::setJITCode(JITCodeRef& jitCode)
    1682 {
    1683     m_jitCode = jitCode;
     1681void CodeBlock::setJITCode(JITCode jitCode)
     1682{
     1683    ownerNode()->setJITCode(jitCode);
    16841684#if !ENABLE(OPCODE_SAMPLING)
    16851685    if (!BytecodeGenerator::dumpsGeneratedCode())
  • trunk/JavaScriptCore/bytecode/CodeBlock.h

    r43839 r44030  
    6464    };
    6565
    66 #if ENABLE(JIT)
    67     // The code, and the associated pool from which it was allocated.
    68     struct JITCodeRef {
    69         JITCode code;
    70 #ifndef NDEBUG
    71         unsigned codeSize;
    72 #endif
    73         RefPtr<ExecutablePool> executablePool;
    74 
    75         JITCodeRef()
    76             : code(0)
    77 #ifndef NDEBUG
    78             , codeSize(0)
    79 #endif
    80         {
    81         }
    82        
    83         JITCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool)
    84             : code(code)
    85 #ifndef NDEBUG
    86             , codeSize(0)
    87 #endif
    88             , executablePool(executablePool)
    89         {
    90         }
    91     };
    92 #endif
    93 
    9466    struct ExpressionRangeInfo {
    9567        enum {
     
    313285        {
    314286            reparseForExceptionInfoIfNecessary(callFrame);
    315             return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), m_jitCode.code.offsetOf(nativePC))->bytecodeIndex;
     287            return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), ownerNode()->generatedJITCode().offsetOf(nativePC))->bytecodeIndex;
    316288        }
    317289       
     
    328300
    329301#if ENABLE(JIT)
    330         void setJITCode(JITCodeRef& jitCode);
    331         JITCode jitCode() { return m_jitCode.code; }
    332         ExecutablePool* executablePool() { return m_jitCode.executablePool.get(); }
     302        void setJITCode(JITCode);
     303        ExecutablePool* executablePool() { return ownerNode()->getExecutablePool(); }
    333304#endif
    334305
     
    474445        unsigned m_instructionCount;
    475446#endif
    476 #if ENABLE(JIT)
    477         JITCodeRef m_jitCode;
    478 #endif
    479447
    480448        int m_thisRegister;
Note: See TracChangeset for help on using the changeset viewer.