gc
gc
This commit is contained in:
@@ -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 #
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ data RLPCOptions = RLPCOptions
|
|||||||
{ _rlpcLogFile :: Maybe FilePath
|
{ _rlpcLogFile :: Maybe FilePath
|
||||||
, _rlpcDebugOpts :: DebugOpts
|
, _rlpcDebugOpts :: DebugOpts
|
||||||
, _rlpcEvaluator :: Evaluator
|
, _rlpcEvaluator :: Evaluator
|
||||||
|
, _rlpcHeapTrigger :: Int
|
||||||
, _rlpcInputFiles :: [FilePath]
|
, _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
|
||||||
|
|||||||
52
src/GM.hs
52
src/GM.hs
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user