This is the 12th day of my participation in the August Text Challenge.More challenges in August

Compiler and interpreter

The concepts covered in this article are Compiler, Interpreter, Abstract syntax tree (AST), Bytecode, just-in-time Compiler (JIT)

JavaScript is a language with both compilation and interpretation.

How does V8 execute a piece of JavaScript code

V8 is implemented with both Ignition, the interpreter, and TurboFan, the compiler. Analyze the process above:

  1. Generate the abstract syntax tree AST and the execution context

    How an AST is generated is divided into two phases.

    1. The first stage is tokenize ::, also known as lexical analysis, which essentially breaks down the source code into tokens.

The abovevarmyName="Geek Time"

  1. The second stage is :: Parse ::, also known as syntax analysis. The function is to convert the token data generated in the previous step into an AST according to the syntax rules. If the source code is syntactically correct, the conversion succeeds. If the source code has a syntactic crop, it terminates and throws a syntax error.

:: Converts the source code into an abstract syntax tree and generates the corresponding execution context for this code ::. Abstract syntax tree AST is similar to the DOM tree that the rendering engine generates after processing HTML

Combining with the code

Var myName = "geektime" function foo(){return 23; } myName = "geektime" foo()Copy the code

The above code generates the AST as follows

The structure of the AST is very similar to the structure of the code, and you can also think of the AST as a structured representation of the code. The compiler or interpreter relies on the AST for subsequent work, not the source code

AST is a very important data structure, which is used in many projects. For example, Babel is a code converter for converting ES6 source code into AST, and then converting THE AST into ES5 syntax. Finally, bytecode is generated based on the ES5 AST, or ESLint, a plugin for checking JavaScript code specifications. The process of checking is to convert the source code into an AST and then use the AST to check code normalization. : :

  1. Generate bytecode

    Now that you have the AST and the execution context, there’s the :: interpreter Ignition, which converts the AST to generate bytecode and interprets the execution of bytecode ::.

    Why bytecode?

    V8 initially had no bytecode and converted it all to machine code, which was efficient, but because it took up too much memory, bytecode was introduced.

You can see that the same code bytecode is more space-efficient than machine code, but bytecode can reduce the memory usage of the system.

  1. Execute the code

    Once the bytecode is generated, it is time to execute.

    For the first execution of the bytecode, the interpreter Ignition interprets the execution line by line, and the: interpreter Ignition interprets the execution of the bytecode in addition to generating it. TurboFan converts the bytecode to machine code and saves it :: when the interpreter executes hot code, the compiler TurboFan converts the bytecode to machine code and saves it ::. This will greatly improve the efficiency of code execution.

Bytecode combined with an interpreter and compiler is a technique called just-in-time compilation (JIT), and virtual machines in Java and Python are implemented based on this technique. In V8, the interpreter detects the condition of the code while executing the bytecode, and when some of the code becomes hot, the compiler converts the bytecode corresponding to the hot code into machine code, which is then executed the next time.

JIT working mechanism