[commit: ghc] master: Allow the linker to be used without retaining CAFs unconditionally (5874f13)
git at git.haskell.org
git at git.haskell.org
Thu Nov 21 13:28:04 UTC 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/5874f13fd83409b28c4f781a93e80f4605d0593e/ghc
>---------------------------------------------------------------
commit 5874f13fd83409b28c4f781a93e80f4605d0593e
Author: Simon Marlow <marlowsd at gmail.com>
Date: Thu Nov 21 12:27:27 2013 +0000
Allow the linker to be used without retaining CAFs unconditionally
This creates a new C API:
initLinker_ (int retain_cafs)
The old initLinker() was left as-is for backwards compatibility. See
documentation in Linker.h.
>---------------------------------------------------------------
5874f13fd83409b28c4f781a93e80f4605d0593e
includes/rts/Linker.h | 21 +++++++++++++++++++--
rts/Linker.c | 18 ++++++++++++++++--
rts/sm/GC.c | 8 ++++----
3 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/includes/rts/Linker.h b/includes/rts/Linker.h
index ea4daeb..e7e2ea5 100644
--- a/includes/rts/Linker.h
+++ b/includes/rts/Linker.h
@@ -22,8 +22,25 @@ typedef char pathchar;
#define PATH_FMT "s"
#endif
-/* initialize the object linker */
-void initLinker( void );
+/* Initialize the object linker. Equivalent to initLinker_(1). */
+void initLinker (void);
+
+/* Initialize the object linker.
+ * The retain_cafs argument is:
+ *
+ * non-zero => Retain CAFs unconditionally in linked Haskell code.
+ * Note that this prevents any code from being unloaded.
+ * It should not be necessary unless you are GHCi or
+ * hs-plugins, which needs to be able call any function
+ * in the compiled code.
+ *
+ * zero => Do not retain CAFs. Everything reachable from foreign
+ * exports will be retained, due to the StablePtrs
+ * created by the module initialisation code. unloadObj
+ * free these StablePtrs, which will allow the CAFs to
+ * be GC'd and the code to be removed.
+ */
+void initLinker_ (int retain_cafs);
/* insert a symbol in the hash table */
void insertSymbol(pathchar* obj_name, char* key, void* data);
diff --git a/rts/Linker.c b/rts/Linker.c
index 285984a..1a663cb 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1133,6 +1133,7 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(hs_hpc_rootModule) \
SymI_HasProto(hs_hpc_module) \
SymI_HasProto(initLinker) \
+ SymI_HasProto(initLinker_) \
SymI_HasProto(stg_unpackClosurezh) \
SymI_HasProto(stg_getApStackValzh) \
SymI_HasProto(stg_getSparkzh) \
@@ -1155,7 +1156,6 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(stg_newByteArrayzh) \
SymI_HasProto(stg_casIntArrayzh) \
SymI_HasProto(stg_fetchAddIntArrayzh) \
- SymI_HasProto_redirect(newCAF, newDynCAF) \
SymI_HasProto(stg_newMVarzh) \
SymI_HasProto(stg_newMutVarzh) \
SymI_HasProto(stg_newTVarzh) \
@@ -1558,8 +1558,16 @@ static Mutex dl_mutex; // mutex to protect dlopen/dlerror critical section
#endif
#endif
+void initLinker (void)
+{
+ // default to retaining CAFs for backwards compatibility. Most
+ // users will want initLinker_(0): otherwise unloadObj() will not
+ // be able to object files when they contain CAFs.
+ initLinker_(1);
+}
+
void
-initLinker( void )
+initLinker_ (int retain_cafs)
{
RtsSymbolVal *sym;
#if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
@@ -1603,6 +1611,12 @@ initLinker( void )
ghciInsertSymbolTable(WSTR("(GHCi special symbols)"),
symhash, "__dso_handle", (void *)0x12345687, HS_BOOL_FALSE, NULL);
+ // Redurect newCAF to newDynCAF if retain_cafs is true.
+ ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"), symhash,
+ MAYBE_LEADING_UNDERSCORE_STR("newCAF"),
+ retain_cafs ? newDynCAF : newCAF,
+ HS_BOOL_FALSE, NULL);
+
# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
# if defined(RTLD_DEFAULT)
dl_prog_handle = RTLD_DEFAULT;
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 80e34fb..58698e9 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -662,15 +662,15 @@ GarbageCollect (nat collect_gen,
resetNurseries();
- if (major_gc) {
- checkUnload (gct->scavenged_static_objects);
- }
-
// mark the garbage collected CAFs as dead
#if defined(DEBUG)
if (major_gc) { gcCAFs(); }
#endif
+ if (major_gc) {
+ checkUnload (gct->scavenged_static_objects);
+ }
+
#ifdef PROFILING
// resetStaticObjectForRetainerProfiling() must be called before
// zeroing below.
More information about the ghc-commits
mailing list