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
-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 {