diff options
author | Ben Gamari <ben@smart-cactus.org> | 2023-03-23 13:43:50 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-03-25 20:23:47 -0400 |
commit | c6ec4cd1a94a1b76b7b094d5c92ee605031ecf60 (patch) | |
tree | 1982d3a2e63cfb935dc279ac98a8bd4ae818b923 | |
parent | 80729d96e47c99dc38e83612dfcfe01cf565eac0 (diff) | |
download | haskell-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.c | 27 | ||||
-rw-r--r-- | rts/include/Cmm.h | 8 | ||||
-rw-r--r-- | rts/include/rts/storage/ClosureMacros.h | 34 | ||||
-rw-r--r-- | rts/rts.cabal.in | 1 |
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 |