Skip to content

Commit a535cfb

Browse files
committed
Remove & -> &mut transmute from Arena
1 parent e0855bc commit a535cfb

File tree

1 file changed

+48
-42
lines changed

1 file changed

+48
-42
lines changed

src/libarena/lib.rs

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ pub struct Arena {
8181
// The head is separated out from the list as a unbenchmarked
8282
// microoptimization, to avoid needing to case on the list to access the
8383
// head.
84-
head: Chunk,
85-
copy_head: Chunk,
84+
head: RefCell<Chunk>,
85+
copy_head: RefCell<Chunk>,
8686
chunks: RefCell<Vec<Chunk>>,
8787
}
8888

@@ -95,8 +95,8 @@ impl Arena {
9595
/// Allocate a new Arena with `initial_size` bytes preallocated.
9696
pub fn new_with_size(initial_size: uint) -> Arena {
9797
Arena {
98-
head: chunk(initial_size, false),
99-
copy_head: chunk(initial_size, true),
98+
head: RefCell::new(chunk(initial_size, false)),
99+
copy_head: RefCell::new(chunk(initial_size, true)),
100100
chunks: RefCell::new(Vec::new()),
101101
}
102102
}
@@ -114,7 +114,7 @@ fn chunk(size: uint, is_copy: bool) -> Chunk {
114114
impl Drop for Arena {
115115
fn drop(&mut self) {
116116
unsafe {
117-
destroy_chunk(&self.head);
117+
destroy_chunk(&*self.head.borrow());
118118
for chunk in self.chunks.borrow().iter() {
119119
if !chunk.is_copy.get() {
120120
destroy_chunk(chunk);
@@ -171,38 +171,40 @@ fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
171171

172172
impl Arena {
173173
fn chunk_size(&self) -> uint {
174-
self.copy_head.capacity()
174+
self.copy_head.borrow().capacity()
175175
}
176+
176177
// Functions for the POD part of the arena
177-
fn alloc_copy_grow(&mut self, n_bytes: uint, align: uint) -> *u8 {
178+
fn alloc_copy_grow(&self, n_bytes: uint, align: uint) -> *u8 {
178179
// Allocate a new chunk.
179180
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
180-
self.chunks.borrow_mut().push(self.copy_head.clone());
181-
self.copy_head =
181+
self.chunks.borrow_mut().push(self.copy_head.borrow().clone());
182+
183+
*self.copy_head.borrow_mut() =
182184
chunk(num::next_power_of_two(new_min_chunk_size + 1u), true);
183185

184186
return self.alloc_copy_inner(n_bytes, align);
185187
}
186188

187189
#[inline]
188-
fn alloc_copy_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
189-
unsafe {
190-
let start = round_up(self.copy_head.fill.get(), align);
191-
let end = start + n_bytes;
192-
if end > self.chunk_size() {
193-
return self.alloc_copy_grow(n_bytes, align);
194-
}
195-
self.copy_head.fill.set(end);
190+
fn alloc_copy_inner(&self, n_bytes: uint, align: uint) -> *u8 {
191+
let start = round_up(self.copy_head.borrow().fill.get(), align);
192+
193+
let end = start + n_bytes;
194+
if end > self.chunk_size() {
195+
return self.alloc_copy_grow(n_bytes, align);
196+
}
196197

197-
//debug!("idx = {}, size = {}, align = {}, fill = {}",
198-
// start, n_bytes, align, head.fill.get());
198+
let copy_head = self.copy_head.borrow();
199+
copy_head.fill.set(end);
199200

200-
self.copy_head.as_ptr().offset(start as int)
201+
unsafe {
202+
copy_head.as_ptr().offset(start as int)
201203
}
202204
}
203205

204206
#[inline]
205-
fn alloc_copy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
207+
fn alloc_copy<'a, T>(&'a self, op: || -> T) -> &'a T {
206208
unsafe {
207209
let ptr = self.alloc_copy_inner(mem::size_of::<T>(),
208210
mem::min_align_of::<T>());
@@ -213,42 +215,48 @@ impl Arena {
213215
}
214216

215217
// Functions for the non-POD part of the arena
216-
fn alloc_noncopy_grow(&mut self, n_bytes: uint, align: uint)
217-
-> (*u8, *u8) {
218+
fn alloc_noncopy_grow(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
218219
// Allocate a new chunk.
219220
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
220-
self.chunks.borrow_mut().push(self.head.clone());
221-
self.head =
221+
self.chunks.borrow_mut().push(self.head.borrow().clone());
222+
223+
*self.head.borrow_mut() =
222224
chunk(num::next_power_of_two(new_min_chunk_size + 1u), false);
223225

224226
return self.alloc_noncopy_inner(n_bytes, align);
225227
}
226228

227229
#[inline]
228-
fn alloc_noncopy_inner(&mut self, n_bytes: uint, align: uint)
229-
-> (*u8, *u8) {
230-
unsafe {
231-
let tydesc_start = self.head.fill.get();
232-
let after_tydesc = self.head.fill.get() + mem::size_of::<*TyDesc>();
230+
fn alloc_noncopy_inner(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
231+
// Be careful to not maintain any `head` borrows active, because
232+
// `alloc_noncopy_grow` borrows it mutably.
233+
let (start, end, tydesc_start, head_capacity) = {
234+
let head = self.head.borrow();
235+
let fill = head.fill.get();
236+
237+
let tydesc_start = fill;
238+
let after_tydesc = fill + mem::size_of::<*TyDesc>();
233239
let start = round_up(after_tydesc, align);
234240
let end = start + n_bytes;
235241

236-
if end > self.head.capacity() {
237-
return self.alloc_noncopy_grow(n_bytes, align);
238-
}
242+
(start, end, tydesc_start, head.capacity())
243+
};
239244

240-
self.head.fill.set(round_up(end, mem::align_of::<*TyDesc>()));
245+
if end > head_capacity {
246+
return self.alloc_noncopy_grow(n_bytes, align);
247+
}
241248

242-
//debug!("idx = {}, size = {}, align = {}, fill = {}",
243-
// start, n_bytes, align, head.fill);
249+
let head = self.head.borrow();
250+
head.fill.set(round_up(end, mem::align_of::<*TyDesc>()));
244251

245-
let buf = self.head.as_ptr();
252+
unsafe {
253+
let buf = head.as_ptr();
246254
return (buf.offset(tydesc_start as int), buf.offset(start as int));
247255
}
248256
}
249257

250258
#[inline]
251-
fn alloc_noncopy<'a, T>(&'a mut self, op: || -> T) -> &'a T {
259+
fn alloc_noncopy<'a, T>(&'a self, op: || -> T) -> &'a T {
252260
unsafe {
253261
let tydesc = get_tydesc::<T>();
254262
let (ty_ptr, ptr) =
@@ -274,12 +282,10 @@ impl Arena {
274282
#[inline]
275283
pub fn alloc<'a, T>(&'a self, op: || -> T) -> &'a T {
276284
unsafe {
277-
// FIXME #13933: Remove/justify all `&T` to `&mut T` transmutes
278-
let this: &mut Arena = mem::transmute::<&_, &mut _>(self);
279285
if intrinsics::needs_drop::<T>() {
280-
this.alloc_noncopy(op)
286+
self.alloc_noncopy(op)
281287
} else {
282-
this.alloc_copy(op)
288+
self.alloc_copy(op)
283289
}
284290
}
285291
}

0 commit comments

Comments
 (0)