diff options
author | Austin Seipp <aseipp@pobox.com> | 2013-09-08 16:17:36 -0500 |
---|---|---|
committer | Austin Seipp <aseipp@pobox.com> | 2013-09-08 16:17:36 -0500 |
commit | 88dba610df290ff7807a76f702f2e5d41887500b (patch) | |
tree | e1324062ceef817866771e5bb3f4a93151ba3fb4 /rts | |
parent | c798a8c6c66d826efdc0201fa56d45337eecc2af (diff) | |
download | haskell-88dba610df290ff7807a76f702f2e5d41887500b.tar.gz |
Revert "Default to infinite stack size (#8189)"
This reverts commit d85044f6b201eae0a9e453b89c0433608e0778f0.
Diffstat (limited to 'rts')
-rw-r--r-- | rts/RtsFlags.c | 4 | ||||
-rw-r--r-- | rts/RtsUtils.c | 6 | ||||
-rw-r--r-- | rts/Schedule.c | 2 | ||||
-rw-r--r-- | rts/Threads.c | 10 | ||||
-rw-r--r-- | rts/sm/Storage.c | 55 |
5 files changed, 24 insertions, 53 deletions
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 46a8462dca..1e541a0201 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -94,7 +94,7 @@ void initRtsFlagsDefaults(void) RtsFlags.GcFlags.statsFile = NULL; RtsFlags.GcFlags.giveStats = NO_GC_STATS; - RtsFlags.GcFlags.maxStkSize = 0; /* off by default */ + RtsFlags.GcFlags.maxStkSize = (8 * 1024 * 1024) / sizeof(W_); RtsFlags.GcFlags.initialStkSize = 1024 / sizeof(W_); RtsFlags.GcFlags.stkChunkSize = (32 * 1024) / sizeof(W_); RtsFlags.GcFlags.stkChunkBufferSize = (1 * 1024) / sizeof(W_); @@ -233,7 +233,7 @@ usage_text[] = { " -? Prints this message and exits; the program is not executed", " --info Print information about the RTS used by this program", "", -" -K<size> Sets the maximum stack size (defaults to infinite) Egs: -K32k -K512k", +" -K<size> Sets the maximum stack size (default 8M) Egs: -K32k -K512k", " -ki<size> Sets the initial thread stack size (default 1k) Egs: -ki4k -ki2m", " -kc<size> Sets the stack chunk size (default 32k)", " -kb<size> Sets the stack chunk buffer size (default 1k)", diff --git a/rts/RtsUtils.c b/rts/RtsUtils.c index 604c7eed61..cb9002c361 100644 --- a/rts/RtsUtils.c +++ b/rts/RtsUtils.c @@ -114,12 +114,12 @@ stgFree(void* p) -------------------------------------------------------------------------- */ void -stackOverflow(StgTSO* tso) +stackOverflow(void) { - StackOverflowHook(tso->tot_stack_size * sizeof(W_)); + StackOverflowHook(RtsFlags.GcFlags.maxStkSize * sizeof(W_)); #if defined(TICKY_TICKY) - if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo(); + if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo(); #endif } diff --git a/rts/Schedule.c b/rts/Schedule.c index 20077b1d53..07ebec62b1 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -393,7 +393,7 @@ schedule (Capability *initialCapability, Task *task) run_thread: - // CurrentTSO is the thread to run. It might be different if we + // CurrentTSO is the thread to run. t might be different if we // loop back to run_thread, so make sure to set CurrentTSO after // that. cap->r.rCurrentTSO = t; diff --git a/rts/Threads.c b/rts/Threads.c index 90d3dfd115..14fb7e872c 100644 --- a/rts/Threads.c +++ b/rts/Threads.c @@ -499,8 +499,7 @@ threadStackOverflow (Capability *cap, StgTSO *tso) IF_DEBUG(sanity,checkTSO(tso)); - if ( (RtsFlags.GcFlags.maxStkSize > 0) // don't throw if we have infinite stack - && (tso->tot_stack_size >= RtsFlags.GcFlags.maxStkSize) + if (tso->tot_stack_size >= RtsFlags.GcFlags.maxStkSize && !(tso->flags & TSO_BLOCKEX)) { // NB. never raise a StackOverflow exception if the thread is // inside Control.Exceptino.block. It is impractical to protect @@ -576,12 +575,7 @@ threadStackOverflow (Capability *cap, StgTSO *tso) "allocating new stack chunk of size %d bytes", chunk_size * sizeof(W_)); - new_stack = (StgStack*) allocateFail(cap, chunk_size); - if (new_stack == NULL) { - // We've really run out of memory in the heap, so die. - stackOverflow(tso); - stg_exit(EXIT_STACKOVERFLOW); - } + new_stack = (StgStack*) allocate(cap, chunk_size); SET_HDR(new_stack, &stg_STACK_info, old_stack->header.prof.ccs); TICK_ALLOC_STACK(chunk_size); diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index df088132e3..b575fc3e52 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -624,27 +624,27 @@ move_STACK (StgStack *src, StgStack *dest) } /* ----------------------------------------------------------------------------- - allocateFail() + allocate() This allocates memory in the current thread - it is intended for - use primarily from STG-land where we have a Capability. + use primarily from STG-land where we have a Capability. It is + better than allocate() because it doesn't require taking the + sm_mutex lock in the common case. Memory is allocated directly from the nursery if possible (but not from the current nursery block, so as not to interfere with Hp/HpLim). - - We return NULL in the event of a heap overflow. -------------------------------------------------------------------------- */ StgPtr -allocateFail (Capability *cap, W_ n) +allocate (Capability *cap, W_ n) { bdescr *bd; StgPtr p; TICK_ALLOC_HEAP_NOCTR(WDS(n)); CCS_ALLOC(cap->r.rCCCS,n); - + if (n >= LARGE_OBJECT_THRESHOLD/sizeof(W_)) { W_ req_blocks = (W_)BLOCK_ROUND_UP(n*sizeof(W_)) / BLOCK_SIZE; @@ -655,7 +655,14 @@ allocateFail (Capability *cap, W_ n) req_blocks >= HS_INT32_MAX) // avoid overflow when // calling allocGroup() below { - return NULL; // heap overflow + heapOverflow(); + // heapOverflow() doesn't exit (see #2592), but we aren't + // in a position to do a clean shutdown here: we + // either have to allocate the memory or exit now. + // Allocating the memory would be bad, because the user + // has requested that we not exceed maxHeapSize, so we + // just exit. + stg_exit(EXIT_HEAPOVERFLOW); } ACQUIRE_SM_LOCK @@ -675,12 +682,12 @@ allocateFail (Capability *cap, W_ n) bd = cap->r.rCurrentAlloc; if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) { - + // The CurrentAlloc block is full, we need to find another // one. First, we try taking the next block from the // nursery: bd = cap->r.rCurrentNursery->link; - + if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) { // The nursery is empty, or the next block is already // full: allocate a fresh block (we can't fail here). @@ -713,36 +720,6 @@ allocateFail (Capability *cap, W_ n) return p; } -/* ----------------------------------------------------------------------------- - allocate() - - This allocates memory in the current thread - it is intended for - use primarily from STG-land where we have a Capability. - - Memory is allocated directly from the nursery if possible (but not - from the current nursery block, so as not to interfere with - Hp/HpLim). - - We crash with a HeapOverflow when the allocation fails. - -------------------------------------------------------------------------- */ - -StgPtr -allocate (Capability *cap, W_ n) -{ - StgPtr p = allocateFail(cap, n); - if (p == NULL) { - heapOverflow(); - // heapOverflow() doesn't exit (see #2592), but we aren't - // in a position to do a clean shutdown here: we - // either have to allocate the memory or exit now. - // Allocating the memory would be bad, because the user - // has requested that we not exceed maxHeapSize, so we - // just exit. - stg_exit(EXIT_HEAPOVERFLOW); - } - return p; -} - /* --------------------------------------------------------------------------- Allocate a fixed/pinned object. |