Implement specialized array setting in VectorTranslator

This mimics what TranslatorX64 does in translateSetMArray,
but it does it with fewer helpers and (often) fewer instructions in
translated code. I also found a bug in both jits and the interpreter
when dealing with arrays that hold refs to themselves. The new test
case exercises the fix, which involved a bit of refactoring of the
refcounting logic.

Enabling VectorTranslator while punting to tx64 is no longer a
regression so I removed the punt in emit().
Esse commit está contido em:
bsimmers
2013-03-08 21:56:53 -08:00
commit de Sara Golemon
commit ea56a8383e
15 arquivos alterados com 269 adições e 37 exclusões
+13 -16
Ver Arquivo
@@ -30,6 +30,7 @@
#include <util/trace.h>
#include <util/util.h>
#include <runtime/base/execution_context.h>
#include <runtime/vm/member_operations.h>
#include <runtime/vm/stats.h>
// If PEDANTIC is defined, extra checks are performed to ensure correct
@@ -1762,27 +1763,14 @@ ArrayData* nvCheckedSet(ArrayData* a, StringData* key, TypedValue* value,
a->nvSet(key, value, copy);
}
ArrayData* nvCheckedSet(ArrayData* a, int64_t key, TypedValue* value, bool 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); }
static inline ArrayData*
array_mutate_post(Cell *cell, ArrayData* old, ArrayData* retval) {
if (nullptr == retval) {
return old;
}
retval->incRefCount();
// 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
decRefArr(old);
if (cell) cell->m_data.parr = retval;
return retval;
}
template<typename Key, bool DecRefValue, bool CheckInt, bool DecRefKey>
static inline
ArrayData*
@@ -1794,8 +1782,17 @@ array_setm(TypedValue* cell, ArrayData* ad, Key key, TypedValue* value) {
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);
return array_mutate_post(cell, ad, retval);
if (cell == nullptr) {
return arrayRefShuffle<false>(ad, retval, cell);
} else {
arrayRefShuffle<true>(ad, retval, cell);
return nullptr;
}
}
/**