Exemplo n.º 1
0
ArrayData* PackedArray::NonSmartCopy(const ArrayData* adIn) {
  assert(checkInvariants(adIn));

  // There's no reason to use the full capacity, since non-smart
  // arrays are not mutable.
  auto const cap  = adIn->m_size;
  auto const size = adIn->m_size;

  auto const ad = static_cast<ArrayData*>(
    std::malloc(sizeof(ArrayData) + cap * sizeof(TypedValue))
  );
  ad->m_kindAndSize = uint64_t{size} << 32 | cap; // zero kind
  ad->m_posAndCount = static_cast<uint32_t>(adIn->m_pos);

  auto const srcData = packedData(adIn);
  auto const stop    = srcData + size;
  auto targetData    = reinterpret_cast<TypedValue*>(ad + 1);
  for (auto ptr = srcData; ptr != stop; ++ptr, ++targetData) {
    tvDupFlattenVars(ptr, targetData, adIn);
  }

  assert(ad->m_kind == ArrayData::kPackedKind);
  assert(ad->m_packedCap == cap);
  assert(ad->m_size == size);
  assert(ad->m_pos == adIn->m_pos);
  assert(ad->m_count == 0);
  assert(checkInvariants(ad));
  return ad;
}
Exemplo n.º 2
0
NEVER_INLINE
ArrayData* PackedArray::Copy(const ArrayData* adIn) {
  assert(checkInvariants(adIn));

  auto const cap  = adIn->m_packedCap;
  auto const size = adIn->m_size;

  auto const ad = static_cast<ArrayData*>(
    MM().objMallocLogged(sizeof(ArrayData) + cap * sizeof(TypedValue))
  );
  ad->m_kindAndSize = uint64_t{size} << 32 | cap; // zero kind
  ad->m_posAndCount = static_cast<uint32_t>(adIn->m_pos);

  auto const srcData = packedData(adIn);
  auto const stop    = srcData + size;
  auto targetData    = reinterpret_cast<TypedValue*>(ad + 1);
  for (auto ptr = srcData; ptr != stop; ++ptr, ++targetData) {
    tvDupFlattenVars(ptr, targetData, adIn);
  }

  assert(ad->m_kind == ArrayData::kPackedKind);
  assert(ad->m_packedCap == cap);
  assert(ad->m_size == size);
  assert(ad->m_pos == adIn->m_pos);
  assert(ad->m_count == 0);
  assert(checkInvariants(ad));
  return ad;
}
Exemplo n.º 3
0
/*
 * Convert to mixed, reserving space for at least `neededSize' elems.
 * The `neededSize' should include old->size(), but may be equal to
 * it.
 *
 * Unlike the other ToMixed functions, the returned array already has
 * a reference count of 1.
 */
MixedArray* PackedArray::ToMixedCopyReserve(const ArrayData* old,
                                           size_t neededSize) {
  assert(neededSize >= old->m_size);
  auto const ad      = ToMixedHeader(old, neededSize);
  ad->m_count = 1;
  auto const oldSize = old->m_size;
  auto const mask    = ad->m_tableMask;
  auto dstData       = ad->data();
  auto dstHash       = ad->hashTab();
  auto const srcData = packedData(old);

  auto i = uint32_t{0};
  for (; i < oldSize; ++i) {
    dstData->setIntKey(i);
    tvDupFlattenVars(&srcData[i], &dstData->data, old);
    *dstHash = i;
    ++dstData;
    ++dstHash;
  }
  for (; i <= mask; ++i) {
    *dstHash++ = MixedArray::Empty;
  }

  assert(ad->checkInvariants());
  return ad;
}
Exemplo n.º 4
0
void c_Continuation::dupContVar(const StringData* name, TypedValue* src) {
  ActRec *fp = actRec();
  Id destId = fp->m_func->lookupVarId(name);
  if (destId != kInvalidId) {
    // Copy the value of the local to the cont object.
    tvDupFlattenVars(src, frame_local(fp, destId));
  } else {
    if (!fp->hasVarEnv()) {
      fp->setVarEnv(VarEnv::createLocal(fp));
    }
    fp->getVarEnv()->setWithRef(name, src);
  }
}
Exemplo n.º 5
0
void c_Continuation::dupContVar(const StringData* name, TypedValue* src) {
  ActRec *fp = actRec();
  Id destId = fp->m_func->lookupVarId(name);
  if (destId != kInvalidId) {
    // Copy the value of the local to the cont object.
    tvDupFlattenVars(src, frame_local(fp, destId));
  } else {
    if (!fp->hasVarEnv()) {
      // This VarEnv may potentially outlive the most recently stack-allocated
      // VarEnv, so we need to heap allocate it.
      fp->setVarEnv(VarEnv::createLocalOnHeap(fp));
    }
    fp->getVarEnv()->setWithRef(name, src);
  }
}
Exemplo n.º 6
0
ArrayData* StructArray::CopyStatic(const ArrayData* ad) {
  auto structArray = asStructArray(ad);
  auto shape = structArray->shape();
  auto ret = StructArray::createStatic(shape, structArray->size());

  ret->m_pos = structArray->m_pos;

  auto const srcData = structArray->data();
  auto const size    = structArray->size();
  auto const stop    = srcData + size;
  auto targetData    = ret->data();
  for (auto ptr = srcData; ptr != stop; ++ptr, ++targetData) {
    tvDupFlattenVars(ptr, targetData, structArray);
  }

  assert(ret->isStatic());
  return ret;
}
Exemplo n.º 7
0
ArrayData* StructArray::Copy(const ArrayData* ad) {
  auto old = asStructArray(ad);
  auto shape = old->shape();

  auto result = StructArray::createNoCopy(shape, shape->size());
  result->m_pos = old->m_pos;

  assert(result->m_size == result->shape()->size());
  assert(result->size() == old->size());
  auto const srcData = old->data();
  auto const stop = srcData + old->size();
  auto targetData = result->data();
  for (auto ptr = srcData; ptr != stop; ++ptr, ++targetData) {
    tvDupFlattenVars(ptr, targetData, old);
  }

  assert(result->m_size == result->shape()->size());
  assert(result->hasExactlyOneRef());
  return result;
}
Exemplo n.º 8
0
MixedArray* StructArray::ToMixedCopy(const StructArray* old) {
  auto const oldSize = old->size();
  auto const ad      = ToMixedHeader(oldSize + 1);
  auto const srcData = old->data();
  auto shape         = old->shape();

  memset(ad->hashTab(), static_cast<uint8_t>(MixedArray::Empty),
    sizeof(int32_t) * ad->hashSize());

  for (auto i = 0; i < oldSize; ++i) {
    auto key = const_cast<StringData*>(shape->keyForOffset(i));
    auto& e = ad->addKeyAndGetElem(key);
    tvDupFlattenVars(&srcData[i], &e.data, old);
  }

  ad->m_pos = old->m_pos;
  assert(ad->checkInvariants());
  assert(!ad->isFull());
  assert(ad->hasExactlyOneRef());
  return ad;
}
Exemplo n.º 9
0
void Generator::copyVars(const ActRec* srcFp) {
  const auto dstFp = actRec();
  const auto func = dstFp->func();
  assert(srcFp->func() == dstFp->func());

  for (Id i = 0; i < func->numLocals(); ++i) {
    tvDupFlattenVars(frame_local(srcFp, i), frame_local(dstFp, i));
  }

  if (dstFp->hasThis()) {
    dstFp->getThis()->incRefCount();
  }

  if (LIKELY(!(srcFp->func()->attrs() & AttrMayUseVV))) return;
  if (LIKELY(srcFp->m_varEnv == nullptr)) return;

  if (srcFp->hasExtraArgs()) {
    dstFp->setExtraArgs(srcFp->getExtraArgs()->clone(dstFp));
  } else {
    assert(srcFp->hasVarEnv());
    dstFp->setVarEnv(srcFp->getVarEnv()->clone(dstFp));
  }
}
Exemplo n.º 10
0
NameValueTable::NameValueTable(const NameValueTable& nvTable, ActRec* fp)
  : m_fp(fp)
  , m_elms(nvTable.m_elms)
{
  allocate(nvTable.m_tabMask + 1);
  assert(m_tabMask == nvTable.m_tabMask);

  for (int i = 0; i <= m_tabMask; ++i) {
    Elm& src = nvTable.m_table[i];
    Elm& dst = m_table[i];

    dst.m_name = src.m_name;
    if (dst.m_name) {
      dst.m_name->incRefCount();
      if (src.m_tv.m_type == kNamedLocalDataType) {
        dst.m_tv.m_type = kNamedLocalDataType;
        dst.m_tv.m_data.num = src.m_tv.m_data.num;
      } else {
        tvDupFlattenVars(&src.m_tv, &dst.m_tv);
      }
    }
  }
}
Exemplo n.º 11
0
void c_Continuation::copyContinuationVars(ActRec* srcFp) {
  const auto dstFp = actRec();
  const auto func = dstFp->func();
  assert(srcFp->func() == dstFp->func());

  for (Id i = 0; i < func->numLocals(); ++i) {
    tvDupFlattenVars(frame_local(srcFp, i), frame_local(dstFp, i));
  }

  if (dstFp->hasThis()) {
    dstFp->getThis()->incRefCount();
  }

  if (LIKELY(srcFp->m_varEnv == nullptr)) {
    return;
  }

  if (srcFp->hasExtraArgs()) {
    dstFp->setExtraArgs(srcFp->getExtraArgs()->clone(dstFp));
  } else {
    assert(srcFp->hasVarEnv());
    dstFp->setVarEnv(srcFp->getVarEnv()->clone(dstFp));
  }
}