Skip to content

Consolidate raw representations of rust values #7986

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 27 additions & 32 deletions src/libstd/at_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

//! Managed vectors

use cast::transmute;
use clone::Clone;
use container::Container;
use iterator::IteratorUtil;
use option::Option;
use sys;
use uint;
use unstable::raw::Repr;
use vec::{ImmutableVector, OwnedVector};

/// Code for dealing with @-vectors. This is pretty incomplete, and
Expand All @@ -26,8 +26,8 @@ use vec::{ImmutableVector, OwnedVector};
#[inline]
pub fn capacity<T>(v: @[T]) -> uint {
unsafe {
let repr: **raw::VecRepr = transmute(&v);
(**repr).unboxed.alloc / sys::size_of::<T>()
let box = v.repr();
(*box).data.alloc / sys::size_of::<T>()
}
}

Expand All @@ -45,10 +45,10 @@ pub fn capacity<T>(v: @[T]) -> uint {
*/
#[inline]
pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
let mut vec: @[A] = @[];
let mut vec = @[];
unsafe { raw::reserve(&mut vec, size); }
builder(|x| unsafe { raw::push(&mut vec, x) });
return unsafe { transmute(vec) };
vec
}

/**
Expand Down Expand Up @@ -151,7 +151,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
for v.consume_iter().advance |x| {
raw::push(&mut av, x);
}
transmute(av)
av
}
}

Expand Down Expand Up @@ -195,13 +195,9 @@ pub mod raw {
use ptr;
use sys;
use uint;
use unstable::intrinsics;
use unstable::intrinsics::{move_val_init, TyDesc};
use vec;
use vec::UnboxedVecRepr;

pub type VecRepr = vec::raw::VecRepr;
pub type SliceRepr = vec::raw::SliceRepr;
use unstable::intrinsics;
use unstable::raw::{Box, Vec};

/**
* Sets the length of a vector
Expand All @@ -211,19 +207,21 @@ pub mod raw {
* the vector is actually the specified size.
*/
#[inline]
pub unsafe fn set_len<T>(v: @[T], new_len: uint) {
let repr: **mut VecRepr = transmute(&v);
(**repr).unboxed.fill = new_len * sys::size_of::<T>();
pub unsafe fn set_len<T>(v: &mut @[T], new_len: uint) {
let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
(*repr).data.fill = new_len * sys::size_of::<T>();
}

/**
* Pushes a new value onto this vector.
*/
#[inline]
pub unsafe fn push<T>(v: &mut @[T], initval: T) {
let repr: **VecRepr = transmute_copy(&v);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc > fill {
let full = {
let repr: *Box<Vec<T>> = cast::transmute_copy(v);
(*repr).data.alloc > (*repr).data.fill
};
if full {
push_fast(v, initval);
} else {
push_slow(v, initval);
Expand All @@ -232,16 +230,15 @@ pub mod raw {

#[inline] // really pretty please
unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
let repr: **mut VecRepr = ::cast::transmute(v);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::size_of::<T>();
let p = &((**repr).unboxed.data);
let p = ptr::offset(p, fill) as *mut T;
let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
let amt = v.len();
(*repr).data.fill += sys::size_of::<T>();
let p = ptr::offset(&(*repr).data.data as *T, amt) as *mut T;
move_val_init(&mut(*p), initval);
}

unsafe fn push_slow<T>(v: &mut @[T], initval: T) {
reserve_at_least(&mut *v, v.len() + 1u);
reserve_at_least(v, v.len() + 1u);
push_fast(v, initval);
}

Expand All @@ -259,7 +256,7 @@ pub mod raw {
pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
// Only make the (slow) call into the runtime if we have to
if capacity(*v) < n {
let ptr: *mut *mut VecRepr = transmute(v);
let ptr: *mut *mut Box<Vec<()>> = transmute(v);
let ty = intrinsics::get_tydesc::<T>();
// XXX transmute shouldn't be necessary
let ty = cast::transmute(ty);
Expand All @@ -269,16 +266,14 @@ pub mod raw {

// Implementation detail. Shouldn't be public
#[allow(missing_doc)]
pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut VecRepr, n: uint) {
pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut Box<Vec<()>>, n: uint) {

unsafe {
let size_in_bytes = n * (*ty).size;
if size_in_bytes > (**ptr).unboxed.alloc {
let total_size = size_in_bytes + sys::size_of::<UnboxedVecRepr>();
// XXX: UnboxedVecRepr has an extra u8 at the end
let total_size = total_size - sys::size_of::<u8>();
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr;
(**ptr).unboxed.alloc = size_in_bytes;
if size_in_bytes > (**ptr).data.alloc {
let total_size = size_in_bytes + sys::size_of::<Vec<()>>();
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box<Vec<()>>;
(**ptr).data.alloc = size_in_bytes;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/libstd/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
#[cfg(test)]
mod tests {
use cast::{bump_box_refcount, transmute};
use unstable::raw;

#[test]
fn test_transmute_copy() {
Expand All @@ -156,10 +157,9 @@ mod tests {

#[test]
fn test_transmute() {
use managed::raw::BoxRepr;
unsafe {
let x = @100u8;
let x: *BoxRepr = transmute(x);
let x: *raw::Box<u8> = transmute(x);
assert!((*x).data == 100);
let _x: @int = transmute(x);
}
Expand Down
31 changes: 14 additions & 17 deletions src/libstd/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@

use libc::c_void;
use ptr::{mut_null};
use repr::BoxRepr;
use cast::transmute;
use unstable::intrinsics::TyDesc;
use unstable::raw;

type DropGlue<'self> = &'self fn(**TyDesc, *c_void);

Expand All @@ -31,27 +30,25 @@ struct AnnihilateStats {
}

unsafe fn each_live_alloc(read_next_before: bool,
f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) -> bool {
f: &fn(box: *mut raw::Box<()>, uniq: bool) -> bool) -> bool {
//! Walks the internal list of allocations

use managed;
use rt::local_heap;

let box = local_heap::live_allocs();
let mut box: *mut BoxRepr = transmute(box);
let mut box = local_heap::live_allocs();
while box != mut_null() {
let next_before = transmute((*box).header.next);
let uniq =
(*box).header.ref_count == managed::raw::RC_MANAGED_UNIQUE;
let next_before = (*box).next;
let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;

if !f(box, uniq) {
if !f(box as *mut raw::Box<()>, uniq) {
return false;
}

if read_next_before {
box = next_before;
} else {
box = transmute((*box).header.next);
box = (*box).next;
}
}
return true;
Expand Down Expand Up @@ -102,7 +99,7 @@ pub unsafe fn annihilate() {
if uniq {
stats.n_unique_boxes += 1;
} else {
(*box).header.ref_count = managed::raw::RC_IMMORTAL;
(*box).ref_count = managed::RC_IMMORTAL;
}
}

Expand All @@ -113,9 +110,9 @@ pub unsafe fn annihilate() {
// callback, as the original value may have been freed.
for each_live_alloc(false) |box, uniq| {
if !uniq {
let tydesc: *TyDesc = transmute((*box).header.type_desc);
let data = transmute(&(*box).data);
((*tydesc).drop_glue)(data);
let tydesc = (*box).type_desc;
let data = &(*box).data as *();
((*tydesc).drop_glue)(data as *i8);
}
}

Expand All @@ -128,9 +125,9 @@ pub unsafe fn annihilate() {
for each_live_alloc(true) |box, uniq| {
if !uniq {
stats.n_bytes_freed +=
(*((*box).header.type_desc)).size
+ sys::size_of::<BoxRepr>();
local_free(transmute(box));
(*((*box).type_desc)).size
+ sys::size_of::<raw::Box<()>>();
local_free(box as *i8);
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/libstd/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ pub mod rustrt {
}

unsafe fn bump<T, U>(ptr: *T, count: uint) -> *U {
return cast::transmute(ptr::offset(ptr, count));
return ptr::offset(ptr, count) as *U;
}

unsafe fn align_to_pointer<T>(ptr: *T) -> *T {
let align = sys::min_align_of::<*T>();
let ptr: uint = cast::transmute(ptr);
let ptr = ptr as uint;
let ptr = (ptr + (align - 1)) & -align;
return cast::transmute(ptr);
return ptr as *T;
}

unsafe fn get_safe_point_count() -> uint {
Expand Down Expand Up @@ -126,8 +126,8 @@ type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool;
// Walks the list of roots for the given safe point, and calls visitor
// on each root.
unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
let fp_bytes: *u8 = cast::transmute(fp);
let sp_meta: *u32 = cast::transmute(sp.sp_meta);
let fp_bytes = fp as *u8;
let sp_meta = sp.sp_meta as *u32;

let num_stack_roots = *sp_meta as uint;
let num_reg_roots = *ptr::offset(sp_meta, 1) as uint;
Expand Down Expand Up @@ -173,9 +173,9 @@ unsafe fn walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {

// Is fp contained in segment?
unsafe fn is_frame_in_segment(fp: *Word, segment: *StackSegment) -> bool {
let begin: Word = cast::transmute(segment);
let end: Word = cast::transmute((*segment).end);
let frame: Word = cast::transmute(fp);
let begin = segment as Word;
let end = (*segment).end as Word;
let frame = fp as Word;

return begin <= frame && frame <= end;
}
Expand Down
23 changes: 2 additions & 21 deletions src/libstd/managed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,8 @@ use ptr::to_unsafe_ptr;

#[cfg(not(test))] use cmp::{Eq, Ord};

pub mod raw {
use std::unstable::intrinsics::TyDesc;

pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;

#[allow(missing_doc)]
pub struct BoxHeaderRepr {
ref_count: uint,
type_desc: *TyDesc,
prev: *BoxRepr,
next: *BoxRepr,
}

#[allow(missing_doc)]
pub struct BoxRepr {
header: BoxHeaderRepr,
data: u8
}

}
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
pub static RC_IMMORTAL : uint = 0x77777777;

/// Determine if two shared boxes point to the same object
#[inline]
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Runtime type reflection
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
use libc::c_void;
use sys;
use vec;
use unstable::raw;

/**
* Trait for visitor that wishes to reflect on data. To use this, create a
Expand Down Expand Up @@ -260,7 +260,7 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
}

fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<vec::UnboxedVecRepr>();
self.align_to::<raw::Vec<()>>();
if ! self.inner.visit_vec(mtbl, inner) { return false; }
true
}
Expand Down
Loading