Пример #1
0
ALWAYS_INLINE
MixedArray* PackedArray::ToMixedHeader(const ArrayData* old,
                                      size_t neededSize) {
  assert(PackedArray::checkInvariants(old));

  auto const oldSize = old->m_size;
  auto const cmret   = computeCapAndMask(neededSize);
  auto const cap     = cmret.first;
  auto const mask    = cmret.second;
  auto const ad      = smartAllocArray(cap, mask);

  auto const shiftedSize = uint64_t{oldSize} << 32;
  ad->m_kindAndSize      = shiftedSize | MixedArray::kMixedKind << 24;
  ad->m_posAndCount      = static_cast<uint32_t>(old->m_pos);  // zero count
  ad->m_capAndUsed       = shiftedSize | cap;
  ad->m_maskAndLoad      = shiftedSize | mask;
  ad->m_nextKI           = oldSize;

  assert(ad->m_kind == ArrayData::kMixedKind);
  assert(ad->m_size == oldSize);
  assert(ad->m_pos == old->m_pos);
  assert(ad->m_count == 0);
  assert(ad->m_used == oldSize);
  assert(ad->m_cap == cap);
  assert(ad->m_tableMask = mask);
  assert(ad->m_hLoad == oldSize);
  assert(ad->m_nextKI == oldSize);
  // Can't checkInvariants yet, since we haven't populated the payload.
  return ad;
}
Пример #2
0
/*
 * Creating a single-element mixed array with a integer key.  The
 * value is already incref'd.
 */
std::pair<ArrayData*,TypedValue*>
EmptyArray::MakeMixed(int64_t key, TypedValue val) {
  auto const ad = smartAllocArray(MixedArray::SmallScale);
  InitMixed(ad, 0/*count*/, 1/*size*/, (key >= 0) ? key + 1 : 0);
  auto const data = ad->data();
  auto const hash = reinterpret_cast<int32_t*>(data + MixedArray::SmallSize);
  assert(ad->hashSize() == MixedArray::SmallHashSize);
  auto const emptyVal = int64_t{MixedArray::Empty};
  reinterpret_cast<int64_t*>(hash)[0] = emptyVal;
  reinterpret_cast<int64_t*>(hash)[1] = emptyVal;

  auto const mask = MixedArray::SmallMask;
  hash[key & mask] = 0;
  data[0].setIntKey(key);

  auto& lval  = data[0].data;
  lval.m_data = val.m_data;
  lval.m_type = val.m_type;

  assert(ad->kind() == ArrayData::kMixedKind);
  assert(ad->m_size == 1);
  assert(ad->m_pos == 0);
  assert(ad->getCount() == 0);
  assert(ad->m_scale == MixedArray::SmallScale);
  assert(ad->m_used == 1);
  assert(ad->checkInvariants());
  return { ad, &lval };
}
Пример #3
0
/*
 * Helper for creating a single-element mixed array with a string key.
 *
 * Note: the key is not already incref'd, but the value must be.
 */
NEVER_INLINE
std::pair<ArrayData*,TypedValue*>
EmptyArray::MakeMixed(StringData* key, TypedValue val) {
  auto const ad = smartAllocArray(MixedArray::SmallScale);
  InitMixed(ad, 0/*count*/, 1/*size*/, 0/*nextIntKey*/);
  auto const data = ad->data();
  auto const hash = reinterpret_cast<int32_t*>(data + MixedArray::SmallSize);
  auto const khash = key->hash();
  auto const mask = MixedArray::SmallMask;
  hash[khash & mask] = 0;
  data[0].setStrKey(key, khash);

  auto& lval  = data[0].data;
  lval.m_data = val.m_data;
  lval.m_type = val.m_type;

  assert(ad->m_size == 1);
  assert(ad->m_pos == 0);
  assert(ad->m_scale == MixedArray::SmallScale);
  assert(ad->kind() == ArrayData::kMixedKind);
  assert(ad->getCount() == 0);
  assert(ad->m_used == 1);
  assert(ad->checkInvariants());
  return { ad, &lval };
}
Пример #4
0
/*
 * Helper for creating a single-element mixed array with a string key.
 *
 * Note: the key is not already incref'd, but the value must be.
 */
NEVER_INLINE
std::pair<ArrayData*,TypedValue*>
EmptyArray::MakeMixed(StringData* key, TypedValue val) {
  auto const mask = MixedArray::SmallMask;            // 3
  auto const cap  = MixedArray::computeMaxElms(mask); // 3
  auto const ad   = smartAllocArray(cap, mask);

  ad->m_kindAndSize = uint64_t{1} << 32 | ArrayData::kMixedKind << 24;
  ad->m_posAndCount = 0;
  ad->m_capAndUsed  = uint64_t{1} << 32 | cap;
  ad->m_tableMask   = mask;
  ad->m_nextKI      = 0;
  ad->m_hLoad       = 1;

  auto const data = reinterpret_cast<MixedArray::Elm*>(ad + 1);
  auto const hash = reinterpret_cast<int32_t*>(data + cap);

  assert(mask + 1 == 4);
  auto const emptyVal = int64_t{MixedArray::Empty};
  reinterpret_cast<int64_t*>(hash)[0] = emptyVal;
  reinterpret_cast<int64_t*>(hash)[1] = emptyVal;

  auto const khash = key->hash();
  hash[khash & mask] = 0;
  data[0].setStrKey(key, khash);

  auto& lval  = data[0].data;
  lval.m_data = val.m_data;
  lval.m_type = val.m_type;

  assert(ad->m_kind == ArrayData::kMixedKind);
  assert(ad->m_size == 1);
  assert(ad->m_pos == 0);
  assert(ad->m_count == 0);
  assert(ad->m_cap == cap);
  assert(ad->m_used == 1);
  assert(ad->checkInvariants());
  return { ad, &lval };
}
Пример #5
0
/*
 * Creating a single-element mixed array with a integer key.  The
 * value is already incref'd.
 */
std::pair<ArrayData*,TypedValue*>
EmptyArray::MakeMixed(int64_t key, TypedValue val) {
  auto const mask = MixedArray::SmallMask;            // 3
  auto const cap  = MixedArray::computeMaxElms(mask); // 3
  auto const ad   = smartAllocArray(cap, mask);

  ad->m_sizeAndPos    = 1; // size=1, pos=0
  ad->m_kindAndCount  = MixedArray::kMixedKind << 24; // capcode=0, count=0
  ad->m_capAndUsed    = uint64_t{1} << 32 | cap;
  ad->m_tableMask     = mask;
  ad->m_nextKI        = (key >= 0) ? key + 1 : 0;

  auto const data = reinterpret_cast<MixedArray::Elm*>(ad + 1);
  auto const hash = reinterpret_cast<int32_t*>(data + cap);

  assert(mask + 1 == 4);
  auto const emptyVal = int64_t{MixedArray::Empty};
  reinterpret_cast<int64_t*>(hash)[0] = emptyVal;
  reinterpret_cast<int64_t*>(hash)[1] = emptyVal;

  hash[key & mask] = 0;
  data[0].setIntKey(key);

  auto& lval  = data[0].data;
  lval.m_data = val.m_data;
  lval.m_type = val.m_type;

  assert(ad->m_kind == ArrayData::kMixedKind);
  assert(ad->m_size == 1);
  assert(ad->m_pos == 0);
  assert(ad->m_count == 0);
  assert(ad->m_cap == cap);
  assert(ad->m_used == 1);
  assert(ad->checkInvariants());
  return { ad, &lval };
}