+/* -----------------------------------------------------------------------------
+ Replacing a closure with a different one. We must call
+ OVERWRITING_CLOSURE(p) on the old closure that is about to be
+ overwritten.
+
+ In PROFILING mode, LDV profiling requires that we fill the slop
+ with zeroes, and record the old closure as dead (LDV_recordDead()).
+
+ In DEBUG mode, we must overwrite the slop with zeroes, because the
+ sanity checker wants to walk through the heap checking all the
+ pointers.
+
+ In multicore mode, we *cannot* overwrite slop with zeroes, because
+ another thread might be reading it. So,
+
+ PROFILING is not compatible with +RTS -N<n> (for n > 1)
+
+ THREADED_RTS can be used with DEBUG, but full heap sanity
+ checking is disabled.
+
+ -------------------------------------------------------------------------- */
+
+#if defined(PROFILING) || (!defined(THREADED_RTS) && defined(DEBUG))
+#define OVERWRITING_CLOSURE(c) overwritingClosure(c)
+#else
+#define OVERWRITING_CLOSURE(c) /* nothing */
+#endif
+
+#ifdef PROFILING
+void LDV_recordDead (StgClosure *c, nat size);
+#endif
+
+EXTERN_INLINE void overwritingClosure (StgClosure *p);
+EXTERN_INLINE void overwritingClosure (StgClosure *p)
+{
+ nat size, i;
+
+#if defined(PROFILING)
+ if (era <= 0) return;
+#endif
+
+ size = closure_sizeW(p);
+
+ // For LDV profiling, we need to record the closure as dead
+#if defined(PROFILING)
+ LDV_recordDead((StgClosure *)(p), size);
+#endif
+
+ for (i = 0; i < size - sizeofW(StgThunkHeader); i++) {
+ ((StgThunk *)(p))->payload[i] = 0;
+ }
+}
+