@@ -27,16 +27,16 @@ use crate::vm::native::{
2727 non_yielding_i64_host_call_signature, non_yielding_scalar_host_call_entry_address,
2828 non_yielding_scalar_host_call_signature, pack_shared_signature, regex_match_entry_address,
2929 regex_match_signature, regex_replace_entry_address, regex_replace_signature,
30- restore_active_sparse_exit_state_entry_address , restore_virtual_frame_entry_address ,
31- restore_virtual_frame_signature , shared_array_from_buffer_entry_address ,
32- shared_bytes_from_buffer_entry_address , shared_string_from_buffer_entry_address ,
33- sparse_restore_exit_signature , string_binary_transform_signature ,
34- string_contains_entry_address , string_contains_signature , string_lower_ascii_entry_address ,
35- string_replace_literal_entry_address , string_replace_signature ,
36- string_split_literal_entry_address , string_unary_transform_signature , to_string_entry_address ,
37- type_of_entry_address, value_eq_entry_address, value_eq_signature, value_len_entry_address ,
38- value_len_signature , value_slot_signature , write_heap_value_to_slot_entry_address ,
39- zero_bytes_entry_address,
30+ replace_value_in_slot_entry_address , restore_active_sparse_exit_state_entry_address ,
31+ restore_virtual_frame_entry_address , restore_virtual_frame_signature ,
32+ shared_array_from_buffer_entry_address , shared_bytes_from_buffer_entry_address ,
33+ shared_string_from_buffer_entry_address , sparse_restore_exit_signature ,
34+ string_binary_transform_signature , string_contains_entry_address , string_contains_signature ,
35+ string_lower_ascii_entry_address , string_replace_literal_entry_address ,
36+ string_replace_signature , string_split_literal_entry_address , string_unary_transform_signature ,
37+ to_string_entry_address , type_of_entry_address, value_eq_entry_address, value_eq_signature,
38+ value_len_entry_address , value_len_signature , value_slot_signature ,
39+ write_heap_value_to_slot_entry_address , zero_bytes_entry_address,
4040} ;
4141use cranelift_codegen:: ir:: condcodes:: { FloatCC , IntCC } ;
4242use cranelift_codegen:: ir:: immediates:: Ieee64 ;
@@ -667,7 +667,8 @@ fn try_compile_ssa_trace(
667667 } ;
668668 let frame_state_ref = b. import_signature ( frame_state_sig) ;
669669 let deopt_refs = SsaDeoptHelperRefs {
670- clone_value_ref : b. import_signature ( clone_value_sig) ,
670+ clone_value_ref : b. import_signature ( clone_value_sig. clone ( ) ) ,
671+ replace_value_ref : b. import_signature ( clone_value_sig) ,
671672 value_eq_ref : b. import_signature ( value_eq_sig) ,
672673 value_len_ref : b. import_signature ( value_len_sig) ,
673674 non_yielding_host_call_ref : b. import_signature ( non_yielding_host_call_sig) ,
@@ -693,6 +694,7 @@ fn try_compile_ssa_trace(
693694 } ;
694695 let deopt_addrs = SsaDeoptHelperAddrs {
695696 clone_value : clone_value_to_slot_entry_address ( ) ,
697+ replace_value : replace_value_in_slot_entry_address ( ) ,
696698 value_eq : value_eq_entry_address ( ) ,
697699 value_len : value_len_entry_address ( ) ,
698700 non_yielding_host_call : non_yielding_host_call_entry_address ( ) ,
@@ -1104,6 +1106,7 @@ enum SsaExitAction {
11041106#[ derive( Clone , Copy ) ]
11051107struct SsaDeoptHelperRefs {
11061108 clone_value_ref : cranelift_codegen:: ir:: SigRef ,
1109+ replace_value_ref : cranelift_codegen:: ir:: SigRef ,
11071110 value_eq_ref : cranelift_codegen:: ir:: SigRef ,
11081111 value_len_ref : cranelift_codegen:: ir:: SigRef ,
11091112 non_yielding_host_call_ref : cranelift_codegen:: ir:: SigRef ,
@@ -1130,6 +1133,7 @@ struct SsaDeoptHelperRefs {
11301133#[ derive( Clone , Copy ) ]
11311134struct SsaDeoptHelperAddrs {
11321135 clone_value : usize ,
1136+ replace_value : usize ,
11331137 value_eq : usize ,
11341138 value_len : usize ,
11351139 non_yielding_host_call : usize ,
@@ -2080,8 +2084,8 @@ fn lower_ssa_inst(
20802084 b,
20812085 exit_block,
20822086 pointer_type,
2083- helper_refs. clone_value_ref ,
2084- helper_addrs. clone_value ,
2087+ helper_refs. replace_value_ref ,
2088+ helper_addrs. replace_value ,
20852089 & [ out, values[ input] ] ,
20862090 ) ?;
20872091 out
@@ -4701,6 +4705,7 @@ fn lower_ssa_exit_block(
47014705 active_local_base,
47024706 layout. value . size ,
47034707 ) ;
4708+ let mut cloned_local_addrs = HashMap :: new ( ) ;
47044709 for ( local_index, materialization) in
47054710 exit. locals
47064711 . iter ( )
@@ -4709,13 +4714,6 @@ fn lower_ssa_exit_block(
47094714 exit. dirty_locals [ local_index] . then_some ( ( local_index, materialization) )
47104715 } )
47114716 {
4712- let index = b. ins ( ) . iconst (
4713- pointer_type,
4714- i64:: try_from ( local_index) . map_err ( |_| {
4715- VmError :: JitNative ( "SSA dirty local index out of range" . to_string ( ) )
4716- } ) ?,
4717- ) ;
4718- let dst_addr = ssa_value_addr ( b, pointer_type, vm_locals_ptr, index, layout. value . size ) ;
47194717 let clone_before_clear = match materialization {
47204718 SsaMaterialization :: BoxHeapPtr { .. } => true ,
47214719 SsaMaterialization :: Value ( value) => !moved_owned_values. contains ( value) ,
@@ -4725,6 +4723,25 @@ fn lower_ssa_exit_block(
47254723 let temp_slot = ssa_create_value_stack_slot ( b, layout. value . size ) ?;
47264724 let temp_addr = b. ins ( ) . stack_addr ( pointer_type, temp_slot, 0 ) ;
47274725 ssa_materialize_slot ( b, materialize_ctx, materialization, temp_addr, "local" ) ?;
4726+ cloned_local_addrs. insert ( local_index, temp_addr) ;
4727+ }
4728+ }
4729+ for ( local_index, materialization) in
4730+ exit. locals
4731+ . iter ( )
4732+ . enumerate ( )
4733+ . filter_map ( |( local_index, materialization) | {
4734+ exit. dirty_locals [ local_index] . then_some ( ( local_index, materialization) )
4735+ } )
4736+ {
4737+ let index = b. ins ( ) . iconst (
4738+ pointer_type,
4739+ i64:: try_from ( local_index) . map_err ( |_| {
4740+ VmError :: JitNative ( "SSA dirty local index out of range" . to_string ( ) )
4741+ } ) ?,
4742+ ) ;
4743+ let dst_addr = ssa_value_addr ( b, pointer_type, vm_locals_ptr, index, layout. value . size ) ;
4744+ if let Some ( temp_addr) = cloned_local_addrs. get ( & local_index) . copied ( ) {
47284745 clear_owned_value_temp_slot ( b, pointer_type, deopt_refs, deopt_addrs, dst_addr) ?;
47294746 ssa_copy_value_bytes ( b, temp_addr, dst_addr, layout. value . size ) ;
47304747 ssa_store_tag ( b, layout. value , temp_addr, layout. value . null_tag ) ;
0 commit comments