Skip to content

Commit 6cf63a6

Browse files
committed
simx86: stop using e_querymark to stop codegen (except prejit)
Only stop if 1. there's a jump op generated, or 2. we're in single step mode (SINGLEBLOCK or TF), or 3. we encounter a compatible block we can jump into other code is going to be invalidated in DoClose(), we're just going to bulldoze over it here. SPEC_PREJIT should avoid overwriting, but instead of using a gap, I let it give up, by not calling Close() and resetting CurrIMeta, thereby throwing away the prejitted code, instead of generating an early tailcode.
1 parent 83895c7 commit 6cf63a6

File tree

1 file changed

+30
-31
lines changed

1 file changed

+30
-31
lines changed

src/base/emu-i386/simx86/interp.c

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -95,23 +95,20 @@ static char R1Tab_l[14] =
9595
* by the next DoExec.
9696
*/
9797
static TNode *DoClose(unsigned int PC, unsigned int Interp_LONG_CS, int mode,
98-
int flags)
98+
int flags, TNode *nextG)
9999
{
100100
unsigned int P0 = InstrMeta[0].npc;
101-
TNode *G, *nextG = NULL;
101+
TNode *G;
102102

103103
assert(CurrIMeta >= 0);
104104
/* If the code doesn't terminate with a jump/loop instruction
105105
* it still lacks the tail code; add it here */
106106
IMeta *GL = &InstrMeta[CurrIMeta];
107107
if (GL->gen[GL->ngen-1].op < JMP_TAILCODE) {
108-
/* almost always we get here because e_querymark() in
109-
_Interp86() found code. If there is no overlap
110-
and the node is compatible we can generate a jump
108+
/* we get here because _Interp86() found code or in
109+
single-step mode. For code we can generate a jump
111110
to it and link as well */
112-
nextG = FindTree(PC);
113-
if (nextG && nextG->mode == mode &&
114-
nextG->cs == Interp_LONG_CS)
111+
if (nextG)
115112
JMPGen(JMP_LINK, mode, PC);
116113
else
117114
JMPGen(JMP_TAILCODE, mode, PC);
@@ -125,7 +122,7 @@ static TNode *DoClose(unsigned int PC, unsigned int Interp_LONG_CS, int mode,
125122

126123
/* in case of prejit, the page content could
127124
* be altered, so we better re-jit */
128-
if (flags & (F_PREJ | F_SPRJ))
125+
if (flags & F_PREJ)
129126
return NULL;
130127
abeg = P0 & _PAGE_MASK;
131128
aend = PC & _PAGE_MASK;
@@ -464,23 +461,13 @@ static unsigned int FindExecCode(unsigned int PC)
464461
else if (debug_level('e')>2)
465462
e_printf("** Found compiled code at %08x\n",PC);
466463
}
467-
else if (e_querymark(PC, 1)) {
468-
/* slow path */
469-
InvalidateNodeRange(PC, 1, NULL);
470-
}
471464
/* future proofing: _Interp86() can't fail now in non-prejit mode
472465
but if it ever does, retry */
473466
while (!G) {
474467
if (CEmuStat & (CeS_PREJIT_RM | CeS_PREJIT_PM)) {
475468
TheCPU.err = EXCP_GOBACK;
476469
return PC;
477470
}
478-
#if 0
479-
/* this obviously can't happen with current code, but
480-
* slows down execution under debug a lot */
481-
if (debug_level('e') && e_querymark(PC, 1))
482-
error("simx86: code nodes clashed at %x\n", PC);
483-
#endif
484471
if (debug_level('e')>=9)
485472
dbug_printf("\n%s",e_print_regs(LONG_CS));
486473
G = _Interp86(PC, LONG_CS, TheCPU.cs, TheCPU.mode, 0);
@@ -554,10 +541,6 @@ void Interp86(void)
554541
TheCPU.eip = PC - LONG_CS;
555542
}
556543

557-
/* safety gap should be definitely longer than 1 instruction to not
558-
* overwrite something unintentionally */
559-
#define SAFE_PRJ_GAP 16
560-
561544
static void sprj_deep(TNode *G, unsigned int Interp_LONG_CS,
562545
unsigned short ocs, int basemode, int flags)
563546
{
@@ -567,8 +550,8 @@ static void sprj_deep(TNode *G, unsigned int Interp_LONG_CS,
567550
while (G->clink_t.link && !(G->flags & F_LJMP)) {
568551
TNode *oldG = G;
569552
unsigned int PC = G->clink_t.target;
570-
if (e_querymark(PC, SAFE_PRJ_GAP)) break;
571553
G = _Interp86(PC, Interp_LONG_CS, ocs, basemode, flags);
554+
if (!G) break;
572555
i++;
573556
NodesPrejitted++;
574557
NodeLinker(oldG, G);
@@ -581,23 +564,39 @@ static void sprj_deep(TNode *G, unsigned int Interp_LONG_CS,
581564
static TNode *_Interp86(unsigned int PC, unsigned int Interp_LONG_CS,
582565
unsigned short ocs, int basemode, int flags)
583566
{
584-
int gap = (flags & F_SPRJ) ? SAFE_PRJ_GAP : 1;
567+
TNode *nextG = NULL;
585568
CurrIMeta = -1;
586569
if (debug_level('e')>2) e_printf("============ Opening sequence at %08x\n",PC);
587570
for (;;) {
588-
PC = InterpOne(PC, Interp_LONG_CS, ocs, basemode);
571+
unsigned int newPC = InterpOne(PC, Interp_LONG_CS, ocs, basemode);
589572
assert (CurrIMeta>=0);
573+
#ifdef SPEC_PREJIT
574+
/* let SPEC_PREJIT give up if it overwrites */
575+
if ((flags & F_SPRJ) && e_querymark(PC, newPC - PC))
576+
return NULL;
577+
#endif
578+
PC = newPC;
590579

591580
#ifndef SINGLEBLOCK
592581
IMeta *GL = &InstrMeta[CurrIMeta];
593582
if ((basemode & MSSTP) ||
594-
GL->gen[GL->ngen-1].op >= JMP_TAILCODE ||
595-
e_querymark(PC, gap))
596-
#endif
583+
GL->gen[GL->ngen-1].op >= JMP_TAILCODE)
597584
break;
585+
586+
/* if we find compatible code, stop compiling and let
587+
DoClose() generate a jump to it */
588+
nextG = FindTree(PC);
589+
if (nextG) {
590+
if (nextG->mode == basemode && nextG->cs == Interp_LONG_CS)
591+
break;
592+
nextG = NULL;
593+
}
594+
#else
595+
break;
596+
#endif
598597
}
599598
InstrMeta[0].flags |= flags;
600-
return DoClose(PC, Interp_LONG_CS, basemode, flags);
599+
return DoClose(PC, Interp_LONG_CS, basemode, flags, nextG);
601600
}
602601

603602
static unsigned int InterpOne(unsigned int PC, unsigned int Interp_LONG_CS,
@@ -2780,7 +2779,7 @@ static void prejit_run(TNode *G)
27802779
ds = e_emu_disasm(EMU_BASE32(PC),basemode&MBIGCS,ocs);
27812780
e_printf("prejit at %s\n", ds);
27822781
}
2783-
if (e_querymark(PC, SAFE_PRJ_GAP))
2782+
if (e_querymark(PC, 1))
27842783
return;
27852784
#if PROFILE
27862785
SpecPrejits++;

0 commit comments

Comments
 (0)