diff options
author | Simon Marlow <marlowsd@gmail.com> | 2014-12-04 10:12:26 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2014-12-05 10:06:16 +0000 |
commit | a48bee9fa1cf51c9df3bd87079eb8ff9b222e717 (patch) | |
tree | 060d1e8f07af6601ddff1851de742c2d5a82e944 /rts | |
parent | 55a2a0b4893486e5dde151620d7f46e8035d2af5 (diff) | |
download | haskell-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.c | 74 |
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; } |