TCA genFuncBodyDispatch(Func* func, const DVFuncletsVec& dvs, CodeCache::View code) { auto context = prologue_context(kInvalidTransID, TransKind::Live, func, func->base()); IRUnit unit{context}; irgen::IRGS env{unit}; auto& main = code.main(); auto& frozen = code.frozen(); auto const start = main.frontier(); irgen::emitFuncBodyDispatch(env, dvs); irgen::sealUnit(env); CGMeta fixups; irlower::genCode(env.unit, code, fixups, CodeKind::CrossTrace); if (RuntimeOption::EvalPerfRelocate) { GrowableVector<IncomingBranch> ibs; recordPerfRelocMap(start, main.frontier(), frozen.frontier(), frozen.frontier(), SrcKey { func, dvs[0].second, false }, 0, ibs, fixups); } fixups.process(nullptr); return start; }
void relocateStubs(TransLoc& loc, TCA frozenStart, TCA frozenEnd, RelocationInfo& rel, CodeCache::View cache, CGMeta& fixups) { auto const stubSize = svcreq::stub_size(); for (auto addr : fixups.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); }
TCA genFuncPrologue(TransID transID, TransKind kind, Func* func, int argc, CodeCache::View code, CGMeta& fixups) { auto context = prologue_context(transID, kind, func, func->getEntryForNumArgs(argc)); IRUnit unit{context}; irgen::IRGS env{unit}; auto& cb = code.main(); // Dump the func guard in the TC before anything else. emitFuncGuard(func, cb, fixups); auto const start = cb.frontier(); irgen::emitFuncPrologue(env, argc, transID); irgen::sealUnit(env); irlower::genCode(env.unit, code, fixups, CodeKind::CrossTrace); return start; }