diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2014-02-05 23:05:30 -0500 | 
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2014-02-07 20:08:35 -0500 | 
| commit | 940d1ae2f3b1cba8cfd858ab3a54d6408b53b033 (patch) | |
| tree | c1060d4799cecaca94f31f6b1cae8bc9aa66a170 /src/libstd/cleanup.rs | |
| parent | 56565eb129018a708445afcd6ea14f5b51cf27e5 (diff) | |
| download | rust-940d1ae2f3b1cba8cfd858ab3a54d6408b53b033.tar.gz rust-940d1ae2f3b1cba8cfd858ab3a54d6408b53b033.zip | |
remove type descriptors from proc and @T
This also drops support for the managed pointer POISON_ON_FREE feature as it's not worth adding back the support for it. After a snapshot, the leftovers can be removed.
Diffstat (limited to 'src/libstd/cleanup.rs')
| -rw-r--r-- | src/libstd/cleanup.rs | 71 | 
1 files changed, 50 insertions, 21 deletions
| diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 82c1ed7440c..a43dca94970 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -11,11 +11,8 @@ #[doc(hidden)]; use ptr; -use unstable::intrinsics::TyDesc; use unstable::raw; -type DropGlue<'a> = 'a |**TyDesc, *u8|; - static RC_IMMORTAL : uint = 0x77777777; /* @@ -24,11 +21,6 @@ static RC_IMMORTAL : uint = 0x77777777; * This runs at task death to free all boxes. */ -struct AnnihilateStats { - n_total_boxes: uint, - n_bytes_freed: uint -} - unsafe fn each_live_alloc(read_next_before: bool, f: |alloc: *mut raw::Box<()>| -> bool) -> bool { @@ -65,21 +57,18 @@ fn debug_mem() -> bool { } /// Destroys all managed memory (i.e. @ boxes) held by the current task. +#[cfg(stage0)] pub unsafe fn annihilate() { use rt::local_heap::local_free; - use mem; - let mut stats = AnnihilateStats { - n_total_boxes: 0, - n_bytes_freed: 0 - }; + let mut n_total_boxes = 0u; // Pass 1: Make all boxes immortal. // // In this pass, nothing gets freed, so it does not matter whether // we read the next field before or after the callback. each_live_alloc(true, |alloc| { - stats.n_total_boxes += 1; + n_total_boxes += 1; (*alloc).ref_count = RC_IMMORTAL; true }); @@ -103,18 +92,58 @@ pub unsafe fn annihilate() { // left), so we must read the `next` field before, since it will // not be valid after. each_live_alloc(true, |alloc| { - stats.n_bytes_freed += - (*((*alloc).type_desc)).size - + mem::size_of::<raw::Box<()>>(); local_free(alloc as *u8); true }); if debug_mem() { // We do logging here w/o allocation. - debug!("annihilator stats:\n \ - total boxes: {}\n \ - bytes freed: {}", - stats.n_total_boxes, stats.n_bytes_freed); + debug!("total boxes annihilated: {}", n_total_boxes); + } +} + +/// Destroys all managed memory (i.e. @ boxes) held by the current task. +#[cfg(not(stage0))] +pub unsafe fn annihilate() { + use rt::local_heap::local_free; + + let mut n_total_boxes = 0u; + + // Pass 1: Make all boxes immortal. + // + // In this pass, nothing gets freed, so it does not matter whether + // we read the next field before or after the callback. + each_live_alloc(true, |alloc| { + n_total_boxes += 1; + (*alloc).ref_count = RC_IMMORTAL; + true + }); + + // Pass 2: Drop all boxes. + // + // In this pass, unique-managed boxes may get freed, but not + // managed boxes, so we must read the `next` field *after* the + // callback, as the original value may have been freed. + each_live_alloc(false, |alloc| { + let drop_glue = (*alloc).drop_glue; + let data = &mut (*alloc).data as *mut (); + drop_glue(data as *mut u8); + true + }); + + // Pass 3: Free all boxes. + // + // In this pass, managed boxes may get freed (but not + // unique-managed boxes, though I think that none of those are + // left), so we must read the `next` field before, since it will + // not be valid after. + each_live_alloc(true, |alloc| { + local_free(alloc as *u8); + true + }); + + if debug_mem() { + // We do logging here w/o allocation. + debug!("total boxes annihilated: {}", n_total_boxes); } } | 
