Skip to content

Commit 5aaaca0

Browse files
committed
Consolidate raw representations of rust values
This moves the raw struct layout of closures, vectors, boxes, and strings into a new `unstable::raw` module. This is meant to be a centralized location to find information for the layout of these values. As safe method, `repr`, is provided to convert a rust value to its raw representation. Unsafe methods to convert back are not provided because they are rarely used and too numerous to write an implementation for each (not much of a common pattern).
1 parent 7fd23e4 commit 5aaaca0

File tree

18 files changed

+239
-238
lines changed

18 files changed

+239
-238
lines changed

src/libstd/at_vec.rs

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
//! Managed vectors
1212
13-
use cast::transmute;
1413
use clone::Clone;
1514
use container::Container;
1615
use iterator::IteratorUtil;
1716
use option::Option;
1817
use sys;
1918
use uint;
19+
use unstable::raw::Repr;
2020
use vec::{ImmutableVector, OwnedVector};
2121

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

@@ -45,10 +45,10 @@ pub fn capacity<T>(v: @[T]) -> uint {
4545
*/
4646
#[inline]
4747
pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
48-
let mut vec: @[A] = @[];
48+
let mut vec = @[];
4949
unsafe { raw::reserve(&mut vec, size); }
5050
builder(|x| unsafe { raw::push(&mut vec, x) });
51-
return unsafe { transmute(vec) };
51+
vec
5252
}
5353

5454
/**
@@ -151,7 +151,7 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
151151
for v.consume_iter().advance |x| {
152152
raw::push(&mut av, x);
153153
}
154-
transmute(av)
154+
av
155155
}
156156
}
157157

@@ -195,13 +195,9 @@ pub mod raw {
195195
use ptr;
196196
use sys;
197197
use uint;
198-
use unstable::intrinsics;
199198
use unstable::intrinsics::{move_val_init, TyDesc};
200-
use vec;
201-
use vec::UnboxedVecRepr;
202-
203-
pub type VecRepr = vec::raw::VecRepr;
204-
pub type SliceRepr = vec::raw::SliceRepr;
199+
use unstable::intrinsics;
200+
use unstable::raw::{Box, Vec};
205201

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

219215
/**
220216
* Pushes a new value onto this vector.
221217
*/
222218
#[inline]
223219
pub unsafe fn push<T>(v: &mut @[T], initval: T) {
224-
let repr: **VecRepr = transmute_copy(&v);
225-
let fill = (**repr).unboxed.fill;
226-
if (**repr).unboxed.alloc > fill {
220+
let full = {
221+
let repr: *Box<Vec<T>> = cast::transmute_copy(v);
222+
(*repr).data.alloc > (*repr).data.fill
223+
};
224+
if full {
227225
push_fast(v, initval);
228226
} else {
229227
push_slow(v, initval);
@@ -232,16 +230,15 @@ pub mod raw {
232230

233231
#[inline] // really pretty please
234232
unsafe fn push_fast<T>(v: &mut @[T], initval: T) {
235-
let repr: **mut VecRepr = ::cast::transmute(v);
236-
let fill = (**repr).unboxed.fill;
237-
(**repr).unboxed.fill += sys::size_of::<T>();
238-
let p = &((**repr).unboxed.data);
239-
let p = ptr::offset(p, fill) as *mut T;
233+
let repr: *mut Box<Vec<T>> = cast::transmute_copy(v);
234+
let amt = v.len();
235+
(*repr).data.fill += sys::size_of::<T>();
236+
let p = ptr::offset(&(*repr).data.data as *T, amt) as *mut T;
240237
move_val_init(&mut(*p), initval);
241238
}
242239

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

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

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

274271
unsafe {
275272
let size_in_bytes = n * (*ty).size;
276-
if size_in_bytes > (**ptr).unboxed.alloc {
277-
let total_size = size_in_bytes + sys::size_of::<UnboxedVecRepr>();
278-
// XXX: UnboxedVecRepr has an extra u8 at the end
279-
let total_size = total_size - sys::size_of::<u8>();
280-
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut VecRepr;
281-
(**ptr).unboxed.alloc = size_in_bytes;
273+
if size_in_bytes > (**ptr).data.alloc {
274+
let total_size = size_in_bytes + sys::size_of::<Vec<()>>();
275+
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box<Vec<()>>;
276+
(**ptr).data.alloc = size_in_bytes;
282277
}
283278
}
284279

src/libstd/cast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
133133
#[cfg(test)]
134134
mod tests {
135135
use cast::{bump_box_refcount, transmute};
136+
use unstable::raw;
136137

137138
#[test]
138139
fn test_transmute_copy() {
@@ -156,10 +157,9 @@ mod tests {
156157
157158
#[test]
158159
fn test_transmute() {
159-
use managed::raw::BoxRepr;
160160
unsafe {
161161
let x = @100u8;
162-
let x: *BoxRepr = transmute(x);
162+
let x: *raw::Box<u8> = transmute(x);
163163
assert!((*x).data == 100);
164164
let _x: @int = transmute(x);
165165
}

src/libstd/cleanup.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
use libc::c_void;
1414
use ptr::{mut_null};
15-
use repr::BoxRepr;
1615
use unstable::intrinsics::TyDesc;
16+
use unstable::raw;
1717

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

@@ -30,14 +30,13 @@ struct AnnihilateStats {
3030
}
3131

3232
unsafe fn each_live_alloc(read_next_before: bool,
33-
f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) -> bool {
33+
f: &fn(box: *mut raw::Box<()>, uniq: bool) -> bool) -> bool {
3434
//! Walks the internal list of allocations
3535
3636
use managed;
3737
use rt::local_heap;
3838

39-
let box = local_heap::live_allocs();
40-
let mut box: *mut BoxRepr = transmute(box);
39+
let mut box = local_heap::live_allocs();
4140
while box != mut_null() {
4241
let next_before = (*box).next;
4342
let uniq = (*box).ref_count == managed::RC_MANAGED_UNIQUE;
@@ -100,7 +99,7 @@ pub unsafe fn annihilate() {
10099
if uniq {
101100
stats.n_unique_boxes += 1;
102101
} else {
103-
(*box).header.ref_count = managed::raw::RC_IMMORTAL;
102+
(*box).ref_count = managed::RC_IMMORTAL;
104103
}
105104
}
106105

@@ -126,9 +125,9 @@ pub unsafe fn annihilate() {
126125
for each_live_alloc(true) |box, uniq| {
127126
if !uniq {
128127
stats.n_bytes_freed +=
129-
(*((*box).header.type_desc)).size
130-
+ sys::size_of::<BoxRepr>();
131-
local_free(box as *u8);
128+
(*((*box).type_desc)).size
129+
+ sys::size_of::<raw::Box<()>>();
130+
local_free(box as *i8);
132131
}
133132
}
134133

src/libstd/managed.rs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,8 @@ use ptr::to_unsafe_ptr;
1414

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

17-
pub mod raw {
18-
use std::unstable::intrinsics::TyDesc;
19-
20-
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
21-
pub static RC_IMMORTAL : uint = 0x77777777;
22-
23-
#[allow(missing_doc)]
24-
pub struct BoxHeaderRepr {
25-
ref_count: uint,
26-
type_desc: *TyDesc,
27-
prev: *BoxRepr,
28-
next: *BoxRepr,
29-
}
30-
31-
#[allow(missing_doc)]
32-
pub struct BoxRepr {
33-
header: BoxHeaderRepr,
34-
data: u8
35-
}
36-
37-
}
17+
pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
18+
pub static RC_IMMORTAL : uint = 0x77777777;
3819

3920
/// Determine if two shared boxes point to the same object
4021
#[inline]

src/libstd/reflect.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Runtime type reflection
1919
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
2020
use libc::c_void;
2121
use sys;
22-
use vec;
22+
use unstable::raw;
2323

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

262262
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
263-
self.align_to::<vec::UnboxedVecRepr>();
263+
self.align_to::<raw::Vec<()>>();
264264
if ! self.inner.visit_vec(mtbl, inner) { return false; }
265265
true
266266
}

src/libstd/repr.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,17 @@ use container::Container;
2222
use io::{Writer, WriterUtil};
2323
use iterator::IteratorUtil;
2424
use libc::c_void;
25-
use managed;
2625
use ptr;
2726
use reflect;
2827
use reflect::{MovePtr, align};
2928
use str::StrSlice;
3029
use to_str::ToStr;
31-
use vec::raw::{VecRepr, SliceRepr};
32-
use vec;
33-
use vec::{OwnedVector, UnboxedVecRepr};
30+
use vec::OwnedVector;
3431
use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
32+
use unstable::raw;
3533

3634
#[cfg(test)] use io;
3735

38-
pub use managed::raw::BoxRepr;
39-
4036
/// Helpers
4137
4238
trait EscapedCharWriter {
@@ -198,11 +194,11 @@ impl ReprVisitor {
198194

199195
pub fn write_vec_range(&self,
200196
_mtbl: uint,
201-
ptr: *u8,
197+
ptr: *(),
202198
len: uint,
203199
inner: *TyDesc)
204200
-> bool {
205-
let mut p = ptr;
201+
let mut p = ptr as *u8;
206202
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
207203
self.writer.write_char('[');
208204
let mut first = true;
@@ -225,7 +221,7 @@ impl ReprVisitor {
225221

226222
pub fn write_unboxed_vec_repr(&self,
227223
mtbl: uint,
228-
v: &UnboxedVecRepr,
224+
v: &raw::Vec<()>,
229225
inner: *TyDesc)
230226
-> bool {
231227
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
@@ -289,7 +285,7 @@ impl TyVisitor for ReprVisitor {
289285
fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool {
290286
self.writer.write_char('@');
291287
self.write_mut_qualifier(mtbl);
292-
do self.get::<&managed::raw::BoxRepr> |b| {
288+
do self.get::<&raw::Box<()>> |b| {
293289
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
294290
self.visit_ptr_inner(p, inner);
295291
}
@@ -304,7 +300,7 @@ impl TyVisitor for ReprVisitor {
304300

305301
fn visit_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
306302
self.writer.write_char('~');
307-
do self.get::<&managed::raw::BoxRepr> |b| {
303+
do self.get::<&raw::Box<()>> |b| {
308304
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
309305
self.visit_ptr_inner(p, inner);
310306
}
@@ -330,43 +326,43 @@ impl TyVisitor for ReprVisitor {
330326

331327

332328
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool {
333-
do self.get::<vec::UnboxedVecRepr> |b| {
329+
do self.get::<raw::Vec<()>> |b| {
334330
self.write_unboxed_vec_repr(mtbl, b, inner);
335331
}
336332
}
337333

338334
fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool {
339-
do self.get::<&VecRepr> |b| {
335+
do self.get::<&raw::Box<raw::Vec<()>>> |b| {
340336
self.writer.write_char('@');
341337
self.write_mut_qualifier(mtbl);
342-
self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
338+
self.write_unboxed_vec_repr(mtbl, &b.data, inner);
343339
}
344340
}
345341

346342
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
347-
do self.get::<&UnboxedVecRepr> |b| {
343+
do self.get::<&raw::Vec<()>> |b| {
348344
self.writer.write_char('~');
349345
self.write_unboxed_vec_repr(mtbl, *b, inner);
350346
}
351347
}
352348

353349
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
354-
do self.get::<&VecRepr> |b| {
350+
do self.get::<&raw::Box<raw::Vec<()>>> |b| {
355351
self.writer.write_char('~');
356-
self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);
352+
self.write_unboxed_vec_repr(mtbl, &b.data, inner);
357353
}
358354
}
359355

360356
fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool {
361-
do self.get::<SliceRepr> |s| {
357+
do self.get::<raw::Slice<()>> |s| {
362358
self.writer.write_char('&');
363359
self.write_vec_range(mtbl, s.data, s.len, inner);
364360
}
365361
}
366362

367363
fn visit_evec_fixed(&self, _n: uint, sz: uint, _align: uint,
368364
mtbl: uint, inner: *TyDesc) -> bool {
369-
do self.get::<u8> |b| {
365+
do self.get::<()> |b| {
370366
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), sz, inner);
371367
}
372368
}
@@ -547,9 +543,9 @@ impl TyVisitor for ReprVisitor {
547543

548544
fn visit_opaque_box(&self) -> bool {
549545
self.writer.write_char('@');
550-
do self.get::<&managed::raw::BoxRepr> |b| {
546+
do self.get::<&raw::Box<()>> |b| {
551547
let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
552-
self.visit_ptr_inner(p, b.header.type_desc);
548+
self.visit_ptr_inner(p, b.type_desc);
553549
}
554550
}
555551

0 commit comments

Comments
 (0)