]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
Remove the `jumpabsolute` member from `mstatement_s`. divVerent/mstatement-smaller
authorRudolf Polzer <divVerent@gmail.com>
Mon, 23 Sep 2024 13:02:27 +0000 (15:02 +0200)
committerRudolf Polzer <divVerent@gmail.com>
Mon, 23 Sep 2024 14:22:19 +0000 (16:22 +0200)
This reduces the struct from 20 to 16 bytes, and thus may save some
RAM. It also may improve CPU cache behavior by keeping more QC code in
L1 and L2 cache, and possibly also improve instruction processing inside
the CPU as all statements are aligned the same way.

On `srv04`, this speeds up Xonotic's `serverbench` from 58.92s real,
57.72s user to 57.72s real, 56.59s user (median of 25).

pr_comp.h
prvm_edict.c
prvm_exec.c
prvm_execprogram.h

index f69b63200ca0193b0411a2998b633f38a564d30c..7ca0c28a43403554954c4c29a996c7b073d13ba9 100644 (file)
--- a/pr_comp.h
+++ b/pr_comp.h
@@ -409,8 +409,7 @@ mfunction_t;
 typedef struct mstatement_s
 {
        opcode_t        op;
-       int                     operand[3]; // always a global or -1 for unused
-       int                     jumpabsolute; // only used by IF, IFNOT, GOTO
+       int                     operand[3]; // always a global, or a relative statement offset ([0] for GOTO, [1] for IF/IFNOT), or -1 for unused
 }
 mstatement_t;
 
index cc318e9914a01b585ab6158c84462c0c26f504e2..3d51018765899e2db0411169a7578cf602293747 100644 (file)
@@ -2294,19 +2294,17 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data
                                prog->error_cmd("%s: out of bounds IF/IFNOT (statement %d) in %s", __func__, i, prog->name);
                        prog->statements[i].op = op;
                        prog->statements[i].operand[0] = remapglobal(a);
-                       prog->statements[i].operand[1] = -1;
+                       prog->statements[i].operand[1] = b;
                        prog->statements[i].operand[2] = -1;
-                       prog->statements[i].jumpabsolute = i + b;
                        break;
                case OP_GOTO:
                        a = (short)a;
                        if (a + i < 0 || a + i >= prog->progs_numstatements)
                                prog->error_cmd("%s: out of bounds GOTO (statement %d) in %s", __func__, i, prog->name);
                        prog->statements[i].op = op;
-                       prog->statements[i].operand[0] = -1;
+                       prog->statements[i].operand[0] = a;
                        prog->statements[i].operand[1] = -1;
                        prog->statements[i].operand[2] = -1;
-                       prog->statements[i].jumpabsolute = i + a;
                        break;
                default:
                        Con_DPrintf("%s: unknown opcode %d at statement %d in %s\n", __func__, (int)op, i, prog->name);
@@ -2316,7 +2314,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data
                        prog->statements[i].operand[0] = 0;
                        prog->statements[i].operand[1] =
                        prog->statements[i].operand[2] = op;
-                       prog->statements[i].jumpabsolute = -1;
                        break;
                case OP_STORE_I:
                case OP_ADD_I:
@@ -2427,7 +2424,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = remapglobal(b);
                        prog->statements[i].operand[2] = remapglobal(c);
-                       prog->statements[i].jumpabsolute = -1;
                        break;
                // global none global
                case OP_NOT_F:
@@ -2441,7 +2437,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
                        prog->statements[i].operand[2] = remapglobal(c);
-                       prog->statements[i].jumpabsolute = -1;
                        break;
                // 2 globals
                case OP_STOREP_F:
@@ -2466,7 +2461,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = remapglobal(b);
                        prog->statements[i].operand[2] = -1;
-                       prog->statements[i].jumpabsolute = -1;
                        break;
                // 1 global
                case OP_CALL0:
@@ -2493,7 +2487,6 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data
                        prog->statements[i].operand[0] = remapglobal(a);
                        prog->statements[i].operand[1] = -1;
                        prog->statements[i].operand[2] = -1;
-                       prog->statements[i].jumpabsolute = -1;
                        break;
                }
        }
index 3c68f6d1dce4c506eca06cfe574bc6aea808bdcc..e7f5468092aa23d6f4c4ca4e29cba7514ad57992 100644 (file)
@@ -332,10 +332,17 @@ static void PRVM_PrintStatement(prvm_prog_t *prog, mstatement_t *s)
        for ( ; i<10 ; i++)
                Con_Print(" ");
 
-       if (s->operand[0] >= 0) Con_Printf(  "%s", PRVM_GlobalString(prog, s->operand[0], valuebuf, sizeof(valuebuf)));
-       if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[1], valuebuf, sizeof(valuebuf)));
+       if (s->op == OP_GOTO) {
+               Con_Printf("statement %i", (int)(s - prog->statements) + s->operand[0]);
+       } else {
+               if (s->operand[0] >= 0) Con_Printf(  "%s", PRVM_GlobalString(prog, s->operand[0], valuebuf, sizeof(valuebuf)));
+       }
+       if (s->op == OP_IF || s->op == OP_IFNOT) {
+               Con_Printf(", statement %i", (int)(s - prog->statements) + s->operand[1]);
+       } else {
+               if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[1], valuebuf, sizeof(valuebuf)));
+       }
        if (s->operand[2] >= 0) Con_Printf(", %s", PRVM_GlobalString(prog, s->operand[2], valuebuf, sizeof(valuebuf)));
-       if (s->jumpabsolute >= 0) Con_Printf(", statement %i", s->jumpabsolute);
        Con_Print("\n");
 }
 
index 2a70bfc8ce75701410fa987ea3ac720a3b5315bb..34dd8d29d67dac02a10d03d9ecbc24dc5f8920d4 100644 (file)
@@ -637,7 +637,7 @@ int i;
                                // and entity, string, field values can never have that value
                                {
                                        ADVANCE_PROFILE_BEFORE_JUMP();
-                                       st = cached_statements + st->jumpabsolute - 1;  // offset the st++
+                                       st += st->operand[1] - 1;       // offset the st++
                                        startst = st;
                                        // no bounds check needed, it is done when loading progs
                                        if (++jumpcount == 10000000 && prvm_runawaycheck)
@@ -657,7 +657,7 @@ int i;
                                // and entity, string, field values can never have that value
                                {
                                        ADVANCE_PROFILE_BEFORE_JUMP();
-                                       st = cached_statements + st->jumpabsolute - 1;  // offset the st++
+                                       st += st->operand[1] - 1;       // offset the st++
                                        startst = st;
                                        // no bounds check needed, it is done when loading progs
                                        if (++jumpcount == 10000000 && prvm_runawaycheck)
@@ -671,7 +671,7 @@ int i;
 
                        HANDLE_OPCODE(OP_GOTO):
                                ADVANCE_PROFILE_BEFORE_JUMP();
-                               st = cached_statements + st->jumpabsolute - 1;  // offset the st++
+                               st += st->operand[0] - 1;       // offset the st++
                                startst = st;
                                // no bounds check needed, it is done when loading progs
                                if (++jumpcount == 10000000 && prvm_runawaycheck)