1
1
mirror of https://github.com/github/semantic.git synced 2024-11-24 17:04:47 +03:00

Move gc/reachable into Control.Abstract.Heap.

This commit is contained in:
Rob Rix 2018-05-31 09:33:04 -04:00
parent 91122566df
commit a72515b858
2 changed files with 33 additions and 27 deletions

View File

@ -5,8 +5,6 @@ module Analysis.Abstract.Collecting
) where
import Control.Abstract
import Data.Abstract.Heap
import Data.Abstract.Live
import Data.Semilattice.Lower
import Prologue
@ -24,31 +22,6 @@ collectingTerms recur term = do
v <- recur term
v <$ TermEvaluator (modifyHeap (gc (roots <> valueRoots v)))
-- | Collect any addresses in the heap not rooted in or reachable from the given 'Live' set.
gc :: ( Ord address
, Foldable (Cell address)
, ValueRoots address value
)
=> Live address -- ^ The set of addresses to consider rooted.
-> Heap address (Cell address) value -- ^ A heap to collect unreachable addresses within.
-> Heap address (Cell address) value -- ^ A garbage-collected heap.
gc roots heap = heapRestrict heap (reachable roots heap)
-- | Compute the set of addresses reachable from a given root set in a given heap.
reachable :: ( Ord address
, Foldable (Cell address)
, ValueRoots address value
)
=> Live address -- ^ The set of root addresses.
-> Heap address (Cell address) value -- ^ The heap to trace addresses through.
-> Live address -- ^ The set of addresses reachable from the root set.
reachable roots heap = go mempty roots
where go seen set = case liveSplit set of
Nothing -> seen
Just (a, as) -> go (liveInsert a seen) $ case heapLookupAll a heap of
Just values -> liveDifference (foldr ((<>) . valueRoots) mempty values <> as) seen
_ -> seen
providingLiveSet :: Effectful (m address value) => m address value (Reader (Live address) ': effects) a -> m address value effects a
providingLiveSet = runReader lowerBound

View File

@ -11,6 +11,9 @@ module Control.Abstract.Heap
, letrec
, letrec'
, variable
-- * Garbage collection
, gc
, reachable
-- * Effects
, Store(..)
, runStore
@ -22,7 +25,9 @@ module Control.Abstract.Heap
import Control.Abstract.Addressable
import Control.Abstract.Environment
import Control.Abstract.Evaluator
import Control.Abstract.Roots
import Data.Abstract.Heap
import Data.Abstract.Live
import Data.Abstract.Name
import Data.Semigroup.Reducer
import Prologue
@ -100,6 +105,34 @@ variable :: ( Member (Store address value) effects
variable name = lookupEnv name >>= maybeM (freeVariableError name) >>= deref
-- Garbage collection
-- | Collect any addresses in the heap not rooted in or reachable from the given 'Live' set.
gc :: ( Ord address
, Foldable (Cell address)
, ValueRoots address value
)
=> Live address -- ^ The set of addresses to consider rooted.
-> Heap address (Cell address) value -- ^ A heap to collect unreachable addresses within.
-> Heap address (Cell address) value -- ^ A garbage-collected heap.
gc roots heap = heapRestrict heap (reachable roots heap)
-- | Compute the set of addresses reachable from a given root set in a given heap.
reachable :: ( Ord address
, Foldable (Cell address)
, ValueRoots address value
)
=> Live address -- ^ The set of root addresses.
-> Heap address (Cell address) value -- ^ The heap to trace addresses through.
-> Live address -- ^ The set of addresses reachable from the root set.
reachable roots heap = go mempty roots
where go seen set = case liveSplit set of
Nothing -> seen
Just (a, as) -> go (liveInsert a seen) $ case heapLookupAll a heap of
Just values -> liveDifference (foldr ((<>) . valueRoots) mempty values <> as) seen
_ -> seen
-- Effects
data Store address value return where