Skip to content

Commit 14300c3

Browse files
committed
Use UnsafeCell instead of read_volatile
This allows stripping accesses to unused selectors, while still loading the pointer correctly
1 parent 61213ad commit 14300c3

10 files changed

Lines changed: 135 additions & 294 deletions

File tree

objc2/src/__macro_helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use crate::rc::{Id, Ownership};
22
use crate::runtime::{Class, Sel};
33
use crate::{Message, MessageArguments, MessageError, MessageReceiver};
44

5+
pub use core::cell::UnsafeCell;
56
pub use core::compile_error;
6-
pub use core::ptr::read_volatile;
77
#[cfg(feature = "unstable-static-sel")]
88
pub use objc2_proc_macros::__hash_idents;
99

objc2/src/macros.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,24 @@ macro_rules! __sel_inner_statics_apple_generic {
188188

189189
/// Place the constant value in the correct section.
190190
///
191+
/// We use `UnsafeCell` because this somewhat resembles internal
192+
/// mutation - this pointer will be changed by dyld at startup, so we
193+
/// _must_ prevent Rust/LLVM from trying to "peek inside" it and just
194+
/// use a pointer to `NAME_DATA` directly.
195+
///
196+
/// Clang does this by marking `REF` with LLVM's
197+
/// `externally_initialized`.
198+
///
199+
/// `static mut` is used so that we don't need to wrap the
200+
/// `UnsafeCell` in something that implements `Sync`.
201+
///
191202
/// Clang uses `no_dead_strip` in the link section for some reason,
192-
/// which other tools now assume is present (so we have to add it as
193-
/// well). Doesn't really matter, since the selector access can't be
194-
/// optimized away anyhow (it uses read_volatile).
203+
/// which other tools (notably some LLVM tools) now assume is present,
204+
/// so we have to add it as well.
195205
#[link_section = $selector_ref_section]
196206
#[export_name = concat!("\x01L_OBJC_SELECTOR_REFERENCES_", $crate::__macro_helpers::__hash_idents!($($idents)+))]
197-
static mut REF: $crate::runtime::Sel = unsafe {
198-
$crate::runtime::Sel::from_ptr(NAME_DATA.as_ptr().cast())
207+
static mut REF: $crate::__macro_helpers::UnsafeCell<$crate::runtime::Sel> = unsafe {
208+
$crate::__macro_helpers::UnsafeCell::new($crate::runtime::Sel::from_ptr(NAME_DATA.as_ptr().cast()))
199209
};
200210
};
201211
}
@@ -261,13 +271,11 @@ macro_rules! __sel_inner {
261271
#[inline(never)]
262272
fn objc_static_workaround() -> $crate::runtime::Sel {
263273
// SAFETY: The actual selector is replaced by dyld when the
264-
// program is loaded, so we need to use a volatile read to prevent
265-
// the optimizer from thinking it can circumvent the read through
266-
// REF.
274+
// program is loaded.
267275
//
268-
// Clang avoids this by marking `REF` with LLVM's
269-
// `externally_initialized`.
270-
unsafe { $crate::__macro_helpers::read_volatile(&REF) }
276+
// This is similar to a volatile read, except it can be stripped
277+
// if unused.
278+
unsafe { *REF.get() }
271279
}
272280

273281
objc_static_workaround()
@@ -283,7 +291,7 @@ macro_rules! __sel_inner {
283291

284292
#[allow(unused_unsafe)]
285293
// SAFETY: See above
286-
unsafe { $crate::__macro_helpers::read_volatile(&REF) }
294+
unsafe { *REF.get() }
287295
}};
288296
}
289297

tests/assembly/test_msg_send_static_sel/expected/apple-armv7.s

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ LPC0_0:
1616
_handle_alloc_init:
1717
push {r4, r7, lr}
1818
add r7, sp, #4
19-
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
20-
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
19+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
20+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
2121
LPC1_0:
22-
ldr r4, [pc, r4]
23-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
24-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
25-
LPC1_1:
2622
ldr r1, [pc, r1]
23+
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
24+
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
25+
LPC1_1:
26+
ldr r4, [pc, r4]
2727
bl _objc_msgSend
2828
mov r1, r4
2929
pop {r4, r7, lr}
@@ -35,35 +35,35 @@ LPC1_1:
3535
_use_generic:
3636
push {r4, r7, lr}
3737
add r7, sp, #4
38-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
38+
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
3939
mov r4, r0
40-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
40+
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
4141
LPC2_0:
42-
ldr r1, [pc, r1]
43-
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
44-
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
45-
LPC2_1:
4642
ldr r2, [pc, r2]
43+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
44+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
45+
LPC2_1:
46+
ldr r1, [pc, r1]
4747
bl _objc_msgSend
48-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
48+
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
4949
mov r0, r4
50-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
50+
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
5151
LPC2_2:
52-
ldr r1, [pc, r1]
53-
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
54-
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
55-
LPC2_3:
5652
ldr r2, [pc, r2]
53+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
54+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
55+
LPC2_3:
56+
ldr r1, [pc, r1]
5757
bl _objc_msgSend
58-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
58+
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
5959
mov r0, r4
60-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
60+
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
6161
LPC2_4:
62-
ldr r1, [pc, r1]
63-
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
64-
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
65-
LPC2_5:
6662
ldr r2, [pc, r2]
63+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
64+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
65+
LPC2_5:
66+
ldr r1, [pc, r1]
6767
pop {r4, r7, lr}
6868
b _objc_msgSend
6969

tests/assembly/test_msg_send_static_sel/expected/apple-armv7s.s

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ LPC0_0:
1919
_handle_alloc_init:
2020
push {r4, r7, lr}
2121
add r7, sp, #4
22-
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
23-
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
22+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
23+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
2424
LPC1_0:
25-
ldr r4, [pc, r4]
26-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
27-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
28-
LPC1_1:
2925
ldr r1, [pc, r1]
26+
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
27+
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
28+
LPC1_1:
29+
ldr r4, [pc, r4]
3030
bl _objc_msgSend
3131
mov r1, r4
3232
bl _objc_msgSend
@@ -38,35 +38,35 @@ LPC1_1:
3838
_use_generic:
3939
push {r4, r7, lr}
4040
add r7, sp, #4
41-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
41+
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
4242
mov r4, r0
43-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
43+
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
4444
LPC2_0:
45-
ldr r1, [pc, r1]
46-
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
47-
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
48-
LPC2_1:
4945
ldr r2, [pc, r2]
46+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
47+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
48+
LPC2_1:
49+
ldr r1, [pc, r1]
5050
bl _objc_msgSend
51-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
51+
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
5252
mov r0, r4
53-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
53+
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
5454
LPC2_2:
55-
ldr r1, [pc, r1]
56-
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
57-
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
58-
LPC2_3:
5955
ldr r2, [pc, r2]
56+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
57+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
58+
LPC2_3:
59+
ldr r1, [pc, r1]
6060
bl _objc_msgSend
61-
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
61+
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
6262
mov r0, r4
63-
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
63+
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
6464
LPC2_4:
65-
ldr r1, [pc, r1]
66-
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
67-
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
68-
LPC2_5:
6965
ldr r2, [pc, r2]
66+
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
67+
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
68+
LPC2_5:
69+
ldr r1, [pc, r1]
7070
bl _objc_msgSend
7171
pop {r4, r7, pc}
7272

tests/assembly/test_static_sel/expected/apple-aarch64.s

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ _get_different_sel:
3232
.globl _unused_sel
3333
.p2align 2
3434
_unused_sel:
35-
b __RNvNvCsai54Y9dtG4h_15test_static_sel10unused_sel22objc_static_workaround
35+
ret
3636

3737
.globl _use_fns
3838
.p2align 2
@@ -64,28 +64,14 @@ _use_same_twice:
6464
add x29, sp, #16
6565
mov x19, x8
6666
bl __RNvNvCsai54Y9dtG4h_15test_static_sel7get_sel22objc_static_workaround
67-
mov x20, x0
68-
bl __RNvNvCsai54Y9dtG4h_15test_static_sel7get_sel22objc_static_workaround
69-
stp x20, x0, [x19]
67+
stp x0, x0, [x19]
7068
ldp x29, x30, [sp, #16]
7169
ldp x20, x19, [sp], #32
7270
ret
7371

7472
.globl _use_in_loop
7573
.p2align 2
7674
_use_in_loop:
77-
stp x20, x19, [sp, #-32]!
78-
stp x29, x30, [sp, #16]
79-
add x29, sp, #16
80-
cbz x0, LBB7_3
81-
mov x19, x0
82-
LBB7_2:
83-
bl __RNvNvCsai54Y9dtG4h_15test_static_sel11use_in_loop22objc_static_workaround
84-
subs x19, x19, #1
85-
b.ne LBB7_2
86-
LBB7_3:
87-
ldp x29, x30, [sp, #16]
88-
ldp x20, x19, [sp], #32
8975
ret
9076

9177
.p2align 2
@@ -133,32 +119,14 @@ Lloh9:
133119
ret
134120
.loh AdrpLdr Lloh8, Lloh9
135121

136-
.p2align 2
137-
__RNvNvCsai54Y9dtG4h_15test_static_sel10unused_sel22objc_static_workaround:
138-
Lloh10:
139-
adrp x8, L_OBJC_SELECTOR_REFERENCES_2c505e110d181b25@PAGE
140-
Lloh11:
141-
ldr xzr, [x8, L_OBJC_SELECTOR_REFERENCES_2c505e110d181b25@PAGEOFF]
142-
ret
143-
.loh AdrpLdr Lloh10, Lloh11
144-
145122
.p2align 2
146123
__RNvNvCsai54Y9dtG4h_15test_static_sel7use_fns22objc_static_workaround:
147-
Lloh12:
124+
Lloh10:
148125
adrp x8, L_OBJC_SELECTOR_REFERENCES_5419c3f7fc0a6f99@PAGE
149-
Lloh13:
126+
Lloh11:
150127
ldr x0, [x8, L_OBJC_SELECTOR_REFERENCES_5419c3f7fc0a6f99@PAGEOFF]
151128
ret
152-
.loh AdrpLdr Lloh12, Lloh13
153-
154-
.p2align 2
155-
__RNvNvCsai54Y9dtG4h_15test_static_sel11use_in_loop22objc_static_workaround:
156-
Lloh14:
157-
adrp x8, L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b@PAGE
158-
Lloh15:
159-
ldr xzr, [x8, L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b@PAGEOFF]
160-
ret
161-
.loh AdrpLdr Lloh14, Lloh15
129+
.loh AdrpLdr Lloh10, Lloh11
162130

163131
.section __DATA,__objc_imageinfo,regular,no_dead_strip
164132
.globl L_OBJC_IMAGE_INFO_68381ba894e318e9
@@ -280,20 +248,20 @@ L_OBJC_SELECTOR_REFERENCES_5419c3f7fc0a6f99:
280248
.quad L_OBJC_METH_VAR_NAME_5419c3f7fc0a6f99
281249

282250
.section __DATA,__objc_imageinfo,regular,no_dead_strip
283-
.globl L_OBJC_IMAGE_INFO_9845965b987ed54b
251+
.globl L_OBJC_IMAGE_INFO_f46908e864c86c6b
284252
.p2align 2
285-
L_OBJC_IMAGE_INFO_9845965b987ed54b:
253+
L_OBJC_IMAGE_INFO_f46908e864c86c6b:
286254
.asciz "\000\000\000\000@\000\000"
287255

288256
.section __TEXT,__objc_methname,cstring_literals
289-
.globl L_OBJC_METH_VAR_NAME_9845965b987ed54b
290-
L_OBJC_METH_VAR_NAME_9845965b987ed54b:
257+
.globl L_OBJC_METH_VAR_NAME_f46908e864c86c6b
258+
L_OBJC_METH_VAR_NAME_f46908e864c86c6b:
291259
.asciz "loopedSelector"
292260

293261
.section __DATA,__objc_selrefs,literal_pointers,no_dead_strip
294-
.globl L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b
262+
.globl L_OBJC_SELECTOR_REFERENCES_f46908e864c86c6b
295263
.p2align 3
296-
L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b:
297-
.quad L_OBJC_METH_VAR_NAME_9845965b987ed54b
264+
L_OBJC_SELECTOR_REFERENCES_f46908e864c86c6b:
265+
.quad L_OBJC_METH_VAR_NAME_f46908e864c86c6b
298266

299267
.subsections_via_symbols

0 commit comments

Comments
 (0)