rustc: Mark an obstack fencepost when entering a dynamically-sized frame

This commit is contained in:
Patrick Walton 2011-08-17 13:15:04 -07:00
parent 62ac9d0b2e
commit 3aab46b020
4 changed files with 22 additions and 12 deletions

View file

@ -466,6 +466,14 @@ fn alloca(cx: &@block_ctxt, t: TypeRef) -> ValueRef {
} }
fn array_alloca(cx: &@block_ctxt, t: TypeRef, n: ValueRef) -> ValueRef { fn array_alloca(cx: &@block_ctxt, t: TypeRef, n: ValueRef) -> ValueRef {
alt bcx_fcx(cx).llobstacktoken {
none. {
bcx_fcx(cx).llobstacktoken =
some(cx.build.Call(bcx_ccx(cx).upcalls.dynastack_mark,
~[bcx_fcx(cx).lltaskptr]));
}
some(_) { /* no-op */ }
}
ret new_builder(cx.fcx.lldynamicallocas).ArrayAlloca(t, n); ret new_builder(cx.fcx.lldynamicallocas).ArrayAlloca(t, n);
} }
@ -5632,18 +5640,6 @@ fn llderivedtydescs_block_ctxt(fcx: &@fn_ctxt) -> @block_ctxt {
fcx: fcx}; fcx: fcx};
} }
fn lldynamicallocas_block_ctxt(fcx: &@fn_ctxt) -> @block_ctxt {
let cleanups: [cleanup] = ~[];
ret @{llbb: fcx.lldynamicallocas,
build: new_builder(fcx.lldynamicallocas),
parent: parent_none,
kind: SCOPE_BLOCK,
mutable cleanups: cleanups,
sp: fcx.sp,
fcx: fcx};
}
fn alloc_ty(cx: &@block_ctxt, t: &ty::t) -> result { fn alloc_ty(cx: &@block_ctxt, t: &ty::t) -> result {
let bcx = cx; let bcx = cx;
@ -5798,6 +5794,7 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: &span, llfndecl: ValueRef,
mutable llderivedtydescs_first: llbbs.dt, mutable llderivedtydescs_first: llbbs.dt,
mutable llderivedtydescs: llbbs.dt, mutable llderivedtydescs: llbbs.dt,
mutable lldynamicallocas: llbbs.da, mutable lldynamicallocas: llbbs.da,
mutable llobstacktoken: none::<ValueRef>,
mutable llself: none::<val_self_pair>, mutable llself: none::<val_self_pair>,
mutable lliterbody: none::<ValueRef>, mutable lliterbody: none::<ValueRef>,
mutable iterbodyty: none::<ty::t>, mutable iterbodyty: none::<ty::t>,

View file

@ -214,6 +214,10 @@ type fn_ctxt = {
// alloca'd by code in llallocas? // alloca'd by code in llallocas?
mutable lldynamicallocas: BasicBlockRef, mutable lldynamicallocas: BasicBlockRef,
// The token used to clear the dynamic allocas at the end of this frame.
// Will be |none| if there are no dynamic allocas.
mutable llobstacktoken: option::t<ValueRef>,
// The 'self' object currently in use in this function, if there // The 'self' object currently in use in this function, if there
// is one. // is one.
mutable llself: option::t<val_self_pair>, mutable llself: option::t<val_self_pair>,

View file

@ -58,6 +58,14 @@ rust_obstack::alloc_new(size_t len) {
return chunk->alloc(len); return chunk->alloc(len);
} }
rust_obstack::~rust_obstack() {
while (chunk) {
rust_obstack_chunk *prev = chunk->prev;
task->free(chunk);
chunk = prev;
}
}
void * void *
rust_obstack::alloc(size_t len) { rust_obstack::alloc(size_t len) {
if (!chunk) if (!chunk)

View file

@ -15,6 +15,7 @@ class rust_obstack {
public: public:
rust_obstack(rust_task *in_task) : chunk(NULL), task(in_task) {} rust_obstack(rust_task *in_task) : chunk(NULL), task(in_task) {}
~rust_obstack();
void *alloc(size_t len); void *alloc(size_t len);
void free(void *ptr); void free(void *ptr);