File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1257,8 +1257,13 @@ impl Vm {
12571257 continue ;
12581258 }
12591259
1260+ // SSA traces currently model locals but have no entry operand-stack parameters.
1261+ // Running one with ambient values would drop values that remain live across a loop
1262+ // (for example, the left operand of `100 + inlined_loop()`). Keep such loops in the
1263+ // interpreter until trace entry stacks are represented explicitly.
12601264 if allow_jit
12611265 && self . jit_config ( ) . enabled
1266+ && self . stack . is_empty ( )
12621267 && self . builtin_overrides . is_empty ( )
12631268 && !self . drop_contract_events_enabled ( )
12641269 {
Original file line number Diff line number Diff line change @@ -3435,3 +3435,38 @@ fn trace_jit_supports_float_comparisons_in_ssa() {
34353435 vm. dump_jit_info( )
34363436 ) ;
34373437}
3438+
3439+ #[ test]
3440+ fn trace_jit_skips_loop_with_live_entry_stack ( ) {
3441+ if !native_jit_supported ( ) {
3442+ return ;
3443+ }
3444+
3445+ let source = r#"
3446+ fn sum_to(limit: int) -> int {
3447+ let mut sum = 0;
3448+ for i in 0..limit {
3449+ sum = sum + i;
3450+ }
3451+ sum
3452+ }
3453+
3454+ 100 + sum_to(10);
3455+ "# ;
3456+ let compiled = compile_source ( source) . expect ( "live entry stack source should compile" ) ;
3457+ let mut vm = Vm :: new ( compiled. program ) ;
3458+ vm. set_jit_config ( JitConfig {
3459+ enabled : true ,
3460+ hot_loop_threshold : 1 ,
3461+ max_trace_len : 512 ,
3462+ } ) ;
3463+
3464+ let status = vm. run ( ) . expect ( "live entry stack program should run" ) ;
3465+ assert_eq ! ( status, VmStatus :: Halted ) ;
3466+ assert_eq ! ( vm. stack( ) , & [ Value :: Int ( 145 ) ] ) ;
3467+ assert_eq ! (
3468+ vm. jit_native_exec_count( ) ,
3469+ 0 ,
3470+ "a trace with an unmodeled live entry stack must remain in the interpreter"
3471+ ) ;
3472+ }
You can’t perform that action at this time.
0 commit comments