summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2023-03-23 13:43:50 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-03-25 20:23:47 -0400
commitc6ec4cd1a94a1b76b7b094d5c92ee605031ecf60 (patch)
tree1982d3a2e63cfb935dc279ac98a8bd4ae818b923
parent80729d96e47c99dc38e83612dfcfe01cf565eac0 (diff)
downloadhaskell-c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60.tar.gz
rts: Don't rely on EXTERN_INLINE for slop-zeroing logic
Previously we relied on calling EXTERN_INLINE functions defined in ClosureMacros.h from Cmm to zero slop. However, as far as I can tell, this is no longer safe to do in C99 as EXTERN_INLINE definitions may be emitted in each compilation unit. Fix this by explicitly declaring a new set of non-inline functions in ZeroSlop.c which can be called from Cmm and marking the ClosureMacros.h definitions as INLINE_HEADER. In the future we should try to eliminate EXTERN_INLINE.
-rw-r--r--rts/ZeroSlop.c27
-rw-r--r--rts/include/Cmm.h8
-rw-r--r--rts/include/rts/storage/ClosureMacros.h34
-rw-r--r--rts/rts.cabal.in1
4 files changed, 47 insertions, 23 deletions
diff --git a/rts/ZeroSlop.c b/rts/ZeroSlop.c
new file mode 100644
index 0000000000..734fa2d323
--- /dev/null
+++ b/rts/ZeroSlop.c
@@ -0,0 +1,27 @@
+/* ----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 1998-2012
+ *
+ * Utilities for zeroing slop callable from Cmm
+ *
+ * N.B. If you are in C you should rather using the inlineable utilities
+ * (e.g. overwritingClosure) defined in ClosureMacros.h.
+ *
+ * -------------------------------------------------------------------------- */
+
+#include "Rts.h"
+
+void stg_overwritingClosure (StgClosure *p)
+{
+ overwritingClosure(p);
+}
+
+void stg_overwritingMutableClosureOfs (StgClosure *p, uint32_t offset)
+{
+ overwritingMutableClosureOfs(p, offset);
+}
+
+void stg_overwritingClosureSize (StgClosure *p, uint32_t size /* in words */)
+{
+ overwritingClosureSize(p, size);
+}
diff --git a/rts/include/Cmm.h b/rts/include/Cmm.h
index 9d2ebda52f..15df6d0df1 100644
--- a/rts/include/Cmm.h
+++ b/rts/include/Cmm.h
@@ -647,9 +647,9 @@
#define mutArrPtrsCardWords(n) ROUNDUP_BYTES_TO_WDS(mutArrPtrCardUp(n))
#if defined(PROFILING) || defined(DEBUG)
-#define OVERWRITING_CLOSURE_SIZE(c, size) foreign "C" overwritingClosureSize(c "ptr", size)
-#define OVERWRITING_CLOSURE(c) foreign "C" overwritingClosure(c "ptr")
-#define OVERWRITING_CLOSURE_MUTABLE(c, off) foreign "C" overwritingMutableClosureOfs(c "ptr", off)
+#define OVERWRITING_CLOSURE_SIZE(c, size) foreign "C" stg_overwritingClosureSize(c "ptr", size)
+#define OVERWRITING_CLOSURE(c) foreign "C" stg_overwritingClosure(c "ptr")
+#define OVERWRITING_CLOSURE_MUTABLE(c, off) foreign "C" stg_overwritingMutableClosureOfs(c "ptr", off)
#else
#define OVERWRITING_CLOSURE_SIZE(c, size) /* nothing */
#define OVERWRITING_CLOSURE(c) /* nothing */
@@ -657,7 +657,7 @@
* this whenever profiling is enabled as described in Note [slop on the heap]
* in Storage.c. */
#define OVERWRITING_CLOSURE_MUTABLE(c, off) \
- if (TO_W_(RtsFlags_ProfFlags_doHeapProfile(RtsFlags)) != 0) { foreign "C" overwritingMutableClosureOfs(c "ptr", off); }
+ if (TO_W_(RtsFlags_ProfFlags_doHeapProfile(RtsFlags)) != 0) { foreign "C" stg_overwritingMutableClosureOfs(c "ptr", off); }
#endif
#define IS_STACK_CLEAN(stack) \
diff --git a/rts/include/rts/storage/ClosureMacros.h b/rts/include/rts/storage/ClosureMacros.h
index ecfca8a81c..e005dc5f78 100644
--- a/rts/include/rts/storage/ClosureMacros.h
+++ b/rts/include/rts/storage/ClosureMacros.h
@@ -517,16 +517,12 @@ void LDV_recordDead (const StgClosure *c, uint32_t size);
RTS_PRIVATE bool isInherentlyUsed ( StgHalfWord closure_type );
#endif
-EXTERN_INLINE void
-zeroSlop (
- StgClosure *p,
- uint32_t offset, /*< offset to start zeroing at, in words */
- uint32_t size, /*< total closure size, in words */
- bool known_mutable /*< is this a closure who's slop we can always zero? */
- );
-
-EXTERN_INLINE void
-zeroSlop (StgClosure *p, uint32_t offset, uint32_t size, bool known_mutable)
+INLINE_HEADER void
+zeroSlop (StgClosure *p,
+ uint32_t offset, /*< offset to start zeroing at, in words */
+ uint32_t size, /*< total closure size, in words */
+ bool known_mutable /*< is this a closure who's slop we can always zero? */
+ )
{
// see Note [zeroing slop when overwriting closures], also #8402
@@ -574,8 +570,10 @@ zeroSlop (StgClosure *p, uint32_t offset, uint32_t size, bool known_mutable)
}
}
-EXTERN_INLINE void overwritingClosure (StgClosure *p);
-EXTERN_INLINE void overwritingClosure (StgClosure *p)
+// N.B. the stg_* variants of the utilities below are only for calling from
+// Cmm. The INLINE_HEADER functions should be used when in C.
+void stg_overwritingClosure (StgClosure *p);
+INLINE_HEADER void overwritingClosure (StgClosure *p)
{
W_ size = closure_sizeW(p);
#if defined(PROFILING)
@@ -585,15 +583,13 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p)
zeroSlop(p, sizeofW(StgThunkHeader), size, /*known_mutable=*/false);
}
+
// Version of 'overwritingClosure' which overwrites only a suffix of a
// closure. The offset is expressed in words relative to 'p' and shall
// be less than or equal to closure_sizeW(p), and usually at least as
// large as the respective thunk header.
-EXTERN_INLINE void
-overwritingMutableClosureOfs (StgClosure *p, uint32_t offset);
-
-EXTERN_INLINE void
-overwritingMutableClosureOfs (StgClosure *p, uint32_t offset)
+void stg_overwritingMutableClosureOfs (StgClosure *p, uint32_t offset);
+INLINE_HEADER void overwritingMutableClosureOfs (StgClosure *p, uint32_t offset)
{
// Since overwritingClosureOfs is only ever called by:
//
@@ -610,8 +606,8 @@ overwritingMutableClosureOfs (StgClosure *p, uint32_t offset)
}
// Version of 'overwritingClosure' which takes closure size as argument.
-EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size /* in words */);
-EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size)
+void stg_OverwritingClosureSize (StgClosure *p, uint32_t size /* in words */);
+INLINE_HEADER void overwritingClosureSize (StgClosure *p, uint32_t size)
{
// This function is only called from stg_AP_STACK so we can assume it's not
// inherently used.
diff --git a/rts/rts.cabal.in b/rts/rts.cabal.in
index e2374964b3..df25403654 100644
--- a/rts/rts.cabal.in
+++ b/rts/rts.cabal.in
@@ -603,6 +603,7 @@ library
TSANUtils.c
WSDeque.c
Weak.c
+ ZeroSlop.c
eventlog/EventLog.c
eventlog/EventLogWriter.c
hooks/FlagDefaults.c