The core process consists of two steps:

  1. Compilation: Converts JS code to low-level intermediate code or machine code that the machine can understand
  2. Execute: Execute the transformed code and print the results

What is V8?

V8 is a Google open source JS engine that can be viewed as a virtual machine that simulates various functions of a computer to implement code execution. For example: simulation of the actual computer CPU, stack, registers, etc., there is V8’s own set of instruction system.

Why is high-level code compiled before it is executed?

Because the CPU can only recognize binary instructions, but binary is difficult to read and remember, so there is the “assembly instruction set”, the assembly code written by the assembly instruction set can be converted into binary code by the assembly compiler, and then handed to the CPU to execute.

Mov AX,bx // assembler instruction 1000100111011000 // machine instructionCopy the code

Disadvantages of assembly language (why high-level languages?)

  1. Different cpus have different instruction sets. If assembly language is used to realize a function, specific assembly code needs to be written for each architecture CPU. Each new CPU has to be written again, which has high cost and small benefit.

  2. To write assembly code, we also need to understand the hardware knowledge related to the processor architecture, such as: using registers, memory, operating CPU, etc. In order for engineers to concentrate on business logic, they needed a language that could mask the details of a computer’s architecture while accommodating many different CPU architectures. So there are high-level languages, C, C++, Java, JavaScript, etc.

How should a high-level language be implemented?

The CPU does not recognize assembly language directly, nor does it recognize high-level languages, which need to be converted to binary for execution. There are two ways to do this:

  1. Interpreted execution compiles the input source code through the parser into intermediate code, which is then interpreted and executed directly using the interpreter, and then outputs the result. (Interpreters are usually software and cannot be used directly with hardware, resulting in less efficient execution.)

  1. Compilation execution compiles the input source code through the parser into intermediate code, which is then converted into machine code by the compiler. Machine code is usually stored directly as a binary file and can be executed directly.

How does V8 execute JS code?

V8 mixes compile execution and explain execution strategies. Description The execution speed is fast but slow. Compilation execution is slow to start, but fast to execute.

The following is a flow chart of V8 executing JS code:

Steps to execute JS code:

  1. As you can see from the left part of the figure above, before V8 executes JS, the following basic environment needs to be prepared for use during execution.
  • Heap and stack space
  • Global execution context: contains global information during execution, such as built-in functions and global variables.
  • Global scope: Contains global variables that need to be stored in memory during execution.
  • Event loop system: contains message drivers and message queues that continuously receive messages and decide what to do with them.
  1. Once the source code is parsed to generate the AST and the scope base environment is ready, you have to deal with the JS code, which to V8 is just a bunch of strings that cannot be understood directly and needs to be structured as abstract syntax numbers (AST). Structuration: After analysis, information can be decomposed into multiple interrelated components. Each component has a clear hierarchical structure for easy maintenance and use.

  2. Once you have the AST and scope, you can generate bytecode, which is the middle code shown in the figure above. The interpreter executes the bytecode sequentially and outputs the result.

  3. The monitoring robot next to listening for hot code and optimized for binary machine code is a module that monitors the state of the interpreter’s execution, and flags a piece of code as hot code if it is found to be repeatedly executed during the interpretation of bytecode execution. V8 will throw this hot code to the compiler to compile into binary code. The next time it executes, the binary code will be directly executed to speed up execution.

  4. In JS, the structure and properties of the object can be arbitrarily modified at runtime, and the optimized code is only for a fixed structure, once the structure is modified, it will become invalid code. This is when you need to de-optimize and fall back to the interpreter to explain the execution the next time.

The resources

How does V8 execute a piece of JavaScript code?