summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-06-23 16:13:55 -0400
committerBen Gamari <ben@smart-cactus.org>2020-06-24 16:08:56 -0400
commite90af2f456f0430d11eea19b285986e732034798 (patch)
treee8cb29b49ce1d6029fb9b786f33a68ee51ab234c
parenta50487a5644dc4df2248b7cd35c77e39ab4f963c (diff)
downloadhaskell-wip/free-censuses.tar.gz
rts/ProfHeap: Free old allocations when reinitialising Censuseswip/free-censuses
Previously when not LDV profiling we would repeatedly reinitialise `censuses[0]` with `initEra`. This failed to free the `Arena` and `HashTable` from the old census, resulting in a memory leak. Fixes #18348.
-rw-r--r--rts/ProfHeap.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index 0b7b386249..06bff048e7 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -347,6 +347,16 @@ LDV_recordDead( const StgClosure *c, uint32_t size )
STATIC_INLINE void
initEra(Census *census)
{
+ // N.B. When not LDV profiling we reinitialise the same Census over
+ // and over again. Consequently, we need to ensure that we free the
+ // resources from the previous census.
+ if (census->hash) {
+ freeHashTable(census->hash, NULL);
+ }
+ if (census->arena) {
+ arenaFree(census->arena);
+ }
+
census->hash = allocHashTable();
census->ctrs = NULL;
census->arena = newArena();
@@ -511,6 +521,11 @@ initHeapProfiling(void)
censuses = stgMallocBytes(sizeof(Census) * n_censuses, "initHeapProfiling");
+ // Ensure that arena and hash are NULL since otherwise initEra will attempt to free them.
+ for (unsigned int i=0; i < n_censuses; i++) {
+ censuses[i].arena = NULL;
+ censuses[i].hash = NULL;
+ }
initEra( &censuses[era] );
/* initProfilingLogFile(); */