Пример #1
0
void FunctionExecutable::discardCode()
{
#if ENABLE(JIT)
    // These first two checks are to handle the rare case where
    // we are trying to evict code for a function during its
    // codegen.
    if (!m_jitCodeForCall && m_codeBlockForCall)
        return;
    if (!m_jitCodeForConstruct && m_codeBlockForConstruct)
        return;
    m_jitCodeForCall = JITCode();
    m_jitCodeForConstruct = JITCode();
    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
    m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
#endif
    if (m_codeBlockForCall)
        m_codeBlockForCall->clearEvalCache();
    m_codeBlockForCall.clear();
    if (m_codeBlockForConstruct)
        m_codeBlockForConstruct->clearEvalCache();
    m_codeBlockForConstruct.clear();
    m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
    m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;

}
Пример #2
0
void getFunctionEntrypoint(JSGlobalData& globalData, CodeSpecializationKind kind, JITCode& jitCode, MacroAssemblerCodePtr& arityCheck)
{
    if (!globalData.canUseJIT()) {
        if (kind == CodeForCall) {
            jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_prologue))));
            arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_call_arity_check));
            return;
        }

        ASSERT(kind == CodeForConstruct);
        jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_prologue))));
        arityCheck = MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_function_for_construct_arity_check));
        return;
    }
    
    if (kind == CodeForCall) {
        jitCode = JITCode(globalData.getCTIStub(functionForCallEntryThunkGenerator), JITCode::InterpreterThunk);
        arityCheck = globalData.getCTIStub(functionForCallArityCheckThunkGenerator).code();
        return;
    }

    ASSERT(kind == CodeForConstruct);
    jitCode = JITCode(globalData.getCTIStub(functionForConstructEntryThunkGenerator), JITCode::InterpreterThunk);
    arityCheck = globalData.getCTIStub(functionForConstructArityCheckThunkGenerator).code();
}
Пример #3
0
MacroAssemblerCodePtr StructureStubInfo::addAccessCase(
    CodeBlock* codeBlock, const Identifier& ident, std::unique_ptr<AccessCase> accessCase)
{
    VM& vm = *codeBlock->vm();
    
    if (!accessCase)
        return MacroAssemblerCodePtr();
    
    if (cacheType == CacheType::Stub)
        return u.stub->regenerateWithCase(vm, codeBlock, *this, ident, WTFMove(accessCase));

    std::unique_ptr<PolymorphicAccess> access = std::make_unique<PolymorphicAccess>();
    
    Vector<std::unique_ptr<AccessCase>> accessCases;
    
    std::unique_ptr<AccessCase> previousCase =
        AccessCase::fromStructureStubInfo(vm, codeBlock, *this);
    if (previousCase)
        accessCases.append(WTFMove(previousCase));

    accessCases.append(WTFMove(accessCase));

    MacroAssemblerCodePtr result =
        access->regenerateWithCases(vm, codeBlock, *this, ident, WTFMove(accessCases));

    if (!result)
        return MacroAssemblerCodePtr();

    initStub(codeBlock, WTFMove(access));
    return result;
}
Пример #4
0
void ExecutableBase::clearCode()
{
#if ENABLE(JIT)
    m_jitCodeForCall.clear();
    m_jitCodeForConstruct.clear();
    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
    m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
#endif
    m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
    m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;
}
Пример #5
0
void ExecutableBase::clearCode()
{
#if ENABLE(JIT)
    m_jitCodeForCall = nullptr;
    m_jitCodeForConstruct = nullptr;
    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
    m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
#endif
    m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
    m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;

    if (classInfo() == FunctionExecutable::info()) {
        FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
        executable->m_codeBlockForCall.clear();
        executable->m_codeBlockForConstruct.clear();
        return;
    }

    if (classInfo() == EvalExecutable::info()) {
        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
        executable->m_evalCodeBlock.clear();
        executable->m_unlinkedEvalCodeBlock.clear();
        return;
    }
    
    if (classInfo() == ProgramExecutable::info()) {
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
        executable->m_programCodeBlock.clear();
        executable->m_unlinkedProgramCodeBlock.clear();
        return;
    }

    if (classInfo() == ModuleProgramExecutable::info()) {
        ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this);
        executable->m_moduleProgramCodeBlock.clear();
        executable->m_unlinkedModuleProgramCodeBlock.clear();
        executable->m_moduleEnvironmentSymbolTable.clear();
        return;
    }
    
#if ENABLE(WEBASSEMBLY)
    if (classInfo() == WebAssemblyExecutable::info()) {
        WebAssemblyExecutable* executable = jsCast<WebAssemblyExecutable*>(this);
        executable->m_codeBlockForCall.clear();
        return;
    }
#endif

    ASSERT(classInfo() == NativeExecutable::info());
}
Пример #6
0
static void setProgramEntrypoint(VM& vm, CodeBlock* codeBlock)
{
    if (!vm.canUseJIT()) {
        codeBlock->setJITCode(
            adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), JITCode::InterpreterThunk)),
            MacroAssemblerCodePtr());
        return;
    }
#if ENABLE(JIT)
    codeBlock->setJITCode(
        adoptRef(new DirectJITCode(vm.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk)),
        MacroAssemblerCodePtr());
#endif
}
bool JITFinalizer::finalize()
{
    finalizeCommon();
    
    m_jitCode->initializeCodeRef(m_linkBuffer->finalizeCodeWithoutDisassembly());
    m_plan.codeBlock->setJITCode(m_jitCode, MacroAssemblerCodePtr());
    
    return true;
}
Пример #8
0
LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithoutDisassembly()
{
    performFinalization();
    
    ASSERT(m_didAllocate);
    if (m_executableMemory)
        return CodeRef(m_executableMemory);
    
    return CodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(m_code));
}
Пример #9
0
bool JITFinalizer::finalize()
{
    m_jitCode->initializeCodeRef(
        FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())),
        MacroAssemblerCodePtr());
    
    m_plan.codeBlock->setJITCode(m_jitCode);
    
    finalizeCommon();
    
    return true;
}
Пример #10
0
void WebAssemblyExecutable::prepareForExecution(ExecState* exec)
{
    if (hasJITCodeForCall())
        return;

    VM& vm = exec->vm();
    DeferGC deferGC(vm.heap);

    RefPtr<WebAssemblyCodeBlock> codeBlock = adoptRef(new WebAssemblyCodeBlock(
        this, vm, exec->lexicalGlobalObject()));

    WASMFunctionParser::compile(vm, codeBlock.get(), m_module.get(), m_source, m_functionIndex);

    m_jitCodeForCall = codeBlock->jitCode();
    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
    m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
    m_numParametersForCall = codeBlock->numParameters();

    m_codeBlockForCall = codeBlock;

    Heap::heap(this)->writeBarrier(this);
}
Пример #11
0
void WebAssemblyExecutable::prepareForExecution(ExecState* exec)
{
    if (hasJITCodeForCall())
        return;

    VM& vm = exec->vm();
    DeferGC deferGC(vm.heap);

    WebAssemblyCodeBlock* codeBlock = WebAssemblyCodeBlock::create(&vm,
        this, exec->lexicalGlobalObject());

    WASMFunctionParser::compile(vm, codeBlock, m_module.get(), m_source, m_functionIndex);

    m_jitCodeForCall = codeBlock->jitCode();
    m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
    m_numParametersForCall = codeBlock->numParameters();

    m_codeBlockForCall.set(vm, this, codeBlock);

    Heap::heap(this)->writeBarrier(this);
}
Пример #12
0
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
#if !ENABLE(JIT)
    UNUSED_PARAM(jitType);
#endif
    JSObject* exception = 0;
    JSGlobalData* globalData = &exec->globalData();
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
    if (!programNode) {
        ASSERT(exception);
        return exception;
    }
    recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());

    JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
    
    OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release();
    ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
    m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release()));
    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
    if ((exception = generator->generate())) {
        m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
        programNode->destroyData();
        return exception;
    }

    programNode->destroyData();
    m_programCodeBlock->copyDataFromAlternative();

#if ENABLE(JIT)
    if (exec->globalData().canUseJIT()) {
        bool dfgCompiled = false;
        if (jitType == JITCode::DFGJIT)
            dfgCompiled = DFG::tryCompile(exec, m_programCodeBlock.get(), m_jitCodeForCall);
        if (dfgCompiled) {
            if (m_programCodeBlock->alternative())
                m_programCodeBlock->alternative()->unlinkIncomingCalls();
        } else {
            if (m_programCodeBlock->alternative()) {
                m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
                return 0;
            }
            m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get());
        }
#if !ENABLE(OPCODE_SAMPLING)
        if (!BytecodeGenerator::dumpsGeneratedCode())
            m_programCodeBlock->discardBytecode();
#endif
        m_programCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr());
    }
#endif

#if ENABLE(JIT)
#if ENABLE(INTERPRETER)
    if (!m_jitCodeForCall)
        Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock));
    else
#endif
        Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock) + m_jitCodeForCall.size());
#else
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_programCodeBlock));
#endif

    return 0;
}
Пример #13
0
void ScriptExecutable::installCode(CodeBlock* genericCodeBlock)
{
    RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this);
    RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock->jitType()));
    
    if (Options::verboseOSR())
        dataLog("Installing ", *genericCodeBlock, "\n");
    
    VM& vm = *genericCodeBlock->vm();
    
    if (vm.m_perBytecodeProfiler)
        vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock);
    
    ASSERT(vm.heap.isDeferred());
    
    CodeSpecializationKind kind = genericCodeBlock->specializationKind();
    
    RefPtr<CodeBlock> oldCodeBlock;
    
    switch (kind) {
    case CodeForCall:
        m_jitCodeForCall = genericCodeBlock->jitCode();
        m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
        m_jitCodeForCallWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
        m_numParametersForCall = genericCodeBlock->numParameters();
        break;
    case CodeForConstruct:
        m_jitCodeForConstruct = genericCodeBlock->jitCode();
        m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
        m_jitCodeForConstructWithArityCheckAndPreserveRegs = MacroAssemblerCodePtr();
        m_numParametersForConstruct = genericCodeBlock->numParameters();
        break;
    }
    
    switch (genericCodeBlock->codeType()) {
    case GlobalCode: {
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
        ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock);
        
        ASSERT(kind == CodeForCall);
        
        oldCodeBlock = executable->m_programCodeBlock;
        executable->m_programCodeBlock = codeBlock;
        break;
    }
        
    case EvalCode: {
        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
        EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock);
        
        ASSERT(kind == CodeForCall);
        
        oldCodeBlock = executable->m_evalCodeBlock;
        executable->m_evalCodeBlock = codeBlock;
        break;
    }
        
    case FunctionCode: {
        FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
        FunctionCodeBlock* codeBlock = static_cast<FunctionCodeBlock*>(genericCodeBlock);
        
        switch (kind) {
        case CodeForCall:
            oldCodeBlock = executable->m_codeBlockForCall;
            executable->m_codeBlockForCall = codeBlock;
            break;
        case CodeForConstruct:
            oldCodeBlock = executable->m_codeBlockForConstruct;
            executable->m_codeBlockForConstruct = codeBlock;
            break;
        }
        break;
    } }

    if (oldCodeBlock)
        oldCodeBlock->unlinkIncomingCalls();

    Debugger* debugger = genericCodeBlock->globalObject()->debugger();
    if (debugger)
        debugger->registerCodeBlock(genericCodeBlock);

    Heap::heap(this)->writeBarrier(this);
}
Пример #14
0
void compile(State& state, Safepoint::Result& safepointResult)
{
    char* error = 0;
    
    {
        GraphSafepoint safepoint(state.graph, safepointResult);
        
        LLVMMCJITCompilerOptions options;
        llvm->InitializeMCJITCompilerOptions(&options, sizeof(options));
        options.OptLevel = Options::llvmBackendOptimizationLevel();
        options.NoFramePointerElim = true;
        if (Options::useLLVMSmallCodeModel())
            options.CodeModel = LLVMCodeModelSmall;
        options.EnableFastISel = Options::enableLLVMFastISel();
        options.MCJMM = llvm->CreateSimpleMCJITMemoryManager(
            &state, mmAllocateCodeSection, mmAllocateDataSection, mmApplyPermissions, mmDestroy);
    
        LLVMExecutionEngineRef engine;
        
        if (isARM64())
#if OS(DARWIN)
            llvm->SetTarget(state.module, "arm64-apple-ios");
#elif OS(LINUX)
            llvm->SetTarget(state.module, "aarch64-linux-gnu");
#else
#error "Unrecognized OS"
#endif

        if (llvm->CreateMCJITCompilerForModule(&engine, state.module, &options, sizeof(options), &error)) {
            dataLog("FATAL: Could not create LLVM execution engine: ", error, "\n");
            CRASH();
        }

        // The data layout also has to be set in the module. Get the data layout from the MCJIT and apply
        // it to the module.
        LLVMTargetMachineRef targetMachine = llvm->GetExecutionEngineTargetMachine(engine);
        LLVMTargetDataRef targetData = llvm->GetExecutionEngineTargetData(engine);
        char* stringRepOfTargetData = llvm->CopyStringRepOfTargetData(targetData);
        llvm->SetDataLayout(state.module, stringRepOfTargetData);
        free(stringRepOfTargetData);

        LLVMPassManagerRef functionPasses = 0;
        LLVMPassManagerRef modulePasses;

        if (Options::llvmSimpleOpt()) {
            modulePasses = llvm->CreatePassManager();
            llvm->AddTargetData(targetData, modulePasses);
            llvm->AddAnalysisPasses(targetMachine, modulePasses);
            llvm->AddPromoteMemoryToRegisterPass(modulePasses);
            llvm->AddGlobalOptimizerPass(modulePasses);
            llvm->AddFunctionInliningPass(modulePasses);
            llvm->AddPruneEHPass(modulePasses);
            llvm->AddGlobalDCEPass(modulePasses);
            llvm->AddConstantPropagationPass(modulePasses);
            llvm->AddAggressiveDCEPass(modulePasses);
            llvm->AddInstructionCombiningPass(modulePasses);
            // BEGIN - DO NOT CHANGE THE ORDER OF THE ALIAS ANALYSIS PASSES
            llvm->AddTypeBasedAliasAnalysisPass(modulePasses);
            llvm->AddBasicAliasAnalysisPass(modulePasses);
            // END - DO NOT CHANGE THE ORDER OF THE ALIAS ANALYSIS PASSES
            llvm->AddGVNPass(modulePasses);
            llvm->AddCFGSimplificationPass(modulePasses);
            llvm->AddDeadStoreEliminationPass(modulePasses);

            llvm->RunPassManager(modulePasses, state.module);
        } else {
            LLVMPassManagerBuilderRef passBuilder = llvm->PassManagerBuilderCreate();
            llvm->PassManagerBuilderSetOptLevel(passBuilder, Options::llvmOptimizationLevel());
            llvm->PassManagerBuilderUseInlinerWithThreshold(passBuilder, 275);
            llvm->PassManagerBuilderSetSizeLevel(passBuilder, Options::llvmSizeLevel());
        
            functionPasses = llvm->CreateFunctionPassManagerForModule(state.module);
            modulePasses = llvm->CreatePassManager();
        
            llvm->AddTargetData(llvm->GetExecutionEngineTargetData(engine), modulePasses);
        
            llvm->PassManagerBuilderPopulateFunctionPassManager(passBuilder, functionPasses);
            llvm->PassManagerBuilderPopulateModulePassManager(passBuilder, modulePasses);
        
            llvm->PassManagerBuilderDispose(passBuilder);
        
            llvm->InitializeFunctionPassManager(functionPasses);
            for (LValue function = llvm->GetFirstFunction(state.module); function; function = llvm->GetNextFunction(function))
                llvm->RunFunctionPassManager(functionPasses, function);
            llvm->FinalizeFunctionPassManager(functionPasses);
        
            llvm->RunPassManager(modulePasses, state.module);
        }

        if (shouldShowDisassembly() || verboseCompilationEnabled())
            state.dumpState("after optimization");
    
        // FIXME: Need to add support for the case where JIT memory allocation failed.
        // https://bugs.webkit.org/show_bug.cgi?id=113620
        state.generatedFunction = reinterpret_cast<GeneratedFunction>(llvm->GetPointerToGlobal(engine, state.function));
        if (functionPasses)
            llvm->DisposePassManager(functionPasses);
        llvm->DisposePassManager(modulePasses);
        llvm->DisposeExecutionEngine(engine);
    }
    if (safepointResult.didGetCancelled())
        return;
    RELEASE_ASSERT(!state.graph.m_vm.heap.isCollecting());
    
    if (shouldShowDisassembly()) {
        for (unsigned i = 0; i < state.jitCode->handles().size(); ++i) {
            ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();
            dataLog(
                "Generated LLVM code for ",
                CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT),
                " #", i, ", ", state.codeSectionNames[i], ":\n");
            disassemble(
                MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(),
                "    ", WTF::dataFile(), LLVMSubset);
        }
        
        for (unsigned i = 0; i < state.jitCode->dataSections().size(); ++i) {
            DataSection* section = state.jitCode->dataSections()[i].get();
            dataLog(
                "Generated LLVM data section for ",
                CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT),
                " #", i, ", ", state.dataSectionNames[i], ":\n");
            dumpDataSection(section, "    ");
        }
    }
    
    bool didSeeUnwindInfo = state.jitCode->unwindInfo.parse(
        state.unwindDataSection, state.unwindDataSectionSize,
        state.generatedFunction);
    if (shouldShowDisassembly()) {
        dataLog("Unwind info for ", CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ":\n");
        if (didSeeUnwindInfo)
            dataLog("    ", state.jitCode->unwindInfo, "\n");
        else
            dataLog("    <no unwind info>\n");
    }
    
    if (state.stackmapsSection && state.stackmapsSection->size()) {
        if (shouldShowDisassembly()) {
            dataLog(
                "Generated LLVM stackmaps section for ",
                CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT), ":\n");
            dataLog("    Raw data:\n");
            dumpDataSection(state.stackmapsSection.get(), "    ");
        }
        
        RefPtr<DataView> stackmapsData = DataView::create(
            ArrayBuffer::create(state.stackmapsSection->base(), state.stackmapsSection->size()));
        state.jitCode->stackmaps.parse(stackmapsData.get());
    
        if (shouldShowDisassembly()) {
            dataLog("    Structured data:\n");
            state.jitCode->stackmaps.dumpMultiline(WTF::dataFile(), "        ");
        }
        
        StackMaps::RecordMap recordMap = state.jitCode->stackmaps.computeRecordMap();
        fixFunctionBasedOnStackMaps(
            state, state.graph.m_codeBlock, state.jitCode.get(), state.generatedFunction,
            recordMap, didSeeUnwindInfo);
        
        if (shouldShowDisassembly()) {
            for (unsigned i = 0; i < state.jitCode->handles().size(); ++i) {
                if (state.codeSectionNames[i] != SECTION_NAME("text"))
                    continue;
                
                ExecutableMemoryHandle* handle = state.jitCode->handles()[i].get();
                dataLog(
                    "Generated LLVM code after stackmap-based fix-up for ",
                    CodeBlockWithJITType(state.graph.m_codeBlock, JITCode::FTLJIT),
                    " in ", state.graph.m_plan.mode, " #", i, ", ",
                    state.codeSectionNames[i], ":\n");
                disassemble(
                    MacroAssemblerCodePtr(handle->start()), handle->sizeInBytes(),
                    "    ", WTF::dataFile(), LLVMSubset);
            }
        }
    }
    
    state.module = 0; // We no longer own the module.
}
Пример #15
0
void ScriptExecutable::installCode(VM& vm, CodeBlock* genericCodeBlock, CodeType codeType, CodeSpecializationKind kind)
{
    ASSERT(vm.heap.isDeferred());
    
    CodeBlock* oldCodeBlock = nullptr;
    
    switch (codeType) {
    case GlobalCode: {
        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
        ProgramCodeBlock* codeBlock = static_cast<ProgramCodeBlock*>(genericCodeBlock);
        
        ASSERT(kind == CodeForCall);
        
        oldCodeBlock = executable->m_programCodeBlock.get();
        executable->m_programCodeBlock.setMayBeNull(vm, this, codeBlock);
        break;
    }

    case ModuleCode: {
        ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this);
        ModuleProgramCodeBlock* codeBlock = static_cast<ModuleProgramCodeBlock*>(genericCodeBlock);

        ASSERT(kind == CodeForCall);

        oldCodeBlock = executable->m_moduleProgramCodeBlock.get();
        executable->m_moduleProgramCodeBlock.setMayBeNull(vm, this, codeBlock);
        break;
    }

    case EvalCode: {
        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
        EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock);
        
        ASSERT(kind == CodeForCall);
        
        oldCodeBlock = executable->m_evalCodeBlock.get();
        executable->m_evalCodeBlock.setMayBeNull(vm, this, codeBlock);
        break;
    }
        
    case FunctionCode: {
        FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
        FunctionCodeBlock* codeBlock = static_cast<FunctionCodeBlock*>(genericCodeBlock);
        
        switch (kind) {
        case CodeForCall:
            oldCodeBlock = executable->m_codeBlockForCall.get();
            executable->m_codeBlockForCall.setMayBeNull(vm, this, codeBlock);
            break;
        case CodeForConstruct:
            oldCodeBlock = executable->m_codeBlockForConstruct.get();
            executable->m_codeBlockForConstruct.setMayBeNull(vm, this, codeBlock);
            break;
        }
        break;
    }
    }

    switch (kind) {
    case CodeForCall:
        m_jitCodeForCall = genericCodeBlock ? genericCodeBlock->jitCode() : nullptr;
        m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr();
        m_numParametersForCall = genericCodeBlock ? genericCodeBlock->numParameters() : NUM_PARAMETERS_NOT_COMPILED;
        break;
    case CodeForConstruct:
        m_jitCodeForConstruct = genericCodeBlock ? genericCodeBlock->jitCode() : nullptr;
        m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr();
        m_numParametersForConstruct = genericCodeBlock ? genericCodeBlock->numParameters() : NUM_PARAMETERS_NOT_COMPILED;
        break;
    }

    if (genericCodeBlock) {
        RELEASE_ASSERT(genericCodeBlock->ownerExecutable() == this);
        RELEASE_ASSERT(JITCode::isExecutableScript(genericCodeBlock->jitType()));
        
        if (Options::verboseOSR())
            dataLog("Installing ", *genericCodeBlock, "\n");
        
        if (vm.m_perBytecodeProfiler)
            vm.m_perBytecodeProfiler->ensureBytecodesFor(genericCodeBlock);
        
        if (Debugger* debugger = genericCodeBlock->globalObject()->debugger())
            debugger->registerCodeBlock(genericCodeBlock);
    }

    if (oldCodeBlock)
        oldCodeBlock->unlinkIncomingCalls();

    vm.heap.writeBarrier(this);
}
Пример #16
0
void getProgramEntrypoint(JSGlobalData& globalData, JITCode& jitCode)
{
    if (!globalData.canUseJIT()) {
        jitCode = JITCode::HostFunction(MacroAssemblerCodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(bitwise_cast<void*>(&llint_program_prologue))));
        return;
    }
    
    jitCode = JITCode(globalData.getCTIStub(programEntryThunkGenerator), JITCode::InterpreterThunk);
}