Remove ArrayData::nvSet() wrappers and several dead Array helpers.

nvSet() only casts the value from TypedValue* to const Variant&; do it
at callsites.  Inlined array_setm_ik1_v0() and array_setm_s0k1_v0() into
their only remaining callsites in translator-runtime.cpp.
Esse commit está contido em:
Edwin Smith
2013-06-05 17:18:05 -07:00
commit de sgolemon
commit 3515793e74
11 arquivos alterados com 58 adições e 288 exclusões
-6
Ver Arquivo
@@ -323,12 +323,6 @@ public:
ArrayData *remove(CStrRef k, bool copy);
ArrayData *remove(CVarRef k, bool copy);
/*
* Inline wrappers that just use tvAsCVarRef on the value
*/
ArrayData* nvSet(int64_t ki, const TypedValue* v, bool copy);
ArrayData* nvSet(StringData* k, const TypedValue* v, bool copy);
virtual ssize_t iter_begin() const;
virtual ssize_t iter_end() const;
virtual ssize_t iter_advance(ssize_t prev) const;
-9
Ver Arquivo
@@ -107,15 +107,6 @@ inline ArrayData* ArrayData::set(CVarRef k, CVarRef v, bool copy) {
set(getStringKey(tvk), v, copy);
}
inline ArrayData* ArrayData::nvSet(int64_t ki, const TypedValue* v, bool copy) {
return set(ki, tvAsCVarRef(v), copy);
}
inline ArrayData* ArrayData::nvSet(StringData* k, const TypedValue* v,
bool copy) {
return set(k, tvAsCVarRef(v), copy);
}
inline ArrayData* ArrayData::setRef(CStrRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
return setRef(k.get(), v, copy);
-215
Ver Arquivo
@@ -1643,221 +1643,6 @@ CVarRef HphpArray::endRef() {
return tvAsCVarRef(&e->data);
}
//=============================================================================
// VM runtime support functions.
// Helpers for array_setm.
ArrayData* nvCheckedSet(ArrayData* a, StringData* key, TypedValue* value,
bool copy) {
int64_t i;
return UNLIKELY(key->isStrictlyInteger(i)) ? a->nvSet(i, value, copy) :
a->nvSet(key, value, copy);
}
ArrayData* nvCheckedSet(ArrayData* a, int64_t key, TypedValue* value,
bool copy) {
return a->nvSet(key, value, copy);
}
void setmDecRef(int64_t i) { /* nop */ }
void setmDecRef(StringData* sd) { decRefStr(sd); }
template<typename Key, bool DecRefValue, bool CheckInt, bool DecRefKey>
static inline
ArrayData*
array_setm(RefData* ref, ArrayData* ad, Key key, TypedValue* value) {
ArrayData* retval;
bool copy = ad->getCount() > 1;
// nvSet will decRef any old value that may have been overwritten
// if appropriate
retval = CheckInt ? nvCheckedSet(ad, key, value, copy) :
ad->nvSet(key, value, copy);
if (DecRefKey) setmDecRef(key);
// TODO Task #1970153: It would be great if there were nvSet()
// methods that didn't bump up the refcount so that we didn't
// have to decrement it here
if (DecRefValue) tvRefcountedDecRef(value);
if (!ref) return arrayRefShuffle<false>(ad, retval, nullptr);
arrayRefShuffle<true>(ad, retval, ref->tv());
return retval;
}
/**
* Unary integer keys.
* array_setm_ik1_v --
* Polymorphic value.
*
* array_setm_ik1_v0 --
* Don't count the array's reference to the polymorphic value.
*/
ArrayData* array_setm_ik1_v(RefData* ref, ArrayData* ad, int64_t key,
TypedValue* value) {
return array_setm<int64_t, false, false, false>(ref, ad, key, value);
}
ArrayData* array_setm_ik1_v0(RefData* ref, ArrayData* ad, int64_t key,
TypedValue* value) {
return array_setm<int64_t, true, false, false>(ref, ad, key, value);
}
/**
* String keys.
*
* array_setm_sk1_v --
* $a[$keyOfTypeString] = <polymorphic value>;
*
* array_setm_sk1_v0 --
* Like above, but don't count the new reference.
*
* array_setm_s0k1_v --
* array_setm_s0k1_v0 --
* As above, but dont decRef the key
*
* array_setm_s0k1nc_v --
* array_setm_s0k1nc_v0 --
* Dont decRef the key, and skip the check for
* whether the key is really an integer.
*/
ArrayData* array_setm_sk1_v(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value) {
return array_setm<StringData*, false, true, true>(ref, ad, key, value);
}
ArrayData* array_setm_sk1_v0(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value) {
return array_setm<StringData*, true, true, true>(ref, ad, key, value);
}
ArrayData* array_setm_s0k1_v(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value) {
return array_setm<StringData*, false, true, false>(ref, ad, key, value);
}
ArrayData* array_setm_s0k1_v0(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value) {
return array_setm<StringData*, true, true, false>(ref, ad, key, value);
}
ArrayData* array_setm_s0k1nc_v(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value) {
return array_setm<StringData*, false, false, false>(ref, ad, key, value);
}
ArrayData* array_setm_s0k1nc_v0(RefData* ref, ArrayData* ad,
StringData* key, TypedValue* value) {
return array_setm<StringData*, true, false, false>(ref, ad, key, value);
}
/**
* Append.
*
* array_setm_wk1_v0 --
* $a[] = <polymorphic value>
* ... but don't count the reference to the new value.
*/
ArrayData* array_setm_wk1_v0(ArrayData* ad, TypedValue* value) {
return HphpArray::AddNewElemC(ad, *value);
}
/**
* Array runtime helpers. For code-sharing purposes, all of these handle as
* much ref-counting machinery as possible. They differ by -arity, type
* signature, and necessity of various costly checks.
*
* They return the array that was just passed in as a convenience to
* callers, which may have "lost" the array in volatile registers before
* calling.
*/
ArrayData*
array_getm_i(void* dptr, int64_t key, TypedValue* out) {
assert(dptr);
ArrayData* ad = (ArrayData*)dptr;
TRACE(2, "array_getm_ik1: (%p) <- %p[%" PRId64 "]\n", out, dptr, key);
// Ref-counting the value is the translator's responsibility. We know out
// pointed to uninitialized memory, so no need to dec it.
TypedValue* ret = ad->nvGetCell(key);
tvDup(ret, out);
return ad;
}
NEVER_INLINE
ArrayData* array_getm_s(ArrayData* ad, StringData* sd, TypedValue* out,
int flags) {
bool drKey = flags & DecRefKey;
bool checkInts = flags & CheckInts;
int64_t ikey;
TypedValue* ret = checkInts && UNLIKELY(sd->isStrictlyInteger(ikey)) ?
ad->nvGetCell(ikey) :
ad->nvGetCell(sd);
tvDup((ret), (out));
if (drKey) decRefStr(sd);
TRACE(2, "%s: (%p) <- %p[\"%s\"@sd%p]\n", __FUNCTION__,
out, ad, sd->data(), sd);
return ad;
}
// issetm's DNA.
static bool
issetMUnary(const void* dptr, StringData* sd, bool decRefKey, bool checkInt) {
const ArrayData* ad = (const ArrayData*)dptr;
bool retval;
int64_t keyAsInt;
TypedValue* c;
if (checkInt && sd->isStrictlyInteger(keyAsInt)) {
c = ad->nvGet(keyAsInt);
} else {
c = ad->nvGet(sd);
}
const Variant* cell = &tvAsVariant(c);
retval = cell && !cell->isNull();
TRACE(2, "issetMUnary: %p[\"%s\"@sd%p] -> %d\n",
dptr, sd->data(), sd, retval);
if (decRefKey) decRefStr(sd);
return retval;
}
uint64_t array_issetm_s(const void* dptr, StringData* sd)
{ return issetMUnary(dptr, sd, true /*decRefKey*/, true /*checkInt*/); }
uint64_t array_issetm_s0(const void* dptr, StringData* sd)
{ return issetMUnary(dptr, sd, false /*decRefKey*/, true /*checkInt*/); }
uint64_t array_issetm_s_fast(const void* dptr, StringData* sd)
{ return issetMUnary(dptr, sd, true /*decRefKey*/, false /*checkInt*/); }
uint64_t array_issetm_s0_fast(const void* dptr, StringData* sd)
{ return issetMUnary(dptr, sd, false /*decRefKey*/, false /*checkInt*/); }
uint64_t array_issetm_i(const void* dptr, int64_t key) {
ArrayData* ad = (ArrayData*)dptr;
TypedValue* ret = ad->nvGet(key);
// Variant.isNull unboxes ret if its KindOfRef.
return ret && !tvAsCVarRef(ret).isNull();
}
ArrayData* array_add(ArrayData* a1, ArrayData* a2) {
if (!a2->empty()) {
if (a1->empty()) {
decRefArr(a1);
return a2;
}
if (a1 != a2) {
ArrayData *escalated = a1->append(a2, ArrayData::Plus,
a1->getCount() > 1);
if (escalated != a1) {
escalated->incRefCount();
decRefArr(a2);
decRefArr(a1);
return escalated;
}
}
}
decRefArr(a2);
return a1;
}
//=============================================================================
ALWAYS_INLINE HphpArray* HphpArray::clone(AllocationMode am) const {
-41
Ver Arquivo
@@ -511,47 +511,6 @@ private:
void cloneNonEmpty(HphpArray* target) const;
};
//=============================================================================
// VM runtime support functions.
enum ArrayGetFlags {
DecRefKey = 1,
CheckInts = 2
};
ArrayData* array_setm_ik1_v(RefData* ref, ArrayData* ad, int64_t key,
TypedValue* value);
ArrayData* array_setm_ik1_v0(RefData* ref, ArrayData* ad, int64_t key,
TypedValue* value);
ArrayData* array_setm_sk1_v(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value);
ArrayData* array_setm_sk1_v0(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value);
ArrayData* array_setm_s0k1_v(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value);
ArrayData* array_setm_s0k1_v0(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value);
ArrayData* array_setm_s0k1nc_v(RefData* ref, ArrayData* ad, StringData* key,
TypedValue* value);
ArrayData* array_setm_s0k1nc_v0(RefData* ref, ArrayData* ad,
StringData* key, TypedValue* value);
ArrayData* array_setm_wk1_v0(ArrayData* ad, TypedValue* value);
ArrayData* array_getm_i(void* hphpArray, int64_t key, TypedValue* out);
ArrayData* array_getm_s(ArrayData* a, StringData* key, TypedValue* out,
int flags);
uint64_t array_issetm_s(const void* hphpArray, StringData* sd)
FLATTEN;
uint64_t array_issetm_s0(const void* hphpArray, StringData* sd)
FLATTEN;
uint64_t array_issetm_s_fast(const void* hphpArray, StringData* sd)
FLATTEN;
uint64_t array_issetm_s0_fast(const void* hphpArray, StringData* sd)
FLATTEN;
uint64_t array_issetm_i(const void* hphpArray, int64_t key)
FLATTEN;
ArrayData* array_add(ArrayData* a1, ArrayData* a2);
//=============================================================================
// inline for performance reasons
+3 -3
Ver Arquivo
@@ -414,7 +414,7 @@ Array ObjectData::o_toIterArray(CStrRef context,
}
retval->nvBind(key, val);
} else {
retval->nvSet(key, val, false);
retval->set(key, tvAsCVarRef(val), false);
}
}
}
@@ -441,7 +441,7 @@ Array ObjectData::o_toIterArray(CStrRef context,
}
retval->nvBind(key.m_data.num, val);
} else {
retval->nvSet(key.m_data.num, val, false);
retval->set(key.m_data.num, tvAsCVarRef(val), false);
}
continue;
}
@@ -455,7 +455,7 @@ Array ObjectData::o_toIterArray(CStrRef context,
}
retval->nvBind(strKey, val);
} else {
retval->nvSet(strKey, val, false);
retval->set(strKey, tvAsCVarRef(val), false);
}
decRefStr(strKey);
}
+4 -3
Ver Arquivo
@@ -123,7 +123,7 @@ Array vm_get_class_constants(CStrRef className) {
if (value->m_type == KindOfUninit) {
value = cls->clsCnsGet(consts[i].m_name);
}
retVal->nvSet(name, value, false);
retVal->set(name, tvAsCVarRef(value), false);
}
}
@@ -167,7 +167,7 @@ Array vm_get_class_vars(CStrRef className) {
assert(name->size() != 0);
if (Class::IsPropAccessible(propInfo[i], ctx)) {
const TypedValue* value = &((*propVals)[i]);
ret->nvSet(name, value, false);
ret->set(name, tvAsCVarRef(value), false);
}
}
@@ -175,7 +175,8 @@ Array vm_get_class_vars(CStrRef className) {
bool vis, access;
TypedValue* value = cls->getSProp(ctx, sPropInfo[i].m_name, vis, access);
if (access) {
ret->nvSet(const_cast<StringData*>(sPropInfo[i].m_name), value, false);
ret->set(const_cast<StringData*>(sPropInfo[i].m_name),
tvAsCVarRef(value), false);
}
}
+1 -1
Ver Arquivo
@@ -6869,7 +6869,7 @@ lookupStatic(StringData* name,
if (val == nullptr) {
TypedValue tv;
tvWriteUninit(&tv);
map->nvSet(name, &tv, false);
map->set(name, tvAsCVarRef(&tv), false);
val = map->nvGet(name);
inited = false;
} else {
+4 -5
Ver Arquivo
@@ -1130,9 +1130,9 @@ HphpArray* Class::initClsCnsData() const {
for (Slot i = 0; i < nConstants; ++i) {
const Const& constant = m_constants[i];
TypedValue* tv = (TypedValue*)&constant.m_val;
constants->nvSet((StringData*)constant.m_name, tv, false);
// XXX: nvSet() converts KindOfUninit to KindOfNull, but our class
const TypedValue* tv = &constant.m_val;
constants->set((StringData*)constant.m_name, tvAsCVarRef(tv), false);
// XXX: set() converts KindOfUninit to KindOfNull, but our class
// constant logic needs to store KindOfUninit to indicate the the
// constant's value has not been computed yet. We should find a better
// way to deal with this.
@@ -2379,8 +2379,7 @@ void Class::getMethodNames(const Class* ctx, HphpArray* methods) const {
}
}
}
methods->nvSet(const_cast<StringData*>(func->name()),
(TypedValue*)&true_varNR, false);
methods->set(const_cast<StringData*>(func->name()), true_varNR, false);
}
if (m_parent.get()) m_parent.get()->getMethodNames(ctx, methods);
for (int i = 0, sz = m_declInterfaces.size(); i < sz; i++) {
+2 -2
Ver Arquivo
@@ -109,11 +109,11 @@ Object Instance::FromArray(ArrayData *properties) {
TypedValue key;
properties->nvGetKey(&key, pos);
if (key.m_type == KindOfInt64) {
props->nvSet(key.m_data.num, value, false);
props->set(key.m_data.num, tvAsCVarRef(value), false);
} else {
assert(IS_STRING_TYPE(key.m_type));
StringData* strKey = key.m_data.pstr;
props->nvSet(strKey, value, false);
props->set(strKey, tvAsCVarRef(value), false);
decRefStr(strKey);
}
}
+43 -3
Ver Arquivo
@@ -26,14 +26,54 @@ ArrayData* addElemIntKeyHelper(ArrayData* ad,
int64_t key,
TypedValue value) {
// this does not re-enter
return array_setm_ik1_v0(0, ad, key, &value);
// set will decRef any old value that may have been overwritten
// if appropriate
ArrayData* retval = ad->set(key, tvAsCVarRef(&value),
ad->getCount() > 1);
// TODO Task #1970153: It would be great if there were set()
// methods that didn't bump up the refcount so that we didn't
// have to decrement it here
tvRefcountedDecRef(&value);
return arrayRefShuffle<false>(ad, retval, nullptr);
}
ArrayData* addElemStringKeyHelper(ArrayData* ad,
StringData* key,
TypedValue value) {
// this does not re-enter
return array_setm_s0k1_v0(0, ad, key, &value);
bool copy = ad->getCount() > 1;
// set will decRef any old value that may have been overwritten
// if appropriate
int64_t intkey;
ArrayData* retval = UNLIKELY(key->isStrictlyInteger(intkey)) ?
ad->set(intkey, tvAsCVarRef(&value), copy) :
ad->set(key, tvAsCVarRef(&value), copy);
// TODO Task #1970153: It would be great if there were set()
// methods that didn't bump up the refcount so that we didn't
// have to decrement it here
tvRefcountedDecRef(&value);
return arrayRefShuffle<false>(ad, retval, nullptr);
}
ArrayData* array_add(ArrayData* a1, ArrayData* a2) {
if (!a2->empty()) {
if (a1->empty()) {
decRefArr(a1);
return a2;
}
if (a1 != a2) {
ArrayData *escalated = a1->append(a2, ArrayData::Plus,
a1->getCount() > 1);
if (escalated != a1) {
escalated->incRefCount();
decRefArr(a2);
decRefArr(a1);
return escalated;
}
}
}
decRefArr(a2);
return a1;
}
HOT_FUNC_VM void setNewElem(TypedValue* base, Cell val) {
@@ -280,7 +320,7 @@ RefData* staticLocInitImpl(StringData* name, ActRec* fp, TypedValue val,
TypedValue *mapVal = map->nvGet(name);
if (!mapVal) {
map->nvSet(name, &val, false);
map->set(name, tvAsCVarRef(&val), false);
mapVal = map->nvGet(name);
}
if (mapVal->m_type != KindOfRef) {
+1
Ver Arquivo
@@ -58,6 +58,7 @@ void setNewElem(TypedValue* base, Cell val);
void bindNewElemIR(TypedValue* base, RefData* val, MInstrState* mis);
RefData* box_value(TypedValue tv);
ArrayData* convCellToArrHelper(TypedValue tv);
ArrayData* array_add(ArrayData* a1, ArrayData* a2);
/* Helper functions for conversion instructions that are too
complicated to inline */