diff --git a/ghc-datasize.cabal b/ghc-datasize.cabal
--- a/ghc-datasize.cabal
+++ b/ghc-datasize.cabal
@@ -1,31 +1,32 @@
 name:               ghc-datasize
-version:            0.1.2
+version:            0.2.7
 license:            BSD3
 license-file:       LICENSE
 category:           GHC, Debug, Development
 cabal-version:      >= 1.10
-build-type:         Custom
-author:             Dennis Felsing <dennis@felsin9.de>
-maintainer:         Dennis Felsing <dennis@felsin9.de>
-homepage:           http://felsin9.de/nnis/ghc-datasize
-copyright:          Dennis Felsing 2012
+build-type:         Simple
+author:             Dennis Felsing <dennis@felsing.org>
+maintainer:         Dennis Felsing <dennis@felsing.org>
+homepage:           https://dennis.felsing.org/ghc-datasize
+copyright:          Dennis Felsing 2012-2019
 synopsis:           Determine the size of data structures in GHC's memory
 description:        ghc-datasize is a tool to determine the size of data
                     structures in GHC's memory. Determining the size of
                     recursive data structures is supported. All sizes are in
                     Bytes.
 
-tested-with: GHC == 7.4.2, GHC == 7.6.1, GHC == 7.8.3
+tested-with: GHC == 8.6.5
 
 Library
   Exposed-modules: GHC.DataSize
   Default-Language: Haskell2010
-  Build-depends: base == 4.*,
-                 --containers,
-                 ghc-heap-view >= 0.5
+  Build-depends: base >= 4.12 && < 5.0,
+                 deepseq >= 1.3,
+                 ghc-heap >= 8.0,
+                 ghc-prim >= 0.5
   Hs-source-dirs: src/
   Ghc-options: -Wall
 
 source-repository head
     type:     git
-    location: git://r0q.ath.cx/ghc-datasize
+    location: https://github.com/def-/ghc-datasize.git
diff --git a/src/GHC/DataSize.hs b/src/GHC/DataSize.hs
--- a/src/GHC/DataSize.hs
+++ b/src/GHC/DataSize.hs
@@ -1,42 +1,39 @@
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+
 {- |
    Module      : GHC.DataSize
    Copyright   : (c) Dennis Felsing
    License     : 3-Clause BSD-style
-   Maintainer  : dennis@felsin9.de
+   Maintainer  : dennis@felsing.org
  -}
 module GHC.DataSize (
   closureSize,
-  recursiveSize
-  --mSize
+  recursiveSize,
+  recursiveSizeNF
   )
   where
 
-import GHC.HeapView hiding (size)
+import Control.DeepSeq (NFData, ($!!))
 
+import GHC.Exts
+import GHC.Exts.Heap hiding (size)
+import GHC.Exts.Heap.Constants (wORD_SIZE)
+
 import Control.Monad
 
 import System.Mem
 
--- This used to be available via GHC.Constants
-#include "MachDeps.h"
-wORD_SIZE :: Int
-wORD_SIZE = SIZEOF_HSWORD
-
---import qualified Data.IntMap as IntMap
-
---depth :: Int
---depth = 10^10
-
 -- Inspired by Simon Marlow:
 -- https://ghcmutterings.wordpress.com/2009/02/12/53/
 
 -- | Calculate size of GHC objects in Bytes. Note that an object may not be
 --   evaluated yet and only the size of the initial closure is returned.
-closureSize :: Num b => a -> IO b
+closureSize :: a -> IO Word
 closureSize x = do
-  (_,y,_) <- getClosureRaw x
-  return . fromIntegral $ length y * wORD_SIZE
+  rawWds <- getClosureRawWords x
+  return . fromIntegral $ length rawWds * wORD_SIZE
 
 -- | Calculate the recursive size of GHC objects in Bytes. Note that the actual
 --   size in memory is calculated, so shared values are only counted once.
@@ -56,16 +53,42 @@
 --
 --   A garbage collection is performed before the size is calculated, because
 --   the garbage collector would make heap walks difficult.
+--
+--   This function works very quickly on small data structures, but can be slow
+--   on large and complex ones. If speed is an issue it's probably possible to
+--   get the exact size of a small portion of the data structure and then
+--   estimate the total size from that.
 
-recursiveSize :: Num b => a -> IO b
+recursiveSize :: a -> IO Word
 recursiveSize x = do
   performGC
   liftM snd $ go ([], 0) $ asBox x
-  where go (vs, acc) b@(Box y) = do
+  where go (!vs, !acc) b@(Box y) = do
           isElem <- liftM or $ mapM (areBoxesEqual b) vs
           if isElem
             then return (vs, acc)
             else do
              size    <- closureSize y
              closure <- getClosureData y
-             foldM go (b : vs, acc + size) $ allPtrs closure
+             foldM go (b : vs, acc + size) $ allClosures closure
+
+-- | Calculate the recursive size of GHC objects in Bytes after calling
+-- Control.DeepSeq.force on the data structure to force it into Normal Form.
+-- Using this function requires that the data structure has an `NFData`
+-- typeclass instance.
+
+recursiveSizeNF :: NFData a => a -> IO Word
+recursiveSizeNF x = recursiveSize $!! x
+
+-- | Adapted from 'GHC.Exts.Heap.getClosureRaw' which isn't exported.
+--
+-- This returns the raw words of the closure on the heap. Once back in the
+-- Haskell world, the raw words that hold pointers may be outdated after a
+-- garbage collector run.
+getClosureRawWords :: a -> IO [Word]
+getClosureRawWords x = do
+    case unpackClosure# x of
+        (# _iptr, dat, _pointers #) -> do
+            let nelems = (I# (sizeofByteArray# dat)) `div` wORD_SIZE
+                end = fromIntegral nelems - 1
+            pure [W# (indexWordArray# dat i) | I# i <- [0.. end] ]
