From 246436f13739593d2a211ceb830393338118ca4d Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Sat, 16 Aug 2014 09:49:30 +0200 Subject: Implement {resize,shrink}MutableByteArray# primops The two new primops with the type-signatures resizeMutableByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, MutableByteArray# s #) shrinkMutableByteArray# :: MutableByteArray# s -> Int# -> State# s -> State# s allow to resize MutableByteArray#s in-place (when possible), and are useful for algorithms where memory is temporarily over-allocated. The motivating use-case is for implementing integer backends, where the final target size of the result is either N or N+1, and only known after the operation has been performed. A future commit will implement a stateful variant of the `sizeofMutableByteArray#` operation (see #9447 for details), since now the size of a `MutableByteArray#` may change over its lifetime (i.e before it gets frozen or GCed). Test Plan: ./validate --slow Reviewers: ezyang, austin, simonmar Reviewed By: austin, simonmar Differential Revision: https://phabricator.haskell.org/D133 --- includes/rts/storage/ClosureMacros.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'includes/rts/storage/ClosureMacros.h') diff --git a/includes/rts/storage/ClosureMacros.h b/includes/rts/storage/ClosureMacros.h index 3407b716c8..2a0f197218 100644 --- a/includes/rts/storage/ClosureMacros.h +++ b/includes/rts/storage/ClosureMacros.h @@ -504,8 +504,11 @@ INLINE_HEADER StgWord8 *mutArrPtrsCard (StgMutArrPtrs *a, W_ n) #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) #else #define OVERWRITING_CLOSURE(c) /* nothing */ +#define OVERWRITING_CLOSURE_OFS(c,n) /* nothing */ #endif #ifdef PROFILING @@ -534,4 +537,34 @@ EXTERN_INLINE void overwritingClosure (StgClosure *p) } } +// 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. +// +// Note: As this calls LDV_recordDead() you have to call LDV_RECORD() +// on the final state of the closure at the call-site +EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, nat offset); +EXTERN_INLINE void overwritingClosureOfs (StgClosure *p, nat offset) +{ + nat size, i; + +#if ZERO_SLOP_FOR_LDV_PROF && !ZERO_SLOP_FOR_SANITY_CHECK + // see Note [zeroing slop], also #8402 + if (era <= 0) return; +#endif + + size = closure_sizeW(p); + + ASSERT(offset <= size); + + // For LDV profiling, we need to record the closure as dead +#if defined(PROFILING) + LDV_recordDead(p, size); +#endif + + for (i = offset; i < size; i++) + ((StgWord *)p)[i] = 0; +} + #endif /* RTS_STORAGE_CLOSUREMACROS_H */ -- cgit v1.2.1