56
56
#define JIT_OP_MOD_REG (JIT_CLS_ALU | JIT_SRC_REG | 0x90)
57
57
58
58
#define STACK_SIZE 512
59
- #define MAX_INSNS 1024
59
+ #define MAX_JUMPS 1024
60
+ #define MAX_BLOCKS 8192
60
61
#define IN_JUMP_THRESHOLD 256
61
62
#if defined(__x86_64__ )
62
63
#define JUMP_LOC jump_loc + 2
@@ -243,8 +244,8 @@ static inline void emit_load_imm(struct jit_state *state, int dst, int64_t imm);
243
244
244
245
static inline void offset_map_insert (struct jit_state * state , int32_t target_pc )
245
246
{
246
- struct offset_map * map_entry = & state -> offset_map [state -> n_insn ++ ];
247
- assert (state -> n_insn < MAX_INSNS );
247
+ struct offset_map * map_entry = & state -> offset_map [state -> n_blocks ++ ];
248
+ assert (state -> n_blocks < MAX_BLOCKS );
248
249
map_entry -> pc = target_pc ;
249
250
map_entry -> offset = state -> offset ;
250
251
}
@@ -354,7 +355,7 @@ static inline void emit_jump_target_address(struct jit_state *state,
354
355
int32_t target_pc )
355
356
{
356
357
struct jump * jump = & state -> jumps [state -> n_jumps ++ ];
357
- assert (state -> n_jumps < MAX_INSNS );
358
+ assert (state -> n_jumps < MAX_JUMPS );
358
359
jump -> offset_loc = state -> offset ;
359
360
jump -> target_pc = target_pc ;
360
361
emit4 (state , 0 );
@@ -556,7 +557,7 @@ static inline void emit_jump_target_offset(struct jit_state *state,
556
557
uint32_t jump_state_offset )
557
558
{
558
559
struct jump * jump = & state -> jumps [state -> n_jumps ++ ];
559
- assert (state -> n_jumps < MAX_INSNS );
560
+ assert (state -> n_jumps < MAX_JUMPS );
560
561
jump -> offset_loc = jump_loc ;
561
562
jump -> target_offset = jump_state_offset ;
562
563
}
@@ -934,7 +935,7 @@ static inline void emit_jmp(struct jit_state *state, uint32_t target_pc)
934
935
emit_jump_target_address (state , target_pc );
935
936
#elif defined(__aarch64__ )
936
937
struct jump * jump = & state -> jumps [state -> n_jumps ++ ];
937
- assert (state -> n_jumps < MAX_INSNS );
938
+ assert (state -> n_jumps < MAX_JUMPS );
938
939
jump -> offset_loc = state -> offset ;
939
940
jump -> target_pc = target_pc ;
940
941
emit_a64 (state , UBR_B );
@@ -1512,7 +1513,7 @@ static void resolve_jumps(struct jit_state *state)
1512
1513
#endif
1513
1514
else {
1514
1515
target_loc = jump .offset_loc + sizeof (uint32_t );
1515
- for (int i = 0 ; i < state -> n_insn ; i ++ ) {
1516
+ for (int i = 0 ; i < state -> n_blocks ; i ++ ) {
1516
1517
if (jump .target_pc == state -> offset_map [i ].pc ) {
1517
1518
target_loc = state -> offset_map [i ].offset ;
1518
1519
break ;
@@ -1534,27 +1535,26 @@ static void resolve_jumps(struct jit_state *state)
1534
1535
1535
1536
static void translate_chained_block (struct jit_state * state ,
1536
1537
riscv_t * rv ,
1537
- block_t * block ,
1538
- set_t * set )
1538
+ block_t * block )
1539
1539
{
1540
- if (set_has (set , block -> pc_start ))
1540
+ if (set_has (& state -> set , block -> pc_start ))
1541
1541
return ;
1542
1542
1543
- set_add (set , block -> pc_start );
1543
+ set_add (& state -> set , block -> pc_start );
1544
1544
offset_map_insert (state , block -> pc_start );
1545
1545
translate (state , rv , block );
1546
1546
rv_insn_t * ir = block -> ir_tail ;
1547
- if (ir -> branch_untaken && !set_has (set , ir -> branch_untaken -> pc )) {
1547
+ if (ir -> branch_untaken && !set_has (& state -> set , ir -> branch_untaken -> pc )) {
1548
1548
block_t * block1 =
1549
1549
cache_get (rv -> block_cache , ir -> branch_untaken -> pc , false);
1550
1550
if (block1 -> translatable )
1551
- translate_chained_block (state , rv , block1 , set );
1551
+ translate_chained_block (state , rv , block1 );
1552
1552
}
1553
- if (ir -> branch_taken && !set_has (set , ir -> branch_taken -> pc )) {
1553
+ if (ir -> branch_taken && !set_has (& state -> set , ir -> branch_taken -> pc )) {
1554
1554
block_t * block1 =
1555
1555
cache_get (rv -> block_cache , ir -> branch_taken -> pc , false);
1556
1556
if (block1 -> translatable )
1557
- translate_chained_block (state , rv , block1 , set );
1557
+ translate_chained_block (state , rv , block1 );
1558
1558
}
1559
1559
branch_history_table_t * bt = ir -> branch_table ;
1560
1560
if (bt ) {
@@ -1566,26 +1566,30 @@ static void translate_chained_block(struct jit_state *state,
1566
1566
max_idx = i ;
1567
1567
}
1568
1568
if (bt -> PC [max_idx ] && bt -> times [max_idx ] >= IN_JUMP_THRESHOLD &&
1569
- !set_has (set , bt -> PC [max_idx ])) {
1569
+ !set_has (& state -> set , bt -> PC [max_idx ])) {
1570
1570
block_t * block1 =
1571
1571
cache_get (rv -> block_cache , bt -> PC [max_idx ], false);
1572
1572
if (block1 && block1 -> translatable )
1573
- translate_chained_block (state , rv , block1 , set );
1573
+ translate_chained_block (state , rv , block1 );
1574
1574
}
1575
1575
}
1576
1576
}
1577
1577
1578
1578
uint32_t jit_translate (riscv_t * rv , block_t * block )
1579
1579
{
1580
1580
struct jit_state * state = rv -> jit_state ;
1581
- memset (state -> offset_map , 0 , MAX_INSNS * sizeof (struct offset_map ));
1582
- memset (state -> jumps , 0 , MAX_INSNS * sizeof (struct jump ));
1583
- state -> n_insn = 0 ;
1581
+ if (set_has (& state -> set , block -> pc_start )) {
1582
+ for (int i = 0 ; i < state -> n_blocks ; i ++ ) {
1583
+ if (block -> pc_start == state -> offset_map [i ].pc ) {
1584
+ return state -> offset_map [i ].offset ;
1585
+ }
1586
+ }
1587
+ __UNREACHABLE ;
1588
+ }
1589
+ memset (state -> jumps , 0 , 1024 * sizeof (struct jump ));
1584
1590
state -> n_jumps = 0 ;
1585
1591
uint32_t entry_loc = state -> offset ;
1586
- set_t set ;
1587
- set_reset (& set );
1588
- translate_chained_block (& (* state ), rv , block , & set );
1592
+ translate_chained_block (& (* state ), rv , block );
1589
1593
if (state -> offset == state -> size ) {
1590
1594
printf ("Target buffer too small\n" );
1591
1595
goto out ;
@@ -1608,10 +1612,12 @@ struct jit_state *jit_state_init(size_t size)
1608
1612
#endif
1609
1613
,
1610
1614
-1 , 0 );
1615
+ state -> n_blocks = 0 ;
1611
1616
assert (state -> buf != MAP_FAILED );
1617
+ set_reset (& state -> set );
1612
1618
prepare_translate (state );
1613
- state -> offset_map = calloc (MAX_INSNS , sizeof (struct offset_map ));
1614
- state -> jumps = calloc (MAX_INSNS , sizeof (struct jump ));
1619
+ state -> offset_map = calloc (MAX_BLOCKS , sizeof (struct offset_map ));
1620
+ state -> jumps = calloc (MAX_JUMPS , sizeof (struct jump ));
1615
1621
return state ;
1616
1622
}
1617
1623
0 commit comments