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:
Edwin Smith
2013-07-18 10:58:04 -07:00
commit de Sara Golemon
commit 353b33928b
10 arquivos alterados com 48 adições e 51 exclusões
+7 -12
Ver Arquivo
@@ -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);
}
///////////////////////////////////////////////////////////////////////////////
+3 -3
Ver Arquivo
@@ -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;
}
+18 -16
Ver Arquivo
@@ -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();
+4 -4
Ver Arquivo
@@ -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());
+6 -6
Ver Arquivo
@@ -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;
+4 -4
Ver Arquivo
@@ -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);
}
+2 -2
Ver Arquivo
@@ -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);
}
+1 -1
Ver Arquivo
@@ -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();
+2 -2
Ver Arquivo
@@ -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);
}
+1 -1
Ver Arquivo
@@ -54,7 +54,7 @@ namespace HPHP {
*/
struct NameValueTableWrapper : public ArrayData {
explicit NameValueTableWrapper(NameValueTable* tab)
: ArrayData(ArrayKind::kNameValueTableWrapper)
: ArrayData(kNvtwKind)
, m_tab(tab)
{ }