- took VMFunction out of the DObject hierarchy.
As it stood, just compiling the internal ZScript code created more than 9000 DObjects, none of which really need to be subjected to garbage collection, aside from allowing lazy deallocation. This puts an incredible drag on the garbage collector which often needs several minutes to finish processing before actual deletion can start. The VM functions with roughly 1800 of these objects were by far the easiest to refactor so they are now. They also use a memory arena now which significantly reduces their memory footprint.
This commit is contained in:
parent
3cddcc8524
commit
3cbd62479b
8 changed files with 59 additions and 73 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include "vectors.h"
|
||||
#include "cmdlib.h"
|
||||
#include "doomerrors.h"
|
||||
#include "memarena.h"
|
||||
|
||||
#define MAX_RETURNS 8 // Maximum number of results a function called by script code can return
|
||||
#define MAX_TRY_DEPTH 8 // Maximum number of nested TRYs in a single function
|
||||
|
|
@ -693,10 +694,8 @@ do_double: if (inexact)
|
|||
}
|
||||
};
|
||||
|
||||
class VMFunction : public DObject
|
||||
class VMFunction
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(VMFunction, DObject);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
bool Native;
|
||||
bool Final = false; // cannot be overridden
|
||||
|
|
@ -709,7 +708,30 @@ public:
|
|||
|
||||
class PPrototype *Proto;
|
||||
|
||||
VMFunction(FName name = NAME_None) : Native(false), ImplicitArgs(0), Name(name), Proto(NULL) {}
|
||||
VMFunction(FName name = NAME_None) : Native(false), ImplicitArgs(0), Name(name), Proto(NULL)
|
||||
{
|
||||
AllFunctions.Push(this);
|
||||
}
|
||||
virtual ~VMFunction() {}
|
||||
|
||||
void *operator new(size_t size)
|
||||
{
|
||||
return Allocator.Alloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void *block) {}
|
||||
void operator delete[](void *block) {}
|
||||
static void DeleteAll()
|
||||
{
|
||||
for (auto f : AllFunctions)
|
||||
{
|
||||
f->~VMFunction();
|
||||
}
|
||||
AllFunctions.Clear();
|
||||
}
|
||||
static FMemArena Allocator;
|
||||
static TArray<VMFunction *> AllFunctions;
|
||||
protected:
|
||||
};
|
||||
|
||||
// VM frame layout:
|
||||
|
|
@ -838,11 +860,9 @@ struct FStatementInfo
|
|||
|
||||
class VMScriptFunction : public VMFunction
|
||||
{
|
||||
DECLARE_CLASS(VMScriptFunction, VMFunction);
|
||||
public:
|
||||
VMScriptFunction(FName name=NAME_None);
|
||||
~VMScriptFunction();
|
||||
size_t PropagateMark();
|
||||
void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta, int numlinenumbers);
|
||||
|
||||
VM_ATAG *KonstATags() { return (VM_UBYTE *)(KonstA + NumKonstA); }
|
||||
|
|
@ -910,7 +930,6 @@ private:
|
|||
|
||||
class VMNativeFunction : public VMFunction
|
||||
{
|
||||
DECLARE_CLASS(VMNativeFunction, VMFunction);
|
||||
public:
|
||||
typedef int (*NativeCallType)(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,14 +42,10 @@ cycle_t VMCycles[10];
|
|||
int VMCalls[10];
|
||||
|
||||
IMPLEMENT_CLASS(VMException, false, false)
|
||||
IMPLEMENT_CLASS(VMFunction, true, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(VMFunction)
|
||||
IMPLEMENT_POINTER(Proto)
|
||||
IMPLEMENT_POINTERS_END
|
||||
FMemArena VMFunction::Allocator(32768);
|
||||
TArray<VMFunction *> VMFunction::AllFunctions;
|
||||
|
||||
IMPLEMENT_CLASS(VMScriptFunction, false, false)
|
||||
IMPLEMENT_CLASS(VMNativeFunction, false, false)
|
||||
|
||||
VMScriptFunction::VMScriptFunction(FName name)
|
||||
{
|
||||
|
|
@ -87,7 +83,6 @@ VMScriptFunction::~VMScriptFunction()
|
|||
KonstS[i].~FString();
|
||||
}
|
||||
}
|
||||
M_Free(Code);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +95,7 @@ void VMScriptFunction::Alloc(int numops, int numkonstd, int numkonstf, int numko
|
|||
assert(numkonsts >= 0 && numkonsts <= 65535);
|
||||
assert(numkonsta >= 0 && numkonsta <= 65535);
|
||||
assert(numlinenumbers >= 0 && numlinenumbers <= 65535);
|
||||
void *mem = M_Malloc(numops * sizeof(VMOP) +
|
||||
void *mem = Allocator.Alloc(numops * sizeof(VMOP) +
|
||||
numkonstd * sizeof(int) +
|
||||
numkonstf * sizeof(double) +
|
||||
numkonsts * sizeof(FString) +
|
||||
|
|
@ -166,24 +161,6 @@ void VMScriptFunction::Alloc(int numops, int numkonstd, int numkonstf, int numko
|
|||
NumKonstA = numkonsta;
|
||||
}
|
||||
|
||||
size_t VMScriptFunction::PropagateMark()
|
||||
{
|
||||
if (KonstA != NULL)
|
||||
{
|
||||
FVoidObj *konsta = KonstA;
|
||||
VM_UBYTE *atag = KonstATags();
|
||||
for (int count = NumKonstA; count > 0; --count)
|
||||
{
|
||||
if (*atag++ == ATAG_OBJECT)
|
||||
{
|
||||
GC::Mark(konsta->o);
|
||||
}
|
||||
konsta++;
|
||||
}
|
||||
}
|
||||
return NumKonstA * sizeof(void *) + Super::PropagateMark();
|
||||
}
|
||||
|
||||
void VMScriptFunction::InitExtra(void *addr)
|
||||
{
|
||||
char *caddr = (char*)addr;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue