void SrcRec::chainFrom(IncomingBranch br) { assert(br.type() == IncomingBranch::Tag::ADDR || mcg->code.isValidCodeAddress(br.toSmash())); TCA destAddr = getTopTranslation(); m_incomingBranches.push_back(br); TRACE(1, "SrcRec(%p)::chainFrom %p -> %p (type %d); %zd incoming branches\n", this, br.toSmash(), destAddr, br.type(), m_incomingBranches.size()); br.patch(destAddr); }
void SrcRec::chainFrom(IncomingBranch br) { assertx(br.type() == IncomingBranch::Tag::ADDR || tc::isValidCodeAddress(br.toSmash())); TCA destAddr = getTopTranslation(); m_incomingBranches.push_back(br); TRACE(1, "SrcRec(%p)::chainFrom %p -> %p (type %d); %zd incoming branches\n", this, br.toSmash(), destAddr, static_cast<int>(br.type()), m_incomingBranches.size()); br.patch(destAddr); if (RuntimeOption::EvalEnableReusableTC) { tc::recordJump(br.toSmash(), this); } }
void SrcRec::patch(IncomingBranch branch, TCA dest) { switch (branch.type()) { case IncomingBranch::Tag::JMP: { JIT::smashJmp(branch.toSmash(), dest); break; } case IncomingBranch::Tag::JCC: { JIT::smashJcc(branch.toSmash(), dest); break; } case IncomingBranch::Tag::ADDR: // Note that this effectively ignores a atomic_release_store(reinterpret_cast<TCA*>(branch.toSmash()), dest); } }
void SrcRec::patch(IncomingBranch branch, TCA dest) { switch (branch.type()) { case IncomingBranch::Tag::JMP: { JIT::smashJmp(branch.toSmash(), dest); break; } case IncomingBranch::Tag::JCC: { JIT::smashJcc(branch.toSmash(), dest); break; } case IncomingBranch::Tag::ADDR: { // Note that this effectively ignores a TCA* addr = reinterpret_cast<TCA*>(branch.toSmash()); assert_address_is_atomically_accessible(addr); *addr = dest; break; } } }
void SrcRec::patch(IncomingBranch branch, TCA dest) { switch (branch.type()) { case IncomingBranch::Tag::JMP: { auto& a = tx64->getAsmFor(branch.toSmash()); CodeCursor cg(a, branch.toSmash()); TranslatorX64::smashJmp(a, branch.toSmash(), dest); break; } case IncomingBranch::Tag::JCC: { // patch destination, but preserve the condition code int32_t delta = safe_cast<int32_t>((dest - branch.toSmash()) - kJmpccLen); int32_t* addr = (int32_t*)(branch.toSmash() + kJmpccLen - 4); atomic_release_store(addr, delta); break; } case IncomingBranch::Tag::ADDR: // Note that this effectively ignores a atomic_release_store(reinterpret_cast<TCA*>(branch.toSmash()), dest); } }