Make ArrayKind a regular enum
We use ArrayKind as a simple unsigned integer, its an index, we do range-based comparisons, and in the future we'll likely do bit-ops for fast sub-kind tests. Just be honest that this is an old-school enum.
Esse commit está contido em:
@@ -167,37 +167,32 @@ inline Variant ArrayData::getKey(ssize_t pos) const {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline unsigned ArrayData::index() const {
|
||||
assert(unsigned(m_kind) < unsigned(ArrayKind::kNumKinds));
|
||||
return unsigned(m_kind);
|
||||
}
|
||||
|
||||
inline void ArrayData::release() {
|
||||
return g_array_funcs.release[index()](this);
|
||||
return g_array_funcs.release[m_kind](this);
|
||||
}
|
||||
|
||||
inline ArrayData* ArrayData::append(CVarRef v, bool copy) {
|
||||
return g_array_funcs.append[index()](this, v, copy);
|
||||
return g_array_funcs.append[m_kind](this, v, copy);
|
||||
}
|
||||
|
||||
inline TypedValue* ArrayData::nvGet(int64_t ikey) const {
|
||||
return g_array_funcs.nvGetInt[index()](this, ikey);
|
||||
return g_array_funcs.nvGetInt[m_kind](this, ikey);
|
||||
}
|
||||
|
||||
inline TypedValue* ArrayData::nvGet(const StringData* skey) const {
|
||||
return g_array_funcs.nvGetStr[index()](this, skey);
|
||||
return g_array_funcs.nvGetStr[m_kind](this, skey);
|
||||
}
|
||||
|
||||
inline void ArrayData::nvGetKey(TypedValue* out, ssize_t pos) const {
|
||||
g_array_funcs.nvGetKey[index()](this, out, pos);
|
||||
g_array_funcs.nvGetKey[m_kind](this, out, pos);
|
||||
}
|
||||
|
||||
inline ArrayData* ArrayData::set(int64_t k, CVarRef v, bool copy) {
|
||||
return g_array_funcs.setInt[index()](this, k, v, copy);
|
||||
return g_array_funcs.setInt[m_kind](this, k, v, copy);
|
||||
}
|
||||
|
||||
inline ArrayData* ArrayData::set(StringData* k, CVarRef v, bool copy) {
|
||||
return g_array_funcs.setStr[index()](this, k, v, copy);
|
||||
return g_array_funcs.setStr[m_kind](this, k, v, copy);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -64,7 +64,7 @@ ArrayData *ArrayData::GetScalarArray(ArrayData *arr,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// order: kVector, kHphpArray, kSharedMap, kNameValueTableWrapper, kPolicyArray
|
||||
// order: kVectorKind, kMixedKind, kSharedKind, kNvtwKind, kPolicyKind
|
||||
extern const ArrayFunctions g_array_funcs = {
|
||||
// release
|
||||
{ &HphpArray::ReleaseVec, &HphpArray::Release,
|
||||
@@ -503,12 +503,12 @@ CVarRef ArrayData::getNotFound(const StringData* k) {
|
||||
}
|
||||
|
||||
CVarRef ArrayData::getNotFound(int64_t k, bool error) const {
|
||||
return error && m_kind != ArrayKind::kNameValueTableWrapper ? getNotFound(k) :
|
||||
return error && m_kind != kNvtwKind ? getNotFound(k) :
|
||||
null_variant;
|
||||
}
|
||||
|
||||
CVarRef ArrayData::getNotFound(const StringData* k, bool error) const {
|
||||
return error && m_kind != ArrayKind::kNameValueTableWrapper ? getNotFound(k) :
|
||||
return error && m_kind != kNvtwKind ? getNotFound(k) :
|
||||
null_variant;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,13 +38,17 @@ class ArrayData : public Countable {
|
||||
enum class AllocationMode : bool { smart, nonSmart };
|
||||
|
||||
// enum of possible array types, so we can guard nonvirtual
|
||||
// fast paths in runtime code.
|
||||
enum class ArrayKind : uint8_t {
|
||||
kVector,
|
||||
kHphpArray,
|
||||
kSharedMap,
|
||||
kNameValueTableWrapper,
|
||||
kPolicyArray,
|
||||
// fast paths in runtime code. This is intentionally not
|
||||
// an enum class, to avoid boilerplate when:
|
||||
// - doing relational comparisons
|
||||
// - using kind as an index
|
||||
// - maybe doing bitops in the future
|
||||
enum ArrayKind : uint8_t {
|
||||
kVectorKind, // HphpArray vector-shape
|
||||
kMixedKind, // HphpArray generic shape
|
||||
kSharedKind, // SharedMap
|
||||
kNvtwKind, // NameValueTableWrapper
|
||||
kPolicyKind, // PolicyArray
|
||||
kNumKinds // insert new values before kNumKinds.
|
||||
};
|
||||
|
||||
@@ -134,7 +138,7 @@ public:
|
||||
* return the array kind for fast typechecks
|
||||
*/
|
||||
ArrayKind kind() const {
|
||||
return (ArrayKind)m_kind;
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,15 +167,15 @@ public:
|
||||
/*
|
||||
* Specific derived class type querying operators.
|
||||
*/
|
||||
bool isPolicyArray() const { return m_kind == ArrayKind::kPolicyArray; }
|
||||
bool isVector() const { return m_kind == ArrayKind::kVector; }
|
||||
bool isPolicyArray() const { return m_kind == kPolicyKind; }
|
||||
bool isVector() const { return m_kind == kVectorKind; }
|
||||
bool isHphpArray() const {
|
||||
return m_kind <= ArrayKind::kHphpArray;
|
||||
static_assert(ArrayKind::kVector < ArrayKind::kHphpArray, "");
|
||||
return m_kind <= kMixedKind;
|
||||
static_assert(kVectorKind < kMixedKind, "");
|
||||
}
|
||||
bool isSharedMap() const { return m_kind == ArrayKind::kSharedMap; }
|
||||
bool isSharedMap() const { return m_kind == kSharedKind; }
|
||||
bool isNameValueTableWrapper() const {
|
||||
return m_kind == ArrayKind::kNameValueTableWrapper;
|
||||
return m_kind == kNvtwKind;
|
||||
}
|
||||
|
||||
|
||||
@@ -463,8 +467,6 @@ public:
|
||||
static_assert(offsetof(ArrayData, _count) == FAST_REFCOUNT_OFFSET,
|
||||
"Offset of _count in ArrayData must be FAST_REFCOUNT_OFFSET");
|
||||
}
|
||||
// safely convert m_kind to an array index for dispatching
|
||||
unsigned index() const;
|
||||
|
||||
protected:
|
||||
void freeStrongIterators();
|
||||
|
||||
@@ -104,7 +104,7 @@ void HphpArray::getArrayElm(ssize_t pos, TypedValue* valOut,
|
||||
}
|
||||
|
||||
inline HphpArray* HphpArray::asVector(ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kVector);
|
||||
assert(ad->kind() == kVectorKind);
|
||||
assert(dynamic_cast<HphpArray*>(ad));
|
||||
auto a = static_cast<HphpArray*>(ad);
|
||||
assert(a->checkInvariants());
|
||||
@@ -112,7 +112,7 @@ inline HphpArray* HphpArray::asVector(ArrayData* ad) {
|
||||
}
|
||||
|
||||
inline const HphpArray* HphpArray::asVector(const ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kVector);
|
||||
assert(ad->kind() == kVectorKind);
|
||||
assert(dynamic_cast<const HphpArray*>(ad));
|
||||
auto a = static_cast<const HphpArray*>(ad);
|
||||
assert(a->checkInvariants());
|
||||
@@ -120,7 +120,7 @@ inline const HphpArray* HphpArray::asVector(const ArrayData* ad) {
|
||||
}
|
||||
|
||||
inline HphpArray* HphpArray::asHphpArray(ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kHphpArray);
|
||||
assert(ad->kind() == kMixedKind);
|
||||
assert(dynamic_cast<HphpArray*>(ad));
|
||||
auto a = static_cast<HphpArray*>(ad);
|
||||
assert(a->checkInvariants());
|
||||
@@ -128,7 +128,7 @@ inline HphpArray* HphpArray::asHphpArray(ArrayData* ad) {
|
||||
}
|
||||
|
||||
inline const HphpArray* HphpArray::asHphpArray(const ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kHphpArray);
|
||||
assert(ad->kind() == kMixedKind);
|
||||
assert(dynamic_cast<const HphpArray*>(ad));
|
||||
auto a = static_cast<const HphpArray*>(ad);
|
||||
assert(a->checkInvariants());
|
||||
|
||||
@@ -105,7 +105,7 @@ static inline uint32_t computeMaskFromNumElms(const uint32_t n) {
|
||||
// Construction/destruction.
|
||||
|
||||
HphpArray::HphpArray(uint capacity)
|
||||
: ArrayData(ArrayKind::kVector, AllocationMode::smart, 0)
|
||||
: ArrayData(kVectorKind, AllocationMode::smart, 0)
|
||||
, m_used(0) {
|
||||
#ifdef PEDANTIC
|
||||
if (size > 0x7fffffffU) {
|
||||
@@ -120,7 +120,7 @@ HphpArray::HphpArray(uint capacity)
|
||||
}
|
||||
|
||||
HphpArray::HphpArray(uint size, const TypedValue* values)
|
||||
: ArrayData(ArrayKind::kVector, AllocationMode::smart, size)
|
||||
: ArrayData(kVectorKind, AllocationMode::smart, size)
|
||||
, m_used(size) {
|
||||
#ifdef PEDANTIC
|
||||
if (size > 0x7fffffffU) {
|
||||
@@ -143,7 +143,7 @@ HphpArray::HphpArray(uint size, const TypedValue* values)
|
||||
}
|
||||
|
||||
HphpArray::HphpArray(EmptyMode)
|
||||
: ArrayData(ArrayKind::kVector, AllocationMode::smart, 0)
|
||||
: ArrayData(kVectorKind, AllocationMode::smart, 0)
|
||||
, m_used(0)
|
||||
, m_tableMask(SmallHashSize - 1) {
|
||||
allocData(SmallSize, SmallHashSize);
|
||||
@@ -261,7 +261,7 @@ HphpArray* HphpArray::vectorToGeneric() {
|
||||
m_hash = hashSize <= sizeof(m_inline_hash) ? m_inline_hash :
|
||||
(ElmInd*)(uintptr_t(m_data) + dataSize);
|
||||
}
|
||||
m_kind = ArrayKind::kHphpArray;
|
||||
m_kind = kMixedKind;
|
||||
uint32_t i = 0;
|
||||
auto size = m_size;
|
||||
for (; i < size; ++i) {
|
||||
@@ -316,10 +316,10 @@ bool HphpArray::checkInvariants() const {
|
||||
assert(!isTombstone(m_data[m_used - 1].data.m_type));
|
||||
}
|
||||
switch (m_kind) {
|
||||
case ArrayKind::kVector:
|
||||
case kVectorKind:
|
||||
assert(m_size == m_used);
|
||||
break;
|
||||
case ArrayKind::kHphpArray: {
|
||||
case kMixedKind: {
|
||||
assert(m_hash);
|
||||
assert(m_hLoad >= m_size);
|
||||
size_t load = 0;
|
||||
|
||||
@@ -186,7 +186,7 @@ void SimpleArrayStore::prepend(const Variant& v, uint length,
|
||||
IMPLEMENT_SMART_ALLOCATION(PolicyArray)
|
||||
|
||||
PolicyArray::PolicyArray(uint capacity)
|
||||
: ArrayData(ArrayKind::kPolicyArray)
|
||||
: ArrayData(kPolicyKind)
|
||||
, Store(m_allocMode, capacity) {
|
||||
m_size = 0;
|
||||
m_pos = invalid_index;
|
||||
@@ -197,7 +197,7 @@ PolicyArray::PolicyArray(uint capacity)
|
||||
|
||||
PolicyArray::PolicyArray(const PolicyArray& rhs, uint capacity,
|
||||
AllocationMode am)
|
||||
: ArrayData(ArrayKind::kPolicyArray, am)
|
||||
: ArrayData(kPolicyKind, am)
|
||||
, Store(rhs, rhs.m_size, capacity, am, &rhs) {
|
||||
m_size = rhs.m_size;
|
||||
m_pos = rhs.m_pos;
|
||||
@@ -216,13 +216,13 @@ void PolicyArray::Release(ArrayData* ad) {
|
||||
}
|
||||
|
||||
inline PolicyArray* PolicyArray::asPolicyArray(ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kPolicyArray);
|
||||
assert(ad->kind() == kPolicyKind);
|
||||
assert(dynamic_cast<PolicyArray*>(ad));
|
||||
return static_cast<PolicyArray*>(ad);
|
||||
}
|
||||
|
||||
inline const PolicyArray* PolicyArray::asPolicyArray(const ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kPolicyArray);
|
||||
assert(ad->kind() == kPolicyKind);
|
||||
assert(dynamic_cast<const PolicyArray*>(ad));
|
||||
return static_cast<const PolicyArray*>(ad);
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ void SharedMap::Release(ArrayData* ad) {
|
||||
}
|
||||
|
||||
inline SharedMap* SharedMap::asSharedMap(ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kSharedMap);
|
||||
assert(ad->kind() == kSharedKind);
|
||||
assert(dynamic_cast<SharedMap*>(ad));
|
||||
return static_cast<SharedMap*>(ad);
|
||||
}
|
||||
|
||||
inline const SharedMap* SharedMap::asSharedMap(const ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kSharedMap);
|
||||
assert(ad->kind() == kSharedKind);
|
||||
assert(dynamic_cast<const SharedMap*>(ad));
|
||||
return static_cast<const SharedMap*>(ad);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace HPHP {
|
||||
class SharedMap : public ArrayData {
|
||||
public:
|
||||
explicit SharedMap(SharedVariant* source)
|
||||
: ArrayData(ArrayKind::kSharedMap)
|
||||
: ArrayData(kSharedKind)
|
||||
, m_localCache(nullptr) {
|
||||
m_map = source->getMap();
|
||||
m_isVector = source->getIsVector();
|
||||
|
||||
@@ -24,14 +24,14 @@ namespace HPHP {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline NameValueTableWrapper* NameValueTableWrapper::asNVTW(ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kNameValueTableWrapper);
|
||||
assert(ad->kind() == kNvtwKind);
|
||||
assert(dynamic_cast<NameValueTableWrapper*>(ad));
|
||||
return static_cast<NameValueTableWrapper*>(ad);
|
||||
}
|
||||
|
||||
inline const NameValueTableWrapper*
|
||||
NameValueTableWrapper::asNVTW(const ArrayData* ad) {
|
||||
assert(ad->kind() == ArrayKind::kNameValueTableWrapper);
|
||||
assert(ad->kind() == kNvtwKind);
|
||||
assert(dynamic_cast<const NameValueTableWrapper*>(ad));
|
||||
return static_cast<const NameValueTableWrapper*>(ad);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace HPHP {
|
||||
*/
|
||||
struct NameValueTableWrapper : public ArrayData {
|
||||
explicit NameValueTableWrapper(NameValueTable* tab)
|
||||
: ArrayData(ArrayKind::kNameValueTableWrapper)
|
||||
: ArrayData(kNvtwKind)
|
||||
, m_tab(tab)
|
||||
{ }
|
||||
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário