Skip to content

Commit

Permalink
Use UnsafeCell instead of read_volatile
Browse files Browse the repository at this point in the history
This allows stripping accesses to unused selectors, while still loading the pointer correctly
  • Loading branch information
madsmtm committed Jun 21, 2022
1 parent 61213ad commit 14300c3
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 294 deletions.
2 changes: 1 addition & 1 deletion objc2/src/__macro_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::rc::{Id, Ownership};
use crate::runtime::{Class, Sel};
use crate::{Message, MessageArguments, MessageError, MessageReceiver};

pub use core::cell::UnsafeCell;
pub use core::compile_error;
pub use core::ptr::read_volatile;
#[cfg(feature = "unstable-static-sel")]
pub use objc2_proc_macros::__hash_idents;

Expand Down
32 changes: 20 additions & 12 deletions objc2/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,24 @@ macro_rules! __sel_inner_statics_apple_generic {

/// Place the constant value in the correct section.
///
/// We use `UnsafeCell` because this somewhat resembles internal
/// mutation - this pointer will be changed by dyld at startup, so we
/// _must_ prevent Rust/LLVM from trying to "peek inside" it and just
/// use a pointer to `NAME_DATA` directly.
///
/// Clang does this by marking `REF` with LLVM's
/// `externally_initialized`.
///
/// `static mut` is used so that we don't need to wrap the
/// `UnsafeCell` in something that implements `Sync`.
///
/// Clang uses `no_dead_strip` in the link section for some reason,
/// which other tools now assume is present (so we have to add it as
/// well). Doesn't really matter, since the selector access can't be
/// optimized away anyhow (it uses read_volatile).
/// which other tools (notably some LLVM tools) now assume is present,
/// so we have to add it as well.
#[link_section = $selector_ref_section]
#[export_name = concat!("\x01L_OBJC_SELECTOR_REFERENCES_", $crate::__macro_helpers::__hash_idents!($($idents)+))]
static mut REF: $crate::runtime::Sel = unsafe {
$crate::runtime::Sel::from_ptr(NAME_DATA.as_ptr().cast())
static mut REF: $crate::__macro_helpers::UnsafeCell<$crate::runtime::Sel> = unsafe {
$crate::__macro_helpers::UnsafeCell::new($crate::runtime::Sel::from_ptr(NAME_DATA.as_ptr().cast()))
};
};
}
Expand Down Expand Up @@ -261,13 +271,11 @@ macro_rules! __sel_inner {
#[inline(never)]
fn objc_static_workaround() -> $crate::runtime::Sel {
// SAFETY: The actual selector is replaced by dyld when the
// program is loaded, so we need to use a volatile read to prevent
// the optimizer from thinking it can circumvent the read through
// REF.
// program is loaded.
//
// Clang avoids this by marking `REF` with LLVM's
// `externally_initialized`.
unsafe { $crate::__macro_helpers::read_volatile(&REF) }
// This is similar to a volatile read, except it can be stripped
// if unused.
unsafe { *REF.get() }
}

objc_static_workaround()
Expand All @@ -283,7 +291,7 @@ macro_rules! __sel_inner {

#[allow(unused_unsafe)]
// SAFETY: See above
unsafe { $crate::__macro_helpers::read_volatile(&REF) }
unsafe { *REF.get() }
}};
}

Expand Down
48 changes: 24 additions & 24 deletions tests/assembly/test_msg_send_static_sel/expected/apple-armv7.s
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ LPC0_0:
_handle_alloc_init:
push {r4, r7, lr}
add r7, sp, #4
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
LPC1_0:
ldr r4, [pc, r4]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
LPC1_1:
ldr r1, [pc, r1]
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
LPC1_1:
ldr r4, [pc, r4]
bl _objc_msgSend
mov r1, r4
pop {r4, r7, lr}
Expand All @@ -35,35 +35,35 @@ LPC1_1:
_use_generic:
push {r4, r7, lr}
add r7, sp, #4
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
mov r4, r0
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
LPC2_0:
ldr r1, [pc, r1]
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
LPC2_1:
ldr r2, [pc, r2]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
LPC2_1:
ldr r1, [pc, r1]
bl _objc_msgSend
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
mov r0, r4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
LPC2_2:
ldr r1, [pc, r1]
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
LPC2_3:
ldr r2, [pc, r2]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
LPC2_3:
ldr r1, [pc, r1]
bl _objc_msgSend
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
mov r0, r4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
LPC2_4:
ldr r1, [pc, r1]
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
LPC2_5:
ldr r2, [pc, r2]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
LPC2_5:
ldr r1, [pc, r1]
pop {r4, r7, lr}
b _objc_msgSend

Expand Down
48 changes: 24 additions & 24 deletions tests/assembly/test_msg_send_static_sel/expected/apple-armv7s.s
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ LPC0_0:
_handle_alloc_init:
push {r4, r7, lr}
add r7, sp, #4
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_0+8))
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_0+8))
LPC1_0:
ldr r4, [pc, r4]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1ab35d3713395f9-(LPC1_1+8))
LPC1_1:
ldr r1, [pc, r1]
movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_904c14aa63c4eec9-(LPC1_1+8))
LPC1_1:
ldr r4, [pc, r4]
bl _objc_msgSend
mov r1, r4
bl _objc_msgSend
Expand All @@ -38,35 +38,35 @@ LPC1_1:
_use_generic:
push {r4, r7, lr}
add r7, sp, #4
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
mov r4, r0
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_0+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_0+8))
LPC2_0:
ldr r1, [pc, r1]
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_1+8))
LPC2_1:
ldr r2, [pc, r2]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_cdfe92d39025fdf4-(LPC2_1+8))
LPC2_1:
ldr r1, [pc, r1]
bl _objc_msgSend
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
mov r0, r4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_2+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_2+8))
LPC2_2:
ldr r1, [pc, r1]
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_3+8))
LPC2_3:
ldr r2, [pc, r2]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_79bd65c86d46fbf1-(LPC2_3+8))
LPC2_3:
ldr r1, [pc, r1]
bl _objc_msgSend
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
mov r0, r4
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_4+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_4+8))
LPC2_4:
ldr r1, [pc, r1]
movw r2, :lower16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
movt r2, :upper16:(L_OBJC_SELECTOR_REFERENCES_31f63858e271db32-(LPC2_5+8))
LPC2_5:
ldr r2, [pc, r2]
movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8e0840c6b39b7720-(LPC2_5+8))
LPC2_5:
ldr r1, [pc, r1]
bl _objc_msgSend
pop {r4, r7, pc}

Expand Down
56 changes: 12 additions & 44 deletions tests/assembly/test_static_sel/expected/apple-aarch64.s
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _get_different_sel:
.globl _unused_sel
.p2align 2
_unused_sel:
b __RNvNvCsai54Y9dtG4h_15test_static_sel10unused_sel22objc_static_workaround
ret

.globl _use_fns
.p2align 2
Expand Down Expand Up @@ -64,28 +64,14 @@ _use_same_twice:
add x29, sp, #16
mov x19, x8
bl __RNvNvCsai54Y9dtG4h_15test_static_sel7get_sel22objc_static_workaround
mov x20, x0
bl __RNvNvCsai54Y9dtG4h_15test_static_sel7get_sel22objc_static_workaround
stp x20, x0, [x19]
stp x0, x0, [x19]
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret

.globl _use_in_loop
.p2align 2
_use_in_loop:
stp x20, x19, [sp, #-32]!
stp x29, x30, [sp, #16]
add x29, sp, #16
cbz x0, LBB7_3
mov x19, x0
LBB7_2:
bl __RNvNvCsai54Y9dtG4h_15test_static_sel11use_in_loop22objc_static_workaround
subs x19, x19, #1
b.ne LBB7_2
LBB7_3:
ldp x29, x30, [sp, #16]
ldp x20, x19, [sp], #32
ret

.p2align 2
Expand Down Expand Up @@ -133,32 +119,14 @@ Lloh9:
ret
.loh AdrpLdr Lloh8, Lloh9

.p2align 2
__RNvNvCsai54Y9dtG4h_15test_static_sel10unused_sel22objc_static_workaround:
Lloh10:
adrp x8, L_OBJC_SELECTOR_REFERENCES_2c505e110d181b25@PAGE
Lloh11:
ldr xzr, [x8, L_OBJC_SELECTOR_REFERENCES_2c505e110d181b25@PAGEOFF]
ret
.loh AdrpLdr Lloh10, Lloh11

.p2align 2
__RNvNvCsai54Y9dtG4h_15test_static_sel7use_fns22objc_static_workaround:
Lloh12:
Lloh10:
adrp x8, L_OBJC_SELECTOR_REFERENCES_5419c3f7fc0a6f99@PAGE
Lloh13:
Lloh11:
ldr x0, [x8, L_OBJC_SELECTOR_REFERENCES_5419c3f7fc0a6f99@PAGEOFF]
ret
.loh AdrpLdr Lloh12, Lloh13

.p2align 2
__RNvNvCsai54Y9dtG4h_15test_static_sel11use_in_loop22objc_static_workaround:
Lloh14:
adrp x8, L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b@PAGE
Lloh15:
ldr xzr, [x8, L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b@PAGEOFF]
ret
.loh AdrpLdr Lloh14, Lloh15
.loh AdrpLdr Lloh10, Lloh11

.section __DATA,__objc_imageinfo,regular,no_dead_strip
.globl L_OBJC_IMAGE_INFO_68381ba894e318e9
Expand Down Expand Up @@ -280,20 +248,20 @@ L_OBJC_SELECTOR_REFERENCES_5419c3f7fc0a6f99:
.quad L_OBJC_METH_VAR_NAME_5419c3f7fc0a6f99

.section __DATA,__objc_imageinfo,regular,no_dead_strip
.globl L_OBJC_IMAGE_INFO_9845965b987ed54b
.globl L_OBJC_IMAGE_INFO_f46908e864c86c6b
.p2align 2
L_OBJC_IMAGE_INFO_9845965b987ed54b:
L_OBJC_IMAGE_INFO_f46908e864c86c6b:
.asciz "\000\000\000\000@\000\000"

.section __TEXT,__objc_methname,cstring_literals
.globl L_OBJC_METH_VAR_NAME_9845965b987ed54b
L_OBJC_METH_VAR_NAME_9845965b987ed54b:
.globl L_OBJC_METH_VAR_NAME_f46908e864c86c6b
L_OBJC_METH_VAR_NAME_f46908e864c86c6b:
.asciz "loopedSelector"

.section __DATA,__objc_selrefs,literal_pointers,no_dead_strip
.globl L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b
.globl L_OBJC_SELECTOR_REFERENCES_f46908e864c86c6b
.p2align 3
L_OBJC_SELECTOR_REFERENCES_9845965b987ed54b:
.quad L_OBJC_METH_VAR_NAME_9845965b987ed54b
L_OBJC_SELECTOR_REFERENCES_f46908e864c86c6b:
.quad L_OBJC_METH_VAR_NAME_f46908e864c86c6b

.subsections_via_symbols
Loading

0 comments on commit 14300c3

Please sign in to comment.