Snapshots and Code Caching
October 23, 2018 ยท View on GitHub
This document explains techniques used by V8 in order to avoid having to re-compile and optimized JavaScript whenever an application that embeds it (i.e. Chrome or Node.js) starts up fresh.
Table of Contents generated with DocToc
Code Caching
- lessens overhead of parsing + compiling script
- uses cached data to recreate previous compilation result
- exposed via V8's API to embedders
- pass
v8::ScriptCompiler::kProduceCodeCacheas an option when compiling script- Note: V8 is deprecating
v8::ScriptCompiler::kProduceCodeCachein favor ofv8::ScriptCompiler::GetCodeCache
- Note: V8 is deprecating
- cached data is attached to source object to be retrieved via
v8::ScriptCompiler::Source::GetCachedData - can be persisted for later
- later cache data can be attached to the source object and passed
v8::ScriptCompiler::kConsumeCodeCacheas an option to cause V8 to bypass compileing the code and deserialize the provided cache data instead
- pass
- V8 6.6 caches top level code as well as code generated after script's top-level execution, which means that lazily compiled functions are included in the cache
Chrome's Use of Code Caching
Since Chrome embeds V8 it can make use of Code Caching and does so as follows.
- cold load: page loaded for the first time and thus no cached data is available
- warm load: page loaded before and caches compiled code along with the script file in disk
cache
- to qualify, the last load needs to be within the last 72 hours and the script source be larger than 1KB
- hot load: page loaded twice before and thus can use the cached compiled code instead of parsing + compiling the script again
Resources
Startup Snapshots
Custom Startup Snapshots
- V8 uses snapshots and lazy deserialization to retrieve previously optimized code for builtin functions
- powerful snapshot API exposed to embedders via
v8::SnapshotCreator - among other things this API allows embedders to provide an additional script to customize a start-up snapshot
- new contexts created from the snapshot are initialized in a state obtained after the script executed
- native C++ functions are recognized and encoded by the serializer as long as they have been registered with V8
- serializer cannot directly capture state outside of V8, thus outside state needs to be attached to a JavaScript object via embedder fields
Lazy Deserialization
- only about 30% of builtin functions are used on average
- deserialize builtin function from the snapshot when it is called the first time
- functions have well-known positions within the snapshot's dedicated builtins area
- starting offset of each code object is kept in a dedicated section within builtins area
- additionally implemented lazy deserializations for bytecode handlers, which contain logic to execute each bytecode within Ignition interpreter
- enabled in V8 v6.4 resulting in average V8's heap size savings of 540 KB
Resources
- custom startup snapshots - 2015 somewhat out of date as embedder API changed and lazy deserialization was introduced
- Energizing Atom with V8's custom start-up snapshot - 2017
- Lazy deserialization - 2018
- Speeding up Node.js startup using V8 snapshot