@@ -189,20 +189,30 @@ pub(crate) fn compile_tail_status_body(status: i32) -> VmResult<CompiledTailFunc
189189 )
190190}
191191
192- pub ( crate ) fn compile_tail_side_link_body (
192+ fn compile_tail_side_link_body_with_abi (
193+ prefix : & str ,
193194 slot_address : usize ,
194195 deopt_status : i32 ,
196+ abi : TailCallAbi ,
195197) -> VmResult < CompiledTailFunction > {
198+ debug_assert ! ( matches!( abi, TailCallAbi :: Plain | TailCallAbi :: Owned ) ) ;
196199 compile_standalone_native_function (
197- "pd_vm_tail_side_link" ,
198- |pointer_type, _| tail_entry_signature ( pointer_type) ,
200+ prefix ,
201+ move |pointer_type, _| abi . tail_signature ( pointer_type) ,
199202 move |builder, pointer_type, _| {
200203 let entry = builder. create_block ( ) ;
201204 let deopt = builder. create_block ( ) ;
202205 let linked = builder. create_block ( ) ;
203206 builder. append_block_params_for_function_params ( entry) ;
204207 builder. switch_to_block ( entry) ;
205208 let vm_ptr = builder. block_params ( entry) [ 0 ] ;
209+ let args = match abi {
210+ TailCallAbi :: Plain => vec ! [ vm_ptr] ,
211+ TailCallAbi :: Owned => vec ! [ vm_ptr, builder. block_params( entry) [ 1 ] ] ,
212+ TailCallAbi :: Inherited => {
213+ unreachable ! ( "inherited packets use the trace dispatcher" )
214+ }
215+ } ;
206216 let slot_address = iconst_ptr_from_addr ( builder, pointer_type, slot_address) ?;
207217 let target = builder
208218 . ins ( )
@@ -215,83 +225,130 @@ pub(crate) fn compile_tail_side_link_body(
215225 builder. ins ( ) . return_ ( & [ status] ) ;
216226
217227 builder. switch_to_block ( linked) ;
218- let signature = builder. import_signature ( tail_entry_signature ( pointer_type) ) ;
219- builder
220- . ins ( )
221- . return_call_indirect ( signature, target, & [ vm_ptr] ) ;
228+ let signature = builder. import_signature ( abi. tail_signature ( pointer_type) ) ;
229+ builder. ins ( ) . return_call_indirect ( signature, target, & args) ;
222230 Ok ( ( ) )
223231 } ,
224232 )
225233}
226234
227- pub ( crate ) fn compile_system_tail_wrapper ( root_entry : * const u8 ) -> VmResult < CompiledTailFunction > {
235+ pub ( crate ) fn compile_tail_side_link_body (
236+ slot_address : usize ,
237+ deopt_status : i32 ,
238+ ) -> VmResult < CompiledTailFunction > {
239+ compile_tail_side_link_body_with_abi (
240+ "pd_vm_tail_side_link" ,
241+ slot_address,
242+ deopt_status,
243+ TailCallAbi :: Plain ,
244+ )
245+ }
246+
247+ #[ derive( Clone , Copy ) ]
248+ enum TailCallAbi {
249+ Plain ,
250+ Inherited ,
251+ Owned ,
252+ }
253+
254+ impl TailCallAbi {
255+ fn system_signature (
256+ self ,
257+ pointer_type : cranelift_codegen:: ir:: Type ,
258+ call_conv : CallConv ,
259+ ) -> Signature {
260+ match self {
261+ Self :: Plain | Self :: Inherited => entry_signature ( pointer_type, call_conv) ,
262+ Self :: Owned => system_owned_entry_signature ( pointer_type, call_conv) ,
263+ }
264+ }
265+
266+ fn tail_signature ( self , pointer_type : cranelift_codegen:: ir:: Type ) -> Signature {
267+ match self {
268+ Self :: Plain => tail_entry_signature ( pointer_type) ,
269+ Self :: Inherited => inherited_tail_entry_signature ( pointer_type) ,
270+ Self :: Owned => tail_owned_entry_signature ( pointer_type) ,
271+ }
272+ }
273+ }
274+
275+ fn create_inherited_state_packet (
276+ builder : & mut FunctionBuilder < ' _ > ,
277+ pointer_type : cranelift_codegen:: ir:: Type ,
278+ ) -> VmResult < cranelift_codegen:: ir:: Value > {
279+ let pointer_bytes = pointer_type. bits ( ) / 8 ;
280+ let packet_bytes = pointer_bytes
281+ . checked_mul ( ( MAX_INHERITED_ENTRY_VALUES + 7 ) as u32 )
282+ . ok_or_else ( || {
283+ VmError :: JitNative ( "native inherited-state packet is too large" . to_string ( ) )
284+ } ) ?;
285+ let packet = builder. create_sized_stack_slot ( StackSlotData :: new (
286+ StackSlotKind :: ExplicitSlot ,
287+ packet_bytes,
288+ pointer_bytes. trailing_zeros ( ) as u8 ,
289+ ) ) ;
290+ let packet_ptr = builder. ins ( ) . stack_addr ( pointer_type, packet, 0 ) ;
291+ let inactive = builder. ins ( ) . iconst ( pointer_type, 0 ) ;
292+ builder. ins ( ) . store (
293+ MemFlags :: new ( ) ,
294+ inactive,
295+ packet_ptr,
296+ INHERITED_STATE_ACTIVE_OFFSET ,
297+ ) ;
298+ builder. ins ( ) . store (
299+ MemFlags :: new ( ) ,
300+ inactive,
301+ packet_ptr,
302+ INHERITED_STATE_DYNAMIC_TARGET_OFFSET ,
303+ ) ;
304+ Ok ( packet_ptr)
305+ }
306+
307+ fn compile_system_tail_wrapper_with_abi (
308+ prefix : & str ,
309+ root_entry : * const u8 ,
310+ abi : TailCallAbi ,
311+ ) -> VmResult < CompiledTailFunction > {
228312 let root_entry = root_entry as usize ;
229313 compile_standalone_native_function (
230- "pd_vm_tail_wrapper" ,
231- entry_signature ,
314+ prefix ,
315+ move |pointer_type , call_conv| abi . system_signature ( pointer_type , call_conv ) ,
232316 move |builder, pointer_type, _| {
233317 let entry = builder. create_block ( ) ;
234318 builder. append_block_params_for_function_params ( entry) ;
235319 builder. switch_to_block ( entry) ;
236320 let vm_ptr = builder. block_params ( entry) [ 0 ] ;
321+ let args = match abi {
322+ TailCallAbi :: Plain => vec ! [ vm_ptr] ,
323+ TailCallAbi :: Inherited => {
324+ vec ! [
325+ vm_ptr,
326+ create_inherited_state_packet( builder, pointer_type) ?,
327+ ]
328+ }
329+ TailCallAbi :: Owned => vec ! [ vm_ptr, builder. block_params( entry) [ 1 ] ] ,
330+ } ;
237331 let root_entry = iconst_ptr_from_addr ( builder, pointer_type, root_entry) ?;
238- let signature = builder. import_signature ( tail_entry_signature ( pointer_type) ) ;
239- let call = builder
240- . ins ( )
241- . call_indirect ( signature, root_entry, & [ vm_ptr] ) ;
332+ let signature = builder. import_signature ( abi. tail_signature ( pointer_type) ) ;
333+ let call = builder. ins ( ) . call_indirect ( signature, root_entry, & args) ;
242334 let status = builder. inst_results ( call) [ 0 ] ;
243335 builder. ins ( ) . return_ ( & [ status] ) ;
244336 Ok ( ( ) )
245337 } ,
246338 )
247339}
248340
341+ pub ( crate ) fn compile_system_tail_wrapper ( root_entry : * const u8 ) -> VmResult < CompiledTailFunction > {
342+ compile_system_tail_wrapper_with_abi ( "pd_vm_tail_wrapper" , root_entry, TailCallAbi :: Plain )
343+ }
344+
249345pub ( crate ) fn compile_system_inherited_tail_wrapper (
250346 root_entry : * const u8 ,
251347) -> VmResult < CompiledTailFunction > {
252- let root_entry = root_entry as usize ;
253- compile_standalone_native_function (
348+ compile_system_tail_wrapper_with_abi (
254349 "pd_vm_inherited_tail_wrapper" ,
255- entry_signature,
256- move |builder, pointer_type, _| {
257- let entry = builder. create_block ( ) ;
258- builder. append_block_params_for_function_params ( entry) ;
259- builder. switch_to_block ( entry) ;
260- let vm_ptr = builder. block_params ( entry) [ 0 ] ;
261- let pointer_bytes = pointer_type. bits ( ) / 8 ;
262- let packet_bytes = pointer_bytes
263- . checked_mul ( ( MAX_INHERITED_ENTRY_VALUES + 7 ) as u32 )
264- . ok_or_else ( || {
265- VmError :: JitNative ( "native inherited-state packet is too large" . to_string ( ) )
266- } ) ?;
267- let packet = builder. create_sized_stack_slot ( StackSlotData :: new (
268- StackSlotKind :: ExplicitSlot ,
269- packet_bytes,
270- pointer_bytes. trailing_zeros ( ) as u8 ,
271- ) ) ;
272- let packet_ptr = builder. ins ( ) . stack_addr ( pointer_type, packet, 0 ) ;
273- let inactive = builder. ins ( ) . iconst ( pointer_type, 0 ) ;
274- builder. ins ( ) . store (
275- MemFlags :: new ( ) ,
276- inactive,
277- packet_ptr,
278- INHERITED_STATE_ACTIVE_OFFSET ,
279- ) ;
280- builder. ins ( ) . store (
281- MemFlags :: new ( ) ,
282- inactive,
283- packet_ptr,
284- INHERITED_STATE_DYNAMIC_TARGET_OFFSET ,
285- ) ;
286- let root_entry = iconst_ptr_from_addr ( builder, pointer_type, root_entry) ?;
287- let signature = builder. import_signature ( inherited_tail_entry_signature ( pointer_type) ) ;
288- let call = builder
289- . ins ( )
290- . call_indirect ( signature, root_entry, & [ vm_ptr, packet_ptr] ) ;
291- let status = builder. inst_results ( call) [ 0 ] ;
292- builder. ins ( ) . return_ ( & [ status] ) ;
293- Ok ( ( ) )
294- } ,
350+ root_entry,
351+ TailCallAbi :: Inherited ,
295352 )
296353}
297354
@@ -455,35 +512,11 @@ pub(crate) fn compile_tail_owned_side_link_body(
455512 slot_address : usize ,
456513 deopt_status : i32 ,
457514) -> VmResult < CompiledTailFunction > {
458- compile_standalone_native_function (
515+ compile_tail_side_link_body_with_abi (
459516 "pd_vm_tail_owned_side_link" ,
460- |pointer_type, _| tail_owned_entry_signature ( pointer_type) ,
461- move |builder, pointer_type, _| {
462- let entry = builder. create_block ( ) ;
463- let deopt = builder. create_block ( ) ;
464- let linked = builder. create_block ( ) ;
465- builder. append_block_params_for_function_params ( entry) ;
466- builder. switch_to_block ( entry) ;
467- let vm_ptr = builder. block_params ( entry) [ 0 ] ;
468- let owned_slot = builder. block_params ( entry) [ 1 ] ;
469- let slot_address = iconst_ptr_from_addr ( builder, pointer_type, slot_address) ?;
470- let target = builder
471- . ins ( )
472- . atomic_load ( pointer_type, MemFlags :: new ( ) , slot_address) ;
473- let is_null = builder. ins ( ) . icmp_imm ( IntCC :: Equal , target, 0 ) ;
474- builder. ins ( ) . brif ( is_null, deopt, & [ ] , linked, & [ ] ) ;
475-
476- builder. switch_to_block ( deopt) ;
477- let status = builder. ins ( ) . iconst ( types:: I32 , i64:: from ( deopt_status) ) ;
478- builder. ins ( ) . return_ ( & [ status] ) ;
479-
480- builder. switch_to_block ( linked) ;
481- let signature = builder. import_signature ( tail_owned_entry_signature ( pointer_type) ) ;
482- builder
483- . ins ( )
484- . return_call_indirect ( signature, target, & [ vm_ptr, owned_slot] ) ;
485- Ok ( ( ) )
486- } ,
517+ slot_address,
518+ deopt_status,
519+ TailCallAbi :: Owned ,
487520 )
488521}
489522
@@ -530,26 +563,7 @@ pub(crate) fn compile_tail_owned_clear_body(success_status: i32) -> VmResult<Com
530563pub ( crate ) fn compile_system_owned_tail_wrapper (
531564 root_entry : * const u8 ,
532565) -> VmResult < CompiledTailFunction > {
533- let root_entry = root_entry as usize ;
534- compile_standalone_native_function (
535- "pd_vm_tail_owned_wrapper" ,
536- system_owned_entry_signature,
537- move |builder, pointer_type, _| {
538- let entry = builder. create_block ( ) ;
539- builder. append_block_params_for_function_params ( entry) ;
540- builder. switch_to_block ( entry) ;
541- let vm_ptr = builder. block_params ( entry) [ 0 ] ;
542- let owned_slot = builder. block_params ( entry) [ 1 ] ;
543- let root_entry = iconst_ptr_from_addr ( builder, pointer_type, root_entry) ?;
544- let signature = builder. import_signature ( tail_owned_entry_signature ( pointer_type) ) ;
545- let call = builder
546- . ins ( )
547- . call_indirect ( signature, root_entry, & [ vm_ptr, owned_slot] ) ;
548- let status = builder. inst_results ( call) [ 0 ] ;
549- builder. ins ( ) . return_ ( & [ status] ) ;
550- Ok ( ( ) )
551- } ,
552- )
566+ compile_system_tail_wrapper_with_abi ( "pd_vm_tail_owned_wrapper" , root_entry, TailCallAbi :: Owned )
553567}
554568
555569fn try_compile_ssa_trace (
0 commit comments