Master the fundamental concepts of jit compilation through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksJIT optimizers run under millisecond budgets. JavaScriptCore's DFG folds constants and eliminates type checks on known shapes. LuaJIT traces specialize on observed types. Inline caching replaces polymorphic dispatch. HotSpot's C2 only runs after C1 has gathered enough profile data to justify the compile cost.
Specialize on runtime types seen at compile time. Guard instructions verify assumptions; failure triggers deopt. Strength-reduce within trace bounds. Keep the fast path branch-free where possible so the CPU predictor stays hot.
cLoading…
Production compilers embed this step inside a longer pipeline. GCC flows through cpp, cc1, assembly, and ld; Clang uses the driver, Sema, LLVM IR passes, and a target backend. LLVM bitcode, JVM bytecode, and WASM are other familiar IRs at the same layer. The exercise isolates one pass so you can test it alone before chaining it to the next stage.
You will implement JIT-specific optimizations guarded by runtime checks. This exercise requires specializing code on profiled types and inserting deoptimization points when assumptions fail.
Implement the decision logic of a profiling JIT for a dynamically typed language: collect type feedback at each operation site, and when a site gets hot, choose how to compile it: a guarded fast path for the dominant types, a small polymorphic chain, or a generic slow call.
cLoading…
Types are int, float and string.
For each site, collect counts per ordered type pair (left, right), keeping pairs in order of first appearance. Then:
threshold → cold (interpreted).count × 100 ≥ total × 90) → monomorphic.CALL generic_OP.| Operand types | + | * | < |
|---|---|---|---|
| int, int | ADD_INT | MUL_INT | LT_INT |
| float, float | ADD_FLOAT | MUL_FLOAT | LT_FLOAT |
| int, float | CVT_LEFT ADD_FLOAT | CVT_LEFT MUL_FLOAT | CVT_LEFT LT_FLOAT |
| float, int | CVT_RIGHT ADD_FLOAT | CVT_RIGHT MUL_FLOAT | CVT_RIGHT LT_FLOAT |
| string, string | CONCAT | - | STRCMP_LT |
A pair with no entry (—, or any pair involving a string and a number) cannot be specialised; if it is chosen by rule 2 or 3, fall back to megamorphic.
One line per site in site order:
cLoading…
where TYPES is left/right and DECISION is one of:
cLoading…
P is the percentage of this site's executions not covered by its guards, truncated to an integer. Finish with sites=N hot=H specialised=S.
Input:
cLoading…
Output:
cLoading…
exec lines.Hidden tests cover polymorphic sites, mixed int/float pairs, string concatenation, a string/number mix that forces megamorphic, and ties in counts.