@@ -95,23 +95,20 @@ static char R1Tab_l[14] =
9595 * by the next DoExec.
9696 */
9797static 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-
561544static 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,
581564static 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
603602static 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