diff options
author | Ben Gamari <ben@smart-cactus.org> | 2021-01-06 11:20:44 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-01-17 05:53:02 -0500 |
commit | d159041b44049d87db7e26d09120e0b2633b3b3c (patch) | |
tree | 5e6c92f9c03b703f8b1b100ebf18562a9409b144 /includes | |
parent | 84dcb8440e94fab5aaba66e613de27d89264f076 (diff) | |
download | haskell-d159041b44049d87db7e26d09120e0b2633b3b3c.tar.gz |
rts: Initialize card table in newArray#
Previously we would leave the card table of new arrays uninitialized.
This wasn't a soundness issue: at worst we would end up doing
unnecessary scavenging during GC, after which the card table would be
reset. That being said, it seems worth initializing this properly to
avoid both unnecessary work and non-determinism.
Fixes #19143.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/Cmm.h | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/includes/Cmm.h b/includes/Cmm.h index fdb4badf9a..84c6fca125 100644 --- a/includes/Cmm.h +++ b/includes/Cmm.h @@ -814,7 +814,7 @@ return (dst); #define copyArray(src, src_off, dst, dst_off, n) \ - W_ dst_elems_p, dst_p, src_p, dst_cards_p, bytes; \ + W_ dst_elems_p, dst_p, src_p, bytes; \ \ if ((n) != 0) { \ SET_HDR(dst, stg_MUT_ARR_PTRS_DIRTY_info, CCCS); \ @@ -826,14 +826,13 @@ \ prim %memcpy(dst_p, src_p, bytes, SIZEOF_W); \ \ - dst_cards_p = dst_elems_p + WDS(StgMutArrPtrs_ptrs(dst)); \ - setCards(dst_cards_p, dst_off, n); \ + setCards(dst, dst_off, n); \ } \ \ return (); #define copyMutableArray(src, src_off, dst, dst_off, n) \ - W_ dst_elems_p, dst_p, src_p, dst_cards_p, bytes; \ + W_ dst_elems_p, dst_p, src_p, bytes; \ \ if ((n) != 0) { \ SET_HDR(dst, stg_MUT_ARR_PTRS_DIRTY_info, CCCS); \ @@ -849,22 +848,30 @@ prim %memcpy(dst_p, src_p, bytes, SIZEOF_W); \ } \ \ - dst_cards_p = dst_elems_p + WDS(StgMutArrPtrs_ptrs(dst)); \ - setCards(dst_cards_p, dst_off, n); \ + setCards(dst, dst_off, n); \ } \ \ return (); /* - * Set the cards in the cards table pointed to by dst_cards_p for an + * Set the cards in the array pointed to by arr for an * update to n elements, starting at element dst_off. */ -#define setCards(dst_cards_p, dst_off, n) \ - W_ __start_card, __end_card, __cards; \ - __start_card = mutArrPtrCardDown(dst_off); \ - __end_card = mutArrPtrCardDown((dst_off) + (n) - 1); \ - __cards = __end_card - __start_card + 1; \ - prim %memset((dst_cards_p) + __start_card, 1, __cards, 1); +#define setCards(arr, dst_off, n) \ + setCardsValue(arr, dst_off, n, 1) + +/* + * Set the cards in the array pointed to by arr for an + * update to n elements, starting at element dst_off to value (0 to indicate + * clean, 1 to indicate dirty). + */ +#define setCardsValue(arr, dst_off, n, value) \ + W_ __start_card, __end_card, __cards, __dst_cards_p; \ + __dst_cards_p = (arr) + SIZEOF_StgMutArrPtrs + WDS(StgMutArrPtrs_ptrs(arr)); \ + __start_card = mutArrPtrCardDown(dst_off); \ + __end_card = mutArrPtrCardDown((dst_off) + (n) - 1); \ + __cards = __end_card - __start_card + 1; \ + prim %memset(__dst_cards_p + __start_card, (value), __cards, 1) /* Complete function body for the clone family of small (mutable) array ops. Defined as a macro to avoid function call overhead or |