@@ -6498,6 +6498,55 @@ fn trace_jit_guards_static_inline_callable_identity() {
64986498 assert ! ( vm. jit_native_exec_count( ) > 0 , "{}" , vm. dump_jit_info( ) ) ;
64996499}
65006500
6501+ #[ test]
6502+ fn trace_jit_invalidates_native_inline_after_callable_local_replacement ( ) {
6503+ if !native_jit_supported ( ) {
6504+ return ;
6505+ }
6506+ let source = r#"
6507+ fn add_one(value: int) -> int { value + 1 }
6508+ fn add_ten(value: int) -> int { value + 10 }
6509+ let mut i = 0;
6510+ let mut total = 0;
6511+ while i < 100 {
6512+ total = add_one(total);
6513+ i = i + 1;
6514+ }
6515+ total;
6516+ "# ;
6517+ let compiled = compile_source ( source) . expect ( "callable invalidation source should compile" ) ;
6518+ let bindings = compiled. program . root_callable_bindings . clone ( ) ;
6519+ let replaced_slot = bindings. first ( ) . expect ( "add_one binding" ) . local_slot ;
6520+ let replacement_id = bindings. get ( 1 ) . expect ( "add_ten binding" ) . prototype_id ;
6521+ let replacement_kind = compiled. program . callable_prototypes [ replacement_id as usize ] . kind ;
6522+ let mut vm = Vm :: new ( compiled. program . with_local_count ( compiled. locals ) ) ;
6523+ vm. set_jit_config ( JitConfig {
6524+ enabled : true ,
6525+ hot_loop_threshold : 1 ,
6526+ max_trace_len : 512 ,
6527+ } ) ;
6528+
6529+ assert_eq ! ( vm. run( ) . expect( "initial inline run" ) , VmStatus :: Halted ) ;
6530+ assert_eq ! ( vm. stack( ) , & [ Value :: Int ( 100 ) ] ) ;
6531+ assert ! ( vm. jit_native_trace_count( ) > 0 , "{}" , vm. dump_jit_info( ) ) ;
6532+
6533+ vm. reset_for_reuse ( ) ;
6534+ vm. set_local (
6535+ u8:: try_from ( replaced_slot) . expect ( "root callable slot should fit u8" ) ,
6536+ Value :: Callable ( Arc :: new ( vm:: CallableValue {
6537+ prototype_id : replacement_id,
6538+ kind : replacement_kind,
6539+ env : None ,
6540+ } ) ) ,
6541+ )
6542+ . expect ( "callable replacement should succeed" ) ;
6543+ assert_eq ! ( vm. jit_native_trace_count( ) , 0 ) ;
6544+
6545+ assert_eq ! ( vm. run( ) . expect( "replacement inline run" ) , VmStatus :: Halted ) ;
6546+ assert_eq ! ( vm. stack( ) , & [ Value :: Int ( 1_000 ) ] ) ;
6547+ assert ! ( vm. jit_native_exec_count( ) > 0 , "{}" , vm. dump_jit_info( ) ) ;
6548+ }
6549+
65016550#[ test]
65026551fn trace_jit_preserves_inline_callable_argument_schema_checks ( ) {
65036552 if !native_jit_supported ( ) {
0 commit comments