Skip to content

Commit 5ea2a94

Browse files
committed
Prevent tail-call optimizations from interfering with fast autorelease
1 parent e8fa4d2 commit 5ea2a94

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

objc2/src/rc/id.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,29 @@ impl<T: Message, O: Ownership> Id<T, O> {
338338
// SAFETY: Same as `retain`, `objc_retainAutoreleasedReturnValue` is
339339
// just an optimization.
340340
let res = unsafe { ffi::objc_retainAutoreleasedReturnValue(ptr) };
341+
342+
// Ideally, we'd be able to specify that the above call should never
343+
// be tail-call optimized (become a `jmp` instruction instead of a
344+
// `call`); Rust doesn't really have a way of doing this currently, so
345+
// we just emit a simple `nop` to make such tail-call optimizations
346+
// less likely to occur.
347+
//
348+
// This is brittle! We should find a better solution!
349+
#[cfg(all(apple, not(target_os = "windows"), target_arch = "x86_64"))]
350+
{
351+
// SAFETY: Similar to above.
352+
unsafe { core::arch::asm!("nop", options(nomem, preserves_flags, nostack)) };
353+
// TODO: Possibly more efficient alternative?
354+
// #![feature(asm_sym)]
355+
// core::arch::asm!(
356+
// "mov rdi, rax",
357+
// "call {}",
358+
// sym objc2::ffi::objc_retainAutoreleasedReturnValue,
359+
// inout("rax") obj,
360+
// clobber_abi("C"),
361+
// );
362+
}
363+
341364
debug_assert_eq!(
342365
res, ptr,
343366
"objc_retainAutoreleasedReturnValue did not return the same pointer"

tests/assembly/test_retain_autoreleased/expected/x86_64-apple-darwin.s

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ _handle:
77
mov rbp, rsp
88
call _objc_msgSend
99
mov rdi, rax
10+
call _objc_retainAutoreleasedReturnValue
11+
## InlineAsm Start
12+
13+
nop
14+
15+
## InlineAsm End
1016
pop rbp
11-
jmp _objc_retainAutoreleasedReturnValue
17+
ret
1218

1319
.subsections_via_symbols

tests/assembly/test_retain_autoreleased/expected/x86_64-apple-ios.s

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ _handle:
77
mov rbp, rsp
88
call _objc_msgSend
99
mov rdi, rax
10+
call _objc_retainAutoreleasedReturnValue
11+
## InlineAsm Start
12+
13+
nop
14+
15+
## InlineAsm End
1016
pop rbp
11-
jmp _objc_retainAutoreleasedReturnValue
17+
ret
1218

1319
.subsections_via_symbols

0 commit comments

Comments
 (0)