newArray# fails to initialize card table correctly
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)
.
Trac metadata
Trac field | Value |
---|---|
Version | 7.6.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Runtime System |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | simonmar |
Operating system | |
Architecture |