示例#1
0
Trace* TraceBuilder::genExitTrace(uint32_t   bcOff,
                                  int32_t    stackDeficit,
                                  uint32_t   numOpnds,
                                  SSATmp* const* opnds,
                                  TraceExitType::ExitType exitType,
                                  uint32_t   notTakenBcOff,
                                  std::function<void(IRFactory*, Trace*)>
                                    beforeExit) {
  Trace* exitTrace = makeExitTrace(bcOff);

  MarkerData marker;
  marker.bcOff    = bcOff;
  marker.stackOff = m_spOffset + numOpnds - stackDeficit;
  marker.func     = m_curFunc->getValFunc();
  exitTrace->back()->push_back(m_irFactory.gen(Marker, marker));

  if (beforeExit) {
    beforeExit(&m_irFactory, exitTrace);
  }
  SSATmp* sp = m_spValue;
  if (numOpnds != 0 || stackDeficit != 0) {
    SSATmp* srcs[numOpnds + 2];
    srcs[0] = m_spValue;
    srcs[1] = cns(stackDeficit);
    std::copy(opnds, opnds + numOpnds, srcs + 2);

    SSATmp** decayedPtr = srcs;
    auto* spillInst = m_irFactory.gen(
      SpillStack,
      std::make_pair(numOpnds + 2, decayedPtr)
    );
    sp = spillInst->getDst();
    exitTrace->back()->push_back(spillInst);
  }
  SSATmp* pc = cns(int64_t(bcOff));
  if (exitType == TraceExitType::NormalCc) {
    assert(notTakenBcOff != 0);
    SSATmp* notTakenPC = cns(notTakenBcOff);
    genFor(exitTrace, getExitOpcode(exitType),
           m_curFunc,
           pc, sp, m_fpValue,
           notTakenPC);
  } else {
    assert(notTakenBcOff == 0);
    genFor(exitTrace, getExitOpcode(exitType),
           m_curFunc,
           pc, sp, m_fpValue);
  }
  return exitTrace;
}
示例#2
0
void TraceBuilder::genTraceEnd(uint32_t nextPc,
                               TraceExitType::ExitType exitType /* = Normal */) {
  gen(getExitOpcode(TraceExitType::Normal),
      m_curFunc,
      cns(nextPc),
      m_spValue,
      m_fpValue);
}
示例#3
0
IRInstruction* IRFactory::exitTrace(TraceExitType::ExitType exitType,
                                    SSATmp* func,
                                    SSATmp* pc,
                                    SSATmp* sp,
                                    SSATmp* fp) {
  SSATmp* args[2] = { sp, fp };
  return new (m_arena) ExtendedInstruction(*this,
                                           getExitOpcode(exitType),
                                           Type::None,
                                           func,
                                           pc,
                                           (sizeof(args) / sizeof(SSATmp*)),
                                           args);
}