Ignore:
Timestamp:
May 18, 2009, 12:46:37 PM (16 years ago)
Author:
[email protected]
Message:

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

Reviewed by Darin Adler.

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):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/yarr/RegexJIT.cpp

    r43038 r43837  
    13321332        generate();
    13331333
    1334         jitObject.m_executablePool = globalData->executableAllocator.poolForSize(size());
    1335         void* code = copyCode(jitObject.m_executablePool.get());
    1336 
    1337         PatchBuffer patchBuffer(code);
     1334        PatchBuffer patchBuffer(this, globalData->executableAllocator.poolForSize(size()));
     1335
    13381336        for (unsigned i = 0; i < m_backtrackRecords.size(); ++i)
    1339             patchBuffer.patch(m_backtrackRecords[i].dataLabel, patchBuffer.trampolineAt(m_backtrackRecords[i].backtrackLocation));
    1340 
    1341         jitObject.m_jitCode = code;
     1337            patchBuffer.patch(m_backtrackRecords[i].dataLabel, patchBuffer.locationOf(m_backtrackRecords[i].backtrackLocation));
     1338
     1339        jitObject.set(patchBuffer.finalizeCode());
    13421340    }
    13431341
     
    13681366        JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
    13691367        JSRegExpMultilineOption multilineOption = multiline ? JSRegExpMultiline : JSRegExpSingleLine;
    1370         jitObject.m_pcreFallback = jsRegExpCompile(reinterpret_cast<const UChar*>(patternString.data()), patternString.size(), ignoreCaseOption, multilineOption, &numSubpatterns, &error);
     1368        jitObject.setFallback(jsRegExpCompile(reinterpret_cast<const UChar*>(patternString.data()), patternString.size(), ignoreCaseOption, multilineOption, &numSubpatterns, &error));
    13711369    }
    13721370}
     
    13741372int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize)
    13751373{
    1376     if (jitObject.m_pcreFallback) {
    1377         int result = jsRegExpExecute(jitObject.m_pcreFallback, input, length, start, output, outputArraySize);
    1378         return (result < 0) ? -1 : output[0];
    1379     } else {
    1380 #if PLATFORM(X86) && !COMPILER(MSVC)
    1381         typedef int (*RegexJITCode)(const UChar* input, unsigned start, unsigned length, int* output) __attribute__ ((regparm (3)));
    1382 #else
    1383         typedef int (*RegexJITCode)(const UChar* input, unsigned start, unsigned length, int* output);
     1374    if (JSRegExp* fallback = jitObject.getFallback())
     1375        return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0];
     1376
     1377    return jitObject.execute(input, start, length, output);
     1378}
     1379
     1380}}
     1381
    13841382#endif
    1385         return reinterpret_cast<RegexJITCode>(jitObject.m_jitCode)(input, start, length, output);
    1386     }
    1387 }
    1388 
    1389 }}
    1390 
    1391 #endif
    1392 
    1393 
    1394 
    1395 
    1396 
     1383
     1384
     1385
     1386
     1387
Note: See TracChangeset for help on using the changeset viewer.