preface

This article is the fourth article of the V8 engine, a series of key content is about the V8 is how to explain the implementation of the bytecode, about the execution of the bytecode in V8’s link to see the author before the V8 engine, (3) – the evolution of the look from the bytecode V8, this paper will by describing an official of examples to help you to understand, There will be links to the finished series at the end of this article, which is still being updated.

Execution of bytecode

In a nutshell, V8 engines usually go through the following process: Source code — AST — bytecode — binary code. The process of converting the source code to AST through Parse has been described in the series OF V8 engine details (ii) — AST. Next, the V8 BytecodeGenerator class converts the AST structure from the abstract syntax tree to the structure of bytecode, which is an abstraction of machine code. See v8’s evolution from bytecode, and the Ignition engine interprets and executes the resulting bytecode.

One, register-based

The Ignition engine interprets and executes bytecode, which means it functions like a Java JVM, essentially a virtual machine. There are usually two types of virtual machines: Stack and Register. For example, Stack virtual machines with JVMS are a more general implementation method, whereas Ignition in the V8 engine is Register, or register-based virtual machine. Register-based VMS typically execute faster than stack-based VMS, but the instructions are relatively long.

Ignition is an accumulator, and I’ll give you a little example. Let’s get rid of the bytecode and see how this simple piece of code calculates the result.

var x = 100;
var y = x +10;
x = x * y;
Copy the code

The general operation process of using accumulative registers is as follows:

This is the general process of our registrie-based virtual machine. In short, it is to create a virtual space to store parameters and intermediate calculation results.

Interpreting bytecode through official cases

The following is an example of the implementation of bytecode on V8 from Google’s official POWERPOINT presentation. I’ll add a few text annotations to help you read them.

  • Start by converting the source code to bytecode

  • Initialize f

  • Storing the small integer -100 in the accumulator, LdaSmi can be interpreted as a defined handle function whose argument is followed by #100

  • Sum the 150 stored in A2 with the values in the accumulator and store the result in the accumulator.

  • Save the 50 stored in the accumulator into register R0, which has a value of 50.

  • The value of register A1, parameter B, is stored in the accumulator with a value of 2. (A0, A1, a2 are also registers)

  • Multiply the value in register R0 and the value in the accumulator and store the result in the accumulator.

  • Sum the value in register A0 with the value in the accumulator and store the result in the accumulator.

  • Return (including the above statement) is itself a defined handle function. Return stands for returning the value of the accumulator.

(With newer versions of V8, the resulting bytecode structure may differ slightly from version to version, but these defined functions generally do not change much.)

Through the example that you can probably understand byte code execution, but the v8 define key case that not only in the appendix (complete), began to a lot of key words in the learning process does not understand, but we can write some simple javascript code and then generate bytecode, because we know js execution results, Bytecode can be understood by working backwards.

conclusion

This article gives you a brief overview of how V8 explains bytecode execution.

People ask me, what’s the use of learning all this stuff as a front-end? These things are not that easy to understand, so if you have time to do two more tests, look at the interview questions, look at the framework. In the short term, learning V8 engine will not improve your interview ability, but every little acreage starts with a little acreage. Learning V8 engine will help you to have a deeper understanding of SOME things in JS. For example, learning AST will help you understand the working principle of Babel better. Why a page loads faster the second time than the first time (not just for caching static resources), and why Node uses V8 as its JS engine, is just a recap of other people’s conclusions.

When I was writing this chapter, I was asked why switch is faster than if else when I was interviewed. When I went home and looked up the relevant articles, I found that switch is faster than if else when I looked at the bytecode and realized that at least in normal V8 environment, switch is faster than if else. Bytecodes show that both are almost equally fast in most conditions, so you can play with them yourself if you’re interested.

V8 byte code table

Refer to the article

Docs.google.com/presentatio… Time.geekbang.org/column/arti…

series

V8 Engine Details (1) — Overview V8 engine details (2) — AST V8 engine details (3) — Bytecode evolution V8 engine details (4) — Bytecode execution V8 engine details (5) — Inline caching V8 engine details (6) — Memory structure V8 engine details (7) – Garbage collection mechanism V8 engine details (8) – message queue V8 engine details (9) – coroutines & generator functions