A closer look at the V8 JavaScript engine
What is a JavaScript engine?
A JavaScript engine is the software component responsible for parsing, compiling, and executing JavaScript code. This can be client-side code that’s executed inside a web browser (e.g., Chrome or Firefox) or server-side code executed in a runtime like Node.js or Deno.
Here are some popular JavaScript engines:
Name | Used in |
---|---|
V8 | Chromium based browsers (Chrome, Edge, Brave, Electron), Node.js, Deno |
SpiderMonkey | Firefox |
JavaScriptCore | Safari |
Chakra | Internet Explorer |
A closer look at V8
Let’s take a closer look at what the V8 engine does when you execute a Node.js program like this:
function printMessage() {
const message = 'Hello world'
console.log(message)
}
printMessage()
Here’s an approximate overview of what V8 does. We’ll take a closer look at each step.
1. Scanner converts source code into known tokens
Your source code is usually encoded (UTF-8 by default in Chrome and Node) as a stream of bytes. A program called the scanner parses this stream and converts it into a list of known tokens .
For example, our sample program would be encoded in UTF-8 as follows:
\x66\x75\x6E\x63\x74\x69\x6F\x6E\x20\x70\x72\x69\x6E\x74\x4D\x65\x73\x73\x61\x67\x65\x28\x29\x20\x7B\x0A\x20\x20\x63\x6F\x6E\x73\x74\x20\x6D\x65\x73\x73\x61\x67\x65\x20\x3D\x20\x27\x48\x65\x6C\x6C\x6F\x20\x77\x6F\x72\x6C\x64\x27\x3B\x0A\x20\x20\x63\x6F\x6E\x73\x6F\x6C\x65\x2E\x6C\x6F\x67\x28\x6D\x65\x73\x73\x61\x67\x65\x29\x3B\x0A\x7D\x0A\x0A\x70\x72\x69\x6E\x74\x4D\x65\x73\x73\x61\x67\x65\x28\x29\x3B\x0A
Check out this link to see how source code translates to UTF-8.
Every time the scanner comes across a known construct like function
, const
, or var
, it will convert it into its corresponding token. Refer to keywords.txt for the full list of mappings between source code constructs and tokens.
2. Parser converts tokens into AST
A parser parses the list of tokens to generate an Abstract Syntax Tree (AST). An AST is a tree representation of source code in which each node represents a code construct (e.g., function literal, block, variable declaration, assignment) .
Here’s an example AST:
Check out this link to get an idea of what an AST looks like for the sample Node.js program shown earlier.
3. Ignition interpreter compiles AST into bytecode
V8’s Ignition interpreter compiles the generated AST into bytecode that’s not tied to any processor or machine implementation.
You can see bytecode output for a Node program by running something like:
node --print-bytecode --print-bytecode-filter=<func-name> <file>
Assuming you print the bytecode for the printMessage
function from above:
node --print-bytecode --print-bytecode-filter=printMessage program.js
You’ll get something like this:
[generated bytecode for function: printMessage (0x1c616aa37f89 <SharedFunctionInfo printMessage>)]
Bytecode length: 19
Parameter count 1
Register count 3
Frame size 24
OSR nesting level: 0
Bytecode Age: 0
44 S> 0x1c616aa38cee @ 0 : 13 00 LdaConstant [0]
0x1c616aa38cf0 @ 2 : c3 Star0
61 S> 0x1c616aa38cf1 @ 3 : 21 01 00 LdaGlobal [1], [0]
0x1c616aa38cf4 @ 6 : c1 Star2
69 E> 0x1c616aa38cf5 @ 7 : 2d f8 02 02 LdaNamedProperty r2, [2], [2]
0x1c616aa38cf9 @ 11 : c2 Star1
69 E> 0x1c616aa38cfa @ 12 : 5d f9 f8 fa 04 CallProperty1 r1, r2, r0, [4]
0x1c616aa38cff @ 17 : 0e LdaUndefined
83 S> 0x1c616aa38d00 @ 18 : a8 Return
Constant pool (size = 3)
0x1c616aa38c91: [FixedArray] in OldSpace
- map: 0x2834596412c1 <Map>
- length: 3
0: 0x1c616aa38c29 <String[11]: #Hello world>
1: 0x28c6e5db90e9 <String[7]: #console>
2: 0x28c6e5d8c0e1 <String[3]: #log>
Handler Table (size = 0)
Source Position Table (size = 12)
0x1c616aa38d09 <ByteArray[12]>
Hello world
4. Turbofan compiler compiles bytecode into machine code
V8’s Turbofan compiler compiles the bytecode into optimized machine code (binary) for the current processor (Intel, ARM, Apple Silicon, etc). Turbofan will analyze the bytecode and do a bunch of clever optimizations (maybe need to learn more about this).
5. Machine code is executed
The machine code is executed by the CPU.
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment