From a442c4f7bf81b862eb5a6b8a4427b8dec9f29bf2 Mon Sep 17 00:00:00 2001 From: hendricks266 Date: Wed, 23 May 2018 05:58:12 +0000 Subject: [PATCH] CON: Remix resizearray in the following ways: Make only one allocation instead of two. Calculate array byte sizes in a way compatible with GAMEARRAY_BOOLEAN. Clear the expanded part of grown arrays using correct counts for non-int32 sizes. Support resizing an array to 0 to free it. git-svn-id: https://svn.eduke32.com/eduke32@6900 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/gameexec.cpp | 55 ++++++++++++++++++++-------------- source/duke3d/src/gamevars.cpp | 13 ++++++-- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index 493639bf6..cc501dd50 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -5004,33 +5004,42 @@ GAMEEXEC_STATIC void VM_Execute(native_t loop) { tw = *insptr++; + gamearray_t & array = aGameArrays[tw]; int const newSize = Gv_GetVarX(*insptr++); - int const oldSize = aGameArrays[tw].size; + int const oldSize = array.size; - if (newSize >= 0 && newSize != oldSize) + if (newSize == oldSize || newSize < 0) + continue; + +#if 0 + OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", + array.szLabel, array.size, newSize); +#endif + + if (newSize == 0) { - // OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", - // aGameArrays[j].szLabel, aGameArrays[j].size, newSize); - - int const eltSize = Gv_GetArrayElementSize(tw); - intptr_t *const pArray = oldSize != 0 ? (intptr_t *)Xmalloc(eltSize * oldSize) : NULL; - - if (oldSize != 0) - Bmemcpy(pArray, aGameArrays[tw].pValues, eltSize * oldSize); - - Baligned_free(aGameArrays[tw].pValues); - - aGameArrays[tw].pValues = newSize != 0 ? (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, eltSize * newSize) : NULL; - aGameArrays[tw].size = newSize; - - if (oldSize != 0) - Bmemcpy(aGameArrays[tw].pValues, pArray, eltSize * min(oldSize, newSize)); - - if (newSize > oldSize) - Bmemset(&aGameArrays[tw].pValues[oldSize], 0, eltSize * (newSize - oldSize)); - - Bfree(pArray); + Baligned_free(array.pValues); + array.pValues = nullptr; + array.size = 0; + continue; } + + size_t const oldBytes = Gv_GetArrayAllocSizeForCount(tw, oldSize); + size_t const newBytes = Gv_GetArrayAllocSizeForCount(tw, newSize); + intptr_t * const oldArray = array.pValues; + intptr_t * const newArray = (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, newBytes); + + if (oldSize != 0) + Bmemcpy(newArray, oldArray, min(oldBytes, newBytes)); + + if (newSize > oldSize) + Bmemset((char *)newArray + oldBytes, 0, newBytes - oldBytes); + + array.pValues = newArray; + array.size = newSize; + + Baligned_free(oldArray); + continue; } diff --git a/source/duke3d/src/gamevars.cpp b/source/duke3d/src/gamevars.cpp index 0f103e1f9..a92dd6a50 100644 --- a/source/duke3d/src/gamevars.cpp +++ b/source/duke3d/src/gamevars.cpp @@ -376,7 +376,7 @@ unsigned __fastcall Gv_GetArrayElementSize(int const arrayIdx) void Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags) { - Bassert(asize); + Bassert(asize >= 0); if (EDUKE32_PREDICT_FALSE(g_gameArrayCount >= MAXGAMEARRAYS)) { @@ -434,8 +434,15 @@ void Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t int const allocSize = Gv_GetArrayAllocSize(i); aGameArrays[i].flags |= GAMEARRAY_ALLOCATED; - aGameArrays[i].pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, allocSize); - Bmemset(aGameArrays[i].pValues, 0, allocSize); + if (allocSize > 0) + { + aGameArrays[i].pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, allocSize); + Bmemset(aGameArrays[i].pValues, 0, allocSize); + } + else + { + aGameArrays[i].pValues = nullptr; + } } g_gameArrayCount++;