From 7c92ea9cd62eb07732b1aa9877290314f290da31 Mon Sep 17 00:00:00 2001 From: Daniel Svensson Date: Thu, 12 Dec 2024 14:37:38 +0100 Subject: [PATCH 1/2] MEMORY: Always expose hunk_print. Also names some previously unnamed allocations. Useful for mappers to see how much memory various game data uses in a map. This used to be a server-only command. In addition to exposing the command, the current allocations are also printed on OOM, and will be found in qconsole.log. --- src/cmd.c | 4 ++-- src/pr2_exec.c | 2 +- src/pr_edict.c | 2 +- src/r_aliasmodel_md3.c | 8 ++++---- src/r_brushmodel_warpsurfaces.c | 4 ++-- src/r_lightmaps.c | 2 +- src/r_refrag.c | 4 ++-- src/sv_save.c | 2 +- src/vm.c | 6 +++--- src/vm_interpreted.c | 2 +- src/wad.c | 2 +- src/zone.c | 18 ++++++------------ src/zone.h | 1 - 13 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index 78b604743..48be1190c 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -120,7 +120,7 @@ static void Cbuf_Register (cbuf_t *cbuf, int maxsize) { assert (!host_initialized); cbuf->maxsize = maxsize; - cbuf->text_buf = (char *) Hunk_Alloc(maxsize); + cbuf->text_buf = (char *) Hunk_AllocName(maxsize, "cbuf"); cbuf->text_start = cbuf->text_end = (cbuf->maxsize >> 1); cbuf->wait = false; cbuf->waitCount = 0; @@ -1180,7 +1180,7 @@ void Cmd_AddCommand (char *cmd_name, xcommand_t function) } } - cmd = (cmd_function_t *) Hunk_Alloc (sizeof(cmd_function_t)); + cmd = (cmd_function_t *) Hunk_AllocName (sizeof(cmd_function_t), "cmd"); cmd->name = cmd_name; cmd->function = function; cmd->zmalloced = false; diff --git a/src/pr2_exec.c b/src/pr2_exec.c index fa0ea14cb..06d99136b 100644 --- a/src/pr2_exec.c +++ b/src/pr2_exec.c @@ -530,7 +530,7 @@ void LoadFields(void) while (fieldvm_p[num].name) { num++; } - f = fields = (field_t *)Hunk_Alloc(sizeof(field_t) * (num + 1)); + f = fields = (field_t *)Hunk_AllocName(sizeof(field_t) * (num + 1), "edfields"); while (fieldvm_p->name){ f->name = (stringptr_t)fieldvm_p->name; f->ofs = fieldvm_p->ofs; diff --git a/src/pr_edict.c b/src/pr_edict.c index 66c42c9db..65857a30d 100644 --- a/src/pr_edict.c +++ b/src/pr_edict.c @@ -770,7 +770,7 @@ char *ED_NewString (char *string) int i,l; l = strlen(string) + 1; - nuw = (char *) Hunk_Alloc (l); + nuw = (char *) Hunk_AllocName (l, "edstring"); new_p = nuw; for (i=0 ; i< l ; i++) diff --git a/src/r_aliasmodel_md3.c b/src/r_aliasmodel_md3.c index 4a7dc4940..731b43d62 100644 --- a/src/r_aliasmodel_md3.c +++ b/src/r_aliasmodel_md3.c @@ -158,7 +158,7 @@ static void Mod_MD3LoadSkins(model_t* mod, md3Header_t* header, md3model_t* mode header->numSkins = found_skins; // Convert linked list to array so it's moveable & easier to access - surfinf_t* surface_info = Hunk_Alloc(sizeof(surfinf_t) * header->numSkins * header->numSurfaces); + surfinf_t* surface_info = Hunk_AllocName(sizeof(surfinf_t) * header->numSkins * header->numSurfaces, "md3surfinfo"); model->surfinf = (int)((intptr_t)surface_info - (intptr_t)model); while (skin_list) { md3_skin_list_entry_t* next = skin_list->next; @@ -194,8 +194,8 @@ void Mod_LoadAlias3Model(model_t *mod, void *buffer, int filesize) numsurfs = LittleLong(((md3Header_t *)buffer)->numSurfaces); - pheader = (md3model_t *)Hunk_Alloc(sizeof(md3model_t)); - mem = (md3Header_t *)Hunk_Alloc(filesize); + pheader = (md3model_t *)Hunk_AllocName(sizeof(md3model_t), "md3model"); + mem = (md3Header_t *)Hunk_AllocName(filesize, "md3header"); pheader->md3model = (char *)mem - (char *)pheader; memcpy(mem, buffer, filesize); //casually load the entire thing. As you do. @@ -269,7 +269,7 @@ void Mod_LoadAlias3Model(model_t *mod, void *buffer, int filesize) // swap all the vertices, convert to our format vert = (md3XyzNormal_t *)((char *)surf + surf->ofsXyzNormals); - output_vert = (ezMd3XyzNormal_t*)Hunk_Alloc(surf->numVerts * surf->numFrames * sizeof(ezMd3XyzNormal_t)); + output_vert = (ezMd3XyzNormal_t*)Hunk_AllocName(surf->numVerts * surf->numFrames * sizeof(ezMd3XyzNormal_t), "md3normal"); for (j = 0; j < surf->numVerts * surf->numFrames; j++) { vert[j].xyz[0] = LittleShort(vert[j].xyz[0]); vert[j].xyz[1] = LittleShort(vert[j].xyz[1]); diff --git a/src/r_brushmodel_warpsurfaces.c b/src/r_brushmodel_warpsurfaces.c index 993e2885e..03b1374a4 100644 --- a/src/r_brushmodel_warpsurfaces.c +++ b/src/r_brushmodel_warpsurfaces.c @@ -116,7 +116,7 @@ static void R_WarpSurfaceSubdividePolygon(int numverts, float *verts) return; } - poly = (glpoly_t *)Hunk_Alloc(sizeof(glpoly_t) + (numverts - 4) * VERTEXSIZE * sizeof(float)); + poly = (glpoly_t *)Hunk_AllocName(sizeof(glpoly_t) + (numverts - 4) * VERTEXSIZE * sizeof(float), "subdivpoly"); poly->next = warpface->subdivided; warpface->subdivided = poly; poly->numverts = numverts; @@ -189,7 +189,7 @@ void R_SkySurfacesBuildPolys(msurface_t *fa) numverts++; } - poly = Hunk_Alloc(sizeof(glpoly_t) + (numverts - 4) * VERTEXSIZE * sizeof(float)); + poly = Hunk_AllocName(sizeof(glpoly_t) + (numverts - 4) * VERTEXSIZE * sizeof(float), "subdivpoly"); poly->next = NULL; fa->polys = poly; poly->numverts = numverts; diff --git a/src/r_lightmaps.c b/src/r_lightmaps.c index fda2d561f..4d7c615d3 100644 --- a/src/r_lightmaps.c +++ b/src/r_lightmaps.c @@ -652,7 +652,7 @@ static void R_BuildSurfaceDisplayList(model_t* currentmodel, msurface_t *fa) // draw texture if (!fa->polys) { // seems map loaded first time, so light maps loaded first time too - poly = (glpoly_t *)Hunk_Alloc(sizeof(glpoly_t) + (lnumverts - 4) * VERTEXSIZE * sizeof(float)); + poly = (glpoly_t *)Hunk_AllocName(sizeof(glpoly_t) + (lnumverts - 4) * VERTEXSIZE * sizeof(float), "lmpoly"); poly->next = fa->polys; fa->polys = poly; poly->numverts = lnumverts; diff --git a/src/r_refrag.c b/src/r_refrag.c index c935c30c6..4db5e5c8a 100644 --- a/src/r_refrag.c +++ b/src/r_refrag.c @@ -39,7 +39,7 @@ entity_t *r_addent; void R_Init_EFrags (void) { - cl.free_efrags = (efrag_t *) Hunk_Alloc (sizeof (efrag_t)); + cl.free_efrags = (efrag_t *) Hunk_AllocName (sizeof (efrag_t), "efrag"); memset (cl.free_efrags, 0, sizeof (efrag_t)); } @@ -48,7 +48,7 @@ void R_Next_Free_EFrag (void) // advance the linked list, growing it as needed if (cl.free_efrags->entnext == NULL) { - cl.free_efrags->entnext = (efrag_t *) Hunk_Alloc (sizeof (efrag_t)); + cl.free_efrags->entnext = (efrag_t *) Hunk_AllocName (sizeof (efrag_t), "efrag"); memset (cl.free_efrags->entnext, 0, sizeof (efrag_t)); } cl.free_efrags = cl.free_efrags->entnext; diff --git a/src/sv_save.c b/src/sv_save.c index 29033b7a4..a47e34eb7 100644 --- a/src/sv_save.c +++ b/src/sv_save.c @@ -252,7 +252,7 @@ void SV_LoadGame_f(void) } str[sizeof(str) - 1] = '\0'; length = strlen(str) + 1; - sv.lightstyles[i] = (char *) Hunk_Alloc (length); + sv.lightstyles[i] = (char *) Hunk_AllocName (length, "lightstyle"); strlcpy (sv.lightstyles[i], str, length); } diff --git a/src/vm.c b/src/vm.c index 52e61d52a..578b03bce 100644 --- a/src/vm.c +++ b/src/vm.c @@ -487,7 +487,7 @@ void VM_LoadSymbols( vm_t *vm ) { break; } chars = strlen( com_token ); - sym = Hunk_Alloc( sizeof( *sym ) + chars); + sym = Hunk_AllocName( sizeof( *sym ) + chars, "qvm-symbols"); *prev = sym; prev = &sym->next; sym->next = NULL; @@ -737,7 +737,7 @@ static vmHeader_t *VM_LoadQVM( vm_t *vm, qbool alloc ) { if ( alloc ) { // allocate zero filled space for initialized and uninitialized data - vm->dataBase = Hunk_Alloc( dataAlloc); + vm->dataBase = Hunk_AllocName( dataAlloc, "qvm"); vm->dataMask = dataLength - 1; vm->dataAlloc = dataAlloc; } else { @@ -766,7 +766,7 @@ static vmHeader_t *VM_LoadQVM( vm_t *vm, qbool alloc ) { Con_Printf( "Loading %d jump table targets\n", vm->numJumpTableTargets ); if ( alloc ) { - vm->jumpTableTargets = Hunk_Alloc( header->jtrgLength); + vm->jumpTableTargets = Hunk_AllocName( header->jtrgLength, "qvm-jtt"); } else { if ( vm->numJumpTableTargets != previousNumJumpTableTargets ) { VM_Free( vm ); diff --git a/src/vm_interpreted.c b/src/vm_interpreted.c index 75b00ca22..ad262ea47 100644 --- a/src/vm_interpreted.c +++ b/src/vm_interpreted.c @@ -110,7 +110,7 @@ qbool VM_PrepareInterpreter2( vm_t *vm, vmHeader_t *header ) { const char *errMsg; instruction_t *buf; - buf = ( instruction_t *) Hunk_Alloc( (vm->instructionCount + 8) * sizeof( instruction_t )); + buf = ( instruction_t *) Hunk_AllocName( (vm->instructionCount + 8) * sizeof( instruction_t ), "vm"); errMsg = VM_LoadInstructions( (byte *) header + header->codeOffset, header->codeLength, header->instructionCount, buf ); if ( !errMsg ) { diff --git a/src/wad.c b/src/wad.c index 306f182a8..f43d541db 100644 --- a/src/wad.c +++ b/src/wad.c @@ -305,7 +305,7 @@ void WAD3_LoadWadFile(const char *filename) } lowmark = Hunk_LowMark(); - if (!(lumps = Hunk_Alloc(sizeof(lumpinfo_t) * numlumps))) { + if (!(lumps = Hunk_AllocName(sizeof(lumpinfo_t) * numlumps, filename))) { Com_Printf("WAD3_LoadWadFile: unable to allocate temporary memory for lump table\n"); return; } diff --git a/src/zone.c b/src/zone.c index cb03b715e..131c5a7b7 100644 --- a/src/zone.c +++ b/src/zone.c @@ -176,6 +176,10 @@ void *Hunk_AllocName(int size, const char *name) size = sizeof(hunk_t) + ((size + 15) & ~15); if (hunk_size - hunk_low_used - hunk_high_used < size) { + if ((int)developer.value) + { + Hunk_Print(true); + } #ifdef SERVERONLY Sys_Error("Hunk_AllocName: Not enough RAM allocated. Try starting using \"-mem 64\" (or more) on the command line."); #else @@ -197,16 +201,6 @@ void *Hunk_AllocName(int size, const char *name) return (void *)(h + 1); } -/* -=================== -Hunk_Alloc -=================== -*/ -void *Hunk_Alloc(int size) -{ - return Hunk_AllocName(size, "unknown"); -} - int Hunk_LowMark(void) { return hunk_low_used; @@ -589,8 +583,6 @@ void Cache_Init_Commands(void) Cmd_AddCommand("flush", Cache_Flush); Cmd_AddCommand("cache_print", Cache_Print); Cmd_AddCommand("cache_report", Cache_Report); - - Cmd_AddCommand("hunk_print", Hunk_Print_f); } #ifndef WITH_DP_MEM @@ -700,4 +692,6 @@ void Memory_Init(void *buf, int size) hunk_high_used = 0; Cache_Init(); + + Cmd_AddCommand("hunk_print", Hunk_Print_f); } diff --git a/src/zone.h b/src/zone.h index 056d9ca51..b53097b98 100644 --- a/src/zone.h +++ b/src/zone.h @@ -82,7 +82,6 @@ startup hunk allocations void Memory_Init (void *buf, int size); -void *Hunk_Alloc (int size); // returns 0 filled memory void *Hunk_AllocName (int size, const char *name); int Hunk_LowMark (void); From 90b4f1132076a51b0a46cbc395f96aca7a2bf5c0 Mon Sep 17 00:00:00 2001 From: Daniel Svensson Date: Thu, 12 Dec 2024 15:33:35 +0100 Subject: [PATCH 2/2] MEMORY: Trim glpoly_s struct. * drawflat_chain was dead code. * all chains except next are unused by modern renderer. Reduces total glpoly_s allocations by 15% if classic renderer is disabled. --- src/gl_model.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gl_model.h b/src/gl_model.h index 79f258332..7590d129e 100644 --- a/src/gl_model.h +++ b/src/gl_model.h @@ -162,12 +162,13 @@ typedef struct vbo_model_vert_s { typedef struct glpoly_s { struct glpoly_s *next; +#ifdef RENDERER_OPTION_CLASSIC_OPENGL struct glpoly_s *chain; //next lightmap poly in chain struct glpoly_s *fb_chain; //next fb poly in chain struct glpoly_s *luma_chain; //next luma poly in chain struct glpoly_s *caustics_chain; //next caustic poly in chain struct glpoly_s *detail_chain; //next detail poly in chain - struct glpoly_s *drawflat_chain; //next drawflat poly in chain +#endif unsigned int vbo_start; int numverts;