| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Unison.Runtime.MCode
Synopsis
- data Args'
- data Args
- newtype FieldRef = FieldRef Word64
- data RecordShape = RecordShape {
- shapeRef :: !RecordRef
- shapeFields :: !(Vector FieldName)
- shapeKeys :: !(PrimArray Word64)
- shapeSlots :: !(PrimArray Int)
- mkRecordShape :: RecordRef -> Vector FieldName -> [FieldRef] -> RecordShape
- shapeSlot :: RecordShape -> FieldRef -> Int
- recordShape :: MonadState RecordFieldMappings m => RecordRef -> RecordSchema -> m RecordShape
- recordShapeFrom :: RecordFieldMappings -> RecordRef -> RecordSchema -> Maybe RecordShape
- data RefNums = RN {}
- data MLit
- data GInstr comb
- = Prim2 !Prim2 !Int !Int
- | Lit !MLit
- | Prim1 !Prim1 !Int
- | ForeignCall !Bool !ForeignFunc !Args
- | Pack !PackedTag !Args
- | Name !(GRef comb) !Args
- | RefCAS !Int !Int !Int
- | DLLCall
- | SetAff !Bool !Int !Int
- | Capture !Word64
- | Discard !Int
- | Info !String
- | PackWide !PackedTag !Bool !Args
- | Box !Int
- | RecPack !RecordShape !Args
- | RecUnpack !(Vector FieldRef) !Int
- | RecSet !FieldRef !Args
- | Print !Int
- | Reset !(EnumSet Word64) !Int !(Maybe Int)
- | InLocal !Int
- | Fork !Int
- | Atomically !Int
- | Seq !Args
- | TryForce !Int
- | SandboxingFailure !Text
- | KeepAlive !Int
- | NewForeignPtr !Int !Int
- | AddFinalizer !Int !Int
- | MkCallback !Int !Int
- type Instr = GInstr CombIx
- type RInstr val = GInstr (RComb val)
- data GSection comb where
- Ins !(GInstr comb) !(GSection comb)
- Call !Bool !CombIx comb !Args
- DMatch !(Maybe Reference) !Int !(GBranch comb)
- Let !(GSection comb) !CombIx !Int !(GSection comb) !(Ptr NativeCell)
- Yield !Args
- App !Bool !(GRef comb) !Args
- Jump !Int !Args
- Match !Int !(GBranch comb)
- Die String
- Exit
- NMatch !(Maybe Reference) !Int !(GBranch comb)
- RMatch !Int !(GSection comb) !(EnumMap Word64 (GBranch comb))
- pattern MatchT :: Int -> GSection comb -> Map Text (GSection comb) -> GSection comb
- pattern MatchW :: Int -> GSection comb -> EnumMap Word64 (GSection comb) -> GSection comb
- type RSection val = GSection (RComb val)
- type Section = GSection CombIx
- data GComb val comb where
- data FrameLayout = FrameLayout {
- wideVars :: [(Int, Int)]
- baseFrames :: Maybe Deopt
- frameDepth :: Int
- enclosingLets :: Int
- emptyLayout :: FrameLayout
- layoutPadding :: Int -> FrameLayout -> Int
- widePadding :: Int -> FrameLayout -> Int
- data Deopt = Deopt [BaseFrame]
- data BaseFrame = BaseFrame !Word64 [Slot]
- data Slot
- data GCombInfo comb = LamI !Int !Int !(GSection comb) !(Ptr NativeCell)
- data NativeCell
- readNativeCode :: Ptr NativeCell -> IO (Ptr ())
- readNativeEntry :: Ptr NativeCell -> IO (Ptr ())
- writeNativeCode :: Ptr NativeCell -> Ptr () -> IO ()
- bumpNativeCount :: Ptr NativeCell -> IO Bool
- readNativeCount :: Ptr NativeCell -> IO Int
- writeNativeCount :: Ptr NativeCell -> Int -> IO ()
- claimNativeCell :: Ptr NativeCell -> IO Bool
- nativeRegisterEntryOffset :: Int
- writeNativeRegisterEntry :: Ptr NativeCell -> Ptr () -> IO ()
- releaseNativeCell :: Ptr NativeCell -> IO ()
- takeNativeCell :: Ptr NativeCell -> IO Bool
- nativeCellRequested :: Ptr NativeCell -> IO Bool
- readNativeVerdict :: Ptr NativeCell -> IO Int
- writeNativeVerdict :: Ptr NativeCell -> Int -> IO ()
- data NativeCellPool = NativeCellPool !(Ptr NativeCell) !Int !Int
- newNativeCells :: Int -> IO (Ptr NativeCell)
- nativeCellAt :: Ptr NativeCell -> Int -> Ptr NativeCell
- newNativeCellPool :: Int -> Int -> IO NativeCellPool
- takeNativeCells :: Int -> NativeCellPool -> Maybe (Ptr NativeCell, NativeCellPool)
- growNativeCellPool :: Int -> Int -> NativeCellPool -> IO NativeCellPool
- noNativeCell :: Ptr NativeCell
- attachNativeCells :: Ptr NativeCell -> EnumMap Word64 (GCombs val comb) -> (Int, EnumMap Word64 (GCombs val comb))
- type Comb = GComb Void CombIx
- newtype RComb val = RComb {}
- type RCombInfo val = GCombInfo (RComb val)
- type GCombs val comb = EnumMap Word64 (GComb val comb)
- type RCombs val = GCombs val (RComb val)
- data CombIx = CIx !Reference !Word64 !Word64
- data GRef comb
- type RRef val = GRef (RComb val)
- type Ref = GRef CombIx
- data Prim1
- = VWLS
- | VWRS
- | SIZS
- | SIZT
- | UCNS
- | REFR
- | DECI
- | DECN
- | INCI
- | INCN
- | NEGI
- | SGNI
- | LZRO
- | TZRO
- | COMN
- | COMI
- | POPC
- | ABSF
- | EXPF
- | LOGF
- | SQRT
- | COSF
- | ACOS
- | COSH
- | ACSH
- | SINF
- | ASIN
- | SINH
- | ASNH
- | TANF
- | ATAN
- | TANH
- | ATNH
- | ITOF
- | NTOF
- | CEIL
- | FLOR
- | TRNF
- | RNDF
- | TRNC
- | NOTB
- | USNC
- | ITOT
- | NTOT
- | FTOT
- | TTOI
- | TTON
- | TTOF
- | PAKT
- | UPKT
- | PAKB
- | UPKB
- | SIZB
- | FLTB
- | MISS
- | CACH
- | LKUP
- | LOAD
- | CVLD
- | VALU
- | TLTT
- | DBTX
- | SDBL
- | REFN
- | RRFC
- | TIKR
- data Prim2
- = ADDN
- | EQLN
- | LESN
- | DRPN
- | LEQN
- | MULN
- | ADDI
- | SUBI
- | SUBN
- | MULI
- | DIVI
- | DIVN
- | MODI
- | MODN
- | SHLI
- | SHLN
- | SHRI
- | SHRN
- | POWI
- | POWN
- | EQLI
- | NEQI
- | NEQN
- | LEQI
- | LESI
- | ANDN
- | ANDI
- | IORN
- | IORI
- | XORN
- | XORI
- | EQLF
- | NEQF
- | LEQF
- | LESF
- | ADDF
- | SUBF
- | MULF
- | DIVF
- | ATN2
- | POWF
- | LOGB
- | MAXF
- | MINF
- | CAST
- | ANDB
- | IORB
- | EQLU
- | CMPU
- | LEQU
- | LESU
- | DRPT
- | CATT
- | TAKT
- | IXOT
- | EQLT
- | LEQT
- | LEST
- | DRPS
- | CATS
- | TAKS
- | CONS
- | SNOC
- | IDXS
- | SPLL
- | SPLR
- | TAKB
- | DRPB
- | IDXB
- | CATB
- | IXOB
- | THRO
- | TRCE
- | SDBX
- | SDBV
- | REFW
- data GBranch comb
- data Arm comb = Arm !ConstructorArity !(GSection comb)
- type ConstructorArity = Int
- armSection :: Arm comb -> GSection comb
- type Branch = GBranch CombIx
- type RBranch val = GBranch (RComb val)
- data RecordFieldMappings = RecordFieldMappings FieldRef (BiMap FieldName FieldRef)
- emptyRecordFieldMappings :: RecordFieldMappings
- convertFieldNamesToRefs :: (MonadState RecordFieldMappings m, Traversable f) => f FieldName -> m (f FieldRef)
- emitCombs :: Var v => RefNums -> Reference -> Word64 -> Word64 -> SuperGroup Reference v -> State RecordFieldMappings (EnumMap Word64 Comb, Maybe (EnumMap Word64 Comb))
- emitComb :: Var v => RefNums -> Reference -> Word64 -> RCtx v -> (Word64, SuperNormal Reference v) -> State RecordFieldMappings (EnumMap Word64 Comb, EnumMap Word64 (Chain v))
- emptyRCtx :: RCtx v
- resolveCombs :: Maybe (EnumMap Word64 (RCombs val)) -> EnumMap Word64 (GCombs val CombIx) -> EnumMap Word64 (RCombs val)
- sanitizeCombsOfForeignFuncs :: Bool -> Set ForeignFunc -> EnumMap Word64 (EnumMap Word64 (GComb Void CombIx)) -> EnumMap Word64 (EnumMap Word64 (GComb Void CombIx))
- absurdCombs :: EnumMap Word64 (EnumMap Word64 (GComb Void cix)) -> EnumMap Word64 (GCombs any cix)
- emptyRNs :: RefNums
- argsToLists :: Args -> [Int]
- argsToArgs' :: Args -> Args'
- countArgs :: Args -> Int
- pushCount :: GInstr comb -> Maybe Int
- combRef :: CombIx -> Reference
- combDeps :: GComb val comb -> [Word64]
- combTypes :: GComb any comb -> [Word64]
- prettyCombs :: Word64 -> EnumMap Word64 Comb -> ShowS
- prettyComb :: (Show val, Show comb) => Word64 -> Word64 -> GComb val comb -> ShowS
- prettySection :: Show comb => Int -> GSection comb -> ShowS
- prettyIns :: Show comb => GInstr comb -> ShowS
Documentation
Efficient mapping for record field names
Instances
| Enum FieldRef Source # | |
Defined in Unison.Runtime.MCode | |
| Show FieldRef Source # | |
| Eq FieldRef Source # | |
| Ord FieldRef Source # | |
Defined in Unison.Runtime.MCode | |
| EnumKey FieldRef Source # | |
data RecordShape Source #
The shape of a record: which fields it has, and where each one sits in a record value's slots.
One of these is built per record-construction site and is carried by every
value built there. Reaching it from the value is what lets Eq and
compareClosure -- which are pure, with no access to the code cache --
order two records of *different* shapes by field name. That case is
reachable: two records with different fields can be compared once they are
wrapped in Any, which erases their types.
Constructors
| RecordShape | |
Fields
| |
Instances
| Show RecordShape Source # | |
Defined in Unison.Runtime.MCode Methods showsPrec :: Int -> RecordShape -> ShowS # show :: RecordShape -> String # showList :: [RecordShape] -> ShowS # | |
| Eq RecordShape Source # | Records are equal and ordered by field name, never by |
Defined in Unison.Runtime.MCode | |
| Ord RecordShape Source # | |
Defined in Unison.Runtime.MCode Methods compare :: RecordShape -> RecordShape -> Ordering # (<) :: RecordShape -> RecordShape -> Bool # (<=) :: RecordShape -> RecordShape -> Bool # (>) :: RecordShape -> RecordShape -> Bool # (>=) :: RecordShape -> RecordShape -> Bool # max :: RecordShape -> RecordShape -> RecordShape # min :: RecordShape -> RecordShape -> RecordShape # | |
mkRecordShape :: RecordRef -> Vector FieldName -> [FieldRef] -> RecordShape Source #
A shape from its reference, its field names ascending, and the number of
each field in that order (so the field at slot i has number refs !! i).
shapeSlot :: RecordShape -> FieldRef -> Int Source #
The slot of a field in a record of this shape: a binary search of
shapeKeys. A field the shape lacks is an error, not a result: typechecked
code only reads fields the record has, so there is nothing to recover
from, and nothing to allocate on the way out.
recordShape :: MonadState RecordFieldMappings m => RecordRef -> RecordSchema -> m RecordShape Source #
Build the shape for a record schema, assigning a FieldRef to any field
name not yet seen.
recordShapeFrom :: RecordFieldMappings -> RecordRef -> RecordSchema -> Maybe RecordShape Source #
Build the shape for a record schema from already-interned field names. Returns Nothing if any of them is unknown, which shouldn't happen for a schema that is itself already interned.
Constructors
| RN | |
Fields
| |
Constructors
| Prim2 !Prim2 !Int !Int | |
| Lit !MLit | |
| Prim1 !Prim1 !Int | |
| ForeignCall !Bool !ForeignFunc !Args | |
| Pack !PackedTag !Args | |
| Name !(GRef comb) !Args | |
| RefCAS !Int !Int !Int | |
| DLLCall | |
| SetAff !Bool !Int !Int | |
| Capture !Word64 | |
| Discard !Int | |
| Info !String | |
| PackWide !PackedTag !Bool !Args | |
| Box !Int | |
| RecPack !RecordShape !Args | |
| RecUnpack !(Vector FieldRef) !Int | |
| RecSet !FieldRef !Args | |
| Print !Int | |
| Reset !(EnumSet Word64) !Int !(Maybe Int) | |
| InLocal !Int | |
| Fork !Int | |
| Atomically !Int | |
| Seq !Args | |
| TryForce !Int | |
| SandboxingFailure !Text | |
| KeepAlive !Int | |
| NewForeignPtr !Int !Int | |
| AddFinalizer !Int !Int | |
| MkCallback !Int !Int |
Instances
| Functor GInstr Source # | |
| Foldable GInstr Source # | |
Defined in Unison.Runtime.MCode Methods fold :: Monoid m => GInstr m -> m # foldMap :: Monoid m => (a -> m) -> GInstr a -> m # foldMap' :: Monoid m => (a -> m) -> GInstr a -> m # foldr :: (a -> b -> b) -> b -> GInstr a -> b # foldr' :: (a -> b -> b) -> b -> GInstr a -> b # foldl :: (b -> a -> b) -> b -> GInstr a -> b # foldl' :: (b -> a -> b) -> b -> GInstr a -> b # foldr1 :: (a -> a -> a) -> GInstr a -> a # foldl1 :: (a -> a -> a) -> GInstr a -> a # elem :: Eq a => a -> GInstr a -> Bool # maximum :: Ord a => GInstr a -> a # minimum :: Ord a => GInstr a -> a # | |
| Traversable GInstr Source # | |
| Show comb => Show (GInstr comb) Source # | |
| Eq (GInstr comb) Source # | |
| Ord (GInstr comb) Source # | |
Defined in Unison.Runtime.MCode | |
Constructors
| Ins !(GInstr comb) !(GSection comb) | |
| Call !Bool !CombIx comb !Args | |
| DMatch !(Maybe Reference) !Int !(GBranch comb) | |
| Let !(GSection comb) !CombIx !Int !(GSection comb) !(Ptr NativeCell) | |
| Yield !Args | |
| App !Bool !(GRef comb) !Args | |
| Jump !Int !Args | |
| Match !Int !(GBranch comb) | |
| Die String | |
| Exit | |
| NMatch !(Maybe Reference) !Int !(GBranch comb) | |
| RMatch !Int !(GSection comb) !(EnumMap Word64 (GBranch comb)) |
Bundled Patterns
| pattern MatchT :: Int -> GSection comb -> Map Text (GSection comb) -> GSection comb | |
| pattern MatchW :: Int -> GSection comb -> EnumMap Word64 (GSection comb) -> GSection comb |
Instances
| Functor GSection Source # | |
| Foldable GSection Source # | |
Defined in Unison.Runtime.MCode Methods fold :: Monoid m => GSection m -> m # foldMap :: Monoid m => (a -> m) -> GSection a -> m # foldMap' :: Monoid m => (a -> m) -> GSection a -> m # foldr :: (a -> b -> b) -> b -> GSection a -> b # foldr' :: (a -> b -> b) -> b -> GSection a -> b # foldl :: (b -> a -> b) -> b -> GSection a -> b # foldl' :: (b -> a -> b) -> b -> GSection a -> b # foldr1 :: (a -> a -> a) -> GSection a -> a # foldl1 :: (a -> a -> a) -> GSection a -> a # elem :: Eq a => a -> GSection a -> Bool # maximum :: Ord a => GSection a -> a # minimum :: Ord a => GSection a -> a # | |
| Traversable GSection Source # | |
| Show comb => Show (GSection comb) Source # | |
| Eq comb => Eq (GSection comb) Source # | |
| Ord comb => Ord (GSection comb) Source # | |
Defined in Unison.Runtime.MCode Methods compare :: GSection comb -> GSection comb -> Ordering # (<) :: GSection comb -> GSection comb -> Bool # (<=) :: GSection comb -> GSection comb -> Bool # (>) :: GSection comb -> GSection comb -> Bool # (>=) :: GSection comb -> GSection comb -> Bool # | |
Constructors
| Comb | |
Fields
| |
| CachedVal !Word64 !val | |
Bundled Patterns
| pattern Lam :: Int -> Int -> GSection comb -> GComb val comb | Matches any combinator, ignoring its native code cell. Building one with this gives it the shared "never compiled" cell, so don't use it to rebuild a combinator that already has a cell of its own. |
Instances
| Bifoldable GComb Source # | |
| Bifunctor GComb Source # | |
| Bitraversable GComb Source # | |
Defined in Unison.Runtime.MCode Methods bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> GComb a b -> f (GComb c d) # | |
| Functor (GComb val) Source # | |
| Foldable (GComb val) Source # | |
Defined in Unison.Runtime.MCode Methods fold :: Monoid m => GComb val m -> m # foldMap :: Monoid m => (a -> m) -> GComb val a -> m # foldMap' :: Monoid m => (a -> m) -> GComb val a -> m # foldr :: (a -> b -> b) -> b -> GComb val a -> b # foldr' :: (a -> b -> b) -> b -> GComb val a -> b # foldl :: (b -> a -> b) -> b -> GComb val a -> b # foldl' :: (b -> a -> b) -> b -> GComb val a -> b # foldr1 :: (a -> a -> a) -> GComb val a -> a # foldl1 :: (a -> a -> a) -> GComb val a -> a # toList :: GComb val a -> [a] # length :: GComb val a -> Int # elem :: Eq a => a -> GComb val a -> Bool # maximum :: Ord a => GComb val a -> a # minimum :: Ord a => GComb val a -> a # | |
| Traversable (GComb val) Source # | |
Defined in Unison.Runtime.MCode | |
| (Show comb, Show val) => Show (GComb val comb) Source # | |
| (Eq comb, Eq val) => Eq (GComb val comb) Source # | |
| (Ord comb, Ord val) => Ord (GComb val comb) Source # | |
Defined in Unison.Runtime.MCode Methods compare :: GComb val comb -> GComb val comb -> Ordering # (<) :: GComb val comb -> GComb val comb -> Bool # (<=) :: GComb val comb -> GComb val comb -> Bool # (>) :: GComb val comb -> GComb val comb -> Bool # (>=) :: GComb val comb -> GComb val comb -> Bool # | |
data FrameLayout Source #
What a let body's combinator knows about the frame it is resumed
over: the wide variables of the frame, each as (the index of its value
slot from the top of the frame, its width in slots), in increasing
order; and, for a section the explosion rewrote, the frames the
unoptimized code has at this point, for a continuation written out
(Deopt).
Constructors
| FrameLayout | |
Fields
| |
Instances
| Show FrameLayout Source # | |
Defined in Unison.Runtime.MCode Methods showsPrec :: Int -> FrameLayout -> ShowS # show :: FrameLayout -> String # showList :: [FrameLayout] -> ShowS # | |
| Eq FrameLayout Source # | |
Defined in Unison.Runtime.MCode | |
| Ord FrameLayout Source # | |
Defined in Unison.Runtime.MCode Methods compare :: FrameLayout -> FrameLayout -> Ordering # (<) :: FrameLayout -> FrameLayout -> Bool # (<=) :: FrameLayout -> FrameLayout -> Bool # (>) :: FrameLayout -> FrameLayout -> Bool # (>=) :: FrameLayout -> FrameLayout -> Bool # max :: FrameLayout -> FrameLayout -> FrameLayout # min :: FrameLayout -> FrameLayout -> FrameLayout # | |
layoutPadding :: Int -> FrameLayout -> Int Source #
The slots a frame layout adds over one per variable, for a frame
that holds n variables. A section inside a let's binding lists the
wide variables of the enclosing frames too, below its own slots
(wideSlots walks the whole context), and those are not this frame's:
a wide variable at wide index i is the frame's when its narrow index,
i less the padding of the wide variables above it, is below n. (Until
2026-11-02 every listed variable counted, so a frame inside a binding
with a wide variable in the enclosing frame came up short.)
widePadding :: Int -> FrameLayout -> Int Source #
The same for a frame of f slots, wide.
How a continuation's frame for a section the explosion rewrote is
written out as the frames the unoptimized code has at that point
(design.md, "Continuations across processes"; built by deoptOf,
applied by deoptCont). The frames come
innermost first, each as the index of the unoptimized section it
resumes, in the group, and its slots from the top; a let whose binding
the rewrite moved into the enclosing frame (sinkCalls) gives two, the
binding's and the let's, and the optimized frame's pending arguments go
with the last. A slot is copied from the optimized frames, by frame (0
this one, 1 the enclosing let's, counting the continuation's Push
frames outward) and narrowed index from the top, or is a product the
optimized code no longer holds, packed from such slots, or is dead, a
slot the unoptimized code never reads there, written as unit.
Instances
| Show BaseFrame Source # | |
| Eq BaseFrame Source # | |
| Ord BaseFrame Source # | |
Instances
data NativeCell Source #
A native code cell (see unison-runtimesrcUnisonRuntimeJIT/design.md): the mutable part of a combinator, 40 bytes outside the Haskell heap, never moved and never freed, so generated code can refer to it by address. As a C struct:
struct cell {
void *code; // offset 0: the compiled entry point, NULL until compiled
int64_t count; // offset 8: calls made while code was NULL
int64_t state; // offset 16: 0 not yet requested, 1 queued, 2 taken by the compile thread
int64_t verdict; // offset 24: whether it is worth compiling (see readNativeVerdict)
void *entry; // offset 32: the register entry, for native callers in other modules
};The state only moves forward, so a combinator is asked for only once.
The layout is a contract between two readers: this module (the
and accessors below, at those offsets) and
the generated code, which loads at offset 0 or at
offset 32 to call through a cell and writes @ at offset 8
(JIT/Codegen.hs); nothing in the C runtime reads a cell. The register
entry is a function with the signature native code agrees on across
modules for the combinator's arity (design.md, "The register entry"):
null when the combinator is not compiled, or compiled without a worker.
The count starts at minus the JIT's compilation threshold when the JIT compiles what gets hot, so that "hot" is the count reaching zero: the interpreter's test is one comparison with a constant. A count that starts at zero or above never gets there.
readNativeCode :: Ptr NativeCell -> IO (Ptr ()) Source #
Reads the compiled code pointer of a cell. Null means "interpret".
An atomic (acquire) load: the compile thread writes a module's pool
entries and exit and frame tables before it publishes the code pointer,
and an interpreter thread that sees the pointer must then see those too,
which on a weakly ordered machine (arm64) a plain load does not promise
(an ldar, a few cycles on an entry that costs tens of nanoseconds).
readNativeEntry :: Ptr NativeCell -> IO (Ptr ()) Source #
The compiled code the interpreter should enter, if any. Null means "interpret": there is no code, or the function is so small that getting into native code and back costs more than interpreting it (verdict 3; native callers still call it directly).
writeNativeCode :: Ptr NativeCell -> Ptr () -> IO () Source #
Installs compiled code. A single atomic (release) pointer write:
readers on other threads see either the old value or the new one, and a
reader that sees the new one sees everything the compile thread wrote
before it (see readNativeCode).
bumpNativeCount :: Ptr NativeCell -> IO Bool Source #
Counts a call made while the cell had no compiled code, and says whether that made it hot (the count reached zero). Not atomic; a lost count under contention does not matter.
readNativeCount :: Ptr NativeCell -> IO Int Source #
writeNativeCount :: Ptr NativeCell -> Int -> IO () Source #
Sets a cell's count: negative, to make it hot after that many more calls.
claimNativeCell :: Ptr NativeCell -> IO Bool Source #
Marks the cell as requested (state 0 to 1), atomically, and says whether this call was the one that did. Whoever does owns the request, and queues it.
nativeRegisterEntryOffset :: Int Source #
The offset of the register entry in a cell, for the generated code.
writeNativeRegisterEntry :: Ptr NativeCell -> Ptr () -> IO () Source #
Installs the register entry (null for none), the same way as the code pointer; written before the code pointer, so that a thread which sees the code sees the entry.
releaseNativeCell :: Ptr NativeCell -> IO () Source #
Puts the state back to 0: for a request that could not be queued.
takeNativeCell :: Ptr NativeCell -> IO Bool Source #
The compile thread takes the cell (state 2), whether it was requested or not, and says whether this call was the one that did. A combinator that is taken is being compiled, or has been, or can't be. A request found already taken when it comes off the queue is dropped: its combinator went into an earlier batch.
nativeCellRequested :: Ptr NativeCell -> IO Bool Source #
Whether a request for the cell is queued.
readNativeVerdict :: Ptr NativeCell -> IO Int Source #
What the JIT has decided about compiling the cell's combinator. Zero: nothing yet. Otherwise the low two bits say: 1 worth compiling, 2 better left to the interpreter, because native code for it would spend its time leaving native code, 3 worth compiling for native callers but too small to be worth entering from the interpreter. The bits above hold an estimate the JIT keeps for judging callers (see JIT.Estimate). Only the thread that compiles writes this; the interpreter reads it when it finds code in the cell.
writeNativeVerdict :: Ptr NativeCell -> Int -> IO () Source #
data NativeCellPool Source #
Cells are handed out from a pool, so that loading code (an STM
transaction) never has to allocate memory: a retried transaction
would leak it. The pool is a block of cells and a count of how many
are in use. When it runs out, a new block is allocated outside the
transaction with growNativeCellPool. Old blocks stay in use, and
are never freed.
Constructors
| NativeCellPool !(Ptr NativeCell) !Int !Int |
newNativeCells :: Int -> IO (Ptr NativeCell) Source #
Allocates zeroed cells for n combinators, as one block that is
never freed.
nativeCellAt :: Ptr NativeCell -> Int -> Ptr NativeCell Source #
The cell at index i of a block from newNativeCells.
newNativeCellPool :: Int -> Int -> IO NativeCellPool Source #
takeNativeCells :: Int -> NativeCellPool -> Maybe (Ptr NativeCell, NativeCellPool) Source #
Takes n cells from the pool, or fails if it has fewer left.
growNativeCellPool :: Int -> Int -> NativeCellPool -> IO NativeCellPool Source #
A fresh block with room for at least n cells, and at least twice
the old capacity so that growing stays rare.
noNativeCell :: Ptr NativeCell Source #
A shared cell for combinators that are never compiled: builtins, and combinators that were not loaded through the code cache.
attachNativeCells :: Ptr NativeCell -> EnumMap Word64 (GCombs val comb) -> (Int, EnumMap Word64 (GCombs val comb)) Source #
Gives every combinator in a group of freshly loaded code its own
cell from base, numbering them in order. Returns the count used.
The fixed point of a GComb where all references to a Comb are themselves Combs.
type GCombs val comb = EnumMap Word64 (GComb val comb) Source #
Map of combinators, parameterized by comb reference type
Instances
| Functor GRef Source # | |
| Foldable GRef Source # | |
Defined in Unison.Runtime.MCode Methods fold :: Monoid m => GRef m -> m # foldMap :: Monoid m => (a -> m) -> GRef a -> m # foldMap' :: Monoid m => (a -> m) -> GRef a -> m # foldr :: (a -> b -> b) -> b -> GRef a -> b # foldr' :: (a -> b -> b) -> b -> GRef a -> b # foldl :: (b -> a -> b) -> b -> GRef a -> b # foldl' :: (b -> a -> b) -> b -> GRef a -> b # foldr1 :: (a -> a -> a) -> GRef a -> a # foldl1 :: (a -> a -> a) -> GRef a -> a # elem :: Eq a => a -> GRef a -> Bool # maximum :: Ord a => GRef a -> a # | |
| Traversable GRef Source # | |
| Show comb => Show (GRef comb) Source # | |
| Eq (GRef comb) Source # | |
| Ord (GRef comb) Source # | |
Constructors
Constructors
Constructors
| Test1 !Word64 !(Arm comb) !(GSection comb) | |
| Test2 !Word64 !(Arm comb) !Word64 !(Arm comb) !(GSection comb) | |
| TestW !(GSection comb) !(EnumMap Word64 (Arm comb)) | |
| TestT !(GSection comb) !(Map Text (GSection comb)) | |
| TestY !(GSection comb) !(Map Bytes (GSection comb)) |
Instances
| Functor GBranch Source # | |
| Foldable GBranch Source # | |
Defined in Unison.Runtime.MCode Methods fold :: Monoid m => GBranch m -> m # foldMap :: Monoid m => (a -> m) -> GBranch a -> m # foldMap' :: Monoid m => (a -> m) -> GBranch a -> m # foldr :: (a -> b -> b) -> b -> GBranch a -> b # foldr' :: (a -> b -> b) -> b -> GBranch a -> b # foldl :: (b -> a -> b) -> b -> GBranch a -> b # foldl' :: (b -> a -> b) -> b -> GBranch a -> b # foldr1 :: (a -> a -> a) -> GBranch a -> a # foldl1 :: (a -> a -> a) -> GBranch a -> a # elem :: Eq a => a -> GBranch a -> Bool # maximum :: Ord a => GBranch a -> a # minimum :: Ord a => GBranch a -> a # | |
| Traversable GBranch Source # | |
| Show comb => Show (GBranch comb) Source # | |
| Eq comb => Eq (GBranch comb) Source # | |
| Ord comb => Ord (GBranch comb) Source # | |
Defined in Unison.Runtime.MCode | |
A case of a branch: the fields it binds and its code.
Constructors
| Arm !ConstructorArity !(GSection comb) |
Instances
| Functor Arm Source # | |
| Foldable Arm Source # | |
Defined in Unison.Runtime.MCode Methods fold :: Monoid m => Arm m -> m # foldMap :: Monoid m => (a -> m) -> Arm a -> m # foldMap' :: Monoid m => (a -> m) -> Arm a -> m # foldr :: (a -> b -> b) -> b -> Arm a -> b # foldr' :: (a -> b -> b) -> b -> Arm a -> b # foldl :: (b -> a -> b) -> b -> Arm a -> b # foldl' :: (b -> a -> b) -> b -> Arm a -> b # foldr1 :: (a -> a -> a) -> Arm a -> a # foldl1 :: (a -> a -> a) -> Arm a -> a # elem :: Eq a => a -> Arm a -> Bool # maximum :: Ord a => Arm a -> a # | |
| Traversable Arm Source # | |
| Show comb => Show (Arm comb) Source # | |
| Eq comb => Eq (Arm comb) Source # | |
| Ord comb => Ord (Arm comb) Source # | |
Defined in Unison.Runtime.MCode | |
type ConstructorArity = Int Source #
How many fields a match arm binds: the number of slots emitCase lays
the arm's context out with. A data or request match's arm carries it
(Arm), because it is the one thing about an arm that the object being
matched cannot say: the interpreter pushes the object's own fields and
runs the arm only when their count is the arm's (dataBranch), and
native code reads the object's count (its pointer tag, or the lengths
of a wide constructor's arrays) and takes the arm only when the two
agree. The arms of a match on an unboxed value bind no fields (0).
armSection :: Arm comb -> GSection comb Source #
data RecordFieldMappings Source #
Constructors
| RecordFieldMappings FieldRef (BiMap FieldName FieldRef) |
Instances
| Show RecordFieldMappings Source # | |
Defined in Unison.Runtime.MCode Methods showsPrec :: Int -> RecordFieldMappings -> ShowS # show :: RecordFieldMappings -> String # showList :: [RecordFieldMappings] -> ShowS # | |
| Eq RecordFieldMappings Source # | |
Defined in Unison.Runtime.MCode Methods (==) :: RecordFieldMappings -> RecordFieldMappings -> Bool # (/=) :: RecordFieldMappings -> RecordFieldMappings -> Bool # | |
| Ord RecordFieldMappings Source # | |
Defined in Unison.Runtime.MCode Methods compare :: RecordFieldMappings -> RecordFieldMappings -> Ordering # (<) :: RecordFieldMappings -> RecordFieldMappings -> Bool # (<=) :: RecordFieldMappings -> RecordFieldMappings -> Bool # (>) :: RecordFieldMappings -> RecordFieldMappings -> Bool # (>=) :: RecordFieldMappings -> RecordFieldMappings -> Bool # max :: RecordFieldMappings -> RecordFieldMappings -> RecordFieldMappings # min :: RecordFieldMappings -> RecordFieldMappings -> RecordFieldMappings # | |
convertFieldNamesToRefs :: (MonadState RecordFieldMappings m, Traversable f) => f FieldName -> m (f FieldRef) Source #
Note that the Ord instance for Field Refs is arbitrary and not tied to the field name Ord instance.
emitCombs :: Var v => RefNums -> Reference -> Word64 -> Word64 -> SuperGroup Reference v -> State RecordFieldMappings (EnumMap Word64 Comb, Maybe (EnumMap Word64 Comb)) Source #
The combinators of a group, under its number, and, when the explosion rewrote any of its lambdas so that a frame differs, the group as the unoptimized code has it, under the second number: what a continuation written out by this process resumes in another, and what one from another process resumes here (design.md, "Continuations across processes").
emitComb :: Var v => RefNums -> Reference -> Word64 -> RCtx v -> (Word64, SuperNormal Reference v) -> State RecordFieldMappings (EnumMap Word64 Comb, EnumMap Word64 (Chain v)) Source #
resolveCombs :: Maybe (EnumMap Word64 (RCombs val)) -> EnumMap Word64 (GCombs val CombIx) -> EnumMap Word64 (RCombs val) Source #
lazily replace all references to combinators with the combinators themselves, tying the knot recursively when necessary.
sanitizeCombsOfForeignFuncs :: Bool -> Set ForeignFunc -> EnumMap Word64 (EnumMap Word64 (GComb Void CombIx)) -> EnumMap Word64 (EnumMap Word64 (GComb Void CombIx)) Source #
If running in a sandboxed environment, replace all restricted foreign functions with an error.
absurdCombs :: EnumMap Word64 (EnumMap Word64 (GComb Void cix)) -> EnumMap Word64 (GCombs any cix) Source #
argsToLists :: Args -> [Int] Source #
argsToArgs' :: Args -> Args' Source #
pushCount :: GInstr comb -> Maybe Int Source #
How many slots an instruction pushes onto the frame, or Nothing where
the interpreter takes over from here (a capture, a sandboxing failure).
The one account of an instruction's effect on the frame: the JIT's code
generator lays frames out by it and resultCount counts a primitive's
results by it, so the two cannot disagree.