diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 19b600e44bbe..d6039da1cd7c 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -466,20 +466,17 @@ fn alloca(cx: &@block_ctxt, t: TypeRef) -> ValueRef { } fn array_alloca(cx: &@block_ctxt, t: TypeRef, n: ValueRef) -> ValueRef { - let bcx = cx; let builder = new_builder(cx.fcx.lldynamicallocas); - let lltaskptr = bcx_fcx(bcx).lltaskptr; - - let dynastack_alloc = bcx_ccx(bcx).upcalls.dynastack_alloc; - let llsz = builder.Mul(C_uint(llsize_of_real(bcx_ccx(bcx), t)), n); - let llresult = builder.Call(dynastack_alloc, ~[lltaskptr, llsz]); - ret builder.PointerCast(llresult, T_ptr(t)); -} - -fn mk_obstack_token(ccx: &@crate_ctxt, lldynamicallocas: BasicBlockRef, - lltaskptr: ValueRef) -> ValueRef { - let builder = new_builder(lldynamicallocas); - ret builder.Call(ccx.upcalls.dynastack_mark, ~[lltaskptr]); + alt bcx_fcx(cx).llobstacktoken { + none. { + let dynastack_mark = bcx_ccx(cx).upcalls.dynastack_mark; + let lltaskptr = bcx_fcx(cx).lltaskptr; + bcx_fcx(cx).llobstacktoken = + some(builder.Call(dynastack_mark, ~[lltaskptr])); + } + some(_) { /* no-op */ } + } + ret builder.ArrayAlloca(t, n); } @@ -4410,8 +4407,6 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t, lltargetfn = bcx.build.PointerCast(lltargetfn, T_ptr(T_ptr(lltargetty))); lltargetfn = bcx.build.Load(lltargetfn); llvm::LLVMSetTailCall(bcx.build.FastCall(lltargetfn, llargs), 1); - - bcx = trans_fn_cleanups(bcx); // TODO: Might break tail call. bcx.build.RetVoid(); finish_fn(fcx, lltop); ret {val: llthunk, ty: llthunk_ty}; @@ -5616,8 +5611,14 @@ fn trans_block_cleanups(cx: &@block_ctxt, cleanup_cx: &@block_ctxt) -> } fn trans_fn_cleanups(bcx: &@block_ctxt) -> @block_ctxt { - bcx.build.Call(bcx_ccx(bcx).upcalls.dynastack_free, - ~[bcx_fcx(bcx).lltaskptr, bcx_fcx(bcx).llobstacktoken]); + alt bcx_fcx(bcx).llobstacktoken { + some(lltoken_) { + let lltoken = lltoken_; // satisfy alias checker + bcx.build.Call(bcx_ccx(bcx).upcalls.dynastack_free, + ~[bcx_fcx(bcx).lltaskptr, lltoken]); + } + none. { /* nothing to do */ } + } ret bcx; } @@ -5806,7 +5807,6 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: &span, llfndecl: ValueRef, let derived_tydescs = map::mk_hashmap::(ty::hash_ty, ty::eq_ty); let llbbs = mk_standard_basic_blocks(llfndecl); - let llobstacktoken = mk_obstack_token(cx.ccx, llbbs.da, lltaskptr); ret @{llfn: llfndecl, lltaskptr: lltaskptr, llenv: llenv, @@ -5816,7 +5816,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: llobstacktoken, + mutable llobstacktoken: none::, mutable llself: none::, mutable lliterbody: none::, mutable iterbodyty: none::, @@ -6137,7 +6137,6 @@ fn trans_res_ctor(cx: @local_ctxt, sp: &span, dtor: &ast::_fn, let flag = GEP_tup_like(bcx, tup_t, llretptr, ~[0, 0]); bcx = flag.bcx; bcx.build.Store(C_int(1), flag.val); - bcx = trans_fn_cleanups(bcx); bcx.build.RetVoid(); finish_fn(fcx, lltop); } @@ -6434,7 +6433,6 @@ fn create_main_wrapper(ccx: &@crate_ctxt, sp: &span, }; bcx.build.FastCall(main_llfn, args); } - bcx = trans_fn_cleanups(bcx); bcx.build.RetVoid(); let lltop = bcx.llbb; @@ -6756,7 +6754,6 @@ fn decl_native_fn_and_pair(ccx: &@crate_ctxt, sp: &span, path: &[str], for d: {val: ValueRef, ty: ty::t} in drop_args { bcx = drop_ty(bcx, d.val, d.ty).bcx; } - bcx = trans_fn_cleanups(bcx); bcx.build.RetVoid(); finish_fn(fcx, lltop); } diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 1ddefcc73ed8..fdb18f819e4d 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -215,7 +215,8 @@ type fn_ctxt = { mutable lldynamicallocas: BasicBlockRef, // The token used to clear the dynamic allocas at the end of this frame. - mutable llobstacktoken: ValueRef, + // 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. diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs index 8d75c7834895..4b2e8f20738f 100644 --- a/src/comp/middle/trans_objects.rs +++ b/src/comp/middle/trans_objects.rs @@ -192,8 +192,6 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj, let p = bcx.build.PointerCast(box.box, llbox_ty); bcx.build.Store(p, pair_box); } - - bcx = trans_fn_cleanups(bcx); bcx.build.RetVoid(); // Insert the mandatory first few basic blocks before lltop. @@ -712,7 +710,6 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method, // And, finally, call the outer method. bcx.build.FastCall(llouter_mthd, llouter_mthd_args); - bcx = trans_fn_cleanups(bcx); bcx.build.RetVoid(); finish_fn(fcx, lltop); @@ -885,7 +882,6 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method, // And, finally, call the original (inner) method. bcx.build.FastCall(llorig_mthd, llorig_mthd_args); - bcx = trans_fn_cleanups(bcx); bcx.build.RetVoid(); finish_fn(fcx, lltop); diff --git a/src/rt/rust_obstack.cpp b/src/rt/rust_obstack.cpp index f76a80aada98..5ec996f4e32f 100644 --- a/src/rt/rust_obstack.cpp +++ b/src/rt/rust_obstack.cpp @@ -14,12 +14,7 @@ #undef max #endif -//#define DPRINT(fmt,...) fprintf(stderr, fmt, ##__VA_ARGS__) -#define DPRINT(fmt,...) - -//const size_t DEFAULT_CHUNK_SIZE = 4096; -const size_t DEFAULT_CHUNK_SIZE = 300000; -const size_t DEFAULT_ALIGNMENT = 16; +const size_t DEFAULT_CHUNK_SIZE = 4096; struct rust_obstack_chunk { rust_obstack_chunk *prev; @@ -37,13 +32,8 @@ struct rust_obstack_chunk { void * rust_obstack_chunk::alloc(size_t len) { - alen = align_to(alen, DEFAULT_ALIGNMENT); - - if (len > size - alen) { - DPRINT("Not enough space, len=%lu!\n", len); - assert(0); + if (len > size - alen) return NULL; // Not enough space. - } void *result = data + alen; alen += len; return result; @@ -52,7 +42,7 @@ rust_obstack_chunk::alloc(size_t len) { bool rust_obstack_chunk::free(void *ptr) { uint8_t *p = (uint8_t *)ptr; - if (p < data || p > data + size) + if (p < data || p >= data + size) return false; assert(p <= data + alen); alen = (size_t)(p - data); @@ -64,7 +54,6 @@ void * rust_obstack::alloc_new(size_t len) { size_t chunk_size = std::max(len, DEFAULT_CHUNK_SIZE); void *ptr = task->malloc(sizeof(chunk) + chunk_size, "obstack"); - DPRINT("making new chunk at %p, len %lu\n", ptr, chunk_size); chunk = new(ptr) rust_obstack_chunk(chunk, chunk_size); return chunk->alloc(len); } @@ -81,12 +70,8 @@ void * rust_obstack::alloc(size_t len) { if (!chunk) return alloc_new(len); - - DPRINT("alloc sz %u", (uint32_t)len); - void *ptr = chunk->alloc(len); ptr = ptr ? ptr : alloc_new(len); - return ptr; } @@ -95,11 +80,8 @@ rust_obstack::free(void *ptr) { if (!ptr) return; - DPRINT("free ptr %p\n", ptr); - assert(chunk); while (!chunk->free(ptr)) { - DPRINT("deleting chunk at %p\n", chunk); rust_obstack_chunk *prev = chunk->prev; task->free(chunk); chunk = prev; diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp index e5b96e7e91f7..c23d3aaa858b 100644 --- a/src/rt/rust_shape.cpp +++ b/src/rt/rust_shape.cpp @@ -64,6 +64,18 @@ const uint8_t CMP_LT = 1u; const uint8_t CMP_LE = 2u; +// Utility functions + +// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power +// of two. +template +static inline T +align_to(T size, size_t alignment) { + assert(alignment); + T x = (T)(((uintptr_t)size + alignment - 1) & ~(alignment - 1)); + return x; +} + // Utility classes struct size_align { @@ -173,18 +185,11 @@ public: } }; -} // end namespace shape - - -inline shape::ptr_pair -align_to(const shape::ptr_pair &pair, size_t n) { - return shape::ptr_pair::make(align_to(pair.fst, n), - align_to(pair.snd, n)); +inline ptr_pair +align_to(const ptr_pair &pair, size_t n) { + return ptr_pair::make(align_to(pair.fst, n), align_to(pair.snd, n)); } - -namespace shape { - // NB: This function does not align. template inline data_pair diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index ac99f501f25a..d04de59a4dfa 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -430,7 +430,7 @@ upcall_dynastack_mark(rust_task *task) { /** Allocates space in the dynamic stack and returns it. */ extern "C" CDECL void * upcall_dynastack_alloc(rust_task *task, size_t sz) { - return sz ? task->dynastack.alloc(sz) : NULL; + return task->dynastack.alloc(sz); } /** Frees space in the dynamic stack. */ diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index 401c39413b65..6e6f364e3a63 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -125,16 +125,6 @@ next_power_of_two(size_t s) return tmp + 1; } -// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power -// of two. -template -static inline T -align_to(T size, size_t alignment) { - assert(alignment); - T x = (T)(((uintptr_t)size + alignment - 1) & ~(alignment - 1)); - return x; -} - // Initialization helper for ISAAC RNG template