GC: implemented basic GC memory swapping; some refactoring
authorHarald Steinlechner <haraldsteinlechner@gmail.com>
Sat, 1 Sep 2012 18:33:58 +0000 (20:33 +0200)
committerHarald Steinlechner <haraldsteinlechner@gmail.com>
Sat, 1 Sep 2012 18:33:58 +0000 (20:33 +0200)
Mate/GC.hs
Mate/MemoryManager.hs
Mate/Tests/MockRefs.hs

index 687197babd98d65a1661f3ca604535cb64e1baa7..eb1f2f7db78bac215c61c8e89bebaa507c893ca7 100644 (file)
@@ -16,7 +16,7 @@ class (Eq a, Ord a, Show a) => RefObj a where
  
   refs      :: a -> IO [a]
   patchRefs :: a -> [a] -> IO ()
-  newRef    :: a -> a -> IO ()
+  setNewRef :: a -> a -> IO ()
   getNewRef :: a -> IO a
   
   marked  :: a -> IO Bool
index 3944f8223833262f549389bb5d55295a9114cccb..c55fb373a289ea75d47b0529abed788e519ea299 100644 (file)
@@ -14,7 +14,12 @@ import Control.Applicative
 import Mate.GC
 
 class AllocationManager a where
+  
+  -- | allocates n bytes in current space to space (may be to space or gen0 space)
   mallocBytes :: Int -> StateT a IO (Ptr b)
+  
+  -- | performs full gc and which is reflected in mem managers state
+  performCollection :: (RefObj b) => [b] ->  StateT a IO ()
 
 data TwoSpace = TwoSpace { fromBase :: IntPtr, 
                            toBase   :: IntPtr, 
@@ -25,6 +30,30 @@ data TwoSpace = TwoSpace { fromBase :: IntPtr,
 
 instance AllocationManager TwoSpace where
   mallocBytes = mallocBytes'
+  performCollection = performCollection'
+
+
+performCollection' :: (RefObj a) => [a] -> StateT TwoSpace IO ()
+performCollection' roots = do oldState <- get
+                              modify switchSpaces
+                              newState <- get
+                              lift (performCollectionIO newState roots)
+                              -- [todo hs]: patch gc roots
+                         
+-- [todo hs] this is slow. merge phases to eliminate list with refs
+performCollectionIO :: (AllocationManager b, RefObj a) => b -> [a] -> IO ()
+performCollectionIO manager refs = do lifeRefs <- liftM concat $ mapM (markTree'' marked mark []) refs
+                                      evacuateList lifeRefs manager
+                                      patchAllRefs lifeRefs                       
+
+switchSpaces :: TwoSpace -> TwoSpace
+switchSpaces old = old { fromHeap = toHeap old,
+                         toHeap = fromBase old, 
+                         fromBase = toBase old,
+                         toBase = fromBase old,
+                         fromExtreme = toExtreme old,
+                         toExtreme = fromExtreme old }
+
 
 mallocBytes' :: Int -> StateT TwoSpace IO (Ptr b)
 mallocBytes' bytes = do state <- get
@@ -41,7 +70,7 @@ mallocBytes' bytes = do state <- get
 
 
 evacuate' :: (RefObj a, AllocationManager b) => [a] -> StateT b IO ()
-evacuate' = foldr (\x evac -> evac >> evacuate'' x) (liftIO (return ())) 
+evacuate' =  mapM_ evacuate'' 
 
 evacuate'' :: (RefObj a, AllocationManager b) => a -> StateT b IO ()
 evacuate'' obj = do (size,payload) <- liftIO ((,) <$> size obj <*> payload obj)
@@ -50,7 +79,7 @@ evacuate'' obj = do (size,payload) <- liftIO ((,) <$> size obj <*> payload obj)
                     liftIO (putStrLn ("evacuating: " ++ show obj ++ " and set: " ++ show newPtr))
                     -- copy data over and leave notice
                     liftIO (copyBytes newPtr (intPtrToPtr payload) size >> 
-                            newRef obj (cast newPtr))
+                            setNewRef obj (cast newPtr))
 
 evacuateList :: (RefObj a, AllocationManager b) => [a] -> b -> IO ()
 evacuateList objs manager = evalStateT (evacuate' objs) manager
index f87d593eb0f70029b0f3e863dd31f10c3e318f9b..b1372606894d8bd18b1d36cc3524313fc85da8a7 100644 (file)
@@ -19,7 +19,7 @@ instance RefObj (Ptr a) where
   marked      = markedRef
   mark        = markRef (0x1::Int32)
   unmark      = markRef (0x0::Int32)
-  newRef      = newRefPtr
+  setNewRef   = setNewRefPtr
   patchRefs   = patchRefsPtr
   cast = castPtr
   getNewRef ptr = peekByteOff ptr newRefOff
@@ -45,8 +45,8 @@ markedRef ptr = liftM ((/=0) . fromIntegral) (peekByteOff ptr markedOff :: IO In
 markRef :: Int32 -> Ptr a -> IO ()
 markRef val ptr = pokeByteOff ptr markedOff val
 
-newRefPtr :: Ptr a -> Ptr a -> IO ()
-newRefPtr ptr newPtr = pokeByteOff ptr newRefOff newPtr
+setNewRefPtr :: Ptr a -> Ptr a -> IO ()
+setNewRefPtr ptr newPtr = pokeByteOff ptr newRefOff newPtr
 
 patchRefsPtr :: Ptr a -> [Ptr a] -> IO ()
 patchRefsPtr ptr xs = pokeArray (ptr `plusPtr` fieldsOff) xs