summaryrefslogtreecommitdiff
path: root/includes/Cmm.h
diff options
context:
space:
mode:
authorJohan Tibell <johan.tibell@gmail.com>2014-03-23 12:06:56 +0100
committerJohan Tibell <johan.tibell@gmail.com>2014-03-29 11:24:07 +0100
commit90329b6cc183b3cd05956ae6bdeb6ac6951549c2 (patch)
treeba7d31656fe75fad2555c8a66b7ebd13dd9ebeb1 /includes/Cmm.h
parent4c8edfd2c722504baaa6896d194fd3a8c3f9b652 (diff)
downloadhaskell-90329b6cc183b3cd05956ae6bdeb6ac6951549c2.tar.gz
Add SmallArray# and SmallMutableArray# types
These array types are smaller than Array# and MutableArray# and are faster when the array size is small, as they don't have the overhead of a card table. Having no card table reduces the closure size with 2 words in the typical small array case and leads to less work when updating or GC:ing the array. Reduces both the runtime and memory allocation by 8.8% on my insert benchmark for the HashMap type in the unordered-containers package, which makes use of lots of small arrays. With tuned GC settings (i.e. `+RTS -A6M`) the runtime reduction is 15%. Fixes #8923.
Diffstat (limited to 'includes/Cmm.h')
-rw-r--r--includes/Cmm.h33
1 files changed, 33 insertions, 0 deletions
diff --git a/includes/Cmm.h b/includes/Cmm.h
index 13e485f627..24bdda30c5 100644
--- a/includes/Cmm.h
+++ b/includes/Cmm.h
@@ -806,6 +806,10 @@
__gen = TO_W_(bdescr_gen_no(__bd)); \
if (__gen > 0) { recordMutableCap(__p, __gen); }
+/* -----------------------------------------------------------------------------
+ Arrays
+ -------------------------------------------------------------------------- */
+
/* Complete function body for the clone family of (mutable) array ops.
Defined as a macro to avoid function call overhead or code
duplication. */
@@ -890,4 +894,33 @@
__cards = __end_card - __start_card + 1; \
prim %memset((dst_cards_p) + __start_card, 1, __cards, 1);
+/* Complete function body for the clone family of small (mutable)
+ array ops. Defined as a macro to avoid function call overhead or
+ code duplication. */
+#define cloneSmallArray(info, src, offset, n) \
+ W_ words, size; \
+ gcptr dst, dst_p, src_p; \
+ \
+ again: MAYBE_GC(again); \
+ \
+ words = BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) + n; \
+ ("ptr" dst) = ccall allocate(MyCapability() "ptr", words); \
+ TICK_ALLOC_PRIM(SIZEOF_StgSmallMutArrPtrs, WDS(n), 0); \
+ \
+ SET_HDR(dst, info, CCCS); \
+ StgSmallMutArrPtrs_ptrs(dst) = n; \
+ \
+ dst_p = dst + SIZEOF_StgSmallMutArrPtrs; \
+ src_p = src + SIZEOF_StgSmallMutArrPtrs + WDS(offset); \
+ while: \
+ if (n != 0) { \
+ n = n - 1; \
+ W_[dst_p] = W_[src_p]; \
+ dst_p = dst_p + WDS(1); \
+ src_p = src_p + WDS(1); \
+ goto while; \
+ } \
+ \
+ return (dst);
+
#endif /* CMM_H */