Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b283c44

Browse files
committedNov 3, 2024·
Store pointer to data directly in Rc and Arc
1 parent 6739555 commit b283c44

File tree

4 files changed

+353
-273
lines changed

4 files changed

+353
-273
lines changed
 

‎library/alloc/src/rc.rs

+148-144
Large diffs are not rendered by default.

‎library/alloc/src/sync.rs

+125-127
Large diffs are not rendered by default.

‎tests/codegen/zero-cost-rc-deref.rs

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//@ compile-flags: -O -Z merge-functions=disabled
2+
3+
#![crate_type = "lib"]
4+
5+
use std::rc::Rc;
6+
use std::sync::Arc;
7+
8+
// CHECK-LABEL: @deref_rc_sized(
9+
// CHECK-NOT: getelementptr
10+
// CHECK: ret
11+
#[no_mangle]
12+
pub fn deref_rc_sized(rc: &Rc<u32>) -> &u32 {
13+
&rc
14+
}
15+
16+
// CHECK-LABEL: @deref_rc_unsized(
17+
// CHECK-NOT: getelementptr
18+
// CHECK: ret
19+
#[no_mangle]
20+
pub fn deref_rc_unsized(rc: &Rc<str>) -> &str {
21+
&rc
22+
}
23+
24+
// CHECK-LABEL: @deref_arc_sized(
25+
// CHECK-NOT: getelementptr
26+
// CHECK: ret
27+
#[no_mangle]
28+
pub fn deref_arc_sized(arc: &Arc<u32>) -> &u32 {
29+
&arc
30+
}
31+
32+
// CHECK-LABEL: @deref_arc_unsized(
33+
// CHECK-NOT: getelementptr
34+
// CHECK: ret
35+
#[no_mangle]
36+
pub fn deref_arc_unsized(arc: &Arc<str>) -> &str {
37+
&arc
38+
}
39+
40+
// CHECK-LABEL: @rc_slice_to_ref_slice_sized(
41+
// CHECK-NOT: getelementptr
42+
// CHECK: tail call void @llvm.memcpy
43+
// CHECK-NOT: getelementptr
44+
// CHECK: ret
45+
#[no_mangle]
46+
pub fn rc_slice_to_ref_slice_sized(s: &[Rc<u32>]) -> Box<[&u32]> {
47+
s.iter().map(|x| &**x).collect()
48+
}
49+
50+
// CHECK-LABEL: @rc_slice_to_ref_slice_unsized(
51+
// CHECK-NOT: getelementptr
52+
// CHECK: tail call void @llvm.memcpy
53+
// CHECK-NOT: getelementptr
54+
// CHECK: ret
55+
#[no_mangle]
56+
pub fn rc_slice_to_ref_slice_unsized(s: &[Rc<str>]) -> Box<[&str]> {
57+
s.iter().map(|x| &**x).collect()
58+
}
59+
60+
// CHECK-LABEL: @arc_slice_to_ref_slice_sized(
61+
// CHECK-NOT: getelementptr
62+
// CHECK: tail call void @llvm.memcpy
63+
// CHECK-NOT: getelementptr
64+
// CHECK: ret
65+
#[no_mangle]
66+
pub fn arc_slice_to_ref_slice_sized(s: &[Arc<u32>]) -> Box<[&u32]> {
67+
s.iter().map(|x| &**x).collect()
68+
}
69+
70+
// CHECK-LABEL: @arc_slice_to_ref_slice_unsized(
71+
// CHECK-NOT: getelementptr
72+
// CHECK: tail call void @llvm.memcpy
73+
// CHECK-NOT: getelementptr
74+
// CHECK: ret
75+
#[no_mangle]
76+
pub fn arc_slice_to_ref_slice_unsized(s: &[Arc<str>]) -> Box<[&str]> {
77+
s.iter().map(|x| &**x).collect()
78+
}

‎tests/ui/abi/compatibility.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ mod prelude {
126126
value: T,
127127
}
128128
pub struct Rc<T: ?Sized, A = Global> {
129-
ptr: NonNull<RcInner<T>>,
129+
ptr: NonNull<T>,
130130
phantom: PhantomData<RcInner<T>>,
131131
alloc: A,
132132
}
@@ -140,7 +140,7 @@ mod prelude {
140140
data: T,
141141
}
142142
pub struct Arc<T: ?Sized, A = Global> {
143-
ptr: NonNull<ArcInner<T>>,
143+
ptr: NonNull<T>,
144144
phantom: PhantomData<ArcInner<T>>,
145145
alloc: A,
146146
}

0 commit comments

Comments
 (0)
Please sign in to comment.