Fix nptr field alignment in RtClosureInspect
authorÖmer Sinan Ağacan <omeragacan@gmail.com>
Wed, 4 Jul 2018 06:12:01 +0000 (09:12 +0300)
committerÖmer Sinan Ağacan <omeragacan@gmail.com>
Wed, 4 Jul 2018 06:12:27 +0000 (09:12 +0300)
`extractSubTerms` (which is extracting pointer and non-pointer fields of a
closure) was computing the alignment incorrectly when aligning a 64-bit value
(e.g. a Double) on i386 by aligning it to 64-bits instead of to word size
(32-bits). This is documented in `mkVirtHeapOffsetsWithPadding`:

> Align the start offset (eg, 2-byte value should be 2-byte aligned).
> But not more than to a word.

Fixes #15061

Test Plan:
Validated on both 32-bit and 64-bit. 32-bit fails with various unrelated stat
failures, but no actual test failures.

Reviewers: hvr, bgamari

Reviewed By: bgamari

Subscribers: simonpj, rwbarton, thomie, carter

GHC Trac Issues: #15061

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

compiler/ghci/RtClosureInspect.hs
testsuite/tests/ghci.debugger/scripts/all.T

index 81bdb61..d540983 100644 (file)
@@ -742,11 +742,14 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0
           dflags <- getDynFlags
           let word_size = wORD_SIZE dflags
               size_b = primRepSizeB dflags rep
-              -- Fields are always aligned.
-              !aligned_idx = roundUpTo arr_i size_b
+              -- Align the start offset (eg, 2-byte value should be 2-byte
+              -- aligned). But not more than to a word. The offset calculation
+              -- should be the same with the offset calculation in
+              -- StgCmmLayout.mkVirtHeapOffsetsWithPadding.
+              !aligned_idx = roundUpTo arr_i (min word_size size_b)
               !new_arr_i = aligned_idx + size_b
               ws | size_b < word_size =
-                     [index size_b array aligned_idx word_size]
+                     [index size_b aligned_idx word_size]
                  | otherwise =
                      let (q, r) = size_b `quotRem` word_size
                      in ASSERT( r == 0 )
@@ -761,7 +764,7 @@ extractSubTerms recurse clos = liftM thdOf3 . go 0 0
                 (error "unboxedTupleTerm: no HValue for unboxed tuple") terms
 
     -- Extract a sub-word sized field from a word
-    index item_size_b array index_b word_size =
+    index item_size_b index_b word_size =
         (word .&. (mask `shiftL` moveBytes)) `shiftR` moveBytes
       where
         mask :: Word
index 88acdb0..f2e2658 100644 (file)
@@ -22,8 +22,7 @@ test('print019', extra_files(['../Test.hs']), ghci_script, ['print019.script'])
 test('print020', extra_files(['../HappyTest.hs']), ghci_script, ['print020.script'])
 test('print021', normal, ghci_script, ['print021.script'])
 test('print022',
-     [when(arch('powerpc64'), expect_broken(14455)),
-      when(wordsize(32), expect_broken(15061))],
+     [when(arch('powerpc64'), expect_broken(14455))],
      ghci_script, ['print022.script'])
 test('print023', extra_files(['../Test.hs']), ghci_script, ['print023.script'])
 test('print024', extra_files(['../Test.hs']), ghci_script, ['print024.script'])