Skip to content

Commit 8c23de1

Browse files
committed
Add fast path for using objc_alloc
1 parent 375d21b commit 8c23de1

File tree

11 files changed

+68
-62
lines changed

11 files changed

+68
-62
lines changed

crates/objc2/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1616
* Added new `encode` traits `EncodeReturn`, `EncodeArgument` and
1717
`EncodeArguments`.
1818
* Added methods `as_ptr` and `as_mut_ptr` to `Allocated`.
19+
* Added optimization for converting `msg_send_id![cls, alloc]` to a call to
20+
the faster runtime function `objc_alloc`.
1921

2022
### Changed
2123
* **BREAKING**: `AnyClass::verify_sel` now take more well-defined types

crates/objc2/src/__macro_helpers/msg_send_id.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<T: MsgSend, U: ?Sized + Message> MsgSendId<T, Option<Id<U>>> for New {
8585
}
8686
}
8787

88-
impl<T: ?Sized + Message> MsgSendId<&'_ AnyClass, Allocated<T>> for Alloc {
88+
impl<T: Message> MsgSendId<&'_ AnyClass, Allocated<T>> for Alloc {
8989
#[inline]
9090
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Allocated<T>>>(
9191
cls: &AnyClass,
@@ -100,6 +100,29 @@ impl<T: ?Sized + Message> MsgSendId<&'_ AnyClass, Allocated<T>> for Alloc {
100100
}
101101
}
102102

103+
impl Alloc {
104+
/// Fast path optimization for `msg_send_id![cls, alloc]`.
105+
#[inline]
106+
pub unsafe fn send_message_id_alloc<T: Message, R: MaybeUnwrap<Input = Allocated<T>>>(
107+
cls: &AnyClass,
108+
) -> R {
109+
// Available on non-fragile Apple runtimes.
110+
#[cfg(all(feature = "apple", not(all(target_os = "macos", target_arch = "x86"))))]
111+
{
112+
// SAFETY: Checked by caller
113+
let obj: *mut T = unsafe { crate::ffi::objc_alloc(cls.as_ptr()).cast() };
114+
// SAFETY: The object is newly allocated, so this has +1 retain count
115+
let obj = unsafe { Allocated::new(obj) };
116+
R::maybe_unwrap::<Alloc>(obj, ())
117+
}
118+
#[cfg(not(all(feature = "apple", not(all(target_os = "macos", target_arch = "x86")))))]
119+
{
120+
// SAFETY: Checked by caller
121+
unsafe { Alloc::send_message_id(cls, sel!(alloc), ()) }
122+
}
123+
}
124+
}
125+
103126
impl<T: ?Sized + Message> MsgSendId<Allocated<T>, Option<Id<T>>> for Init {
104127
#[inline]
105128
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Option<Id<T>>>>(

crates/objc2/src/macros/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,9 +1194,8 @@ macro_rules! msg_send_id {
11941194
result
11951195
});
11961196
[$obj:expr, alloc $(,)?] => ({
1197-
let sel = $crate::sel!(alloc);
11981197
let result;
1199-
result = <$crate::__macro_helpers::Alloc as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ());
1198+
result = $crate::__macro_helpers::Alloc::send_message_id_alloc($obj);
12001199
result
12011200
});
12021201
[$obj:expr, init $(,)?] => ({

crates/objc2/src/top_level_traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ pub unsafe trait ClassType: Message {
289289
#[inline]
290290
fn alloc() -> Allocated<Self>
291291
where
292-
Self: IsAllocableAnyThread,
292+
Self: IsAllocableAnyThread + Sized,
293293
{
294294
// SAFETY:
295295
// - It is always safe to (attempt to) allocate an object.

crates/test-assembly/crates/test_msg_send_static_sel/expected/apple-aarch64.s

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@ Lloh3:
2121
ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_init@GOTPAGEOFF]
2222
Lloh4:
2323
ldr x19, [x8]
24-
Lloh5:
25-
adrp x8, L_OBJC_SELECTOR_REFERENCES_alloc@GOTPAGE
26-
Lloh6:
27-
ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_alloc@GOTPAGEOFF]
28-
Lloh7:
29-
ldr x1, [x8]
30-
bl _objc_msgSend
24+
bl _objc_alloc
3125
mov x20, x0
3226
mov x1, x19
3327
bl _objc_msgSend
@@ -36,16 +30,15 @@ Lloh7:
3630
ldp x20, x19, [sp], #32
3731
ret
3832
LBB1_2:
39-
Lloh8:
33+
Lloh5:
4034
adrp x2, l_anon.[ID].1@PAGE
41-
Lloh9:
35+
Lloh6:
4236
add x2, x2, l_anon.[ID].1@PAGEOFF
4337
mov x0, x20
4438
mov x1, x19
4539
bl SYM(<objc2::__macro_helpers::method_family::RetainSemantics<3_u8> as objc2::__macro_helpers::msg_send_id::MsgSendIdFailed>::failed::GENERATED_ID, 0)
46-
.loh AdrpLdrGotLdr Lloh5, Lloh6, Lloh7
4740
.loh AdrpLdrGotLdr Lloh2, Lloh3, Lloh4
48-
.loh AdrpAdd Lloh8, Lloh9
41+
.loh AdrpAdd Lloh5, Lloh6
4942

5043
.globl _use_generic
5144
.p2align 2
@@ -54,32 +47,32 @@ _use_generic:
5447
stp x29, x30, [sp, #16]
5548
add x29, sp, #16
5649
mov x19, x0
57-
Lloh10:
50+
Lloh7:
5851
adrp x8, L_OBJC_SELECTOR_REFERENCES_1f1c7bd8029c3138@PAGE
59-
Lloh11:
52+
Lloh8:
6053
ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_1f1c7bd8029c3138@PAGEOFF]
6154
adrp x20, L_OBJC_SELECTOR_REFERENCES_5ace898e385eba05@PAGE
6255
ldr x2, [x20, L_OBJC_SELECTOR_REFERENCES_5ace898e385eba05@PAGEOFF]
6356
bl _objc_msgSend
64-
Lloh12:
57+
Lloh9:
6558
adrp x8, L_OBJC_SELECTOR_REFERENCES_eb5b4d2de37744da@PAGE
66-
Lloh13:
59+
Lloh10:
6760
ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_eb5b4d2de37744da@PAGEOFF]
6861
ldr x2, [x20, L_OBJC_SELECTOR_REFERENCES_5ace898e385eba05@PAGEOFF]
6962
mov x0, x19
7063
bl _objc_msgSend
71-
Lloh14:
64+
Lloh11:
7265
adrp x8, L_OBJC_SELECTOR_REFERENCES_c76827c00227cd8a@PAGE
73-
Lloh15:
66+
Lloh12:
7467
ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_c76827c00227cd8a@PAGEOFF]
7568
ldr x2, [x20, L_OBJC_SELECTOR_REFERENCES_5ace898e385eba05@PAGEOFF]
7669
mov x0, x19
7770
ldp x29, x30, [sp, #16]
7871
ldp x20, x19, [sp], #32
7972
b _objc_msgSend
80-
.loh AdrpLdr Lloh14, Lloh15
81-
.loh AdrpLdr Lloh12, Lloh13
82-
.loh AdrpLdr Lloh10, Lloh11
73+
.loh AdrpLdr Lloh11, Lloh12
74+
.loh AdrpLdr Lloh9, Lloh10
75+
.loh AdrpLdr Lloh7, Lloh8
8376

8477
.section __TEXT,__const
8578
l_anon.[ID].0:

crates/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7s.s

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,17 @@ _handle_alloc_init:
2020
movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC1_0+8))
2121
LPC1_0:
2222
ldr r1, [pc, r1]
23-
movw r2, :lower16:(LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-(LPC1_1+8))
24-
movt r2, :upper16:(LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-(LPC1_1+8))
25-
LPC1_1:
26-
ldr r2, [pc, r2]
2723
ldr r4, [r1]
28-
ldr r1, [r2]
29-
bl _objc_msgSend
24+
bl _objc_alloc
3025
mov r5, r0
3126
mov r1, r4
3227
bl _objc_msgSend
3328
cmp r0, #0
3429
popne {r4, r5, r7, pc}
3530
LBB1_1:
36-
movw r2, :lower16:(l_anon.[ID].1-(LPC1_2+8))
37-
movt r2, :upper16:(l_anon.[ID].1-(LPC1_2+8))
38-
LPC1_2:
31+
movw r2, :lower16:(l_anon.[ID].1-(LPC1_1+8))
32+
movt r2, :upper16:(l_anon.[ID].1-(LPC1_1+8))
33+
LPC1_1:
3934
add r2, pc, r2
4035
mov r0, r5
4136
mov r1, r4
@@ -177,9 +172,6 @@ L_OBJC_IMAGE_INFO_c76827c00227cd8a:
177172

178173
.section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
179174
.p2align 2, 0x0
180-
LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr:
181-
.indirect_symbol L_OBJC_SELECTOR_REFERENCES_alloc
182-
.long 0
183175
LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr:
184176
.indirect_symbol L_OBJC_SELECTOR_REFERENCES_init
185177
.long 0

crates/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86.s

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,9 @@ L1$pb:
3131
pop ebx
3232
mov eax, dword ptr [ebx + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L1$pb]
3333
mov edi, dword ptr [eax]
34-
mov eax, dword ptr [ebx + LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-L1$pb]
35-
sub esp, 8
36-
push dword ptr [eax]
34+
sub esp, 12
3735
push dword ptr [ebp + 8]
38-
call _objc_msgSend
36+
call _objc_alloc
3937
add esp, 16
4038
mov esi, eax
4139
sub esp, 8
@@ -187,9 +185,6 @@ L_OBJC_IMAGE_INFO_c76827c00227cd8a:
187185
.asciz "\000\000\000\000@\000\000"
188186

189187
.section __IMPORT,__pointers,non_lazy_symbol_pointers
190-
LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr:
191-
.indirect_symbol L_OBJC_SELECTOR_REFERENCES_alloc
192-
.long 0
193188
LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr:
194189
.indirect_symbol L_OBJC_SELECTOR_REFERENCES_init
195190
.long 0

crates/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86_64.s

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ _handle_alloc_init:
1818
push rbx
1919
mov rax, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_init@GOTPCREL]
2020
mov rbx, qword ptr [rax]
21-
mov rax, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_alloc@GOTPCREL]
22-
mov rsi, qword ptr [rax]
23-
call _objc_msgSend
21+
call _objc_alloc
2422
mov r14, rax
2523
mov rdi, rax
2624
mov rsi, rbx

crates/test-ui/ui/main_thread_only_not_allocable.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ note: required by a bound in `objc2::ClassType::alloc`
1818
| fn alloc() -> Allocated<Self>
1919
| ----- required by a bound in this associated function
2020
| where
21-
| Self: IsAllocableAnyThread,
21+
| Self: IsAllocableAnyThread + Sized,
2222
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `ClassType::alloc`

crates/test-ui/ui/msg_send_id_invalid_receiver.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ error[E0308]: mismatched types
1212
note: associated function defined here
1313
--> $WORKSPACE/crates/objc2/src/__macro_helpers/msg_send_id.rs
1414
|
15-
| unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = U>>(
16-
| ^^^^^^^^^^^^^^^
15+
| pub unsafe fn send_message_id_alloc<T: Message, R: MaybeUnwrap<Input = Allocated<T>>>(
16+
| ^^^^^^^^^^^^^^^^^^^^^
1717

1818
error[E0308]: mismatched types
1919
--> ui/msg_send_id_invalid_receiver.rs

0 commit comments

Comments
 (0)