CON: Implement a new VM dispatch method using an explicit jump table

Most of this patch is by pogokeen.

git-svn-id: https://svn.eduke32.com/eduke32@7358 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2019-02-28 07:21:49 +00:00
parent 12bfbd5a06
commit 5c9b921285

View file

@ -1265,10 +1265,23 @@ void Screen_Play(void)
} \ } \
} }
#if defined __GNUC__ || defined __clang__
# define CON_DIRECT_THREADING_DISPATCH
#endif
#ifdef CON_DIRECT_THREADING_DISPATCH
# define vInstruction(KEYWORDID) VINST_ ## KEYWORDID
# define eval(INSTRUCTION) {if (INSTRUCTION >= 0 && INSTRUCTION <= CON_OPCODE_END) {goto *jumpTable[INSTRUCTION];} else {goto VINST_CON_OPCODE_END;}}
# define dispatch(INSTRUCTION) {if (loop) {tw = *insptr; g_errorLineNum = tw >> 12; g_tw = tw &= VM_INSTMASK; eval(INSTRUCTION)} else {return;}}
# define vInstructionPointer(KEYWORDID) &&VINST_ ## KEYWORDID
# define COMMA ,
# define JUMP_TABLE_ARRAY_LITERAL { TRANSFORM_SCRIPT_KEYWORDS_LIST(vInstructionPointer, COMMA) }
# define vmErrorCase VINST_CON_OPCODE_END
#else
# define vInstruction(KEYWORDID) case KEYWORDID # define vInstruction(KEYWORDID) case KEYWORDID
# define dispatch(INSTRUCTION) continue; # define dispatch(INSTRUCTION) continue;
# define eval(INSTRUCTION) switch(INSTRUCTION) # define eval(INSTRUCTION) switch(INSTRUCTION)
# define vmErrorCase default # define vmErrorCase default
#endif
GAMEEXEC_STATIC void VM_Execute(native_t const poop) GAMEEXEC_STATIC void VM_Execute(native_t const poop)
{ {
@ -1276,13 +1289,18 @@ GAMEEXEC_STATIC void VM_Execute(native_t const poop)
do do
{ {
next_instruction: #ifndef CON_DIRECT_THREADING_DISPATCH
next_instruction:
#endif
native_t tw = *insptr; native_t tw = *insptr;
// set up "p" in between tw and g_errorLineNum to avoid read after write penalty // set up "p" in between tw and g_errorLineNum to avoid read after write penalty
auto &p = *(vm.pPlayer); auto &p = *(vm.pPlayer);
g_errorLineNum = tw >> 12; g_errorLineNum = tw >> 12;
g_tw = tw &= VM_INSTMASK; g_tw = tw &= VM_INSTMASK;
#ifdef CON_DIRECT_THREADING_DISPATCH
static void* jumpTable[] = JUMP_TABLE_ARRAY_LITERAL;
#else
if (tw == CON_ELSE) if (tw == CON_ELSE)
{ {
insptr = (intptr_t *)insptr[1]; insptr = (intptr_t *)insptr[1];
@ -1298,8 +1316,30 @@ next_instruction:
insptr++, loop--; insptr++, loop--;
continue; continue;
} }
else eval(tw) else
#endif
eval(tw)
{ {
#ifdef CON_DIRECT_THREADING_DISPATCH
vInstruction(CON_LEFTBRACE):
{
insptr++, loop++;
dispatch(tw);
}
vInstruction(CON_RIGHTBRACE):
{
insptr++, loop--;
dispatch(tw);
}
vInstruction(CON_ELSE):
{
insptr = (intptr_t *)insptr[1];
dispatch(tw);
}
#endif
vInstruction(CON_IFVARE_GLOBAL): vInstruction(CON_IFVARE_GLOBAL):
insptr++; insptr++;
tw = aGameVars[*insptr++].global; tw = aGameVars[*insptr++].global;
@ -2561,7 +2601,9 @@ next_instruction:
vInstruction(CON_RETURN): vInstruction(CON_RETURN):
vm.flags |= VM_RETURN; vm.flags |= VM_RETURN;
#if !defined CON_DIRECT_THREADING_DISPATCH
fallthrough__; fallthrough__;
#endif
vInstruction(CON_ENDSWITCH): vInstruction(CON_ENDSWITCH):
vInstruction(CON_ENDA): vInstruction(CON_ENDA):
vInstruction(CON_BREAK): vInstruction(CON_BREAK):
@ -6403,7 +6445,9 @@ badindex:
"If you are a developer, please attach all of your script files\n" "If you are a developer, please attach all of your script files\n"
"along with instructions on how to reproduce this error.\n\n" "along with instructions on how to reproduce this error.\n\n"
"Thank you!"); "Thank you!");
#if !defined CON_DIRECT_THREADING_DISPATCH
break; break;
#endif
} }
} while (loop && (vm.flags & (VM_RETURN|VM_KILL|VM_NOEXECUTE)) == 0); } while (loop && (vm.flags & (VM_RETURN|VM_KILL|VM_NOEXECUTE)) == 0);
} }