From 4687e1d67d2601c3a408b74224f5ceb353c77b71 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 21 Feb 2014 07:25:17 -0500 Subject: [PATCH] remove the TyDesc from TypedArena This prevents generating visit glue when using a TypedArena. The problem still exists for the untyped Arena. --- src/libarena/lib.rs | 74 ++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 0f291a56a7099..3f5c268606449 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -31,6 +31,7 @@ use std::cast::{transmute, transmute_mut, transmute_mut_region}; use std::cast; use std::cell::{Cell, RefCell}; use std::mem; +use std::ptr::read; use std::cmp; use std::num; use std::kinds::marker; @@ -345,17 +346,13 @@ pub struct TypedArena { /// reached, a new chunk is allocated. priv end: *T, - /// The type descriptor of the objects in the arena. This should not be - /// necessary, but is until generic destructors are supported. - priv tydesc: *TyDesc, - /// A pointer to the first arena segment. - priv first: Option<~TypedArenaChunk>, + priv first: Option<~TypedArenaChunk>, } -struct TypedArenaChunk { +struct TypedArenaChunk { /// Pointer to the next arena segment. - next: Option<~TypedArenaChunk>, + next: Option<~TypedArenaChunk>, /// The number of elements that this chunk can hold. capacity: uint, @@ -363,11 +360,10 @@ struct TypedArenaChunk { // Objects follow here, suitably aligned. } -impl TypedArenaChunk { +impl TypedArenaChunk { #[inline] - fn new(next: Option<~TypedArenaChunk>, capacity: uint) - -> ~TypedArenaChunk { - let mut size = mem::size_of::(); + fn new(next: Option<~TypedArenaChunk>, capacity: uint) -> ~TypedArenaChunk { + let mut size = mem::size_of::>(); size = round_up(size, mem::min_align_of::()); let elem_size = mem::size_of::(); let elems_size = elem_size.checked_mul(&capacity).unwrap(); @@ -375,7 +371,7 @@ impl TypedArenaChunk { let mut chunk = unsafe { let chunk = global_heap::exchange_malloc(size); - let mut chunk: ~TypedArenaChunk = cast::transmute(chunk); + let mut chunk: ~TypedArenaChunk = cast::transmute(chunk); mem::move_val_init(&mut chunk.next, next); chunk }; @@ -387,16 +383,13 @@ impl TypedArenaChunk { /// Destroys this arena chunk. If the type descriptor is supplied, the /// drop glue is called; otherwise, drop glue is not called. #[inline] - unsafe fn destroy(&mut self, len: uint, opt_tydesc: Option<*TyDesc>) { + unsafe fn destroy(&mut self, len: uint) { // Destroy all the allocated objects. - match opt_tydesc { - None => {} - Some(tydesc) => { - let mut start = self.start(tydesc); - for _ in range(0, len) { - ((*tydesc).drop_glue)(start as *i8); - start = start.offset((*tydesc).size as int) - } + if intrinsics::needs_drop::() { + let mut start = self.start(); + for _ in range(0, len) { + read(start as *T); // run the destructor on the pointer + start = start.offset(mem::size_of::() as int) } } @@ -406,26 +399,26 @@ impl TypedArenaChunk { None => {} Some(mut next) => { // We assume that the next chunk is completely filled. - next.destroy(next.capacity, opt_tydesc) + next.destroy(next.capacity) } } } // Returns a pointer to the first allocated object. #[inline] - fn start(&self, tydesc: *TyDesc) -> *u8 { - let this: *TypedArenaChunk = self; + fn start(&self) -> *u8 { + let this: *TypedArenaChunk = self; unsafe { - cast::transmute(round_up(this.offset(1) as uint, (*tydesc).align)) + cast::transmute(round_up(this.offset(1) as uint, mem::min_align_of::())) } } // Returns a pointer to the end of the allocated space. #[inline] - fn end(&self, tydesc: *TyDesc) -> *u8 { + fn end(&self) -> *u8 { unsafe { - let size = (*tydesc).size.checked_mul(&self.capacity).unwrap(); - self.start(tydesc).offset(size as int) + let size = mem::size_of::().checked_mul(&self.capacity).unwrap(); + self.start().offset(size as int) } } } @@ -441,14 +434,10 @@ impl TypedArena { /// objects. #[inline] pub fn with_capacity(capacity: uint) -> TypedArena { - let chunk = TypedArenaChunk::new::(None, capacity); - let tydesc = unsafe { - intrinsics::get_tydesc::() - }; + let chunk = TypedArenaChunk::::new(None, capacity); TypedArena { - ptr: chunk.start(tydesc) as *T, - end: chunk.end(tydesc) as *T, - tydesc: tydesc, + ptr: chunk.start() as *T, + end: chunk.end() as *T, first: Some(chunk), } } @@ -475,9 +464,9 @@ impl TypedArena { fn grow(&mut self) { let chunk = self.first.take_unwrap(); let new_capacity = chunk.capacity.checked_mul(&2).unwrap(); - let chunk = TypedArenaChunk::new::(Some(chunk), new_capacity); - self.ptr = chunk.start(self.tydesc) as *T; - self.end = chunk.end(self.tydesc) as *T; + let chunk = TypedArenaChunk::::new(Some(chunk), new_capacity); + self.ptr = chunk.start() as *T; + self.end = chunk.end() as *T; self.first = Some(chunk) } } @@ -486,18 +475,13 @@ impl TypedArena { impl Drop for TypedArena { fn drop(&mut self) { // Determine how much was filled. - let start = self.first.get_ref().start(self.tydesc) as uint; + let start = self.first.get_ref().start() as uint; let end = self.ptr as uint; let diff = (end - start) / mem::size_of::(); // Pass that to the `destroy` method. unsafe { - let opt_tydesc = if intrinsics::needs_drop::() { - Some(self.tydesc) - } else { - None - }; - self.first.get_mut_ref().destroy(diff, opt_tydesc) + self.first.get_mut_ref().destroy(diff) } } }