Skip to content

Commit b406de2

Browse files
committed
Use blackholing
1 parent 8400bf3 commit b406de2

File tree

2 files changed

+45
-13
lines changed
  • plutus-core
    • index-envs/src/Data/RandomAccessList
    • untyped-plutus-core/src/UntypedPlutusCore/Evaluation/Machine/Cek

2 files changed

+45
-13
lines changed

plutus-core/index-envs/src/Data/RandomAccessList/SkewBinary.hs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
module Data.RandomAccessList.SkewBinary
99
( RAList(Cons,Nil)
1010
, contIndexZero
11+
, contUpdateZero
1112
, contIndexOne
1213
, safeIndexZero
1314
, unsafeIndexZero
@@ -116,6 +117,30 @@ contIndexZero z f = findTree where
116117
else indexTree halfSize (offset - 1 - halfSize) t2
117118
{-# INLINE contIndexZero #-}
118119

120+
-- See Note [Optimizations of contUpdateZero].
121+
contUpdateZero :: forall a. (a -> a) -> RAList a -> Word64 -> RAList a
122+
contUpdateZero f = findTree where
123+
findTree :: RAList a -> Word64 -> RAList a
124+
-- See Note [Optimizations of contUpdateZero].
125+
findTree Nil !_ = error "out of bounds"
126+
findTree (BHead w t ts) i =
127+
if i < w
128+
then BHead w (indexTree w i t) ts
129+
else BHead w t (findTree ts (i-w))
130+
131+
indexTree :: Word64 -> Word64 -> Tree a -> Tree a
132+
-- See Note [Optimizations of contUpdateZero].
133+
indexTree !w 0 t = case t of
134+
Node x l r -> Node (f x) l r
135+
Leaf x -> if w == 1 then Leaf (f x) else error "out of bounds"
136+
indexTree _ _ (Leaf _) = error "out of bounds"
137+
indexTree treeSize offset (Node x t1 t2) =
138+
let halfSize = unsafeShiftR treeSize 1 -- probably faster than `div w 2`
139+
in if offset <= halfSize
140+
then Node x (indexTree halfSize (offset - 1) t1) t2
141+
else Node x t1 (indexTree halfSize (offset - 1 - halfSize) t2)
142+
{-# INLINE contUpdateZero #-}
143+
119144
contIndexOne :: forall a b. b -> (a -> b) -> RAList a -> Word64 -> b
120145
contIndexOne z _ _ 0 = z
121146
contIndexOne z f t n = contIndexZero z f t (n - 1)

plutus-core/untyped-plutus-core/src/UntypedPlutusCore/Evaluation/Machine/Cek/Internal.hs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ data CekValue uni fun ann =
246246
-- Check the docs of 'BuiltinRuntime' for details.
247247
-- | A constructor value, including fully computed arguments and the tag.
248248
| VConstr {-# UNPACK #-} !Word64 !(ArgStack uni fun ann)
249+
| VBlackHole !Text !Word64
249250

250251
deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni)
251252
=> Show (CekValue uni fun ann)
@@ -508,7 +509,10 @@ dischargeCekValEnv valEnv = go 0
508509
-- var is free, leave it alone
509510
var
510511
-- var is in the env, discharge its value
511-
dischargeCekValue
512+
(\case
513+
VBlackHole recName recLamCnt ->
514+
Var () (NamedDeBruijn recName . coerce $ lamCnt - recLamCnt)
515+
val -> dischargeCekValue val)
512516
-- index relative to (as seen from the point of view of) the environment
513517
(Env.indexOne valEnv $ idx - lamCnt)
514518
Apply ann fun arg -> Apply ann (go lamCnt fun) $ go lamCnt arg
@@ -537,6 +541,7 @@ dischargeCekValue = \case
537541
stack2list = go []
538542
go acc EmptyStack = acc
539543
go acc (ConsStack arg rest) = go (arg : acc) rest
544+
VBlackHole _ _ -> error "can't happen"
540545

541546
instance (PrettyUni uni, Pretty fun) => PrettyBy PrettyConfigPlc (CekValue uni fun ann) where
542547
prettyBy cfg = prettyBy cfg . dischargeCekValue
@@ -571,7 +576,7 @@ data Context uni fun ann
571576
-- ^ @(constr i V0 ... Vj-1 _ Nj ... Nn)@
572577
| FrameCases !(CekValEnv uni fun ann) !(V.Vector (NTerm uni fun ann)) !(Context uni fun ann)
573578
-- ^ @(case _ C0 .. Cn)@
574-
| FrameFix !(Context uni fun ann)
579+
| FrameFix {-# UNPACK #-} !Word64 !(Context uni fun ann)
575580
| NoFrame
576581

577582
deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni)
@@ -580,11 +585,12 @@ deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Clo
580585
-- See Note [ExMemoryUsage instances for non-constants].
581586
instance (Closed uni, uni `Everywhere` ExMemoryUsage) => ExMemoryUsage (CekValue uni fun ann) where
582587
memoryUsage = \case
583-
VCon c -> memoryUsage c
584-
VDelay {} -> singletonRose 1
585-
VLamAbs {} -> singletonRose 1
586-
VBuiltin {} -> singletonRose 1
587-
VConstr {} -> singletonRose 1
588+
VCon c -> memoryUsage c
589+
VDelay {} -> singletonRose 1
590+
VLamAbs {} -> singletonRose 1
591+
VBuiltin {} -> singletonRose 1
592+
VConstr {} -> singletonRose 1
593+
VBlackHole {} -> singletonRose 1
588594
{-# INLINE memoryUsage #-}
589595

590596
{- Note [ArgStack vs Spine]
@@ -703,9 +709,10 @@ enterComputeCek = computeCek
703709
computeCek !ctx !env (Case _ scrut cs) = do
704710
stepAndMaybeSpend BCase
705711
computeCek (FrameCases env cs ctx) env scrut
706-
computeCek !ctx !env (Fix _ _ body) = do
712+
computeCek !ctx !env (Fix _ rec body) = do
707713
stepAndMaybeSpend BFix
708-
computeCek (FrameFix ctx) env body
714+
let !len' = Env.length env + 1
715+
computeCek (FrameFix len' ctx) (Env.cons (VBlackHole (ndbnString rec) len') env) body
709716
-- s ; ρ ▻ error ↦ <> A
710717
computeCek !_ !_ (Error _) =
711718
throwing_ _EvaluationFailure
@@ -759,12 +766,12 @@ enterComputeCek = computeCek
759766
Just t -> computeCek (transferArgStack args ctx) env t
760767
Nothing -> throwingDischarged _MachineError (MissingCaseBranch i) e
761768
_ -> throwingDischarged _MachineError NonConstrScrutinized e
762-
returnCek (FrameFix ctx) bodyV =
769+
returnCek (FrameFix recIx ctx) bodyV =
763770
case bodyV of
764-
VLamAbs nameArg bodyLam env ->
765-
let env' = Env.cons bodyV' env
771+
VLamAbs nameArg bodyLam env -> do
772+
let env' = Env.contUpdateZero (\_ -> bodyV') env (Env.length env - recIx)
766773
bodyV' = VLamAbs nameArg bodyLam env'
767-
in returnCek ctx bodyV'
774+
returnCek ctx bodyV'
768775
_ -> throwingDischarged _MachineError NonLambdaFixedMachineError bodyV
769776

770777
-- | Evaluate a 'HeadSpine' by pushing the arguments (if any) onto the stack and proceeding with

0 commit comments

Comments
 (0)