@@ -272,11 +272,11 @@ static inline void offset_map_insert(struct jit_state *state, int32_t target_pc)
272272 __builtin___clear_cache((char *) (addr), (char *) (addr) + (size));
273273#endif
274274
275+ static bool should_flush = false;
275276static void emit_bytes (struct jit_state * state , void * data , uint32_t len )
276277{
277- assert (state -> offset <= state -> size - len );
278278 if (unlikely ((state -> offset + len ) > state -> size )) {
279- state -> offset = state -> size ;
279+ should_flush = true ;
280280 return ;
281281 }
282282#if defined(__APPLE__ ) && defined(__aarch64__ )
@@ -1274,6 +1274,7 @@ static void prepare_translate(struct jit_state *state)
12741274 emit_addsub_imm (state , true, AS_ADD , SP , SP , state -> stack_size );
12751275 emit_uncond_branch_reg (state , BR_RET , R30 );
12761276#endif
1277+ state -> org_size = state -> offset ;
12771278}
12781279
12791280
@@ -1531,7 +1532,7 @@ static void do_fuse5(struct jit_state *state, riscv_t *rv UNUSED, rv_insn_t *ir)
15311532 emit_load_imm (state , temp_reg , ir -> pc + 4 );
15321533 emit_store (state , S32 , temp_reg , parameter_reg [0 ], offsetof(riscv_t , PC ));
15331534 emit_call (state , (intptr_t ) rv -> io .on_memset );
1534- emit_exit (& ( * state ) );
1535+ emit_exit (state );
15351536}
15361537
15371538static void do_fuse6 (struct jit_state * state , riscv_t * rv UNUSED , rv_insn_t * ir )
@@ -1540,7 +1541,7 @@ static void do_fuse6(struct jit_state *state, riscv_t *rv UNUSED, rv_insn_t *ir)
15401541 emit_load_imm (state , temp_reg , ir -> pc + 4 );
15411542 emit_store (state , S32 , temp_reg , parameter_reg [0 ], offsetof(riscv_t , PC ));
15421543 emit_call (state , (intptr_t ) rv -> io .on_memcpy );
1543- emit_exit (& ( * state ) );
1544+ emit_exit (state );
15441545}
15451546
15461547static void do_fuse7 (struct jit_state * state , riscv_t * rv UNUSED , rv_insn_t * ir )
@@ -1589,6 +1590,21 @@ static const void *dispatch_table[] = {
15891590};
15901591/* clang-format on */
15911592
1593+ void clear_hot (block_t * block )
1594+ {
1595+ block -> hot = false;
1596+ }
1597+
1598+ static void code_cache_flush (struct jit_state * state , riscv_t * rv )
1599+ {
1600+ should_flush = false;
1601+ state -> offset = state -> org_size ;
1602+ state -> n_blocks = 0 ;
1603+ set_reset (& state -> set );
1604+ clear_cache_hot (rv -> block_cache , (clear_func_t ) clear_hot );
1605+ return ;
1606+ }
1607+
15921608typedef void (* codegen_block_func_t )(struct jit_state * ,
15931609 riscv_t * ,
15941610 rv_insn_t * );
@@ -1598,7 +1614,8 @@ static void translate(struct jit_state *state, riscv_t *rv, block_t *block)
15981614 uint32_t idx ;
15991615 rv_insn_t * ir , * next ;
16001616 reset_reg ();
1601- for (idx = 0 , ir = block -> ir_head ; idx < block -> n_insn ; idx ++ , ir = next ) {
1617+ for (idx = 0 , ir = block -> ir_head ; idx < block -> n_insn && !should_flush ;
1618+ idx ++ , ir = next ) {
16021619 next = ir -> next ;
16031620 ((codegen_block_func_t ) dispatch_table [ir -> opcode ])(state , rv , ir );
16041621 }
@@ -1652,6 +1669,8 @@ static void translate_chained_block(struct jit_state *state,
16521669 set_add (& state -> set , block -> pc_start );
16531670 offset_map_insert (state , block -> pc_start );
16541671 translate (state , rv , block );
1672+ if (unlikely (should_flush ))
1673+ return ;
16551674 rv_insn_t * ir = block -> ir_tail ;
16561675 if (ir -> branch_untaken && !set_has (& state -> set , ir -> branch_untaken -> pc )) {
16571676 block_t * block1 =
@@ -1684,28 +1703,29 @@ static void translate_chained_block(struct jit_state *state,
16841703 }
16851704}
16861705
1687- uint32_t jit_translate (riscv_t * rv , block_t * block )
1706+ void jit_translate (riscv_t * rv , block_t * block )
16881707{
16891708 struct jit_state * state = rv -> jit_state ;
16901709 if (set_has (& state -> set , block -> pc_start )) {
16911710 for (int i = 0 ; i < state -> n_blocks ; i ++ ) {
16921711 if (block -> pc_start == state -> offset_map [i ].pc ) {
1693- return state -> offset_map [i ].offset ;
1712+ block -> offset = state -> offset_map [i ].offset ;
1713+ return ;
16941714 }
16951715 }
16961716 __UNREACHABLE ;
16971717 }
1718+ restart :
16981719 memset (state -> jumps , 0 , 1024 * sizeof (struct jump ));
16991720 state -> n_jumps = 0 ;
1700- uint32_t entry_loc = state -> offset ;
1701- translate_chained_block (& ( * state ) , rv , block );
1702- if (state -> offset == state -> size ) {
1703- printf ( "Target buffer too small\n" );
1704- goto out ;
1721+ block -> offset = state -> offset ;
1722+ translate_chained_block (state , rv , block );
1723+ if (unlikely ( should_flush ) ) {
1724+ code_cache_flush ( state , rv );
1725+ goto restart ;
17051726 }
1706- resolve_jumps (& (* state ));
1707- out :
1708- return entry_loc ;
1727+ resolve_jumps (state );
1728+ block -> hot = true;
17091729}
17101730
17111731struct jit_state * jit_state_init (size_t size )
0 commit comments