Skip to content

Commit 940d1ae

Browse files
committed
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.
1 parent 56565eb commit 940d1ae

File tree

10 files changed

+171
-42
lines changed

10 files changed

+171
-42
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,6 @@ pub fn malloc_raw_dyn<'a>(
352352
if heap == heap_exchange {
353353
let llty_value = type_of::type_of(ccx, t);
354354

355-
356355
// Allocate space:
357356
let r = callee::trans_lang_call(
358357
bcx,
@@ -375,17 +374,18 @@ pub fn malloc_raw_dyn<'a>(
375374
// Grab the TypeRef type of box_ptr_ty.
376375
let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
377376
let llty = type_of(ccx, box_ptr_ty);
377+
let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);
378378

379379
// Get the tydesc for the body:
380380
let static_ti = get_tydesc(ccx, t);
381381
glue::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
382382

383383
// Allocate space:
384-
let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p());
384+
let drop_glue = static_ti.drop_glue.get().unwrap();
385385
let r = callee::trans_lang_call(
386386
bcx,
387387
langcall,
388-
[tydesc, size],
388+
[PointerCast(bcx, drop_glue, Type::glue_fn(Type::i8p()).ptr_to()), size, llalign],
389389
None);
390390
rslt(r.bcx, PointerCast(r.bcx, r.val, llty))
391391
}

src/librustc/middle/trans/debuginfo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,7 +1779,7 @@ fn boxed_type_metadata(cx: &CrateContext,
17791779
offset: ComputedMemberOffset,
17801780
},
17811781
MemberDescription {
1782-
name: ~"tydesc",
1782+
name: ~"drop_glue",
17831783
llvm_type: member_llvm_types[1],
17841784
type_metadata: nil_pointer_type_metadata,
17851785
offset: ComputedMemberOffset,
@@ -1824,7 +1824,7 @@ fn boxed_type_metadata(cx: &CrateContext,
18241824
-> bool {
18251825
member_llvm_types.len() == 5 &&
18261826
member_llvm_types[0] == cx.int_type &&
1827-
member_llvm_types[1] == cx.tydesc_type.ptr_to() &&
1827+
member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
18281828
member_llvm_types[2] == Type::i8().ptr_to() &&
18291829
member_llvm_types[3] == Type::i8().ptr_to() &&
18301830
member_llvm_types[4] == content_llvm_type

src/librustc/middle/trans/glue.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,9 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
355355
let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
356356
// Only drop the value when it is non-null
357357
with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
358-
let lldtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
359-
let lldtor = Load(bcx, lldtor_ptr);
360-
Call(bcx, lldtor, [PointerCast(bcx, lluniquevalue, Type::i8p())], []);
358+
let dtor_ptr = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
359+
let dtor = Load(bcx, dtor_ptr);
360+
Call(bcx, dtor, [PointerCast(bcx, lluniquevalue, Type::i8p())], []);
361361
bcx
362362
})
363363
}
@@ -367,18 +367,12 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
367367
let env_ptr_ty = Type::at_box(ccx, Type::i8()).ptr_to();
368368
let env = PointerCast(bcx, env, env_ptr_ty);
369369
with_cond(bcx, IsNotNull(bcx, env), |bcx| {
370-
// Load the type descr found in the env
371-
let lltydescty = ccx.tydesc_type.ptr_to();
372-
let tydescptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
373-
let tydesc = Load(bcx, tydescptr);
374-
let tydesc = PointerCast(bcx, tydesc, lltydescty);
375-
376-
// Drop the tuple data then free the descriptor
370+
let dtor_ptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
371+
let dtor = Load(bcx, dtor_ptr);
377372
let cdata = GEPi(bcx, env, [0u, abi::box_field_body]);
378-
call_tydesc_glue_full(bcx, cdata, tydesc,
379-
abi::tydesc_field_drop_glue, None);
373+
Call(bcx, dtor, [PointerCast(bcx, cdata, Type::i8p())], []);
380374

381-
// Free the ty descr (if necc) and the env itself
375+
// Free the environment itself
382376
trans_exchange_free(bcx, env)
383377
})
384378
}

src/librustc/middle/trans/type_.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl Type {
238238
// The box pointed to by @T.
239239
pub fn at_box(ctx: &CrateContext, ty: Type) -> Type {
240240
Type::struct_([
241-
ctx.int_type, ctx.tydesc_type.ptr_to(),
241+
ctx.int_type, Type::glue_fn(Type::i8p()).ptr_to(),
242242
Type::i8p(), Type::i8p(), ty
243243
], false)
244244
}

src/libstd/cleanup.rs

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@
1111
#[doc(hidden)];
1212

1313
use ptr;
14-
use unstable::intrinsics::TyDesc;
1514
use unstable::raw;
1615

17-
type DropGlue<'a> = 'a |**TyDesc, *u8|;
18-
1916
static RC_IMMORTAL : uint = 0x77777777;
2017

2118
/*
@@ -24,11 +21,6 @@ static RC_IMMORTAL : uint = 0x77777777;
2421
* This runs at task death to free all boxes.
2522
*/
2623

27-
struct AnnihilateStats {
28-
n_total_boxes: uint,
29-
n_bytes_freed: uint
30-
}
31-
3224
unsafe fn each_live_alloc(read_next_before: bool,
3325
f: |alloc: *mut raw::Box<()>| -> bool)
3426
-> bool {
@@ -65,21 +57,18 @@ fn debug_mem() -> bool {
6557
}
6658

6759
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
60+
#[cfg(stage0)]
6861
pub unsafe fn annihilate() {
6962
use rt::local_heap::local_free;
70-
use mem;
7163

72-
let mut stats = AnnihilateStats {
73-
n_total_boxes: 0,
74-
n_bytes_freed: 0
75-
};
64+
let mut n_total_boxes = 0u;
7665

7766
// Pass 1: Make all boxes immortal.
7867
//
7968
// In this pass, nothing gets freed, so it does not matter whether
8069
// we read the next field before or after the callback.
8170
each_live_alloc(true, |alloc| {
82-
stats.n_total_boxes += 1;
71+
n_total_boxes += 1;
8372
(*alloc).ref_count = RC_IMMORTAL;
8473
true
8574
});
@@ -103,18 +92,58 @@ pub unsafe fn annihilate() {
10392
// left), so we must read the `next` field before, since it will
10493
// not be valid after.
10594
each_live_alloc(true, |alloc| {
106-
stats.n_bytes_freed +=
107-
(*((*alloc).type_desc)).size
108-
+ mem::size_of::<raw::Box<()>>();
10995
local_free(alloc as *u8);
11096
true
11197
});
11298

11399
if debug_mem() {
114100
// We do logging here w/o allocation.
115-
debug!("annihilator stats:\n \
116-
total boxes: {}\n \
117-
bytes freed: {}",
118-
stats.n_total_boxes, stats.n_bytes_freed);
101+
debug!("total boxes annihilated: {}", n_total_boxes);
102+
}
103+
}
104+
105+
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
106+
#[cfg(not(stage0))]
107+
pub unsafe fn annihilate() {
108+
use rt::local_heap::local_free;
109+
110+
let mut n_total_boxes = 0u;
111+
112+
// Pass 1: Make all boxes immortal.
113+
//
114+
// In this pass, nothing gets freed, so it does not matter whether
115+
// we read the next field before or after the callback.
116+
each_live_alloc(true, |alloc| {
117+
n_total_boxes += 1;
118+
(*alloc).ref_count = RC_IMMORTAL;
119+
true
120+
});
121+
122+
// Pass 2: Drop all boxes.
123+
//
124+
// In this pass, unique-managed boxes may get freed, but not
125+
// managed boxes, so we must read the `next` field *after* the
126+
// callback, as the original value may have been freed.
127+
each_live_alloc(false, |alloc| {
128+
let drop_glue = (*alloc).drop_glue;
129+
let data = &mut (*alloc).data as *mut ();
130+
drop_glue(data as *mut u8);
131+
true
132+
});
133+
134+
// Pass 3: Free all boxes.
135+
//
136+
// In this pass, managed boxes may get freed (but not
137+
// unique-managed boxes, though I think that none of those are
138+
// left), so we must read the `next` field before, since it will
139+
// not be valid after.
140+
each_live_alloc(true, |alloc| {
141+
local_free(alloc as *u8);
142+
true
143+
});
144+
145+
if debug_mem() {
146+
// We do logging here w/o allocation.
147+
debug!("total boxes annihilated: {}", n_total_boxes);
119148
}
120149
}

src/libstd/rt/env.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! Runtime environment settings
1212
13+
// NOTE: remove `POISON_ON_FREE` after a snapshot
14+
1315
use from_str::from_str;
1416
use option::{Some, None};
1517
use os;

src/libstd/rt/global_heap.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010

1111
use libc::{c_void, size_t, free, malloc, realloc};
1212
use ptr::{RawPtr, mut_null};
13-
use unstable::intrinsics::{TyDesc, abort};
13+
#[cfg(stage0)]
14+
use unstable::intrinsics::TyDesc;
15+
use unstable::intrinsics::abort;
1416
use unstable::raw;
1517
use mem::size_of;
1618

@@ -73,14 +75,23 @@ pub unsafe fn exchange_malloc(size: uint) -> *u8 {
7375
}
7476

7577
// FIXME: #7496
76-
#[cfg(not(test))]
78+
#[cfg(not(test), stage0)]
7779
#[lang="closure_exchange_malloc"]
7880
#[inline]
7981
pub unsafe fn closure_exchange_malloc_(td: *u8, size: uint) -> *u8 {
8082
closure_exchange_malloc(td, size)
8183
}
8284

85+
// FIXME: #7496
86+
#[cfg(not(test), not(stage0))]
87+
#[lang="closure_exchange_malloc"]
8388
#[inline]
89+
pub unsafe fn closure_exchange_malloc_(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
90+
closure_exchange_malloc(drop_glue, size, align)
91+
}
92+
93+
#[inline]
94+
#[cfg(stage0)]
8495
pub unsafe fn closure_exchange_malloc(td: *u8, size: uint) -> *u8 {
8596
let td = td as *TyDesc;
8697
let size = size;
@@ -96,6 +107,18 @@ pub unsafe fn closure_exchange_malloc(td: *u8, size: uint) -> *u8 {
96107
alloc as *u8
97108
}
98109

110+
#[inline]
111+
#[cfg(not(stage0))]
112+
pub unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
113+
let total_size = get_box_size(size, align);
114+
let p = malloc_raw(total_size);
115+
116+
let alloc = p as *mut raw::Box<()>;
117+
(*alloc).drop_glue = drop_glue;
118+
119+
alloc as *u8
120+
}
121+
99122
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
100123
// inside a landing pad may corrupt the state of the exception handler.
101124
#[cfg(not(test))]

src/libstd/rt/local_heap.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rt::env;
2121
use rt::global_heap;
2222
use rt::local::Local;
2323
use rt::task::Task;
24+
#[cfg(stage0)]
2425
use unstable::intrinsics::TyDesc;
2526
use unstable::raw;
2627
use vec::ImmutableVector;
@@ -60,6 +61,7 @@ impl LocalHeap {
6061
}
6162

6263
#[inline]
64+
#[cfg(stage0)]
6365
pub fn alloc(&mut self, td: *TyDesc, size: uint) -> *mut Box {
6466
let total_size = global_heap::get_box_size(size, unsafe { (*td).align });
6567
let alloc = self.memory_region.malloc(total_size);
@@ -80,6 +82,28 @@ impl LocalHeap {
8082
return alloc;
8183
}
8284

85+
#[inline]
86+
#[cfg(not(stage0))]
87+
pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box {
88+
let total_size = global_heap::get_box_size(size, align);
89+
let alloc = self.memory_region.malloc(total_size);
90+
{
91+
// Make sure that we can't use `mybox` outside of this scope
92+
let mybox: &mut Box = unsafe { cast::transmute(alloc) };
93+
// Clear out this box, and move it to the front of the live
94+
// allocations list
95+
mybox.drop_glue = drop_glue;
96+
mybox.ref_count = 1;
97+
mybox.prev = ptr::mut_null();
98+
mybox.next = self.live_allocs;
99+
if !self.live_allocs.is_null() {
100+
unsafe { (*self.live_allocs).prev = alloc; }
101+
}
102+
self.live_allocs = alloc;
103+
}
104+
return alloc;
105+
}
106+
83107
#[inline]
84108
pub fn realloc(&mut self, ptr: *mut Box, size: uint) -> *mut Box {
85109
// Make sure that we can't use `mybox` outside of this scope
@@ -102,6 +126,7 @@ impl LocalHeap {
102126
}
103127

104128
#[inline]
129+
#[cfg(stage0)]
105130
pub fn free(&mut self, alloc: *mut Box) {
106131
{
107132
// Make sure that we can't use `mybox` outside of this scope
@@ -133,6 +158,28 @@ impl LocalHeap {
133158

134159
self.memory_region.free(alloc);
135160
}
161+
162+
#[inline]
163+
#[cfg(not(stage0))]
164+
pub fn free(&mut self, alloc: *mut Box) {
165+
{
166+
// Make sure that we can't use `mybox` outside of this scope
167+
let mybox: &mut Box = unsafe { cast::transmute(alloc) };
168+
169+
// Unlink it from the linked list
170+
if !mybox.prev.is_null() {
171+
unsafe { (*mybox.prev).next = mybox.next; }
172+
}
173+
if !mybox.next.is_null() {
174+
unsafe { (*mybox.next).prev = mybox.prev; }
175+
}
176+
if self.live_allocs == alloc {
177+
self.live_allocs = mybox.next;
178+
}
179+
}
180+
181+
self.memory_region.free(alloc);
182+
}
136183
}
137184

138185
impl Drop for LocalHeap {
@@ -292,6 +339,7 @@ impl Drop for MemoryRegion {
292339
}
293340

294341
#[inline]
342+
#[cfg(stage0)]
295343
pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
296344
// FIXME: Unsafe borrow for speed. Lame.
297345
let task: Option<*mut Task> = Local::try_unsafe_borrow();
@@ -303,6 +351,19 @@ pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
303351
}
304352
}
305353

354+
#[inline]
355+
#[cfg(not(stage0))]
356+
pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
357+
// FIXME: Unsafe borrow for speed. Lame.
358+
let task: Option<*mut Task> = Local::try_unsafe_borrow();
359+
match task {
360+
Some(task) => {
361+
(*task).heap.alloc(drop_glue, size, align) as *u8
362+
}
363+
None => rtabort!("local malloc outside of task")
364+
}
365+
}
366+
306367
// A little compatibility function
307368
#[inline]
308369
pub unsafe fn local_free(ptr: *u8) {

0 commit comments

Comments
 (0)