Ejemplo n.º 1
0
bool IRInstruction::consumesReference(int srcNo) const {
  if (!consumesReferences()) {
    return false;
  }
  // CheckType/AssertType consume a reference if we're guarding from a
  // maybeCounted type to a notCounted type.
  if (m_op == CheckType || m_op == AssertType) {
    assert(srcNo == 0);
    return src(0)->type().maybeCounted() && typeParam().notCounted();
  }
  // SpillStack consumes inputs 2 and onward
  if (m_op == SpillStack) return srcNo >= 2;
  // Call consumes inputs 3 and onward
  if (m_op == Call) return srcNo >= 3;
  // StRetVal only consumes input 1
  if (m_op == StRetVal) return srcNo == 1;

  if (m_op == StLoc || m_op == StLocNT) {
    // StLoc[NT] <stkptr>, <value>
    return srcNo == 1;
  }
  if (m_op == StProp || m_op == StPropNT || m_op == StMem || m_op == StMemNT) {
    // StProp[NT]|StMem[NT] <base>, <offset>, <value>
    return srcNo == 2;
  }
  if (m_op == ArraySet || m_op == ArraySetRef) {
    // Only consumes the reference to its input array
    return srcNo == 1;
  }
  return true;
}
Ejemplo n.º 2
0
bool IRInstruction::canCSE() const {
  auto canCSE = opcodeHasFlags(op(), CanCSE);
  // Make sure that instructions that are CSE'able can't consume reference
  // counts.
  assert(!canCSE || !consumesReferences());
  return canCSE;
}
Ejemplo n.º 3
0
bool IRInstruction::canCSE() const {
  auto canCSE = opcodeHasFlags(op(), CanCSE);
  // Make sure that instructions that are CSE'able can't produce a reference
  // count or consume reference counts. CheckType/AssertType are special
  // because they can refine a maybeCounted type to a notCounted type, so they
  // logically consume and produce a reference without doing any work.
  assert(!canCSE || !consumesReferences() ||
         m_op == CheckType || m_op == AssertType);
  return canCSE && !mayReenterHelper();
}
Ejemplo n.º 4
0
bool IRInstruction::consumesReference(int srcNo) const {
  if (!consumesReferences()) {
    return false;
  }

  switch (op()) {
    case ConcatStrStr:
    case ConcatStrInt:
    case ConcatCellCell:
      // Call a helper that decrefs the first argument
      return srcNo == 0;

    case StRef:
    case StClosureArg:
    case StClosureCtx:
    case StContArValue:
    case StContArKey:
    case StRetVal:
    case StLoc:
    case StLocNT:
      // Consume the value being stored, not the thing it's being stored into
      return srcNo == 1;

    case StProp:
    case StMem:
      // StProp|StMem <base>, <offset>, <value>
      return srcNo == 2;

    case ArraySet:
    case ArraySetRef:
      // Only consumes the reference to its input array
      return srcNo == 1;

    case SpillStack:
      // Inputs 2+ are values to store
      return srcNo >= 2;

    case SpillFrame:
      // Consumes the $this/Class field of the ActRec
      return srcNo == 3;

    case Call:
      // Inputs 3+ are arguments to the function
      return srcNo >= 3;

    case ColAddElemC:
      // value at index 2
      return srcNo == 2;

    case ColAddNewElemC:
      // value at index 1
      return srcNo == 1;

    case CheckNullptr:
      return srcNo == 0;

    case CreateAFWHFunc:
      return srcNo == 1;

    case CreateAFWHMeth:
      return srcNo == 2;

    default:
      return true;
  }
}