summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rts/CheckUnload.c45
1 files changed, 14 insertions, 31 deletions
diff --git a/rts/CheckUnload.c b/rts/CheckUnload.c
index 91af500990..668b70b45d 100644
--- a/rts/CheckUnload.c
+++ b/rts/CheckUnload.c
@@ -495,36 +495,17 @@ gcCostCentreStacks (CostCentreStack *ccs)
}
}
-static bool objectContains (ObjectCode *oc, const void *addr)
-{
- int i;
-
- if (oc != NULL) {
- for (i = 0; i < oc->n_sections; i++) {
- if (oc->sections[i].kind != SECTIONKIND_OTHER) {
- if ((W_)addr >= (W_)oc->sections[i].start &&
- (W_)addr < (W_)oc->sections[i].start
- + oc->sections[i].size) {
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-//
-// Remove all CostCentres which are statically allocated in the given object
-// from the global CC_LIST.
-//
-static void gcCostCentres(ObjectCode *oc)
+// Remove from the global CC_LIST all CostCentres which are statically
+// allocated in an unloaded object that we are about to free in this GC cycle.
+static void gcCostCentres(OCSectionIndices *s_indices)
{
CostCentre *cc, *prev, *next;
+ ObjectCode *oc;
prev = NULL;
for (cc = CC_LIST; cc != NULL; cc = next) {
next = cc->link;
- if (objectContains(oc, cc)) {
+ oc = findOC(s_indices, cc);
+ if (oc != NULL && oc->mark == 0) {
if (prev == NULL) {
CC_LIST = cc->link;
} else {
@@ -556,18 +537,20 @@ void checkUnload()
markObjectLive(NULL, (W_)oc, NULL);
}
+#if defined(PROFILING)
+ // At this point, we know what object should be unloaded based on the
+ // referenced field in its metadata ObjetCode* struct. Thus, we can
+ // traverse CC_LIST to prune CCs that belong to one of the unloaded
+ // objects.
+ gcCostCentres(s_indices);
+#endif
+
// Free unmarked objects
ObjectCode *next = NULL;
for (ObjectCode *oc = old_objects; oc != NULL; oc = next) {
next = oc->next;
ASSERT(oc->status == OBJECT_UNLOADED);
-#if defined(PROFILING)
- // The CCS tree isn't keeping this object alive, and it is unloaded,
- // so we can prune the global CC_LIST of any CCs from this object.
- gcCostCentres(oc);
-#endif
-
removeOCSectionIndices(s_indices, oc);
// Symbols should be removed by unloadObj_.