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; }
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(); }
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; }
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; }
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()); }
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; }
LinkBuffer::CodeRef LinkBuffer::finalizeCodeWithoutDisassembly() { performFinalization(); ASSERT(m_didAllocate); if (m_executableMemory) return CodeRef(m_executableMemory); return CodeRef::createSelfManagedCodeRef(MacroAssemblerCodePtr(m_code)); }
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; }
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); }
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); }
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; }
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); }
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. }
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); }
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); }