Skip to content

Commit 52cd8d7

Browse files
committed
simx86: use a BrokenCodePtr variable to only keep JIT code alive for a bit
This way all the rest for the node can be deleted, and there is no need for dead nodes any more. Also pass the correct jit pointer from sigsegv.c to TryInvalidateNodeRange() Fixes dosemu2#2708
1 parent 540662c commit 52cd8d7

File tree

5 files changed

+39
-32
lines changed

5 files changed

+39
-32
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,10 @@ static unsigned ExecOne(TNode *G)
625625
#endif
626626
prefetch(CPUOFFS(0));
627627
ePC = Exec(G->addr);
628+
if (BrokenCodePtr) {
629+
FreeGenCodeBuf(BrokenCodePtr);
630+
BrokenCodePtr = NULL;
631+
}
628632
#ifdef SKIP_EMU_VBIOS
629633
if ((TheCPU.cs&0xf000)==config.vbios_seg && !TheCPU.err)
630634
TheCPU.err = EXCP_GOBACK;

src/base/emu-i386/simx86/codegen.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,6 @@ static __inline__ int GoodNode(TNode *G)
240240
G->key, G->mode, TheCPU.mode);
241241
return 0;
242242
}
243-
if (G->alive <= 0)
244-
return 0;
245243
return 1;
246244
}
247245

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ int e_emu_fault(sigcontext_t *scp, int in_vm86)
320320
int e_handle_pagefault(dosaddr_t addr, unsigned err, sigcontext_t *scp)
321321
{
322322
int v;
323-
unsigned char *p;
323+
unsigned char *p, *pjit;
324324
int in_dosemu;
325325

326326
/* err:
@@ -366,12 +366,14 @@ int e_handle_pagefault(dosaddr_t addr, unsigned err, sigcontext_t *scp)
366366
if (debug_level('e')) PageFaults++;
367367
#endif
368368
in_dosemu = !(InCompiledCode || in_vm86 || DPMIValidSelector(_scp_cs));
369+
p = (unsigned char *) _scp_rip;
370+
pjit = InCompiledCode ? GetGenCodeBuf(p) : NULL;
369371
if (in_vm86)
370372
p = SEG_ADR((unsigned char *), cs, ip);
371373
else if (DPMIValidSelector(_scp_cs))
372374
p = (unsigned char *)EMU_BASE32(GetSegmentBase(_scp_cs) + _scp_rip);
373-
else
374-
p = GetGenCodeBuf((unsigned char *) _scp_rip);
375+
else if (InCompiledCode)
376+
p = pjit;
375377
if (debug_level('e')>1 || in_dosemu) {
376378
v = *((int *)p);
377379
__asm__("bswap %0" : "=r" (v) : "0" (v));
@@ -404,7 +406,8 @@ int e_handle_pagefault(dosaddr_t addr, unsigned err, sigcontext_t *scp)
404406
/* We HAVE to invalidate all the code in the page
405407
* if the page is going to be unprotected */
406408
addr &= _PAGE_MASK;
407-
return TryInvalidateNodeRange(addr, PAGE_SIZE, p);
409+
TryInvalidateNodeRange(addr, PAGE_SIZE, pjit);
410+
return 1;
408411
}
409412

410413
int e_handle_fault(sigcontext_t *scp)

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

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
IMeta InstrMeta[MAXINODES];
4848
int CurrIMeta;
49+
unsigned char *BrokenCodePtr;
4950

5051
/* Tree structure to store collected code sequences */
5152
static avltr_tree CollectTree;
@@ -1162,8 +1163,7 @@ static TNode *FindTree_tail(int key)
11621163
G = *I;
11631164
assert(G && G->addr);
11641165
if (debug_level('e')>3) e_printf("Found key %08x\n",key);
1165-
if (G->alive > 0)
1166-
G->alive = NODELIFE(G);
1166+
G->alive = NODELIFE(G);
11671167
#if PROFILE
11681168
if (debug_level('e')) {
11691169
NodesFound++;
@@ -1209,8 +1209,7 @@ TNode *FindTree(int key)
12091209
NodesFastFound++;
12101210
#endif
12111211
}
1212-
if (I->alive > 0)
1213-
I->alive = NODELIFE(I);
1212+
I->alive = NODELIFE(I);
12141213
return I;
12151214
}
12161215
if (!e_querymark(key, 1))
@@ -1241,8 +1240,7 @@ TNode *FindTree_unlocked(int key)
12411240
NodesFastFound++;
12421241
#endif
12431242
}
1244-
if (I->alive > 0)
1245-
I->alive = NODELIFE(I);
1243+
I->alive = NODELIFE(I);
12461244
return I;
12471245
}
12481246

@@ -1297,12 +1295,13 @@ static void BreakNode(TNode *G, unsigned char *eip)
12971295
e_printf("============ Node %08x break failed\n",G->key);
12981296
}
12991297

1300-
static void RemoveNode_unlocked(TNode *G)
1298+
static void RemoveNode_unlocked(TNode *G, int keepcode)
13011299
{
13021300
e_unmarkpage(G->key, G->seqlen);
13031301
NodeUnlinker(G);
13041302
assert(!G->bkr && !G->clink_t.ref && !G->clink_nt.ref && G->addr);
1305-
FreeGenCodeBuf(G->addr);
1303+
if (!keepcode)
1304+
FreeGenCodeBuf(G->addr);
13061305
__atomic_store_n(&findtree_cache[G->key&FINDTREE_CACHE_HASH_MASK],
13071306
NULL, __ATOMIC_RELAXED);
13081307
TNode *deleted = avltr_delete(G->key);
@@ -1313,11 +1312,11 @@ static void RemoveNode_unlocked(TNode *G)
13131312
void RemoveNode(TNode *G)
13141313
{
13151314
pthread_mutex_lock_trees();
1316-
RemoveNode_unlocked(G);
1315+
RemoveNode_unlocked(G, 0);
13171316
pthread_mutex_unlock_trees();
13181317
}
13191318

1320-
static int BreakNodeHook(TNode *G, unsigned char *eip)
1319+
static unsigned char *BreakNodeHook(TNode *G, unsigned char *eip)
13211320
{
13221321
unsigned char *ahE;
13231322
/* if the current eip is in *any* chunk of code that is deleted
@@ -1328,6 +1327,7 @@ static int BreakNodeHook(TNode *G, unsigned char *eip)
13281327
call returns to may write to the current unprotected page.
13291328
*/
13301329
ahE = G->addr + G->len;
1330+
e_printf("BreakNodeHook %p ahE=%p eip=%p\n", G->addr, ahE, eip);
13311331
if (ADDR_IN_RANGE(eip,G->addr,ahE)) {
13321332
/* Exclude last instruction, as there is no need to break
13331333
* node after last instruction (it ends there anyway). */
@@ -1337,20 +1337,19 @@ static int BreakNodeHook(TNode *G, unsigned char *eip)
13371337
eip,G->addr,ahE);
13381338
if (ADDR_IN_RANGE(eip,G->addr,ahE1))
13391339
BreakNode(G, eip);
1340-
/* we can only call RemoveNode in codegen.c */
1341-
NodeUnlinker(G);
1342-
G->alive = 0;
1343-
return -1;
1340+
/* return pointer to JIT code that can only be freed in codegen.c
1341+
because we are returning to it */
1342+
return G->addr;
13441343
}
1345-
return 0;
1344+
return NULL;
13461345
}
13471346

1348-
static int DoInvalidateNodeRange(int al, int len, unsigned char *eip,
1349-
int (*hook)(TNode *, unsigned char *))
1347+
static unsigned char *DoInvalidateNodeRange(int al, int len, unsigned char *eip,
1348+
unsigned char * (*hook)(TNode *, unsigned char *))
13501349
{
13511350
TNode *G;
13521351
int ah;
1353-
int rc = 0;
1352+
unsigned char *rc = NULL;
13541353
#if PROFILE >= 2
13551354
hitimer_t t0 = 0;
13561355

@@ -1373,14 +1372,16 @@ static int DoInvalidateNodeRange(int al, int len, unsigned char *eip,
13731372
ahG = G->key + G->seqlen;
13741373
assert (G->addr);
13751374
if (RANGE_INTERSECT(G->key,ahG,al,ah)) {
1375+
unsigned char *p = NULL;
13761376
if (debug_level('e')>1)
13771377
dbug_printf("Invalidated node %p at %08x\n",G,G->key);
1378-
if (eip && hook)
1379-
rc = hook(G, eip);
1380-
if (rc == -1)
1381-
return rc;
1378+
if (eip && hook) {
1379+
p = hook(G, eip);
1380+
if (p)
1381+
rc = p;
1382+
}
13821383
if (debug_level('e')>2) e_printf("Delete node %08x\n",G->key);
1383-
RemoveNode_unlocked(G);
1384+
RemoveNode_unlocked(G, p != NULL);
13841385
}
13851386
if (ahG >= ah)
13861387
break;
@@ -1399,9 +1400,9 @@ void InvalidateNodeRange(int al, int len)
13991400
DoInvalidateNodeRange(al, len, NULL, NULL);
14001401
}
14011402

1402-
int TryInvalidateNodeRange(int al, int len, unsigned char *eip)
1403+
void TryInvalidateNodeRange(int al, int len, unsigned char *eip)
14031404
{
1404-
return DoInvalidateNodeRange(al, len, eip, BreakNodeHook);
1405+
BrokenCodePtr = DoInvalidateNodeRange(al, len, eip, BreakNodeHook);
14051406
}
14061407

14071408
/////////////////////////////////////////////////////////////////////////////

src/base/emu-i386/simx86/trees.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,10 @@ static inline unsigned int FindPC_X(const unsigned char *addr)
161161
return FindPC(GetGenCodeBuf(addr));
162162
}
163163
void InvalidateNodeRange(int addr, int len);
164-
int TryInvalidateNodeRange(int addr, int len, unsigned char *eip);
164+
void TryInvalidateNodeRange(int addr, int len, unsigned char *eip);
165165
void RemoveNode(TNode *G);
166166
void NodeLinker(TNode *LG, TNode *G);
167+
extern unsigned char *BrokenCodePtr;
167168

168169
#ifdef DEBUG_TREE
169170
extern FILE *tLog;

0 commit comments

Comments
 (0)