The Dart VM compiler uses an Intermediate Language (IL) to represent programs during compilation. IL instructions are defined in runtime/vm/compiler/backend/il.h and form the core of the compiler’s optimization pipeline.
IL Instruction Hierarchy
Instructions are organized into concrete and abstract classes:
Concrete Instructions : Directly instantiable instruction types
Abstract Instructions : Base classes providing common functionality
Instruction Attributes
Each instruction can have the following attributes:
kNoGC: Guaranteed not to trigger garbage collection on non-exceptional paths
Default (_): May trigger GC depending on runtime conditions
Block Entry Instructions
Block entry instructions define the entry points for basic blocks in the control flow graph.
Attributes : kNoGCThe root entry point of a flow graph. Every flow graph has exactly one GraphEntry that serves as the starting point for execution. class GraphEntryInstr : public BlockEntry {
// Entry point for the entire function
};
Attributes : kNoGCEntry point for normal function calls. Handles function prologue and parameter setup.
Attributes : kNoGCEntry point for a basic block that has a single predecessor. Used for simple control flow paths.
Attributes : kNoGCEntry point for a basic block with multiple predecessors. Contains Phi instructions to merge values from different control flow paths.
Attributes : kNoGCEntry point for a try block in exception handling.
Attributes : kNoGCEntry point for a catch block that handles exceptions.
Attributes : kNoGCEntry point for On-Stack Replacement (OSR), allowing optimized code to replace unoptimized code during execution.
NativeEntry & IndirectEntry
Attributes : kNoGCSpecial entry points for native calls and indirect control flow.
Control Flow Instructions
Instructions that affect program control flow.
Attributes : kNoGCUnconditional jump to a target block. // Example flow:
// Block A
// Goto Block B
Attributes : kNoGCConditional branch based on a comparison instruction. Has two successors: true and false targets. // if (x < 10) { ... } else { ... }
// Compiles to:
// Branch(x < 10) -> true_block, false_block
Attributes : kNoGCJump to a dynamically computed target. Used for switch statements and other computed control flow.
Value and Data Instructions
Attributes : kNoGCSSA phi instruction that merges values from different control flow paths at join points. // At a join point:
// v3 = Phi(v1 from predecessor1, v2 from predecessor2)
Parameter & NativeParameter
Attributes : kNoGCRepresents function parameters. NativeParameter is used for FFI native function calls.
Attributes : kNoGCRepresents a compile-time constant value.
Attributes : kNoGCRepresents an unboxed constant value (integer, double, etc.) for better performance.
Attributes : kNoGCLoad from and store to local variables. var x = 10 ; // StoreLocal
print (x); // LoadLocal
Arithmetic Instructions
Attributes : kNoGCBinary operations on Small Integers (Smi): addition, subtraction, multiplication, etc. Supported operations:
+, -, *, ~/, %
&, |, ^
<<, >>
BinaryInt32Op & BinaryInt64Op
Attributes : kNoGCBinary operations on 32-bit and 64-bit integers.
Attributes : kNoGCBinary operations on double-precision floating point values. double result = a + b; // BinaryDoubleOp(+)
UnaryInt64Op & UnarySmiOp
Attributes : kNoGCUnary operations like negation and bitwise NOT.
Type Conversion Instructions
Box Attributes : May trigger GC (allocation)
Unbox Attributes : kNoGCConvert between boxed (heap-allocated) and unboxed (register/stack) representations.
BoxInt64: Box a 64-bit integer
UnboxInt64: Unbox to 64-bit integer
BoxInt32: Box a 32-bit integer
UnboxInt32: Unbox to 32-bit integer
BoxUint32: Box an unsigned 32-bit integer
UnboxUint32: Unbox to unsigned 32-bit integer
Attributes : kNoGCConvert Smi to double-precision floating point.
DoubleToInteger & DoubleToSmi
DoubleToInteger Attributes : May trigger GC
DoubleToSmi Attributes : kNoGCConvert double to integer types.
Int32ToDouble & Int64ToDouble
Attributes : kNoGCConvert integer types to double.
Attributes : kNoGCConvert between different integer representations (sign extension, truncation, etc.).
Memory Access Instructions
Attributes : May trigger GC (lazy initialization)Load a field from an object. var value = obj.field; // LoadField
Attributes : May trigger GC (write barrier)Store a value to an object field. May trigger write barriers for garbage collection.
LoadStaticField & StoreStaticField
Load/store static (class-level) fields.
LoadIndexed & StoreIndexed
Attributes : kNoGCArray element access with bounds checking. var elem = array[i]; // LoadIndexed
array[i] = value; // StoreIndexed
Attributes : kNoGCLoad an untagged (raw pointer) value from memory. Used for low-level operations.
Call Instructions
Attributes : May trigger GCDirect call to a statically-known function. staticFunction (arg1, arg2); // StaticCall
Attributes : May trigger GCDynamic method call on an instance. Uses inline caches for optimization. obj. method (arg); // InstanceCall
Attributes : May trigger GCOptimized polymorphic call that handles multiple receiver types efficiently.
Attributes : May trigger GCCall through a closure (function object). var fn = () => print ( 'hello' );
fn (); // ClosureCall
Attributes : May trigger GCForeign Function Interface call to native code.
Allocation Instructions
Attributes : May trigger GCAllocate a new object instance. var obj = MyClass (); // AllocateObject
Attributes : May trigger GCCreate a new array with a specified length.
Attributes : May trigger GCAllocate a closure object.
AllocateRecord & AllocateSmallRecord
Attributes : May trigger GCAllocate record instances (Dart 3.0+ feature).
Attributes : May trigger GCAllocate a context for closure variable capture.
Check and Guard Instructions
Attributes : kNoGCRuntime check that a value is a Smi. Deoptimizes if false.
CheckClass & CheckClassId
Attributes : kNoGCVerify object class. Used for type specialization.
Attributes : kNoGCVerify value is not null. Throws if null.
Attributes : kNoGCBounds check for array access. Throws on out-of-bounds. array[index]; // CheckArrayBound(index, array.length)
Attributes : May trigger GCCheck for stack overflow. Allows runtime to handle deep recursion.
GuardFieldClass & GuardFieldLength
Attributes : May trigger GCGuard instructions for field type and length tracking.
Comparison Instructions
Attributes : kNoGCStrict equality comparison (identical). if (a === b) { } // StrictCompare
Attributes : kNoGCEquality comparison using == operator.
Attributes : kNoGCRelational comparisons: <, <=, >, >=
Attributes : kNoGCTest if object’s class ID is in a specified set.
Return Instructions
Attributes : kNoGCReturn from a Dart function.
Attributes : kNoGCReturn from a native function.
Exception Handling
Attributes : kNoGCThrow an exception. throw Exception ( 'error' ); // Throw
Attributes : kNoGCRe-throw a caught exception.
Special Instructions
Attributes : kNoGCTrigger deoptimization, returning to unoptimized code.
Attributes : kNoGCSSA instruction to refine type information without changing the value.
Attributes : May trigger GCMaterialize an object that was allocation-sunk during optimization.
Attributes : kNoGCSIMD (Single Instruction Multiple Data) operations for vectorized computation.
Instruction Source Location
All instructions can be associated with source code positions via runtime/vm/compiler/backend/il.h:1002:
virtual TokenPosition token_pos () const ;
InstructionSource source () const ;
This enables:
Precise error reporting
Debugging information
Profiling data correlation