summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Tibell <johan.tibell@gmail.com>2014-03-13 22:24:24 +0100
committerJohan Tibell <johan.tibell@gmail.com>2014-03-13 23:00:00 +0100
commit46d05ba03d1491cade4a3fe33f0b8c404ad3c760 (patch)
tree9ebf6f5fb99ec2f75b80a451441a79f94e073401
parente55acf007f5109b42a2e388eaca63445bbbc7376 (diff)
downloadhaskell-46d05ba03d1491cade4a3fe33f0b8c404ad3c760.tar.gz
Fix two issues in stg_newArrayzh
The implementations of newArray# and newArrayArray#, stg_newArrayzh and stg_newArrayArrayzh, had three issues: * The condition for the loop that fills the array with the initial element was incorrect. It would write into the card table as well. The condition for the loop that filled the card table was never executed, as its condition was also wrong. In the end this didn't lead to any disasters as the value of the card table doesn't matter for newly allocated arrays. * The card table was unnecessarily initialized. The card table is only used when the array isn't copied, which new arrays always are. By not writing the card table at all we save some cycles. * The ticky allocation accounting was wrong. The second argument to TICK_ALLOC_PRIM is the size of the closure excluding the header size, but the header size was incorrectly included. Fixes #8867.
-rw-r--r--rts/PrimOps.cmm22
1 files changed, 4 insertions, 18 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index db65a4a268..0e547be388 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -178,7 +178,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
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);
+ TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(size), 0);
SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS);
StgMutArrPtrs_ptrs(arr) = n;
@@ -187,18 +187,11 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
// Initialise all elements of the the array with the value in R2
p = arr + SIZEOF_StgMutArrPtrs;
for:
- if (p < arr + WDS(words)) {
+ if (p < arr + SIZEOF_StgMutArrPtrs + WDS(n)) {
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);
}
@@ -270,7 +263,7 @@ stg_newArrayArrayzh ( W_ n /* 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);
+ TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(size), 0);
SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, W_[CCCS]);
StgMutArrPtrs_ptrs(arr) = n;
@@ -279,18 +272,11 @@ stg_newArrayArrayzh ( W_ n /* words */ )
// Initialise all elements of the array with a pointer to the new array
p = arr + SIZEOF_StgMutArrPtrs;
for:
- if (p < arr + WDS(words)) {
+ if (p < arr + SIZEOF_StgMutArrPtrs + WDS(n)) {
W_[p] = arr;
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);
}