diff options
author | Andrew Martin <andrew.thaddeus@gmail.com> | 2019-08-19 08:18:19 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-10-26 05:19:38 -0400 |
commit | 8916e64e5437c99b82d5610286430328af1d86bc (patch) | |
tree | 3c9f00fbed65cb725b57acb0ee7b83d776475a89 /rts | |
parent | acedfc8b8706a92127c96f487e3e3b1636451704 (diff) | |
download | haskell-8916e64e5437c99b82d5610286430328af1d86bc.tar.gz |
Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.
This is a part of GHC Proposal #25: "Offer more array resizing primitives".
Resources related to the proposal:
- Discussion: https://github.com/ghc-proposals/ghc-proposals/pull/121
- Proposal: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0025-resize-boxed.rst
Only shrinkSmallMutableArray# is implemented as a primop since a
library-space implementation of resizeSmallMutableArray# (in GHC.Exts)
is no less efficient than a primop would be. This may be replaced by
a primop in the future if someone devises a strategy for growing
arrays in-place. The library-space implementation always copies the
array when growing it.
This commit also tweaks the documentation of the deprecated
sizeofMutableByteArray#, removing the mention of concurrency. That
primop is unsound even in single-threaded applications. Additionally,
the non-negativity assertion on the existing shrinkMutableByteArray#
primop has been removed since this predicate is trivially always true.
Diffstat (limited to 'rts')
-rw-r--r-- | rts/PrimOps.cmm | 19 | ||||
-rw-r--r-- | rts/RtsSymbols.c | 1 |
2 files changed, 19 insertions, 1 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index b66c561dcb..b5930363a1 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -174,12 +174,13 @@ stg_isMutableByteArrayPinnedzh ( gcptr mba ) stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size ) // MutableByteArray# s -> Int# -> State# s -> State# s { - ASSERT(new_size >= 0); ASSERT(new_size <= StgArrBytes_bytes(mba)); OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) + ROUNDUP_BYTES_TO_WDS(new_size))); StgArrBytes_bytes(mba) = new_size; + // See the comments in overwritingClosureOfs for an explanation + // of the interaction with LDV profiling. LDV_RECORD_CREATE(mba); return (); @@ -224,6 +225,22 @@ stg_resizzeMutableByteArrayzh ( gcptr mba, W_ new_size ) } } +// shrink size of SmallMutableArray in-place +stg_shrinkSmallMutableArrayzh ( gcptr mba, W_ new_size ) +// SmallMutableArray# s -> Int# -> State# s -> State# s +{ + ASSERT(new_size <= StgSmallMutArrPtrs_ptrs(mba)); + + OVERWRITING_CLOSURE_OFS(mba, (BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) + + new_size)); + StgSmallMutArrPtrs_ptrs(mba) = new_size; + // See the comments in overwritingClosureOfs for an explanation + // of the interaction with LDV profiling. + LDV_RECORD_CREATE(mba); + + return (); +} + // RRN: This one does not use the "ticketing" approach because it // deals in unboxed scalars, not heap pointers. stg_casIntArrayzh( gcptr arr, W_ ind, W_ old, W_ new ) diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c index 0611de11cc..b2f90a892d 100644 --- a/rts/RtsSymbols.c +++ b/rts/RtsSymbols.c @@ -716,6 +716,7 @@ SymI_HasProto(stg_isMutableByteArrayPinnedzh) \ SymI_HasProto(stg_shrinkMutableByteArrayzh) \ SymI_HasProto(stg_resizzeMutableByteArrayzh) \ + SymI_HasProto(stg_shrinkSmallMutableArrayzh) \ SymI_HasProto(newSpark) \ SymI_HasProto(updateRemembSetPushThunk) \ SymI_HasProto(updateRemembSetPushThunk_) \ |