Reworked parts of the VScript save/restore caching code

This commit is contained in:
Blixibon 2020-12-27 00:44:50 -06:00
parent 6ba3cd4c03
commit dd848acba8

View File

@ -79,25 +79,35 @@ struct ReadStateMap
} }
} }
bool CheckCache(CUtlBuffer* pBuffer, HSQOBJECT** obj) bool CheckCache(CUtlBuffer* pBuffer, HSQUIRRELVM vm, int * outmarker)
{ {
int marker = pBuffer->GetInt(); int marker = pBuffer->GetInt();
auto idx = cache.Find(marker); auto idx = cache.Find(marker);
if (idx != cache.InvalidIndex()) if (idx != cache.InvalidIndex())
{ {
*obj = &cache[idx]; sq_pushobject(vm, cache[idx]);
return true; return true;
} }
else else
{ {
HSQOBJECT temp; *outmarker = marker;
sq_resetobject(&temp);
auto idx = cache.Insert(marker, temp);
*obj = &cache[idx];
return false; return false;
} }
} }
void StoreInCache(int marker, HSQOBJECT& obj)
{
cache.Insert(marker, obj);
}
void StoreTopInCache(int marker)
{
HSQOBJECT obj;
sq_getstackobj(vm_, -1, &obj);
sq_addref(vm_, &obj);
cache.Insert(marker, obj);
}
}; };
class SquirrelVM : public IScriptVM class SquirrelVM : public IScriptVM
@ -3085,10 +3095,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
case OT_TABLE: case OT_TABLE:
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
@ -3096,8 +3105,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
int count = pBuffer->GetInt(); int count = pBuffer->GetInt();
sq_newtableex(vm_, count); sq_newtableex(vm_, count);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
sq_push(vm_, -2); sq_push(vm_, -2);
sq_setdelegate(vm_, -2); sq_setdelegate(vm_, -2);
@ -3115,17 +3123,15 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
case OT_ARRAY: case OT_ARRAY:
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
int count = pBuffer->GetInt(); int count = pBuffer->GetInt();
sq_newarray(vm_, count); sq_newarray(vm_, count);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
@ -3137,10 +3143,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
case OT_CLOSURE: case OT_CLOSURE:
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
@ -3152,8 +3157,8 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_pushnull(vm_); sq_pushnull(vm_);
break; break;
} }
sq_getstackobj(vm_, -1, obj);
sq_addref(vm_, obj); readState.StoreTopInCache(marker);
} }
else else
{ {
@ -3187,9 +3192,8 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_poptop(vm_); sq_poptop(vm_);
} }
*obj = ret; vm_->Push(ret);
sq_addref(vm_, obj); readState.StoreTopInCache(marker);
sq_pushobject(vm_, *obj);
} }
ReadObject(pBuffer, readState); ReadObject(pBuffer, readState);
@ -3198,10 +3202,12 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_getstackobj(vm_, -1, &env); sq_getstackobj(vm_, -1, &env);
if (!sq_isnull(env)) if (!sq_isnull(env))
{ {
if (_closure( *obj ) == nullptr) HSQOBJECT obj;
sq_getstackobj(vm_, -2, &obj);
if (_closure(obj) == nullptr)
Warning("Closure is null\n"); Warning("Closure is null\n");
else else
_closure(*obj)->_env = _refcounted(env)->GetWeakRef(sq_type(env)); _closure(obj)->_env = _refcounted(env)->GetWeakRef(sq_type(env));
} }
sq_poptop(vm_); sq_poptop(vm_);
@ -3226,10 +3232,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
case OT_CLASS: case OT_CLASS:
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
@ -3238,8 +3243,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
if (classType == VectorClassType) if (classType == VectorClassType)
{ {
sq_pushobject(vm_, vectorClass_); sq_pushobject(vm_, vectorClass_);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
} }
else if (classType == NativeClassType) else if (classType == NativeClassType)
{ {
@ -3254,8 +3258,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
sq_pushnull(vm_); sq_pushnull(vm_);
} }
sq_remove(vm_, -2); sq_remove(vm_, -2);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
} }
else if (classType == ScriptClassType) else if (classType == ScriptClassType)
{ {
@ -3267,8 +3270,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
sq_newclass(vm_, hasBase); sq_newclass(vm_, hasBase);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
sq_pushnull(vm_); sq_pushnull(vm_);
ReadObject(pBuffer, readState); ReadObject(pBuffer, readState);
@ -3292,10 +3294,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
case OT_INSTANCE: case OT_INSTANCE:
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
@ -3310,8 +3311,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
ReadObject(pBuffer, readState); ReadObject(pBuffer, readState);
sq_call(vm_, 2, SQTrue, SQFalse); sq_call(vm_, 2, SQTrue, SQFalse);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
sq_remove(vm_, -2); sq_remove(vm_, -2);
@ -3340,8 +3340,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
if (sq_isinstance(singleton) && _instance(singleton)->_class == _class(klass)) if (sq_isinstance(singleton) && _instance(singleton)->_class == _class(klass))
{ {
foundSingleton = true; foundSingleton = true;
*obj = singleton;
sq_addref(vm_, obj); readState.StoreInCache(marker, singleton);
sq_addref(vm_, &singleton);
sq_pop(vm_, 2); sq_pop(vm_, 2);
break; break;
} }
@ -3355,25 +3356,28 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
((ScriptClassDesc_t*)typetag)->m_pszScriptName); ((ScriptClassDesc_t*)typetag)->m_pszScriptName);
} }
sq_pushobject(vm_, *obj); sq_pushobject(vm_, singleton);
break; break;
} }
HSQOBJECT obj;
sq_createinstance(vm_, -1); sq_createinstance(vm_, -1);
sq_getstackobj(vm_, -1, obj); sq_getstackobj(vm_, -1, &obj);
sq_addref(vm_, obj); sq_addref(vm_, &obj);
readState.StoreInCache(marker, obj);
sq_remove(vm_, -2); sq_remove(vm_, -2);
{ {
// HACK: No way to get the default values part from accessing the class directly // HACK: No way to get the default values part from accessing the class directly
SQUnsignedInteger nvalues = _instance(*obj)->_class->_defaultvalues.size(); SQUnsignedInteger nvalues = _instance(obj)->_class->_defaultvalues.size();
for (SQUnsignedInteger n = 0; n < nvalues; n++) { for (SQUnsignedInteger n = 0; n < nvalues; n++) {
ReadObject(pBuffer, readState); ReadObject(pBuffer, readState);
HSQOBJECT val; HSQOBJECT val;
sq_resetobject(&val); sq_resetobject(&val);
sq_getstackobj(vm_, -1, &val); sq_getstackobj(vm_, -1, &val);
_instance(*obj)->_values[n] = val; _instance(obj)->_values[n] = val;
sq_pop(vm_, 1); sq_pop(vm_, 1);
} }
} }
@ -3436,10 +3440,9 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
case OT_FUNCPROTO: //internal usage only case OT_FUNCPROTO: //internal usage only
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
@ -3452,15 +3455,13 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
} }
vm_->Push(ret); vm_->Push(ret);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
} }
case OT_OUTER: //internal usage only case OT_OUTER: //internal usage only
{ {
HSQOBJECT* obj = nullptr; int marker = 0;
if (readState.CheckCache(pBuffer, &obj)) if (readState.CheckCache(pBuffer, vm_, &marker))
{ {
sq_pushobject(vm_, *obj);
break; break;
} }
@ -3473,8 +3474,7 @@ void SquirrelVM::ReadObject(CUtlBuffer* pBuffer, ReadStateMap& readState)
outer->_valptr = &(outer->_value); outer->_valptr = &(outer->_value);
sq_poptop(vm_); sq_poptop(vm_);
vm_->Push(outer); vm_->Push(outer);
sq_getstackobj(vm_, -1, obj); readState.StoreTopInCache(marker);
sq_addref(vm_, obj);
break; break;
} }
@ -3496,10 +3496,12 @@ void SquirrelVM::ReadState(CUtlBuffer* pBuffer)
sq_pushroottable(vm_); sq_pushroottable(vm_);
HSQOBJECT* obj = nullptr; HSQOBJECT obj;
readState.CheckCache(pBuffer, &obj); int marker = 0;
sq_getstackobj(vm_, -1, obj); readState.CheckCache(pBuffer, vm_, &marker);
sq_addref(vm_, obj); sq_getstackobj(vm_, -1, &obj);
sq_addref(vm_, &obj);
readState.StoreInCache(marker, obj);
int count = pBuffer->GetInt(); int count = pBuffer->GetInt();