# Static Roots: Objects with Compile-Time Constant Addresses

DevFeed: [Static Roots: Objects with Compile-Time Constant Addresses](<https://devfeed.tech/articles/static-roots-objects-with-compile-time-constant-addresses-3532.md>)

Original publisher: [Read original article](<https://v8.dev/blog/static-roots>)

Author: Olivier Flückiger

Published: 2024-02-05T00:00:00Z

Content type: article

Language: en

Sources: [V8](<https://devfeed.tech/sources/v8.md>)

Topics: [V8](<https://devfeed.tech/topics/v8.md>), [JavaScript](<https://devfeed.tech/topics/javascript.md>), [Chrome](<https://devfeed.tech/topics/chrome.md>), [JIT](<https://devfeed.tech/topics/jit.md>), [C++](<https://devfeed.tech/topics/c-plus-plus.md>)

Tags: [bootstrapping](<https://devfeed.tech/tags/bootstrapping.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [chrome](<https://devfeed.tech/tags/chrome.md>), [javascript](<https://devfeed.tech/tags/javascript.md>), [jit](<https://devfeed.tech/tags/jit.md>), [performance](<https://devfeed.tech/tags/performance.md>)

## AI overview

This article explains V8 static roots, which give frequently used immutable objects compile-time constant addresses in the read-only heap. It describes how V8 bootstraps that heap into a snapshot, uses pointer compression to place it predictably, and improves performance across the VM, especially for C++ code and built-in functions.

## Source excerpt

Did you ever wonder where undefined, true, and other core JavaScript objects come from? These objects are the atoms of any user defined object and need to be there first. V8 calls them immovable immutable roots and they live in their own heap - the read-only heap. Since they are used constantly, quick access is crucial. And what could be quicker than correctly guessing their memory address at compile time? As an example, consider the extremely common IsUndefined API function. Instead of having to look up the address of the undefined object for reference, what if we could simply check if an object's pointer ends in, say, 0x61 to know if it is undefined. This is exactly what the V8's static roots feature achieves. This post explores the hurdles we had to take to get there. The feature landed in Chrome 111 and brought performance benefits across the whole VM, particularly speeding up C++ code and builtin functions. Bootstrapping the Read-Only Heap # Creating the read-only objects takes some time, so V8 creates them at compile time. To compile V8, first a minimal proto-V8 binary called mksnapshot is compiled. This one creates all the shared read-only objects as well as the native code of builtin functions and writes them into a snapshot. Then, the actual V8 binary is compiled and bundled with the snapshot. To start V8 the snapshot is loaded into memory and we can immediately start using its content. The following diagram shows the simplified build process for the standalone d8 binary. Once d8 is up and running all the read-only objects have their fixed place in memory and never move. When we JIT code, we can e.g., directly refer to undefined by its address. However, when building the snapshot and when compiling the C++ for libv8 the address is not known yet. It depends on two things unknown at build time. First, the binary layout of the read-only heap and second, where in the memory space that read-only heap is located. How to Predict Addresses? # V8 uses pointer compre