summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-12-04 10:12:26 +0000
committerSimon Marlow <marlowsd@gmail.com>2014-12-05 10:06:16 +0000
commita48bee9fa1cf51c9df3bd87079eb8ff9b222e717 (patch)
tree060d1e8f07af6601ddff1851de742c2d5a82e944 /rts
parent55a2a0b4893486e5dde151620d7f46e8035d2af5 (diff)
downloadhaskell-a48bee9fa1cf51c9df3bd87079eb8ff9b222e717.tar.gz
Revert "Revert "Add purgeObj() to remove the symbol table entries for an object""
This reverts commit 7932b2adaecac6c86038176d909c20ad1b1f9604.
Diffstat (limited to 'rts')
-rw-r--r--rts/Linker.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index cb2fac6b6b..5c7a64e91d 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -2282,20 +2282,45 @@ mmap_again:
}
#endif // USE_MMAP
+/*
+ * Remove symbols from the symbol table, and free oc->symbols.
+ * This operation is idempotent.
+ */
static void removeOcSymbols (ObjectCode *oc)
{
if (oc->symbols == NULL) return;
- /* Remove all the mappings for the symbols within this object..
- */
+ // Remove all the mappings for the symbols within this object..
int i;
for (i = 0; i < oc->n_symbols; i++) {
if (oc->symbols[i] != NULL) {
ghciRemoveSymbolTable(symhash, oc->symbols[i], oc);
}
}
+
+ stgFree(oc->symbols);
+ oc->symbols = NULL;
+}
+
+/*
+ * Release StablePtrs and free oc->stable_ptrs.
+ * This operation is idempotent.
+ */
+static void freeOcStablePtrs (ObjectCode *oc)
+{
+ // Release any StablePtrs that were created when this
+ // object module was initialized.
+ ForeignExportStablePtr *fe_ptr, *next;
+
+ for (fe_ptr = oc->stable_ptrs; fe_ptr != NULL; fe_ptr = next) {
+ next = fe_ptr->next;
+ freeStablePtr(fe_ptr->stable_ptr);
+ stgFree(fe_ptr);
+ }
+ oc->stable_ptrs = NULL;
}
+
/*
* freeObjectCode() releases all the pieces of an ObjectCode. It is called by
* the GC when a previously unloaded ObjectCode has been determined to be
@@ -3042,6 +3067,7 @@ static HsInt loadObj_ (pathchar *path)
if (! loadOc(oc)) {
// failed; free everything we've allocated
removeOcSymbols(oc);
+ // no need to freeOcStablePtrs, they aren't created until resolveObjs()
freeObjectCode(oc);
return 0;
}
@@ -3177,7 +3203,7 @@ HsInt resolveObjs (void)
/* -----------------------------------------------------------------------------
* delete an object from the pool
*/
-static HsInt unloadObj_ (pathchar *path)
+static HsInt unloadObj_ (pathchar *path, rtsBool just_purge)
{
ObjectCode *oc, *prev, *next;
HsBool unloadedAnyObj = HS_BOOL_FALSE;
@@ -3193,30 +3219,24 @@ static HsInt unloadObj_ (pathchar *path)
if (!pathcmp(oc->fileName,path)) {
+ // these are both idempotent, so in just_purge mode we can
+ // later call unloadObj() to really unload the object.
removeOcSymbols(oc);
+ freeOcStablePtrs(oc);
- if (prev == NULL) {
- objects = oc->next;
- } else {
- prev->next = oc->next;
- }
- oc->next = unloaded_objects;
- unloaded_objects = oc;
-
- // Release any StablePtrs that were created when this
- // object module was initialized.
- {
- ForeignExportStablePtr *fe_ptr, *next;
-
- for (fe_ptr = oc->stable_ptrs; fe_ptr != NULL; fe_ptr = next) {
- next = fe_ptr->next;
- freeStablePtr(fe_ptr->stable_ptr);
- stgFree(fe_ptr);
+ if (!just_purge) {
+ if (prev == NULL) {
+ objects = oc->next;
+ } else {
+ prev->next = oc->next;
}
+ oc->next = unloaded_objects;
+ unloaded_objects = oc;
+ oc->status = OBJECT_UNLOADED;
+ } else {
+ prev = oc;
}
- oc->status = OBJECT_UNLOADED;
-
/* This could be a member of an archive so continue
* unloading other members. */
unloadedAnyObj = HS_BOOL_TRUE;
@@ -3237,7 +3257,15 @@ static HsInt unloadObj_ (pathchar *path)
HsInt unloadObj (pathchar *path)
{
ACQUIRE_LOCK(&linker_mutex);
- HsInt r = unloadObj_(path);
+ HsInt r = unloadObj_(path, rtsFalse);
+ RELEASE_LOCK(&linker_mutex);
+ return r;
+}
+
+HsInt purgeObj (pathchar *path)
+{
+ ACQUIRE_LOCK(&linker_mutex);
+ HsInt r = unloadObj_(path, rtsTrue);
RELEASE_LOCK(&linker_mutex);
return r;
}