Skip to content

Commit b2b4864

Browse files
committed
Use blackholing
1 parent ab2fd81 commit b2b4864

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
@@ -244,6 +244,7 @@ data CekValue uni fun ann =
244244
-- Check the docs of 'BuiltinRuntime' for details.
245245
-- | A constructor value, including fully computed arguments and the tag.
246246
| VConstr {-# UNPACK #-} !Word64 !(ArgStack uni fun ann)
247+
| VBlackHole !Text !Word64
247248

248249
deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni)
249250
=> Show (CekValue uni fun ann)
@@ -492,7 +493,10 @@ dischargeCekValEnv valEnv = go 0
492493
-- var is free, leave it alone
493494
var
494495
-- var is in the env, discharge its value
495-
dischargeCekValue
496+
(\case
497+
VBlackHole recName recLamCnt ->
498+
Var () (NamedDeBruijn recName . coerce $ lamCnt - recLamCnt)
499+
val -> dischargeCekValue val)
496500
-- index relative to (as seen from the point of view of) the environment
497501
(Env.indexOne valEnv $ idx - lamCnt)
498502
Apply ann fun arg -> Apply ann (go lamCnt fun) $ go lamCnt arg
@@ -521,6 +525,7 @@ dischargeCekValue = \case
521525
stack2list = go []
522526
go acc EmptyStack = acc
523527
go acc (ConsStack arg rest) = go (arg : acc) rest
528+
VBlackHole _ _ -> error "can't happen"
524529

525530
instance (PrettyUni uni, Pretty fun) => PrettyBy PrettyConfigPlc (CekValue uni fun ann) where
526531
prettyBy cfg = prettyBy cfg . dischargeCekValue
@@ -555,7 +560,7 @@ data Context uni fun ann
555560
-- ^ @(constr i V0 ... Vj-1 _ Nj ... Nn)@
556561
| FrameCases !(CekValEnv uni fun ann) !(V.Vector (NTerm uni fun ann)) !(Context uni fun ann)
557562
-- ^ @(case _ C0 .. Cn)@
558-
| FrameFix !(Context uni fun ann)
563+
| FrameFix {-# UNPACK #-} !Word64 !(Context uni fun ann)
559564
| NoFrame
560565

561566
deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Closed uni)
@@ -564,11 +569,12 @@ deriving stock instance (GShow uni, Everywhere uni Show, Show fun, Show ann, Clo
564569
-- See Note [ExMemoryUsage instances for non-constants].
565570
instance (Closed uni, uni `Everywhere` ExMemoryUsage) => ExMemoryUsage (CekValue uni fun ann) where
566571
memoryUsage = \case
567-
VCon c -> memoryUsage c
568-
VDelay {} -> singletonRose 1
569-
VLamAbs {} -> singletonRose 1
570-
VBuiltin {} -> singletonRose 1
571-
VConstr {} -> singletonRose 1
572+
VCon c -> memoryUsage c
573+
VDelay {} -> singletonRose 1
574+
VLamAbs {} -> singletonRose 1
575+
VBuiltin {} -> singletonRose 1
576+
VConstr {} -> singletonRose 1
577+
VBlackHole {} -> singletonRose 1
572578
{-# INLINE memoryUsage #-}
573579

574580
{- Note [ArgStack vs Spine]
@@ -687,9 +693,10 @@ enterComputeCek = computeCek
687693
computeCek !ctx !env (Case _ scrut cs) = do
688694
stepAndMaybeSpend BCase
689695
computeCek (FrameCases env cs ctx) env scrut
690-
computeCek !ctx !env (Fix _ _ body) = do
696+
computeCek !ctx !env (Fix _ rec body) = do
691697
stepAndMaybeSpend BFix
692-
computeCek (FrameFix ctx) env body
698+
let !len' = Env.length env + 1
699+
computeCek (FrameFix len' ctx) (Env.cons (VBlackHole (ndbnString rec) len') env) body
693700
-- s ; ρ ▻ error ↦ <> A
694701
computeCek !_ !_ (Error _) =
695702
throwing_ _EvaluationFailure
@@ -743,12 +750,12 @@ enterComputeCek = computeCek
743750
Just t -> computeCek (transferArgStack args ctx) env t
744751
Nothing -> throwingDischarged _MachineError (MissingCaseBranch i) e
745752
_ -> throwingDischarged _MachineError NonConstrScrutinized e
746-
returnCek (FrameFix ctx) bodyV =
753+
returnCek (FrameFix recIx ctx) bodyV =
747754
case bodyV of
748-
VLamAbs nameArg bodyLam env ->
749-
let env' = Env.cons bodyV' env
755+
VLamAbs nameArg bodyLam env -> do
756+
let env' = Env.contUpdateZero (\_ -> bodyV') env (Env.length env - recIx)
750757
bodyV' = VLamAbs nameArg bodyLam env'
751-
in returnCek ctx bodyV'
758+
returnCek ctx bodyV'
752759
_ -> throwingDischarged _MachineError NonLambdaFixedMachineError bodyV
753760

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

0 commit comments

Comments
 (0)