Commit 36a0b6dc authored by Andrew Farmer's avatar Andrew Farmer Committed by Ben Gamari
Browse files

Check CCS tree for pointers into shared object during checkUnload

Prevent shared objects from being unloaded if cost centre stacks point
at the object. This will prevent segfault in #11776, but also prevents
objects from ever being unloaded when profiling. Pruning CCS tree will
enable that in another diff.

Test Plan: make TEST=linker_profiled, examine linker_profiled.run.stderr

Reviewers: austin, simonmar, bgamari

Reviewed By: simonmar, bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2069

GHC Trac Issues: #11776
parent 7005b9f7
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
// - info pointers in heap objects and stack frames // - info pointers in heap objects and stack frames
// - pointers to static objects from the heap // - pointers to static objects from the heap
// - StablePtrs to static objects // - StablePtrs to static objects
// - pointers to cost centres from the cost centre tree
// //
// We can find live static objects after a major GC, so we don't have // We can find live static objects after a major GC, so we don't have
// to look at every closure pointer in the heap. However, we do have // to look at every closure pointer in the heap. However, we do have
...@@ -244,6 +245,25 @@ static void searchHeapBlocks (HashTable *addrs, bdescr *bd) ...@@ -244,6 +245,25 @@ static void searchHeapBlocks (HashTable *addrs, bdescr *bd)
} }
} }
#ifdef PROFILING
//
// Do not unload the object if the CCS tree refers to a CCS or CC which
// originates in the object.
//
static void searchCostCentres (HashTable *addrs, CostCentreStack *ccs)
{
IndexTable *i;
checkAddress(addrs, ccs);
checkAddress(addrs, ccs->cc);
for (i = ccs->indexTable; i != NULL; i = i->next) {
if (!i->back_edge) {
searchCostCentres(addrs, i->ccs);
}
}
}
#endif
// //
// Check whether we can unload any object code. This is called at the // Check whether we can unload any object code. This is called at the
// appropriate point during a GC, where all the heap data is nice and // appropriate point during a GC, where all the heap data is nice and
...@@ -303,6 +323,17 @@ void checkUnload (StgClosure *static_objects) ...@@ -303,6 +323,17 @@ void checkUnload (StgClosure *static_objects)
} }
} }
#ifdef PROFILING
/* Traverse the cost centre tree, calling checkAddress on each CCS/CC */
searchCostCentres(addrs, CCS_MAIN);
/* Also check each cost centre in the CC_LIST */
CostCentre *cc;
for (cc = CC_LIST; cc != NULL; cc = cc->link) {
checkAddress(addrs, cc);
}
#endif /* PROFILING */
// Look through the unloadable objects, and any object that is still // Look through the unloadable objects, and any object that is still
// marked as unreferenced can be physically unloaded, because we // marked as unreferenced can be physically unloaded, because we
// have no references to it. // have no references to it.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment