Skip to content

Commit a0f943c

Browse files
committed
auto merge of #12654 : edwardw/rust/rc-arc, r=huonw
Since `Arc` has been using `Atomic`, this closes 12625. Closes #12625.
2 parents caf17fe + db5206c commit a0f943c

File tree

2 files changed

+65
-42
lines changed

2 files changed

+65
-42
lines changed

src/libstd/rc.rs

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,20 @@ pointers, and then storing the parent pointers as `Weak` pointers.
2424
*/
2525

2626
use cast::transmute;
27+
use cell::Cell;
2728
use clone::Clone;
2829
use cmp::{Eq, Ord};
2930
use kinds::marker;
3031
use ops::{Deref, Drop};
3132
use option::{Option, Some, None};
3233
use ptr;
34+
use ptr::RawPtr;
3335
use rt::global_heap::exchange_free;
3436

3537
struct RcBox<T> {
3638
value: T,
37-
strong: uint,
38-
weak: uint
39+
strong: Cell<uint>,
40+
weak: Cell<uint>
3941
}
4042

4143
/// Immutable reference counted pointer type
@@ -56,7 +58,11 @@ impl<T> Rc<T> {
5658
// destructor never frees the allocation while the
5759
// strong destructor is running, even if the weak
5860
// pointer is stored inside the strong one.
59-
ptr: transmute(~RcBox { value: value, strong: 1, weak: 1 }),
61+
ptr: transmute(~RcBox {
62+
value: value,
63+
strong: Cell::new(1),
64+
weak: Cell::new(1)
65+
}),
6066
nosend: marker::NoSend,
6167
noshare: marker::NoShare
6268
}
@@ -67,13 +73,11 @@ impl<T> Rc<T> {
6773
impl<T> Rc<T> {
6874
/// Downgrade the reference-counted pointer to a weak reference
6975
pub fn downgrade(&self) -> Weak<T> {
70-
unsafe {
71-
(*self.ptr).weak += 1;
72-
Weak {
73-
ptr: self.ptr,
74-
nosend: marker::NoSend,
75-
noshare: marker::NoShare
76-
}
76+
self.inc_weak();
77+
Weak {
78+
ptr: self.ptr,
79+
nosend: marker::NoSend,
80+
noshare: marker::NoShare
7781
}
7882
}
7983
}
@@ -82,24 +86,24 @@ impl<T> Deref<T> for Rc<T> {
8286
/// Borrow the value contained in the reference-counted box
8387
#[inline(always)]
8488
fn deref<'a>(&'a self) -> &'a T {
85-
unsafe { &(*self.ptr).value }
89+
&self.inner().value
8690
}
8791
}
8892

8993
#[unsafe_destructor]
9094
impl<T> Drop for Rc<T> {
9195
fn drop(&mut self) {
9296
unsafe {
93-
if self.ptr != 0 as *mut RcBox<T> {
94-
(*self.ptr).strong -= 1;
95-
if (*self.ptr).strong == 0 {
97+
if !self.ptr.is_null() {
98+
self.dec_strong();
99+
if self.strong() == 0 {
96100
ptr::read(self.deref()); // destroy the contained object
97101

98102
// remove the implicit "strong weak" pointer now
99103
// that we've destroyed the contents.
100-
(*self.ptr).weak -= 1;
104+
self.dec_weak();
101105

102-
if (*self.ptr).weak == 0 {
106+
if self.weak() == 0 {
103107
exchange_free(self.ptr as *u8)
104108
}
105109
}
@@ -111,10 +115,8 @@ impl<T> Drop for Rc<T> {
111115
impl<T> Clone for Rc<T> {
112116
#[inline]
113117
fn clone(&self) -> Rc<T> {
114-
unsafe {
115-
(*self.ptr).strong += 1;
116-
Rc { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare }
117-
}
118+
self.inc_strong();
119+
Rc { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare }
118120
}
119121
}
120122

@@ -151,13 +153,11 @@ pub struct Weak<T> {
151153
impl<T> Weak<T> {
152154
/// Upgrade a weak reference to a strong reference
153155
pub fn upgrade(&self) -> Option<Rc<T>> {
154-
unsafe {
155-
if (*self.ptr).strong == 0 {
156-
None
157-
} else {
158-
(*self.ptr).strong += 1;
159-
Some(Rc { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare })
160-
}
156+
if self.strong() == 0 {
157+
None
158+
} else {
159+
self.inc_strong();
160+
Some(Rc { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare })
161161
}
162162
}
163163
}
@@ -166,11 +166,11 @@ impl<T> Weak<T> {
166166
impl<T> Drop for Weak<T> {
167167
fn drop(&mut self) {
168168
unsafe {
169-
if self.ptr != 0 as *mut RcBox<T> {
170-
(*self.ptr).weak -= 1;
169+
if !self.ptr.is_null() {
170+
self.dec_weak();
171171
// the weak count starts at 1, and will only go to
172172
// zero if all the strong pointers have disappeared.
173-
if (*self.ptr).weak == 0 {
173+
if self.weak() == 0 {
174174
exchange_free(self.ptr as *u8)
175175
}
176176
}
@@ -181,13 +181,44 @@ impl<T> Drop for Weak<T> {
181181
impl<T> Clone for Weak<T> {
182182
#[inline]
183183
fn clone(&self) -> Weak<T> {
184-
unsafe {
185-
(*self.ptr).weak += 1;
186-
Weak { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare }
187-
}
184+
self.inc_weak();
185+
Weak { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare }
188186
}
189187
}
190188

189+
#[allow(missing_doc)]
190+
trait RcBoxPtr<T> {
191+
fn inner<'a>(&'a self) -> &'a RcBox<T>;
192+
193+
#[inline]
194+
fn strong(&self) -> uint { self.inner().strong.get() }
195+
196+
#[inline]
197+
fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
198+
199+
#[inline]
200+
fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
201+
202+
#[inline]
203+
fn weak(&self) -> uint { self.inner().weak.get() }
204+
205+
#[inline]
206+
fn inc_weak(&self) { self.inner().weak.set(self.weak() + 1); }
207+
208+
#[inline]
209+
fn dec_weak(&self) { self.inner().weak.set(self.weak() - 1); }
210+
}
211+
212+
impl<T> RcBoxPtr<T> for Rc<T> {
213+
#[inline(always)]
214+
fn inner<'a>(&'a self) -> &'a RcBox<T> { unsafe { &(*self.ptr) } }
215+
}
216+
217+
impl<T> RcBoxPtr<T> for Weak<T> {
218+
#[inline(always)]
219+
fn inner<'a>(&'a self) -> &'a RcBox<T> { unsafe { &(*self.ptr) } }
220+
}
221+
191222
#[cfg(test)]
192223
mod tests {
193224
use prelude::*;

src/libsyntax/ast.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,14 +1156,6 @@ mod test {
11561156
use codemap::*;
11571157
use super::*;
11581158

1159-
fn is_freeze<T: Freeze>() {}
1160-
1161-
// Assert that the AST remains Freeze (#10693).
1162-
#[test]
1163-
fn ast_is_freeze() {
1164-
is_freeze::<Item>();
1165-
}
1166-
11671159
// are ASTs encodable?
11681160
#[test]
11691161
fn check_asts_encodable() {

0 commit comments

Comments
 (0)