gc
This commit is contained in:
crumbtoo
2023-12-07 15:07:54 -07:00
parent c48a4ef4c0
commit a00405ebd4
3 changed files with 61 additions and 10 deletions

View File

@@ -45,6 +45,12 @@ options = RLPCOptions
<> value EvaluatorGM <> value EvaluatorGM
<> help "the intermediate layer used to model evaluation" <> help "the intermediate layer used to model evaluation"
) )
<*> option auto
( long "heap-trigger"
<> metavar "INT"
<> help "the number of nodes allowed on the heap before\
\triggering the garbage collector"
)
<*> some (argument str $ metavar "FILES...") <*> some (argument str $ metavar "FILES...")
where where
infixr 9 # infixr 9 #

View File

@@ -96,10 +96,11 @@ evalRLPCIO o m = do
data RLPCOptions = RLPCOptions data RLPCOptions = RLPCOptions
{ _rlpcLogFile :: Maybe FilePath { _rlpcLogFile :: Maybe FilePath
, _rlpcDebugOpts :: DebugOpts , _rlpcDebugOpts :: DebugOpts
, _rlpcEvaluator :: Evaluator , _rlpcEvaluator :: Evaluator
, _rlpcInputFiles :: [FilePath] , _rlpcHeapTrigger :: Int
, _rlpcInputFiles :: [FilePath]
} }
deriving Show deriving Show
@@ -128,6 +129,7 @@ instance Default RLPCOptions where
{ _rlpcLogFile = Nothing { _rlpcLogFile = Nothing
, _rlpcDebugOpts = mempty , _rlpcDebugOpts = mempty
, _rlpcEvaluator = EvaluatorGM , _rlpcEvaluator = EvaluatorGM
, _rlpcHeapTrigger = 200
, _rlpcInputFiles = [] , _rlpcInputFiles = []
} }
@@ -138,9 +140,6 @@ data DebugFlag = DDumpEval
| DDumpAST | DDumpAST
deriving (Show, Eq, Generic) deriving (Show, Eq, Generic)
-- deriving (Hashable)
-- via Generically DebugFlag
instance Hashable DebugFlag instance Hashable DebugFlag
makeLenses ''RLPCOptions makeLenses ''RLPCOptions

View File

@@ -15,6 +15,7 @@ module GM
import Data.Default.Class import Data.Default.Class
import Data.List (mapAccumL) import Data.List (mapAccumL)
import Data.Maybe (fromMaybe, mapMaybe) import Data.Maybe (fromMaybe, mapMaybe)
import Data.Monoid (Endo(..))
import Data.Tuple (swap) import Data.Tuple (swap)
import Lens.Micro import Lens.Micro
import Lens.Micro.TH import Lens.Micro.TH
@@ -79,6 +80,7 @@ data Node = NNum Int
| NInd Addr | NInd Addr
| NUninitialised | NUninitialised
| NConstr Tag [Addr] -- NConstr Tag Components | NConstr Tag [Addr] -- NConstr Tag Components
| NMarked Node
deriving (Show, Eq) deriving (Show, Eq)
-- TODO: log executed instructions -- TODO: log executed instructions
@@ -140,6 +142,11 @@ eval st = st : rest
doAdmin :: GmState -> GmState doAdmin :: GmState -> GmState
doAdmin st = st & gmStats . stsReductions %~ succ doAdmin st = st & gmStats . stsReductions %~ succ
& doGC
where
-- TODO: use heapTrigger option in RLPCOptions
heapTrigger = 50
doGC s = if (s ^. gmHeap & length) > heapTrigger then gc s else s
-- the state is considered final if there is no more code to execute. very -- the state is considered final if there is no more code to execute. very
-- simple compared to TI -- simple compared to TI
@@ -870,8 +877,47 @@ lookupC t n = lookup (ConstrKey t n)
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
gc :: GmState -> GmState gc :: GmState -> GmState
gc st = undefined gc st = (sweepNodes . markNodes $ st)
& gmStats . stsGCCycles %~ succ
findRoots :: GmState -> [Addr] markNodes :: GmState -> GmState
findRoots st = undefined markNodes st = st & gmHeap %~ thread (markFrom <$> roots)
where
h = st ^. gmHeap
roots = dumpRoots ++ stackRoots ++ envRoots
dumpRoots, stackRoots, envRoots :: [Addr]
dumpRoots = st ^. gmDump . each . _2
stackRoots = st ^.. gmStack . each
envRoots = st ^.. gmEnv . each . _2
markFrom :: Addr -> GmHeap -> GmHeap
markFrom a h = case hLookup a h of
Just (NMarked _) -> h
Just n@(NNum _) -> h & update a (NMarked n)
Just n@(NAp l r) -> h & update a (NMarked n)
& markFrom l
& markFrom r
Just n@(NInd p) -> h & update a (NMarked n)
& markFrom p
Just n@(NConstr _ as) -> h & update a (NMarked n)
& thread (fmap markFrom as)
Just n@NUninitialised -> h & update a (NMarked n)
-- should we scan for roots in NGlobal code?
Just n@(NGlobal _ _) -> h & update a (NMarked n)
-- we silently ignore dangling pointers without a ruckus as findRoots may
-- scout the same address multiple times
Nothing -> h
sweepNodes :: GmState -> GmState
sweepNodes st = st & gmHeap %~ thread (f <$> addresses h)
where
h = st ^. gmHeap
f a = case hLookupUnsafe a h of
NMarked n -> update a n
_ -> free a
thread :: [a -> a] -> (a -> a)
thread = appEndo . foldMap Endo