From 3aab46b0209adad0fd6f24b5b94b6401b13257b7 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 17 Aug 2011 13:15:04 -0700 Subject: [PATCH] rustc: Mark an obstack fencepost when entering a dynamically-sized frame --- src/comp/middle/trans.rs | 21 +++++++++------------ src/comp/middle/trans_common.rs | 4 ++++ src/rt/rust_obstack.cpp | 8 ++++++++ src/rt/rust_obstack.h | 1 + 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 477c7c6a399..84ca18c7b3f 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -466,6 +466,14 @@ fn alloca(cx: &@block_ctxt, t: TypeRef) -> 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); } @@ -5632,18 +5640,6 @@ fn llderivedtydescs_block_ctxt(fcx: &@fn_ctxt) -> @block_ctxt { 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 { 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: llbbs.dt, mutable lldynamicallocas: llbbs.da, + mutable llobstacktoken: none::, mutable llself: none::, mutable lliterbody: none::, mutable iterbodyty: none::, diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 1c7be7a3583..fdb18f819e4 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -214,6 +214,10 @@ type fn_ctxt = { // alloca'd by code in llallocas? 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, + // The 'self' object currently in use in this function, if there // is one. mutable llself: option::t, diff --git a/src/rt/rust_obstack.cpp b/src/rt/rust_obstack.cpp index 342310d4b5c..9300ec49073 100644 --- a/src/rt/rust_obstack.cpp +++ b/src/rt/rust_obstack.cpp @@ -58,6 +58,14 @@ rust_obstack::alloc_new(size_t len) { return chunk->alloc(len); } +rust_obstack::~rust_obstack() { + while (chunk) { + rust_obstack_chunk *prev = chunk->prev; + task->free(chunk); + chunk = prev; + } +} + void * rust_obstack::alloc(size_t len) { if (!chunk) diff --git a/src/rt/rust_obstack.h b/src/rt/rust_obstack.h index 5a80638aba7..595be6fa3a5 100644 --- a/src/rt/rust_obstack.h +++ b/src/rt/rust_obstack.h @@ -15,6 +15,7 @@ class rust_obstack { public: rust_obstack(rust_task *in_task) : chunk(NULL), task(in_task) {} + ~rust_obstack(); void *alloc(size_t len); void free(void *ptr);