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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário