コード例 #1
0
ファイル: srcdb.cpp プロジェクト: DoomCircus/hhvm
void SrcRec::emitFallbackJump(CodeBlock& cb, ConditionCode cc /* = -1 */) {
  // This is a spurious platform dependency. TODO(2990497)
  JIT::prepareForSmash(
    cb,
    cc == CC_None ? JIT::X64::kJmpLen : JIT::X64::kJmpccLen
  );
  auto from = cb.frontier();

  TCA destAddr = getFallbackTranslation();
  auto incoming = cc < 0 ? IncomingBranch::jmpFrom(from)
                         : IncomingBranch::jccFrom(from);

  JIT::emitSmashableJump(cb, destAddr, cc);

  // We'll need to know the location of this jump later so we can
  // patch it to new translations added to the chain.
  m_inProgressTailJumps.push_back(incoming);
}
コード例 #2
0
ファイル: srcdb.cpp プロジェクト: TingoZhou/hiphop-php
void SrcRec::emitFallbackJump(TCA from, int cc /* = -1 */) {
  TCA destAddr = getFallbackTranslation();
  auto incoming = cc < 0 ? IncomingBranch::jmpFrom(from)
                         : IncomingBranch::jccFrom(from);
  auto& a = tx64->getAsmFor(from);

  // emit dummy jump to be smashed via patch()
  if (cc < 0) {
    a.jmp(a.frontier());
  } else {
    assert(incoming.type() == IncomingBranch::Tag::JCC);
    a.jcc((ConditionCode)cc, a.frontier());
  }

  patch(incoming, destAddr);

  // We'll need to know the location of this jump later so we can
  // patch it to new translations added to the chain.
  m_inProgressTailJumps.push_back(incoming);
}
コード例 #3
0
ファイル: srcdb.cpp プロジェクト: shantanusharma/hhvm
FPInvOffset SrcRec::nonResumedSPOff() const {
  return svcreq::extract_spoff(getFallbackTranslation());
}
コード例 #4
0
ファイル: vasm-internal.cpp プロジェクト: DerPapst/hhvm
void emit_svcreq_stub(Venv& env, const Venv::SvcReqPatch& p) {
  auto& frozen = env.text.frozen().code;

  TCA stub = nullptr;

  switch (p.svcreq.op) {
    case Vinstr::bindjmp:
      { auto const& i = p.svcreq.bindjmp_;
        assertx(p.jmp && !p.jcc);
        stub = svcreq::emit_bindjmp_stub(frozen, env.text.data(),
                                         env.meta, i.spOff, p.jmp,
                                         i.target, i.trflags);
      } break;

    case Vinstr::bindjcc:
      { auto const& i = p.svcreq.bindjcc_;
        assertx(!p.jmp && p.jcc);
        stub = svcreq::emit_bindjmp_stub(frozen, env.text.data(),
                                         env.meta, i.spOff, p.jcc,
                                         i.target, i.trflags);
      } break;

    case Vinstr::bindaddr:
      { auto const& i = p.svcreq.bindaddr_;
        assertx(!p.jmp && !p.jcc);
        stub = svcreq::emit_bindaddr_stub(frozen, env.text.data(),
                                          env.meta, i.spOff, i.addr.get(),
                                          i.target, TransFlags{});
        // The bound pointer may not belong to the data segment, as is the case
        // with SSwitchMap (see #10347945)
        auto realAddr = env.text.data().contains((TCA)i.addr.get())
          ? (TCA*)env.text.data().toDestAddress((TCA)i.addr.get())
          : (TCA*)i.addr.get();
        *realAddr = stub;
      } break;

    case Vinstr::fallback:
      { auto const& i = p.svcreq.fallback_;
        assertx(p.jmp && !p.jcc);

        auto const srcrec = tc::findSrcRec(i.target);
        always_assert(srcrec);
        stub = i.trflags.packed
          ? svcreq::emit_retranslate_stub(frozen, env.text.data(),
                                          i.spOff, i.target, i.trflags)
          : srcrec->getFallbackTranslation();
      } break;

    case Vinstr::fallbackcc:
      { auto const& i = p.svcreq.fallbackcc_;
        assertx(!p.jmp && p.jcc);

        auto const srcrec = tc::findSrcRec(i.target);
        always_assert(srcrec);
        stub = i.trflags.packed
          ? svcreq::emit_retranslate_stub(frozen, env.text.data(),
                                          i.spOff, i.target, i.trflags)
          : srcrec->getFallbackTranslation();
      } break;

    default: always_assert(false);
  }
  assertx(stub != nullptr);

  // Register any necessary patches by creating fake labels for the stubs.
  if (p.jmp) {
    env.jmps.push_back({p.jmp, Vlabel { env.addrs.size() }});
    env.addrs.push_back(stub);
  }
  if (p.jcc) {
    env.jccs.push_back({p.jcc, Vlabel { env.addrs.size() }});
    env.addrs.push_back(stub);
  }
}
コード例 #5
0
ファイル: vasm-internal.cpp プロジェクト: LouisRenWeiWei/hhvm
void emit_svcreq_stub(Venv& env, const Venv::SvcReqPatch& p) {
  auto& frozen = env.text.frozen().code;

  TCA stub = nullptr;

  switch (p.svcreq.op) {
    case Vinstr::bindjmp:
      { auto const& i = p.svcreq.bindjmp_;
        assertx(p.jmp && !p.jcc);
        stub = svcreq::emit_bindjmp_stub(frozen, env.meta, i.spOff, p.jmp,
                                         i.target, i.trflags);
      } break;

    case Vinstr::bindjcc:
      { auto const& i = p.svcreq.bindjcc_;
        assertx(!p.jmp && p.jcc);
        stub = svcreq::emit_bindjmp_stub(frozen, env.meta, i.spOff, p.jcc,
                                         i.target, i.trflags);
      } break;

    case Vinstr::bindaddr:
      { auto const& i = p.svcreq.bindaddr_;
        assertx(!p.jmp && !p.jcc);
        stub = svcreq::emit_bindaddr_stub(frozen, env.meta, i.spOff, i.addr,
                                          i.target, TransFlags{});
        *i.addr = stub;
      } break;

    case Vinstr::bindjcc1st:
      { auto const& i = p.svcreq.bindjcc1st_;
        assertx(p.jmp && p.jcc);
        stub = svcreq::emit_bindjcc1st_stub(frozen, env.meta, i.spOff, p.jcc,
                                            i.targets[1], i.targets[0], i.cc);
      } break;

    case Vinstr::fallback:
      { auto const& i = p.svcreq.fallback_;
        assertx(p.jmp && !p.jcc);

        auto const srcrec = mcg->tx().getSrcRec(i.target);
        stub = i.trflags.packed
          ? svcreq::emit_retranslate_stub(frozen, i.spOff, i.target, i.trflags)
          : srcrec->getFallbackTranslation();
      } break;

    case Vinstr::fallbackcc:
      { auto const& i = p.svcreq.fallbackcc_;
        assertx(!p.jmp && p.jcc);

        auto const srcrec = mcg->tx().getSrcRec(i.target);
        stub = i.trflags.packed
          ? svcreq::emit_retranslate_stub(frozen, i.spOff, i.target, i.trflags)
          : srcrec->getFallbackTranslation();
      } break;

    default: always_assert(false);
  }
  assertx(stub != nullptr);

  // Register any necessary patches by creating fake labels for the stubs.
  if (p.jmp) {
    env.jmps.push_back({p.jmp, Vlabel { env.addrs.size() }});
    env.addrs.push_back(stub);
  }
  if (p.jcc) {
    env.jccs.push_back({p.jcc, Vlabel { env.addrs.size() }});
    env.addrs.push_back(stub);
  }
}