Skip to content

Commit

Permalink
Pick common code changes from 94d63e3
Browse files Browse the repository at this point in the history
94d63e3: Add a mechanism for hinting to the core disassembler loop
  • Loading branch information
mephi42 authored and rhelmot committed Jan 22, 2020
1 parent c93c17f commit fdaaf4c
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 6 deletions.
9 changes: 8 additions & 1 deletion priv/guest_amd64_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -30047,6 +30047,7 @@ Long dis_ESC_0F38__VEX (
if (have66noF2noF3(pfx)) {
delta = dis_FMA( vbi, pfx, delta, opc );
*uses_vvvv = True;
dres->hint = Dis_HintVerbose;
goto decode_success;
}
break;
Expand Down Expand Up @@ -32172,15 +32173,20 @@ Long dis_ESC_0F3A__VEX (
/* else fall though; dis_PCMPxSTRx failed to decode it */
}
break;

case 0x5c: case 0x5d: case 0x5e: case 0x5f:
case 0x68: case 0x69: case 0x6a: case 0x6b:
case 0x6c: case 0x6d: case 0x6e: case 0x6f:
case 0x78: case 0x79: case 0x7a: case 0x7b:
case 0x7c: case 0x7d: case 0x7e: case 0x7f:
/* FIXME: list the instructions decoded here */
if (have66noF2noF3(pfx) && 0==getVexL(pfx)/*128*/) {
Long delta0 = delta;
delta = dis_FMA4( pfx, delta, opc, uses_vvvv, vbi );
if (delta > delta0) goto decode_success;
if (delta > delta0) {
dres->hint = Dis_HintVerbose;
goto decode_success;
}
/* else fall though; dis_FMA4 failed to decode it */
}
break;
Expand Down Expand Up @@ -32293,6 +32299,7 @@ DisResult disInstr_AMD64_WRK (
dres.len = 0;
dres.continueAt = 0;
dres.jk_StopHere = Ijk_INVALID;
dres.hint = Dis_HintNone;
*expect_CAS = False;

vassert(guest_RIP_next_assumed == 0);
Expand Down
1 change: 1 addition & 0 deletions priv/guest_arm64_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -14315,6 +14315,7 @@ Bool disInstr_ARM64_WRK (
dres->len = 4;
dres->continueAt = 0;
dres->jk_StopHere = Ijk_INVALID;
dres->hint = Dis_HintNone;

/* At least this is simple on ARM64: insns are all 4 bytes long, and
4-aligned. So just fish the whole thing out of memory right now
Expand Down
2 changes: 2 additions & 0 deletions priv/guest_arm_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -16173,6 +16173,7 @@ DisResult disInstr_ARM_WRK (
dres.len = 4;
dres.continueAt = 0;
dres.jk_StopHere = Ijk_INVALID;
dres.hint = Dis_HintNone;

/* Set default actions for post-insn handling of writes to r15, if
required. */
Expand Down Expand Up @@ -19070,6 +19071,7 @@ DisResult disInstr_THUMB_WRK (
dres.len = 2;
dres.continueAt = 0;
dres.jk_StopHere = Ijk_INVALID;
dres.hint = Dis_HintNone;

/* Set default actions for post-insn handling of writes to r15, if
required. */
Expand Down
28 changes: 26 additions & 2 deletions priv/guest_generic_bb_to_IR.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ IRSB* bb_to_IR (
vassert((offB_GUEST_IP % 8) == 0);
}

/* Although we will try to disassemble up to vex_control.guest_max_insns
insns into the block, the individual insn assemblers may hint to us that a
disassembled instruction is verbose. In that case we will lower the limit
so as to ensure that the JIT doesn't run out of space. See bug 375839 for
the motivating example. */
Int guest_max_insns_really = vex_control.guest_max_insns;

/* Start a new, empty extent. */
vge->n_used = 1;
vge->base[0] = guest_IP_bbstart;
Expand Down Expand Up @@ -287,7 +294,7 @@ IRSB* bb_to_IR (

/* Process instructions. */
while (True) {
vassert(n_instrs < vex_control.guest_max_insns);
vassert(n_instrs < guest_max_insns_really);

/* Regardless of what chase_into_ok says, is chasing permissible
at all right now? Set resteerOKfn accordingly. */
Expand Down Expand Up @@ -386,6 +393,23 @@ IRSB* bb_to_IR (
if (n_cond_resteers_allowed == 0)
vassert(dres.whatNext != Dis_ResteerC);

/* If the disassembly function passed us a hint, take note of it. */
if (LIKELY(dres.hint == Dis_HintNone)) {
/* Do nothing */
} else {
vassert(dres.hint == Dis_HintVerbose);
/* The current insn is known to be verbose. Lower the max insns limit
if necessary so as to avoid running the JIT out of space in the
event that we've encountered the start of a long sequence of them.
This is expected to be a very rare event. In any case the remaining
limit (30 insns) is still so high that most blocks will terminate
anyway before then. So this is very unlikely to give a perf hit in
practice. See bug 375839 for the motivating example. */
if (guest_max_insns_really > 30) {
guest_max_insns_really = 30;
}
}

/* Fill in the insn-mark length field. */
vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts_used);
imark = irsb->stmts[first_stmt_idx];
Expand Down Expand Up @@ -452,7 +476,7 @@ IRSB* bb_to_IR (
case Dis_Continue:
vassert(dres.continueAt == 0);
vassert(dres.jk_StopHere == Ijk_INVALID);
if (n_instrs < vex_control.guest_max_insns &&
if (n_instrs < guest_max_insns_really &&
vge->len[vge->n_used-1] < vex_control.guest_max_bytes) {
/* keep going */
} else {
Expand Down
11 changes: 8 additions & 3 deletions priv/guest_generic_bb_to_IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,16 @@ typedef
Dis_ResteerC: (speculatively, of course) followed a
conditional branch; continue at 'continueAt'
*/
enum { Dis_StopHere, Dis_Continue,
enum { Dis_StopHere=0x10, Dis_Continue,
Dis_ResteerU, Dis_ResteerC } whatNext;

/* For Dis_StopHere, we need to end the block and create a
/* Any other hints that we should feed back to the disassembler?
Dis_HintNone: no hint
Dis_HintVerbose: this insn potentially generates a lot of code
*/
enum { Dis_HintNone=0x20, Dis_HintVerbose } hint;

/* For whatNext==Dis_StopHere, we need to end the block and create a
transfer to whatever the NIA is. That will have presumably
been set by the IR generated for this insn. So we need to
know the jump kind to use. Should Ijk_INVALID in other Dis_
Expand All @@ -89,7 +95,6 @@ typedef
/* For Dis_Resteer, this is the guest address we should continue
at. Otherwise ignored (should be zero). */
Addr continueAt;

}

DisResult;
Expand Down
1 change: 1 addition & 0 deletions priv/guest_mips_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -12062,6 +12062,7 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *,
dres.len = 0;
dres.continueAt = 0;
dres.jk_StopHere = Ijk_INVALID;
dres.hint = Dis_HintNone;

delay_slot_branch = likely_delay_slot = delay_slot_jump = False;

Expand Down
2 changes: 2 additions & 0 deletions priv/guest_ppc_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -27401,6 +27401,7 @@ DisResult disInstr_PPC_WRK (
dres.len = 0;
dres.continueAt = 0;
dres.jk_StopHere = Ijk_INVALID;
dres.hint = Dis_HintNone;

/* At least this is simple on PPC32: insns are all 4 bytes long, and
4-aligned. So just fish the whole thing out of memory right now
Expand Down Expand Up @@ -29111,6 +29112,7 @@ DisResult disInstr_PPC ( IRSB* irsb_IN,
dres.whatNext = Dis_StopHere;
dres.jk_StopHere = Ijk_NoDecode;
dres.continueAt = 0;
dres.hint = Dis_HintNone;
return dres;
}

Expand Down
1 change: 1 addition & 0 deletions priv/guest_tilegx_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ static DisResult disInstr_TILEGX_WRK ( Bool(*resteerOkFn) (void *, Addr),
dres.len = 0;
dres.continueAt = 0;
dres.jk_StopHere = Ijk_INVALID;
dres.hint = Dis_HintNone;

/* Verify the code addr is 8-byte aligned. */
vassert((((Addr)code) & 7) == 0);
Expand Down
1 change: 1 addition & 0 deletions priv/guest_x86_toIR.c
Original file line number Diff line number Diff line change
Expand Up @@ -8563,6 +8563,7 @@ DisResult disInstr_X86_WRK (
dres.whatNext = Dis_Continue;
dres.len = 0;
dres.continueAt = 0;
dres.hint = Dis_HintNone;
dres.jk_StopHere = Ijk_INVALID;

*expect_CAS = False;
Expand Down

0 comments on commit fdaaf4c

Please sign in to comment.