The Dart VM runtime system provides the execution environment for Dart code natively. It includes object management, garbage collection, isolate management, and multiple execution modes.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/dart-lang/sdk/llms.txt
Use this file to discover all available pages before exploring further.
Runtime Components
The Dart VM runtime consists of several key components:- Object Model - Heap object representation and memory layout
- Garbage Collection - Generational GC with parallel scavenge and concurrent mark-sweep
- Snapshots - Serialization of heap state for fast startup
- Core libraries native methods - Native implementations of dart:core APIs
- Development Experience - Debugging, profiling, hot-reload via service protocol
- Compilation Pipelines - JIT and AOT compilation
- Interpreter - Bytecode execution (optional)
- ARM Simulators - Cross-architecture testing
Execution Modes
The Dart VM supports multiple ways to execute code:JIT Mode (Just-in-Time)
Code is compiled from source or Kernel binary at runtime:- From Source via JIT - Dart source → CFE → Kernel binary → VM execution
- AppJIT Snapshots - Pre-warmed snapshots with JIT-compiled code and type feedback
- Fast development iteration
- Peak performance after warmup
- Speculative optimizations based on runtime profile
- Ability to deoptimize when assumptions are violated
AOT Mode (Ahead-of-Time)
Code is compiled to native machine code before execution:- From AppAOT Snapshots - Fully compiled snapshots with native code
- Precompiled Runtime - Stripped VM without JIT compiler
- Fast startup with no warmup
- Consistent performance
- Smaller runtime footprint
- Required for platforms that prohibit JIT compilation
Isolates and Isolate Groups
All Dart code runs within an isolate - an isolated execution environment with its own:- Global state and memory
- Mutator thread (usually)
- Message queue for communication
- The same GC-managed heap
- The same Dart program code
- Compiled code and internal VM structures
Thread Management
The relationship between OS threads and isolates:- An OS thread can enter only one isolate at a time
- Only one mutator thread can be associated with an isolate at a time
- Multiple helper threads may assist (GC threads, background compiler)
- Background JIT compiler thread
- GC sweeper threads
- Concurrent GC marker threads
dart::ThreadPool) to manage OS threads efficiently.
Compilation Pipeline
Unoptimizing Compiler
When a function is first called:- Kernel AST → Unoptimized IL (Intermediate Language)
- IL → Machine code (direct one-to-many lowering)
- Compile quickly
- Collect type feedback via inline caches
- No optimizations applied
Optimizing Compiler
When a function becomes hot (execution counter threshold reached):- Kernel AST → Unoptimized IL
- Unoptimized IL → SSA-based Optimized IL
- Apply optimizations (inlining, type propagation, etc.)
- Optimized IL → Machine code
- Inlining - Reduce call overhead
- Range analysis - Eliminate bounds checks
- Type propagation - Use type feedback
- Representation selection - Unbox values
- Load forwarding - Eliminate redundant loads
- Global value numbering - Eliminate redundant computations
- Allocation sinking - Eliminate temporary allocations
On-Stack Replacement (OSR)
For long-running loops, execution can switch from unoptimized to optimized code while the function is running. The stack frame is transparently replaced.Deoptimization
Optimized code makes speculative assumptions based on type feedback. When assumptions are violated:- Eager deoptimization - Inline checks fail (e.g.,
CheckSmi,CheckClass) - Lazy deoptimization - Global guards trigger (e.g., class hierarchy changes)
Inline Caching
Dynamic calls use inline caching to speed up method resolution:- Each call site has a cache mapping receiver class → target method
- Cache includes frequency counters for optimization decisions
- Shared lookup stub searches cache and calls method if found
- Cache misses invoke runtime method resolution
- Monomorphic - One observed type (fastest)
- Polymorphic - Few observed types (fast)
- Megamorphic - Many observed types (slower)
Snapshots
Snapshots serialize the heap object graph to binary format for fast startup:- Kernel snapshots - Serialized Kernel AST only
- AppJIT snapshots - Heap + JIT-compiled code + type feedback
- AppAOT snapshots - Heap + AOT-compiled native code
Performance Characteristics
| Mode | Startup | Peak Performance | Code Size | Use Case |
|---|---|---|---|---|
| JIT | Medium | Highest | Medium | Development |
| AppJIT | Fast | High | Medium | CLI tools |
| AOT | Fastest | High | Smallest | Production mobile |
Key Source Files
runtime/vm/object.h- Object definitions (C++ methods)runtime/vm/raw_object.h- Object memory layout (UntaggedXyzclasses)runtime/vm/isolate.h- Isolate implementationruntime/vm/heap/heap.h- Heap managementruntime/vm/compiler/- Compilation pipelineruntime/vm/runtime_entry.cc- Runtime system entry points