[commit: ghc] master: Remote GHCi: Optimize the serialization/deserialization of byte code (2fb6a8c)

git at git.haskell.org git at git.haskell.org
Tue Feb 2 08:21:37 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/2fb6a8c30567e7d071ffcf88e22ea7f72f60b826/ghc

>---------------------------------------------------------------

commit 2fb6a8c30567e7d071ffcf88e22ea7f72f60b826
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Fri Jan 29 11:27:50 2016 +0000

    Remote GHCi: Optimize the serialization/deserialization of byte code
    
    Summary: This cuts allocations by about a quarter.
    
    Test Plan:
    * validate
    * `ghci -fexternal-interpreter` in `nofib/real/anna`
    
    Reviewers: niteria, bgamari, ezyang, austin, hvr, erikd
    
    Subscribers: thomie
    
    Differential Revision: https://phabricator.haskell.org/D1875
    
    GHC Trac Issues: #11100


>---------------------------------------------------------------

2fb6a8c30567e7d071ffcf88e22ea7f72f60b826
 compiler/ghci/ByteCodeLink.hs      | 14 ++++++++-
 libraries/ghci/GHCi/ResolvedBCO.hs | 64 ++++++++++++++++++++++++++++++++------
 2 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/compiler/ghci/ByteCodeLink.hs b/compiler/ghci/ByteCodeLink.hs
index 74f490b..c108d16 100644
--- a/compiler/ghci/ByteCodeLink.hs
+++ b/compiler/ghci/ByteCodeLink.hs
@@ -28,6 +28,7 @@ import SizedSeq
 import GHCi
 import ByteCodeTypes
 import HscTypes
+import DynFlags
 import Name
 import NameEnv
 import PrimOp
@@ -39,6 +40,8 @@ import Util
 
 -- Standard libraries
 import Data.Array.Unboxed
+import Data.Array.Base
+import Data.Word
 import Foreign.Ptr
 import GHC.IO           ( IO(..) )
 import GHC.Exts
@@ -68,10 +71,19 @@ linkBCO hsc_env ie ce bco_ix breakarray
            (UnlinkedBCO _ arity insns bitmap lits0 ptrs0) = do
   lits <- mapM (lookupLiteral hsc_env ie) (ssElts lits0)
   ptrs <- mapM (resolvePtr hsc_env ie ce bco_ix breakarray) (ssElts ptrs0)
-  return (ResolvedBCO arity insns bitmap
+  let dflags = hsc_dflags hsc_env
+  return (ResolvedBCO arity (toWordArray dflags insns) bitmap
               (listArray (0, fromIntegral (sizeSS lits0)-1) lits)
               (addListToSS emptySS ptrs))
 
+-- Turn the insns array from a Word16 array into a Word array.  The
+-- latter is much faster to serialize/deserialize. Assumes the input
+-- array is zero-indexed.
+toWordArray :: DynFlags -> UArray Int Word16 -> UArray Int Word
+toWordArray dflags (UArray _ _ n arr) = UArray 0 (n'-1) n' arr
+  where n' = (n + w16s_per_word - 1) `quot` w16s_per_word
+        w16s_per_word = wORD_SIZE dflags `quot` 2
+
 lookupLiteral :: HscEnv -> ItblEnv -> BCONPtr -> IO Word
 lookupLiteral _ _ (BCONPtrWord lit) = return lit
 lookupLiteral hsc_env _ (BCONPtrLbl  sym) = do
diff --git a/libraries/ghci/GHCi/ResolvedBCO.hs b/libraries/ghci/GHCi/ResolvedBCO.hs
index a349ded..aa63d36 100644
--- a/libraries/ghci/GHCi/ResolvedBCO.hs
+++ b/libraries/ghci/GHCi/ResolvedBCO.hs
@@ -1,4 +1,5 @@
-{-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE RecordWildCards, DeriveGeneric, GeneralizedNewtypeDeriving,
+    BangPatterns #-}
 module GHCi.ResolvedBCO
   ( ResolvedBCO(..)
   , ResolvedBCOPtr(..)
@@ -8,38 +9,81 @@ import SizedSeq
 import GHCi.RemoteTypes
 import GHCi.BreakArray
 
+import Control.Monad.ST
 import Data.Array.Unboxed
+import Data.Array.Base
 import Data.Binary
 import GHC.Generics
 
 -- -----------------------------------------------------------------------------
 -- ResolvedBCO
 
--- A ResolvedBCO is one in which all the Name references have been
+-- A A ResolvedBCO is one in which all the Name references have been
 -- resolved to actual addresses or RemoteHValues.
-
+--
+-- Note, all arrays are zero-indexed (we assume this when
+-- serializing/deserializing)
 data ResolvedBCO
    = ResolvedBCO {
-        resolvedBCOArity  :: Int,
-        resolvedBCOInstrs :: UArray Int Word16,         -- insns
+        resolvedBCOArity  :: {-# UNPACK #-} !Int,
+        resolvedBCOInstrs :: UArray Int Word,           -- insns
         resolvedBCOBitmap :: UArray Int Word,           -- bitmap
         resolvedBCOLits   :: UArray Int Word,           -- non-ptrs
         resolvedBCOPtrs   :: (SizedSeq ResolvedBCOPtr)  -- ptrs
    }
    deriving (Generic, Show)
 
-instance Binary ResolvedBCO
+instance Binary ResolvedBCO where
+  put ResolvedBCO{..} = do
+    put resolvedBCOArity
+    putArray resolvedBCOInstrs
+    putArray resolvedBCOBitmap
+    putArray resolvedBCOLits
+    put resolvedBCOPtrs
+  get = ResolvedBCO <$> get <*> getArray <*> getArray <*> getArray <*> get
+
+-- Specialized versions of the binary get/put for UArray Int Word.
+-- This saves a bit of time and allocation over using the default
+-- get/put, because we get specialisd code and also avoid serializing
+-- the bounds.
+putArray :: UArray Int Word -> Put
+putArray a@(UArray _ _ n _) = do
+  put n
+  mapM_ put (elems a)
+
+getArray :: Get (UArray Int Word)
+getArray = do
+  n  <- get
+  xs <- gets n []
+  return $! mkArray n xs
+ where
+  gets 0 xs = return xs
+  gets n xs = do
+    x <- get
+    gets (n-1) (x:xs)
+
+  mkArray :: Int -> [Word] -> UArray Int Word
+  mkArray n0 xs0 = runST $ do
+    !marr <- newArray (0,n0-1) 0
+    let go 0 _ = return ()
+        go _ [] = error "mkArray"
+        go n (x:xs) = do
+          let n' = n-1
+          unsafeWrite marr n' x
+          go n' xs
+    go n0 xs0
+    unsafeFreezeSTUArray marr
 
 data ResolvedBCOPtr
-  = ResolvedBCORef Int
+  = ResolvedBCORef {-# UNPACK #-} !Int
       -- ^ reference to the Nth BCO in the current set
-  | ResolvedBCOPtr (RemoteRef HValue)
+  | ResolvedBCOPtr {-# UNPACK #-} !(RemoteRef HValue)
       -- ^ reference to a previously created BCO
-  | ResolvedBCOStaticPtr (RemotePtr ())
+  | ResolvedBCOStaticPtr {-# UNPACK #-} !(RemotePtr ())
       -- ^ reference to a static ptr
   | ResolvedBCOPtrBCO ResolvedBCO
       -- ^ a nested BCO
-  | ResolvedBCOPtrBreakArray (RemoteRef BreakArray)
+  | ResolvedBCOPtrBreakArray {-# UNPACK #-} !(RemoteRef BreakArray)
       -- ^ Resolves to the MutableArray# inside the BreakArray
   deriving (Generic, Show)
 



More information about the ghc-commits mailing list