@@ -222,6 +222,122 @@ pub(crate) fn compile_system_tail_wrapper(root_entry: *const u8) -> VmResult<Com
222222 )
223223}
224224
225+ fn tail_owned_entry_signature ( pointer_type : cranelift_codegen:: ir:: Type ) -> Signature {
226+ let mut signature = tail_entry_signature ( pointer_type) ;
227+ signature. params . push ( AbiParam :: new ( pointer_type) ) ;
228+ signature
229+ }
230+
231+ fn system_owned_entry_signature (
232+ pointer_type : cranelift_codegen:: ir:: Type ,
233+ call_conv : CallConv ,
234+ ) -> Signature {
235+ let mut signature = entry_signature ( pointer_type, call_conv) ;
236+ signature. params . push ( AbiParam :: new ( pointer_type) ) ;
237+ signature
238+ }
239+
240+ pub ( crate ) fn compile_tail_owned_side_link_body (
241+ slot_address : usize ,
242+ deopt_status : i32 ,
243+ ) -> VmResult < CompiledTailFunction > {
244+ compile_standalone_native_function (
245+ "pd_vm_tail_owned_side_link" ,
246+ |pointer_type, _| tail_owned_entry_signature ( pointer_type) ,
247+ move |builder, pointer_type, _| {
248+ let entry = builder. create_block ( ) ;
249+ let deopt = builder. create_block ( ) ;
250+ let linked = builder. create_block ( ) ;
251+ builder. append_block_params_for_function_params ( entry) ;
252+ builder. switch_to_block ( entry) ;
253+ let vm_ptr = builder. block_params ( entry) [ 0 ] ;
254+ let owned_slot = builder. block_params ( entry) [ 1 ] ;
255+ let slot_address = iconst_ptr_from_addr ( builder, pointer_type, slot_address) ?;
256+ let target = builder
257+ . ins ( )
258+ . load ( pointer_type, MemFlags :: new ( ) , slot_address, 0 ) ;
259+ let is_null = builder. ins ( ) . icmp_imm ( IntCC :: Equal , target, 0 ) ;
260+ builder. ins ( ) . brif ( is_null, deopt, & [ ] , linked, & [ ] ) ;
261+
262+ builder. switch_to_block ( deopt) ;
263+ let status = builder. ins ( ) . iconst ( types:: I32 , i64:: from ( deopt_status) ) ;
264+ builder. ins ( ) . return_ ( & [ status] ) ;
265+
266+ builder. switch_to_block ( linked) ;
267+ let signature = builder. import_signature ( tail_owned_entry_signature ( pointer_type) ) ;
268+ builder
269+ . ins ( )
270+ . return_call_indirect ( signature, target, & [ vm_ptr, owned_slot] ) ;
271+ Ok ( ( ) )
272+ } ,
273+ )
274+ }
275+
276+ pub ( crate ) fn compile_tail_owned_clear_body ( success_status : i32 ) -> VmResult < CompiledTailFunction > {
277+ compile_standalone_native_function (
278+ "pd_vm_tail_owned_clear" ,
279+ |pointer_type, _| tail_owned_entry_signature ( pointer_type) ,
280+ move |builder, pointer_type, call_conv| {
281+ let entry = builder. create_block ( ) ;
282+ let success = builder. create_block ( ) ;
283+ let failure = builder. create_block ( ) ;
284+ builder. append_block_params_for_function_params ( entry) ;
285+ builder. append_block_param ( failure, types:: I32 ) ;
286+ builder. switch_to_block ( entry) ;
287+ let owned_slot = builder. block_params ( entry) [ 1 ] ;
288+ let helper =
289+ iconst_ptr_from_addr ( builder, pointer_type, clear_value_slot_entry_address ( ) ) ?;
290+ let helper_signature =
291+ builder. import_signature ( value_slot_signature ( pointer_type, call_conv) ) ;
292+ let call = builder
293+ . ins ( )
294+ . call_indirect ( helper_signature, helper, & [ owned_slot] ) ;
295+ let helper_status = builder. inst_results ( call) [ 0 ] ;
296+ let succeeded =
297+ builder
298+ . ins ( )
299+ . icmp_imm ( IntCC :: Equal , helper_status, i64:: from ( STATUS_CONTINUE ) ) ;
300+ builder
301+ . ins ( )
302+ . brif ( succeeded, success, & [ ] , failure, & [ helper_status. into ( ) ] ) ;
303+
304+ builder. switch_to_block ( success) ;
305+ let status = builder. ins ( ) . iconst ( types:: I32 , i64:: from ( success_status) ) ;
306+ builder. ins ( ) . return_ ( & [ status] ) ;
307+
308+ builder. switch_to_block ( failure) ;
309+ let status = builder. block_params ( failure) [ 0 ] ;
310+ builder. ins ( ) . return_ ( & [ status] ) ;
311+ Ok ( ( ) )
312+ } ,
313+ )
314+ }
315+
316+ pub ( crate ) fn compile_system_owned_tail_wrapper (
317+ root_entry : * const u8 ,
318+ ) -> VmResult < CompiledTailFunction > {
319+ let root_entry = root_entry as usize ;
320+ compile_standalone_native_function (
321+ "pd_vm_tail_owned_wrapper" ,
322+ system_owned_entry_signature,
323+ move |builder, pointer_type, _| {
324+ let entry = builder. create_block ( ) ;
325+ builder. append_block_params_for_function_params ( entry) ;
326+ builder. switch_to_block ( entry) ;
327+ let vm_ptr = builder. block_params ( entry) [ 0 ] ;
328+ let owned_slot = builder. block_params ( entry) [ 1 ] ;
329+ let root_entry = iconst_ptr_from_addr ( builder, pointer_type, root_entry) ?;
330+ let signature = builder. import_signature ( tail_owned_entry_signature ( pointer_type) ) ;
331+ let call = builder
332+ . ins ( )
333+ . call_indirect ( signature, root_entry, & [ vm_ptr, owned_slot] ) ;
334+ let status = builder. inst_results ( call) [ 0 ] ;
335+ builder. ins ( ) . return_ ( & [ status] ) ;
336+ Ok ( ( ) )
337+ } ,
338+ )
339+ }
340+
225341fn try_compile_ssa_trace (
226342 trace : & JitTrace ,
227343 ssa : & SsaTrace ,
0 commit comments