summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-06-28 09:05:36 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-06-28 09:05:36 +0000
commitae03da75d16d5d6e00c6f12102846509060a1138 (patch)
tree4a7dffcf02d7180581adab365e6cc57ae2909414 /rts
parent9cf9522864e8110f5c033d58d9d5d867c371a4b6 (diff)
downloadhaskell-ae03da75d16d5d6e00c6f12102846509060a1138.tar.gz
during shutdown, only free the heap if we waited for foreign calls to exit
Diffstat (limited to 'rts')
-rw-r--r--rts/RtsStartup.c7
-rw-r--r--rts/sm/Storage.c4
-rw-r--r--rts/sm/Storage.h2
3 files changed, 8 insertions, 5 deletions
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index b0cddbd18f..d7a8d954a2 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -450,8 +450,11 @@ hs_exit_(rtsBool wait_foreign)
/* free hash table storage */
exitHashTable();
- // Finally, free all our storage
- freeStorage();
+ // Finally, free all our storage. However, we only free the heap
+ // memory if we have waited for foreign calls to complete;
+ // otherwise a foreign call in progress may still be referencing
+ // heap memory (e.g. by being passed a ByteArray#).
+ freeStorage(wait_foreign);
#if defined(DEBUG)
/* and shut down the allocator debugging */
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index c9422e60b7..10a0a38d95 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -213,10 +213,10 @@ exitStorage (void)
}
void
-freeStorage (void)
+freeStorage (rtsBool free_heap)
{
stgFree(generations);
- freeAllMBlocks();
+ if (free_heap) freeAllMBlocks();
#if defined(THREADED_RTS)
closeMutex(&sm_mutex);
#endif
diff --git a/rts/sm/Storage.h b/rts/sm/Storage.h
index f6c50ad2f5..e541193573 100644
--- a/rts/sm/Storage.h
+++ b/rts/sm/Storage.h
@@ -19,7 +19,7 @@
void initStorage(void);
void exitStorage(void);
-void freeStorage(void);
+void freeStorage(rtsBool free_heap);
/* -----------------------------------------------------------------------------
Storage manager state