rts: Fix isByteArrayPinned#'s treatment of large arrays
authorBen Gamari <bgamari.foss@gmail.com>
Mon, 3 Jul 2017 23:09:03 +0000 (19:09 -0400)
committerBen Gamari <ben@smart-cactus.org>
Mon, 3 Jul 2017 23:42:21 +0000 (19:42 -0400)
It should respond with True to both BF_PINNED and BF_LARGE byte arrays.
However, previously it would only check the BF_PINNED flag.

Test Plan: Validate

Reviewers: simonmar, austin, erikd

Subscribers: winterland1989, rwbarton, thomie

GHC Trac Issues: #13894

Differential Revision: https://phabricator.haskell.org/D3685

rts/PrimOps.cmm
testsuite/tests/rts/T13894.hs [new file with mode: 0644]
testsuite/tests/rts/all.T

index dddba39..006c9de 100644 (file)
@@ -147,10 +147,11 @@ stg_isByteArrayPinnedzh ( gcptr ba )
 {
     W_ bd, flags;
     bd = Bdescr(ba);
-    // pinned byte arrays live in blocks with the BF_PINNED flag set.
+    // Pinned byte arrays live in blocks with the BF_PINNED flag set.
+    // We also consider BF_LARGE objects to be unmoveable. See #13894.
     // See the comment in Storage.c:allocatePinned.
     flags = TO_W_(bdescr_flags(bd));
-    return (flags & BF_PINNED != 0);
+    return (flags & (BF_PINNED | BF_LARGE) != 0);
 }
 
 stg_isMutableByteArrayPinnedzh ( gcptr mba )
diff --git a/testsuite/tests/rts/T13894.hs b/testsuite/tests/rts/T13894.hs
new file mode 100644 (file)
index 0000000..e09e908
--- /dev/null
@@ -0,0 +1,18 @@
+-- Test that isByteArray# returns True for large but not explicitly pinned byte
+-- arrays
+
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples  #-}
+
+import Control.Monad
+import GHC.Exts
+import GHC.IO
+
+main :: IO ()
+main = do
+    pinned <- IO $ \s0 ->
+      case newByteArray# 1000000# s0 of
+        (# s1, arr# #) ->
+            case isMutableByteArrayPinned# arr# of
+              n# -> (# s1, isTrue# n# #)
+    unless pinned $ putStrLn "BAD"
index e02f880..e819404 100644 (file)
@@ -377,3 +377,4 @@ test('T12497', [ unless(opsys('mingw32'), skip)
 
 test('T12903', [when(opsys('mingw32'), skip)], compile_and_run, [''])
 test('T13832', exit_code(1), compile_and_run, ['-threaded'])
+test('T13894', normal, compile_and_run, [''])