summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/ghc-compact/tests/T18757.hs44
-rw-r--r--libraries/ghc-compact/tests/T18757.stdout-ws-321
-rw-r--r--libraries/ghc-compact/tests/T18757.stdout-ws-641
-rw-r--r--libraries/ghc-compact/tests/all.T1
-rw-r--r--rts/sm/CNF.c11
5 files changed, 47 insertions, 11 deletions
diff --git a/libraries/ghc-compact/tests/T18757.hs b/libraries/ghc-compact/tests/T18757.hs
new file mode 100644
index 0000000000..70a93b9bd8
--- /dev/null
+++ b/libraries/ghc-compact/tests/T18757.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+import Control.Monad
+import GHC.Compact
+import GHC.Compact.Serialized
+import GHC.IO
+import GHC.Prim
+
+-- | Test case for #18757, ensuring that the compact region allocator doesn't produce blocks
+-- smaller than the chosen default block size.
+main :: IO ()
+main = do
+ let
+ -- Valid for the x86_64 target of GHC
+ blocksPerMBlock, blockSize, dataBytesInMegablock :: Integral a => a
+ blocksPerMBlock = 252
+ blockSize = 4096
+ dataBytesInMegablock = blocksPerMBlock * blockSize
+
+ region <- compactSized dataBytesInMegablock False ()
+ largeObject <- newLargeObject
+
+ -- Add the large object a few times to our compact region:
+ replicateM 510 $ void $ compactAdd region largeObject
+
+ -- Now check how many blocks were allocated,
+ -- and how much data they each contain
+ blockSizes <- withSerializedCompact region $ \serialized ->
+ pure $ map snd $ serializedCompactBlockList serialized
+
+ -- This should print a list with only two entries, as the allocated objects
+ -- should all fit within one megablock.
+ print blockSizes
+
+-- | Create an object larger than the large object threshold
+-- (valid for the x86_64 target of GHC)
+newLargeObject :: IO LargeObject
+newLargeObject = IO $ \s ->
+ case newByteArray# 4000# s of
+ (# s', arr #) -> case unsafeFreezeByteArray# arr s of
+ (# s'', frozenArr #) -> (# s'', LargeObject frozenArr #)
+
+data LargeObject = LargeObject ByteArray#
diff --git a/libraries/ghc-compact/tests/T18757.stdout-ws-32 b/libraries/ghc-compact/tests/T18757.stdout-ws-32
new file mode 100644
index 0000000000..34575b4202
--- /dev/null
+++ b/libraries/ghc-compact/tests/T18757.stdout-ws-32
@@ -0,0 +1 @@
+[1036268,1011956]
diff --git a/libraries/ghc-compact/tests/T18757.stdout-ws-64 b/libraries/ghc-compact/tests/T18757.stdout-ws-64
new file mode 100644
index 0000000000..94081bd9e3
--- /dev/null
+++ b/libraries/ghc-compact/tests/T18757.stdout-ws-64
@@ -0,0 +1 @@
+[1032152,1024296]
diff --git a/libraries/ghc-compact/tests/all.T b/libraries/ghc-compact/tests/all.T
index 45e8d5f378..97cc7bd40a 100644
--- a/libraries/ghc-compact/tests/all.T
+++ b/libraries/ghc-compact/tests/all.T
@@ -22,6 +22,7 @@ test('compact_share', omit_ways(['ghci', 'profasm', 'profthreaded']),
test('compact_bench', [ ignore_stdout, extra_run_opts('100') ],
compile_and_run, [''])
test('T17044', normal, compile_and_run, [''])
+test('T18757', normal, compile_and_run, [''])
# N.B. Sanity check times out due to large list.
test('T16992', [when(wordsize(32), skip), # Resource limit exceeded on 32-bit
high_memory_usage,
diff --git a/rts/sm/CNF.c b/rts/sm/CNF.c
index 25c50adcc3..a6bd3b69f0 100644
--- a/rts/sm/CNF.c
+++ b/rts/sm/CNF.c
@@ -489,17 +489,6 @@ allocateForCompact (Capability *cap,
bd = Bdescr((P_)str->nursery);
bd->free = str->hp;
- // We know it doesn't fit in the nursery
- // if it is a large object, allocate a new block
- if (sizeW > LARGE_OBJECT_THRESHOLD/sizeof(W_)) {
- next_size = BLOCK_ROUND_UP(sizeW*sizeof(W_) + sizeof(StgCompactNFDataBlock));
- block = compactAppendBlock(cap, str, next_size);
- bd = Bdescr((P_)block);
- to = bd->free;
- bd->free += sizeW;
- return to;
- }
-
// move the nursery past full blocks
if (block_is_full (str->nursery)) {
do {