
#8867: newArray# fails to initialize card table correctly ------------------------------------+------------------------------------- Reporter: tibbe | Owner: simonmar Type: bug | Status: new Priority: normal | Milestone: Component: Runtime System | Version: 7.6.3 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- `newArray#` doesn't initialize the card table correctly. It writes the init value to the card table instead of a zero. That happens to be harmless, but slightly inefficient. Consider the implementation of `newArray#` in [[GhcFile(rts/PrimOps.cmm)]]: {{{ stg_newArrayzh ( W_ n /* words */, gcptr init ) { W_ words, size; gcptr p, arr; again: MAYBE_GC(again); // the mark area contains one byte for each 2^MUT_ARR_PTRS_CARD_BITS words // in the array, making sure we round up, and then rounding up to a whole // number of words. size = n + mutArrPtrsCardWords(n); words = BYTES_TO_WDS(SIZEOF_StgMutArrPtrs) + size; ("ptr" arr) = ccall allocate(MyCapability() "ptr",words); TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(n), 0); SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS); StgMutArrPtrs_ptrs(arr) = n; StgMutArrPtrs_size(arr) = size; // Initialise all elements of the the array with the value in R2 p = arr + SIZEOF_StgMutArrPtrs; for: if (p < arr + WDS(words)) { W_[p] = init; p = p + WDS(1); goto for; } // Initialise the mark bits with 0 for2: if (p < arr + WDS(size)) { W_[p] = 0; p = p + WDS(1); goto for2; } return (arr); } }}} The second for-loop never gets executed, as `size` < `words`. The first predicate should check `p < arr + SIZEOF_StgMutArrPtrs + WDS(n)` and the second should be `p < arr + WDS(words)`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8867 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler