[GHC] #8867: newArray# fails to initialize card table correctly

GHC ghc-devs at haskell.org
Sun Mar 9 10:16:43 UTC 2014


#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


More information about the ghc-tickets mailing list