Revert "Delete GlobalCache"
Esse commit está contido em:
@@ -441,6 +441,16 @@ TypedValue* VarEnv::lookupAdd(const StringData* name) {
|
||||
return m_nvTable->lookupAdd(name);
|
||||
}
|
||||
|
||||
TypedValue* VarEnv::lookupRawPointer(const StringData* name) {
|
||||
ensureNvt();
|
||||
return m_nvTable->lookupRawPointer(name);
|
||||
}
|
||||
|
||||
TypedValue* VarEnv::lookupAddRawPointer(const StringData* name) {
|
||||
ensureNvt();
|
||||
return m_nvTable->lookupAddRawPointer(name);
|
||||
}
|
||||
|
||||
bool VarEnv::unset(const StringData* name) {
|
||||
if (!m_nvTable) return true;
|
||||
m_nvTable->unset(name);
|
||||
|
||||
@@ -177,6 +177,8 @@ class VarEnv {
|
||||
void setWithRef(const StringData* name, TypedValue* tv);
|
||||
TypedValue* lookup(const StringData* name);
|
||||
TypedValue* lookupAdd(const StringData* name);
|
||||
TypedValue* lookupRawPointer(const StringData* name);
|
||||
TypedValue* lookupAddRawPointer(const StringData* name);
|
||||
bool unset(const StringData* name);
|
||||
|
||||
Array getDefinedVariables() const;
|
||||
|
||||
@@ -579,6 +579,110 @@ MethodCache::lookup(Handle handle, ActRec* ar, const void* extraKey) {
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// GlobalCache
|
||||
// | - BoxedGlobalCache
|
||||
|
||||
template<bool isBoxed>
|
||||
inline TypedValue*
|
||||
GlobalCache::lookupImpl(StringData *name, bool allowCreate) {
|
||||
bool hit ATTRIBUTE_UNUSED;
|
||||
|
||||
TypedValue* retval;
|
||||
if (!m_tv) {
|
||||
hit = false;
|
||||
|
||||
VarEnv* ve = g_vmContext->m_globalVarEnv;
|
||||
assert(ve->isGlobalScope());
|
||||
if (allowCreate) {
|
||||
m_tv = ve->lookupAddRawPointer(name);
|
||||
} else {
|
||||
m_tv = ve->lookupRawPointer(name);
|
||||
if (!m_tv) {
|
||||
retval = 0;
|
||||
goto miss;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hit = true;
|
||||
}
|
||||
|
||||
retval = tvDerefIndirect(m_tv);
|
||||
if (retval->m_type == KindOfUninit) {
|
||||
if (!allowCreate) {
|
||||
retval = 0;
|
||||
goto miss;
|
||||
} else {
|
||||
tvWriteNull(retval);
|
||||
}
|
||||
}
|
||||
if (isBoxed && retval->m_type != KindOfRef) {
|
||||
tvBox(retval);
|
||||
}
|
||||
if (!isBoxed && retval->m_type == KindOfRef) {
|
||||
retval = retval->m_data.pref->tv();
|
||||
}
|
||||
assert(!isBoxed || retval->m_type == KindOfRef);
|
||||
assert(!allowCreate || retval);
|
||||
|
||||
miss:
|
||||
// decRef the name if we consumed it. If we didn't get a global, we
|
||||
// need to leave the name for the caller to use before decrefing (to
|
||||
// emit warnings).
|
||||
if (retval) decRefStr(name);
|
||||
TRACE(5, "%sGlobalCache::lookup(\"%s\") tv@%p %p -> (%s) %p t%d\n",
|
||||
isBoxed ? "Boxed" : "",
|
||||
name->data(),
|
||||
m_tv,
|
||||
retval,
|
||||
hit ? "hit" : "miss",
|
||||
retval ? retval->m_data.pref : 0,
|
||||
retval ? retval->m_type : 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
TypedValue*
|
||||
GlobalCache::lookup(Handle handle, StringData* name) {
|
||||
GlobalCache* thiz = (GlobalCache*)GlobalCache::cacheAtHandle(handle);
|
||||
TypedValue* retval = thiz->lookupImpl<false>(name, false /* allowCreate */);
|
||||
assert(!retval || retval->m_type != KindOfRef);
|
||||
return retval;
|
||||
}
|
||||
|
||||
TypedValue*
|
||||
GlobalCache::lookupCreate(Handle handle, StringData* name) {
|
||||
GlobalCache* thiz = (GlobalCache*)GlobalCache::cacheAtHandle(handle);
|
||||
TypedValue* retval = thiz->lookupImpl<false>(name, true /* allowCreate */);
|
||||
assert(retval->m_type != KindOfRef);
|
||||
return retval;
|
||||
}
|
||||
|
||||
TypedValue*
|
||||
GlobalCache::lookupCreateAddr(void* cacheAddr, StringData* name) {
|
||||
GlobalCache* thiz = (GlobalCache*)cacheAddr;
|
||||
TypedValue* retval = thiz->lookupImpl<false>(name, true /* allowCreate */);
|
||||
assert(retval->m_type != KindOfRef);
|
||||
return retval;
|
||||
}
|
||||
|
||||
TypedValue*
|
||||
BoxedGlobalCache::lookup(Handle handle, StringData* name) {
|
||||
BoxedGlobalCache* thiz = (BoxedGlobalCache*)
|
||||
BoxedGlobalCache::cacheAtHandle(handle);
|
||||
TypedValue* retval = thiz->lookupImpl<true>(name, false /* allowCreate */);
|
||||
assert(!retval || retval->m_type == KindOfRef);
|
||||
return retval;
|
||||
}
|
||||
|
||||
TypedValue*
|
||||
BoxedGlobalCache::lookupCreate(Handle handle, StringData* name) {
|
||||
BoxedGlobalCache* thiz = (BoxedGlobalCache*)
|
||||
BoxedGlobalCache::cacheAtHandle(handle);
|
||||
TypedValue* retval = thiz->lookupImpl<true>(name, true /* allowCreate */);
|
||||
assert(retval->m_type == KindOfRef);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static CacheHandle allocFuncOrClass(const unsigned* handlep, bool persistent) {
|
||||
if (UNLIKELY(!*handlep)) {
|
||||
Lock l(s_handleMutex);
|
||||
|
||||
@@ -266,6 +266,57 @@ typedef Cache<uintptr_t, const Func*, ActRec*, NSInvalid, 1, void>
|
||||
MethodCache;
|
||||
typedef Cache<StringData*, const Class*, StringData*, NSClass> ClassCache;
|
||||
|
||||
/*
|
||||
* GlobalCache --
|
||||
*
|
||||
* Records offsets into the current global array.
|
||||
*
|
||||
* For both GlobalCache and BoxedGlobalCache, the lookup routine may
|
||||
* return NULL, but lookupCreate will create new entries with
|
||||
* KindOfNull if the global didn't exist.
|
||||
*
|
||||
* Both routines will decRef the name on behalf of the caller, but
|
||||
* only if the lookup was successful (or a global was created).
|
||||
*/
|
||||
class GlobalCache {
|
||||
TypedValue* m_tv;
|
||||
|
||||
protected:
|
||||
static inline GlobalCache* cacheAtHandle(CacheHandle handle) {
|
||||
return (GlobalCache*)(uintptr_t(tl_targetCaches) + handle);
|
||||
}
|
||||
|
||||
template<bool isBoxed>
|
||||
TypedValue* lookupImpl(StringData *name, bool allowCreate);
|
||||
|
||||
public:
|
||||
inline CacheHandle cacheHandle() const {
|
||||
return ptrToHandle(this);
|
||||
}
|
||||
|
||||
static CacheHandle alloc(const StringData* sd) {
|
||||
assert(sd);
|
||||
return namedAlloc<NSGlobal>(sd, sizeof(GlobalCache), sizeof(GlobalCache));
|
||||
}
|
||||
|
||||
static TypedValue* lookup(CacheHandle handle, StringData* nm);
|
||||
static TypedValue* lookupCreate(CacheHandle handle, StringData* nm);
|
||||
static TypedValue* lookupCreateAddr(void* cacheAddr, StringData* nm);
|
||||
};
|
||||
|
||||
class BoxedGlobalCache : public GlobalCache {
|
||||
public:
|
||||
/*
|
||||
* Note: the returned pointer is a pointer to the outer variant.
|
||||
* You'll need to incref (or whatever) it yourself (if desired) and
|
||||
* emitDeref if you are going to put it in a register associated
|
||||
* with some vm location. (Note that KindOfRef in-register
|
||||
* values are the pointers to inner items.)
|
||||
*/
|
||||
static TypedValue* lookup(CacheHandle handle, StringData* nm);
|
||||
static TypedValue* lookupCreate(CacheHandle handle, StringData* nm);
|
||||
};
|
||||
|
||||
/*
|
||||
* Classes.
|
||||
*
|
||||
|
||||
@@ -906,7 +906,13 @@ void Unit::initialMerge() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UnitMergeKindGlobal: break;
|
||||
case UnitMergeKindGlobal: {
|
||||
StringData* s = (StringData*)((char*)obj - (int)k);
|
||||
auto* v = (TypedValueAux*) m_mergeInfo->mergeableData(ix + 1);
|
||||
ix += sizeof(*v) / sizeof(void*);
|
||||
v->cacheHandle() = TargetCache::GlobalCache::alloc(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ix++;
|
||||
}
|
||||
@@ -1020,8 +1026,9 @@ void Unit::defDynamicSystemConstant(const StringData* cnsName,
|
||||
cns->m_data.pref = (RefData*)data;
|
||||
}
|
||||
|
||||
static void setGlobal(StringData* name, TypedValue *value) {
|
||||
g_vmContext->m_globalVarEnv->set(name, value);
|
||||
static void setGlobal(void* cacheAddr, TypedValue *value,
|
||||
StringData *name) {
|
||||
tvSet(*value, *TargetCache::GlobalCache::lookupCreateAddr(cacheAddr, name));
|
||||
}
|
||||
|
||||
void Unit::merge() {
|
||||
@@ -1346,7 +1353,7 @@ void Unit::mergeImpl(void* tcbase, UnitMergeInfo* mi) {
|
||||
Stats::inc(Stats::UnitMerge_mergeable_global);
|
||||
StringData* name = (StringData*)((char*)obj - (int)k);
|
||||
auto* v = (TypedValueAux*)mi->mergeableData(ix + 1);
|
||||
setGlobal(name, v);
|
||||
setGlobal(&getDataRef<char>(tcbase, v->cacheHandle()), v, name);
|
||||
ix += 1 + sizeof(*v) / sizeof(void*);
|
||||
obj = mi->mergeableObj(ix);
|
||||
k = UnitMergeKind(uintptr_t(obj) & 7);
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário