/* * If the jit maturity counter is enabled, update it with the current amount of * emitted code. */ void reportJitMaturity(const CodeCache& code) { auto static jitMaturityCounter = ServiceData::createCounter("jit.maturity"); // Optimized translations are faster than profiling translations, which are // faster than the interpreter. But when optimized translations are // generated, some profiling translations will become dead. We assume the // incremental value of an optimized translation over the corresponding // profiling translations is comparable to the incremental value of a // profiling translation of similar size; thus we don't have to apply // different weights to code in different regions. auto const codeSize = code.hot().used() + code.main().used() + code.prof().used(); if (jitMaturityCounter) { // EvalJitMatureSize is supposed to to be set to approximately 20% of the // code that will give us full performance, so recover the "fully mature" // size with some math. auto const fullSize = RuntimeOption::EvalJitMatureSize * 5; auto const after = codeSize >= fullSize ? 100 : (codeSize * 100 / fullSize); auto const before = jitMaturityCounter->getValue(); if (after > before) jitMaturityCounter->setValue(after); } if (!s_loggedJitMature.load(std::memory_order_relaxed) && StructuredLog::enabled() && codeSize >= RuntimeOption::EvalJitMatureSize && !s_loggedJitMature.exchange(true, std::memory_order_relaxed)) { StructuredLogEntry cols; cols.setInt("jit_mature_sec", time(nullptr) - HttpServer::StartTime); StructuredLog::log("hhvm_warmup", cols); } }
void relocateStubs(TransLoc& loc, TCA frozenStart, TCA frozenEnd, RelocationInfo& rel, CodeCache& cache, CodeGenFixups& fixups) { auto const stubSize = svcreq::stub_size(); for (auto addr : fixups.m_reusedStubs) { if (!loc.contains(addr)) continue; always_assert(frozenStart <= addr); CodeBlock dest; dest.init(cache.frozen().frontier(), stubSize, "New Stub"); x64::relocate(rel, dest, addr, addr + stubSize, fixups, nullptr); cache.frozen().skip(stubSize); if (addr != frozenStart) { rel.recordRange(frozenStart, addr, frozenStart, addr); } frozenStart = addr + stubSize; } if (frozenStart != frozenEnd) { rel.recordRange(frozenStart, frozenEnd, frozenStart, frozenEnd); } x64::adjustForRelocation(rel); x64::adjustMetaDataForRelocation(rel, nullptr, fixups); x64::adjustCodeForRelocation(rel, fixups); }
UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger*, const SourceCode& source, JSObject** exception) { ParserError error; CodeCache* codeCache = exec->globalData().codeCache(); UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(exec->globalData(), name, source, error); if (error.m_type != ParserError::ErrorNone) { *exception = error.toErrorObject(exec->lexicalGlobalObject(), source); return 0; } return executable; }
UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger*, const SourceCode& source, JSObject** exception) { ParserError error; VM& vm = exec->vm(); CodeCache* codeCache = vm.codeCache(); UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error); if (exec->lexicalGlobalObject()->hasDebugger()) exec->lexicalGlobalObject()->debugger()->sourceParsed(exec, source.provider(), error.m_line, error.m_message); if (error.m_type != ParserError::ErrorNone) { *exception = error.toErrorObject(exec->lexicalGlobalObject(), source); return 0; } return executable; }
UnlinkedFunctionExecutable* UnlinkedFunctionExecutable::fromGlobalCode( const Identifier& name, ExecState& exec, const SourceCode& source, JSObject*& exception, int overrideLineNumber) { ParserError error; VM& vm = exec.vm(); CodeCache* codeCache = vm.codeCache(); UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error); auto& globalObject = *exec.lexicalGlobalObject(); if (globalObject.hasDebugger()) globalObject.debugger()->sourceParsed(&exec, source.provider(), error.line(), error.message()); if (error.isValid()) { exception = error.toErrorObject(&globalObject, source, overrideLineNumber); return nullptr; } return executable; }
TransRelocInfo toTRI(const CodeCache& code) { TransRelocInfo tri; tri.sk = SrcKey(skInt); tri.argNum = argNum; tri.coldStart = code.base() + coldRange.first; tri.coldEnd = code.base() + coldRange.second; for (auto& ib : incomingBranches) { tri.incomingBranches.push_back(IncomingBranch(ib)); } for (auto& ai : addressImmediates) { tri.fixups.addressImmediates.insert(ai + code.base()); } for (auto& cp : codePointers) { tri.fixups.codePointers.insert((TCA*)cp); } for (auto v : alignments) { tri.fixups.alignments.emplace(v.first + code.base(), v.second); } return tri; }