From 7ea11cd1698ccb0af53107171108656c277db433 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 17 Oct 2009 02:09:29 +0000 Subject: [PATCH] - Allocate VM script code and constants in a single block for better locality of reference. SVN r1924 (scripting) --- src/info.cpp | 6 +-- src/thingdef/thingdef_exp.h | 4 +- src/zscript/vm.h | 6 +-- src/zscript/vmbuilder.cpp | 11 ++-- src/zscript/vmframe.cpp | 105 +++++++++++++++++++++++------------- 5 files changed, 81 insertions(+), 51 deletions(-) diff --git a/src/info.cpp b/src/info.cpp index 4d56875e38..0edcfea5e5 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -94,9 +94,9 @@ void FState::SetAction(PSymbolActionFunction *func, bool setdefaultparams) // Create a function for this state. VMScriptFunction *vmfunc = new VMScriptFunction; - VMOP *code = vmfunc->AllocCode(sizeof(codetemplate)/sizeof(VMOP)); - memcpy(code, codetemplate, sizeof(codetemplate)); - FVoidObj *konsta = vmfunc->AllocKonstA(2); + vmfunc->Alloc(sizeof(codetemplate)/sizeof(VMOP), 0, 0, 0, 2); + memcpy(vmfunc->Code, codetemplate, sizeof(codetemplate)); + FVoidObj *konsta = vmfunc->KonstA; VM_ATAG *atag = vmfunc->KonstATags(); konsta[0].v = (void *)func->Function; konsta[1].o = callfunc; diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index bcf08f1750..99245d7609 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -342,10 +342,10 @@ public: isresolved = true; } - FxConstant(const char *str, const FScriptPosition &pos) : FxExpression(pos) + FxConstant(const FString &str, const FScriptPosition &pos) : FxExpression(pos) { ValueType = VAL_String; - value = ExpVal(FString(str)); + value = ExpVal(str); isresolved = true; } diff --git a/src/zscript/vm.h b/src/zscript/vm.h index 16987ed72a..acb4a06885 100644 --- a/src/zscript/vm.h +++ b/src/zscript/vm.h @@ -719,11 +719,7 @@ public: VMScriptFunction(); ~VMScriptFunction(); size_t PropagateMark(); - VMOP *AllocCode(int numops); - int *AllocKonstD(int numkonst); - double *AllocKonstF(int numkonst); - FString *AllocKonstS(int numkonst); - FVoidObj *AllocKonstA(int numkonst); + void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta); VM_ATAG *KonstATags() { return (VM_UBYTE *)(KonstA + NumKonstA); } const VM_ATAG *KonstATags() const { return (VM_UBYTE *)(KonstA + NumKonstA); } diff --git a/src/zscript/vmbuilder.cpp b/src/zscript/vmbuilder.cpp index b681c3d66b..60fe7817c2 100644 --- a/src/zscript/vmbuilder.cpp +++ b/src/zscript/vmbuilder.cpp @@ -38,26 +38,27 @@ VMScriptFunction *VMFunctionBuilder::MakeFunction() { VMScriptFunction *func = new VMScriptFunction; + func->Alloc(Code.Size(), NumIntConstants, NumFloatConstants, NumStringConstants, NumAddressConstants); + // Copy code block. - memcpy(func->AllocCode(Code.Size()), &Code[0], Code.Size() * sizeof(VMOP)); + memcpy(func->Code, &Code[0], Code.Size() * sizeof(VMOP)); // Create constant tables. if (NumIntConstants > 0) { - FillIntConstants(func->AllocKonstD(NumIntConstants)); + FillIntConstants(func->KonstD); } if (NumFloatConstants > 0) { - FillFloatConstants(func->AllocKonstF(NumFloatConstants)); + FillFloatConstants(func->KonstF); } if (NumAddressConstants > 0) { - func->AllocKonstA(NumAddressConstants); FillAddressConstants(func->KonstA, func->KonstATags()); } if (NumStringConstants > 0) { - FillStringConstants(func->AllocKonstS(NumStringConstants)); + FillStringConstants(func->KonstS); } // Assign required register space. diff --git a/src/zscript/vmframe.cpp b/src/zscript/vmframe.cpp index 0dce412c29..fdf2d42cc1 100644 --- a/src/zscript/vmframe.cpp +++ b/src/zscript/vmframe.cpp @@ -30,46 +30,79 @@ VMScriptFunction::VMScriptFunction() VMScriptFunction::~VMScriptFunction() { - if (Code != NULL) M_Free(Code); - if (KonstD != NULL) M_Free(KonstD); - if (KonstF != NULL) M_Free(KonstF); - if (KonstS != NULL) delete[] KonstS; - if (KonstA != NULL) M_Free(KonstA); + if (Code != NULL) + { + if (KonstS != NULL) + { + for (int i = 0; i < NumKonstS; ++i) + { + KonstS[i].~FString(); + } + } + M_Free(Code); + } } -VMOP *VMScriptFunction::AllocCode(int numops) +void VMScriptFunction::Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta) { - assert(Code == NULL && numops > 0); + assert(Code == NULL); + assert(numops > 0); + assert(numkonstd >= 0 && numkonstd <= 255); + assert(numkonstf >= 0 && numkonstf <= 255); + assert(numkonsts >= 0 && numkonsts <= 255); + assert(numkonsta >= 0 && numkonsta <= 255); + void *mem = M_Malloc(numops * sizeof(VMOP) + + numkonstd * sizeof(int) + + numkonstf * sizeof(double) + + numkonsts * sizeof(FString) + + numkonsta * (sizeof(FVoidObj) + 1)); + Code = (VMOP *)mem; + mem = (void *)((VMOP *)mem + numops); + + if (numkonstd > 0) + { + KonstD = (int *)mem; + mem = (void *)((int *)mem + numkonstd); + } + else + { + KonstD = NULL; + } + if (numkonstf > 0) + { + KonstF = (double *)mem; + mem = (void *)((double *)mem + numkonstf); + } + else + { + KonstF = NULL; + } + if (numkonsts > 0) + { + KonstS = (FString *)mem; + for (int i = 0; i < numkonsts; ++i) + { + ::new(&KonstS[i]) FString; + } + mem = (void *)((FString *)mem + numkonsts); + } + else + { + KonstS = NULL; + } + if (numkonsta > 0) + { + KonstA = (FVoidObj *)mem; + } + else + { + KonstA = NULL; + } CodeSize = numops; - return Code = (VMOP *)M_Malloc(numops * sizeof(VMOP)); -} - -int *VMScriptFunction::AllocKonstD(int numkonst) -{ - assert(KonstD == NULL && numkonst > 0); - NumKonstD = numkonst; - return KonstD = (int *)M_Malloc(numkonst * sizeof(int)); -} - -double *VMScriptFunction::AllocKonstF(int numkonst) -{ - assert(KonstF == NULL && numkonst > 0); - NumKonstF = numkonst; - return KonstF = (double *)M_Malloc(numkonst * sizeof(double)); -} - -FString *VMScriptFunction::AllocKonstS(int numkonst) -{ - assert(KonstS == NULL && numkonst > 0); - NumKonstS = numkonst; - return KonstS = new FString[numkonst]; -} - -FVoidObj *VMScriptFunction::AllocKonstA(int numkonst) -{ - assert(KonstA == NULL && numkonst > 0); - NumKonstA = numkonst; - return KonstA = (FVoidObj *)M_Malloc(numkonst * sizeof(FVoidObj) + numkonst); + NumKonstD = numkonstd; + NumKonstF = numkonstf; + NumKonstS = numkonsts; + NumKonstA = numkonsta; } size_t VMScriptFunction::PropagateMark()