unison-runtime-0.0.0
Safe HaskellNone
LanguageHaskell2010

Unison.Runtime.JIT

Description

The JIT's entry points for the rest of the runtime, and the handle that holds its state. See unison-runtimesrcUnisonRuntimeJIT/design.md.

Synopsis

Documentation

data JIT Source #

The JIT: its settings and everything it keeps while the process runs. There is one per process, made by ucm at startup (newJIT) and given to every runtime it starts, since what the JIT compiles is shared: generated code refers to the exits and frames tables and the constant pool by index, and native code in one module calls into another directly. Each code cache carries the handle (CCache's jit), which is how the interpreter reaches it.

newJIT :: Config -> IO JIT Source #

A JIT with these settings, not started: nothing is loaded or compiled until loadJIT or startJIT. In the off mode it is inert, and the runtime's calls into it return at once.

typeNumbers :: JIT -> IO (EnumMap Word64 Reference) Source #

The type reference each type number stands for, as the cache numbers them.

readConfig :: IO Config Source #

Reads the settings from the environment. Called once, by ucm at startup, after the --jit options have been put in the environment.

jitTracing :: JIT -> Bool Source #

Whether every transition between native code and the interpreter is logged (UNISON_JIT_TRACE).

jitStats :: JIT -> Bool Source #

Whether entries and exits are counted (UNISON_JIT_STATS).

initialNativeCount :: JIT -> Int Source #

The count a combinator's cell starts with: minus the threshold in the on mode, zero (never hot) otherwise.

stackSlots :: JIT -> Int Source #

The slots a fresh Unison stack has: the stress mode ustack=N makes it tiny, so that growing the stack is exercised constantly.

loadJIT :: JIT -> IO (Maybe (Either [String] String)) Source #

Loads LLVM at startup, when the JIT is turned on, and says how it went: Nothing when the JIT is off, otherwise whether it is activated, and if not, lines explaining why. Whatever the answer, the program runs: without the JIT everything is interpreted.

startJIT :: JIT -> IO () Source #

Gets the JIT going if it is enabled. Called by each runtime as it starts. LLVM is normally loaded already, by loadJIT at ucm's startup; if not (another host of the runtime), eager mode loads it here and on mode on the compile thread, when the first request arrives.

jitCompileGroup :: JIT -> Bool -> Reference -> Word64 -> MCombs -> IO () Source #

Compiles a freshly loaded top-level definition, in eager mode.

jitRequestGroup :: JIT -> Bool -> TVar (EnumMap Word64 MCombs) -> TVar (EnumMap Word64 Reference) -> CombIx -> Ptr NativeCell -> IO () Source #

Asks for the definition this combinator belongs to to be compiled. Called by the interpreter when the combinator's call count says it is hot (see bumpNativeCount). If the queue is full the flag is cleared again and the count set to ask again after another 1024 calls. The cache's combinators and their references are given as the TVars, read again on the compile thread when the request is served.

jitRequestCell :: JIT -> Ptr NativeCell -> IO () Source #

Asks for the re-entry function that belongs in this cell to be generated, if there is one waiting (see pending). Called by the interpreter when it has found the cell empty often enough. The cell's request state keeps it from being queued twice.

noteAdHocExit :: JIT -> Word64 -> Ptr NativeCell -> IO () Source #

The trampoline's report of an ad hoc exit (the poll, the allocation budget, stack growth: isAdHoc) that unwound through a Let whose body has no code yet. The exits the code itself causes count toward the body's re-entry function when its frame is popped (Machine.countReentry) and are bounded by the code; these land wherever the program is, so a long-running function would in time be interrupted at every Let it has and get a copy of its suffix after each. So they count here, and only while the group's budget lasts (reentryAdHoc, 3): the Lets most often on the stack at a tick, where the time goes, are the ones that get in. The frame the trampoline builds for such an exit carries no cell, so the pop interprets the body without counting it again.

registerTypeNumbers :: JIT -> EnumMap Word64 Reference -> IO () Source #

Records the type numbering of the code cache. Called when types are numbered: for the builtins at startup, and whenever code is loaded.

printJITStats :: JIT -> IO () Source #

Prints how often each exit was taken, when UNISON_JIT_STATS is set. Called after each evaluation.

noteOutput :: JIT -> ForeignFunc -> IO () Source #

Called by the interpreter after each foreign call. With UNISON_JIT_STATS=each, a call that wrote output is followed by the exits taken since the program last wrote (the busiest sites only), after which counting starts again; so a program that prints a line per phase gets its exits listed per phase.