summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gröber <dxld@darkboxed.org>2020-04-10 02:40:32 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-06-01 06:32:56 -0400
commit2ee4f36c779674f7237d730460ca83aec9a6808a (patch)
tree117b74a6664904f97f07d4f9f370db23bb13dd64
parent6947231abd8c33840860ad51699b76efd4725f0e (diff)
downloadhaskell-2ee4f36c779674f7237d730460ca83aec9a6808a.tar.gz
Cleanup OVERWRITING_CLOSURE logic
The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those.
-rw-r--r--includes/Cmm.h6
-rw-r--r--includes/Rts.h4
-rw-r--r--includes/rts/storage/ClosureMacros.h81
-rw-r--r--rts/PrimOps.cmm12
-rw-r--r--rts/sm/Storage.c2
5 files changed, 62 insertions, 43 deletions
diff --git a/includes/Cmm.h b/includes/Cmm.h
index 4e2d1b1a22..349d6985f8 100644
--- a/includes/Cmm.h
+++ b/includes/Cmm.h
@@ -623,14 +623,14 @@
#define mutArrPtrCardUp(i) (((i) + mutArrCardMask) >> MUT_ARR_PTRS_CARD_BITS)
#define mutArrPtrsCardWords(n) ROUNDUP_BYTES_TO_WDS(mutArrPtrCardUp(n))
-#if defined(PROFILING) || (!defined(THREADED_RTS) && defined(DEBUG))
+#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_OFS(c,n) foreign "C" overwritingClosureOfs(c "ptr", n)
+#define OVERWRITING_CLOSURE_MUTABLE(c, off) foreign "C" overwritingMutableClosureOfs(c "ptr", off)
#else
#define OVERWRITING_CLOSURE_SIZE(c, size) /* nothing */
#define OVERWRITING_CLOSURE(c) /* nothing */
-#define OVERWRITING_CLOSURE_OFS(c,n) /* nothing */
+#define OVERWRITING_CLOSURE_MUTABLE(c, off) /* nothing */
#endif
// Memory barriers.
diff --git a/includes/Rts.h b/includes/Rts.h
index d0f5371007..989394b590 100644
--- a/includes/Rts.h
+++ b/includes/Rts.h
@@ -184,6 +184,9 @@ void _assertFail(const char *filename, unsigned int linenum)
/* Global constraints */
#include "rts/Constants.h"
+/* Runtime flags */
+#include "rts/Flags.h"
+
/* Profiling information */
#include "rts/prof/CCS.h"
#include "rts/prof/LDV.h"
@@ -214,7 +217,6 @@ void _assertFail(const char *filename, unsigned int linenum)
#include "rts/Signals.h"
#include "rts/BlockSignals.h"
#include "rts/Hpc.h"
-#include "rts/Flags.h"
#include "rts/Adjustor.h"
#include "rts/FileLock.h"
#include "rts/GetTime.h"
diff --git a/includes/rts/storage/ClosureMacros.h b/includes/rts/storage/ClosureMacros.h
index ade8b34631..964537de77 100644
--- a/includes/rts/storage/ClosureMacros.h
+++ b/includes/rts/storage/ClosureMacros.h
@@ -510,24 +510,16 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n)
-------------------------------------------------------------------------- */
-#if defined(PROFILING)
-#define ZERO_SLOP_FOR_LDV_PROF 1
-#else
-#define ZERO_SLOP_FOR_LDV_PROF 0
-#endif
-
-#if defined(DEBUG) && !defined(THREADED_RTS)
-#define ZERO_SLOP_FOR_SANITY_CHECK 1
-#else
-#define ZERO_SLOP_FOR_SANITY_CHECK 0
-#endif
-
-#if ZERO_SLOP_FOR_LDV_PROF || ZERO_SLOP_FOR_SANITY_CHECK
-#define OVERWRITING_CLOSURE(c) overwritingClosure(c)
-#define OVERWRITING_CLOSURE_OFS(c,n) overwritingClosureOfs(c,n)
+#if defined(PROFILING) || defined(DEBUG)
+#define OVERWRITING_CLOSURE(c) \
+ overwritingClosure(c)
+#define OVERWRITING_CLOSURE_MUTABLE(c, off) \
+ overwritingMutableClosureOfs(c, off)
#else
-#define OVERWRITING_CLOSURE(c) /* nothing */
-#define OVERWRITING_CLOSURE_OFS(c,n) /* nothing */
+#define OVERWRITING_CLOSURE(c) \
+ do { (void) sizeof(c); } while(0)
+#define OVERWRITING_CLOSURE_MUTABLE(c, off) \
+ do { (void) sizeof(c); (void) sizeof(off); } while(0)
#endif
#if defined(PROFILING)
@@ -535,21 +527,43 @@ void LDV_recordDead (const StgClosure *c, uint32_t size);
RTS_PRIVATE bool isInherentlyUsed ( StgHalfWord closure_type );
#endif
-EXTERN_INLINE void overwritingClosure_ (StgClosure *p,
- uint32_t offset /* in words */,
- uint32_t size /* closure size, in words */,
- bool inherently_used USED_IF_PROFILING
- );
-EXTERN_INLINE void overwritingClosure_ (StgClosure *p, uint32_t offset, uint32_t size, bool inherently_used USED_IF_PROFILING)
+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 inherently_used /*< whether to call LDV_recordDead */
+ );
+
+EXTERN_INLINE void
+zeroSlop (StgClosure *p, uint32_t offset, uint32_t size,
+ bool inherently_used USED_IF_PROFILING)
{
-#if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK
// see Note [zeroing slop when overwriting closures], also #8402
- if (era <= 0) return;
+
+ const bool want_to_zero_immutable_slop = false
+ // Sanity checking (-DS) is enabled
+ || RTS_DEREF(RtsFlags).DebugFlags.sanity
+#if defined(PROFILING)
+ // LDV profiler is enabled
+ || era > 0
#endif
+ ;
+
+ const bool can_zero_immutable_slop =
+ // Only if we're running single threaded.
+ RTS_DEREF(RtsFlags).ParFlags.nCapabilities <= 1;
+
+ const bool zero_slop_immutable =
+ want_to_zero_immutable_slop && can_zero_immutable_slop;
+
+ if(!zero_slop_immutable)
+ return;
// For LDV profiling, we need to record the closure as dead
#if defined(PROFILING)
- if (!inherently_used) { LDV_recordDead(p, size); };
+ if (!inherently_used)
+ LDV_recordDead(p, size);
#endif
for (uint32_t i = offset; i < size; i++) {
@@ -563,8 +577,8 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p)
#if defined(PROFILING)
ASSERT(!isInherentlyUsed(get_itbl(p)->type));
#endif
- overwritingClosure_(p, sizeofW(StgThunkHeader), closure_sizeW(p),
- /*inherently_used=*/false);
+ zeroSlop(p, sizeofW(StgThunkHeader), closure_sizeW(p),
+ /*inherently_used=*/false);
}
// Version of 'overwritingClosure' which overwrites only a suffix of a
@@ -574,8 +588,11 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p)
//
// Note: As this calls LDV_recordDead() you have to call LDV_RECORD_CREATE()
// on the final state of the closure at the call-site
-EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset);
-EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset)
+EXTERN_INLINE void
+overwritingMutableClosureOfs (StgClosure *p, uint32_t offset);
+
+EXTERN_INLINE void
+overwritingMutableClosureOfs (StgClosure *p, uint32_t offset)
{
// Since overwritingClosureOfs is only ever called by:
//
@@ -586,7 +603,7 @@ EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, uint32_t offset)
// we can safely set inherently_used = true, which means LDV_recordDead
// won't be invoked below. Since these closures are inherenlty used we don't
// need to track their destruction.
- overwritingClosure_(p, offset, closure_sizeW(p), /*inherently_used=*/true);
+ zeroSlop(p, offset, closure_sizeW(p), /*inherently_used=*/true);
}
// Version of 'overwritingClosure' which takes closure size as argument.
@@ -596,5 +613,5 @@ EXTERN_INLINE void overwritingClosureSize (StgClosure *p, uint32_t size)
#if defined(PROFILING)
ASSERT(!isInherentlyUsed(get_itbl(p)->type));
#endif
- overwritingClosure_(p, sizeofW(StgThunkHeader), size, /*inherently_used=*/false);
+ zeroSlop(p, sizeofW(StgThunkHeader), size, /*inherently_used=*/false);
}
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 048cde8065..090f915035 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -175,8 +175,8 @@ stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size )
{
ASSERT(new_size <= StgArrBytes_bytes(mba));
- OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) +
- ROUNDUP_BYTES_TO_WDS(new_size)));
+ OVERWRITING_CLOSURE_MUTABLE(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) +
+ ROUNDUP_BYTES_TO_WDS(new_size)));
StgArrBytes_bytes(mba) = new_size;
// No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays]
@@ -199,8 +199,8 @@ stg_resizzeMutableByteArrayzh ( gcptr mba, W_ new_size )
new_size_wds = ROUNDUP_BYTES_TO_WDS(new_size);
if (new_size_wds <= BYTE_ARR_WDS(mba)) {
- OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) +
- new_size_wds));
+ OVERWRITING_CLOSURE_MUTABLE(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) +
+ new_size_wds));
StgArrBytes_bytes(mba) = new_size;
// No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays]
@@ -228,8 +228,8 @@ stg_shrinkSmallMutableArrayzh ( gcptr mba, W_ new_size )
{
ASSERT(new_size <= StgSmallMutArrPtrs_ptrs(mba));
- OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) +
- new_size));
+ OVERWRITING_CLOSURE_MUTABLE(mba, (BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) +
+ new_size));
StgSmallMutArrPtrs_ptrs(mba) = new_size;
// No need to call LDV_RECORD_CREATE. See Note [LDV profiling and resizing arrays]
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index a73228dce6..b47afaf7df 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -948,7 +948,7 @@ accountAllocation(Capability *cap, W_ n)
*
* When profiling we zero:
* - Pinned object alignment slop, see MEMSET_IF_PROFILING_W in allocatePinned.
- * - Shrunk array slop, see OVERWRITING_MUTABLE_CLOSURE.
+ * - Shrunk array slop, see OVERWRITING_CLOSURE_MUTABLE.
*
* When performing LDV profiling or using a (single threaded) debug RTS we zero
* slop even when overwriting immutable closures, see Note [zeroing slop when