In the last article, we explained how to compile V8 source code using GN, and the resulting executable is not V8, but D8. This article will show you how to debug javascript code using D8.

If d8 is not available, node can be used instead.

Create the add-of-ints.js file and enter the following:

function add(obj) {
    return obj.prop + obj.prop;
}

const length = 1000 * 1000;

const o = { prop: 1 };

for (let i = 0; i < length; i++) {
    add(o);

}Copy the code

Run:

d8 --trace-opt-verbose add-of-ints.js or node --trace-opt-verbose add-of-ints.jsCopy the code

The output is:

From the output, we can see that the add function is optimized by the compiler and explain why. ICs stands for inline caches, a common optimization technique, and this short code has been optimized twice by the V8 engine, but for different reasons.

  • The reason for the first optimization is small function. Add is a small function. In order to reduce the overhead of function calls, the V8 engine optimized Add.

  • The second reason is hot and stable. V8 has two compilers, a general-purpose compiler that compiles javascript code to machine code and an optimized compiler. You can see from the output above that the optimized compiler engine used by V8 is Crankshaft. Crankshafts were responsible for finding frequently called code and doing inline cache optimizations, further explained by the following information: ICs with TypeInfo: 7/7 (100%), Generic ICs: 0/7 (0%).

I’ll correct the previous two questions here.

One is that V8 has no interpreter, only a compiler, and the code is compiled directly into the machine. This is the old V8, and most of the articles on V8 on the web are old. In order to read the V8 source code these days, I have checked many articles and papers about V8 on the web and found that V8 has introduced the interpreter. Because V8 can not only optimize code, but also deopt, the introduction of the interpreter can save some code recompile time. Another reason is that the interpreter can interpret not only javascript code, but also ASM or other binary intermediate code.

Another error is about V8 optimization. Have you written JavaScript functional programming before? Tathagata:

The ones that can never be optimized are:

  • Functions that contain a debugger statement
  • Functions that call literally eval()
  • Functions that contain a with statement

This was also the result of the previous article based on the Crankshaft engine. V8 has developed a new optimization engine, TurboFan.

Let’s create another file, add-of-mixed-.js, and type:

// flag: --trace-opt-verbose

function add(obj) {
    return obj.prop + obj.prop;
}

var length = 1000 * 1000;

var objs = new Array(length);

var i = 0;

for (i = 0; i < length; i++) {
    objs[i] = Math.random();
}

var a = { prop: 'a' };
var b = { prop: 1 };

for (i = 0; i < length; i++) {
    add(objs[i] > 0.5 ? a : b);

}Copy the code

Run:

d8 --trace-opt-verbose add-of-mixed. Js or node --trace-opt-verbose add-of-mixed.jsCopy the code

The output is:

As you can see, it’s up to the RP to do inline cache optimization.

Let’s use the –trace-opt –trace-deopt parameter to see how the V8 engine is optimized.

Create a new add-of-mixed-dep.js file and type:

// flags: --trace-opt --trace-deopt

function add(obj) {
    return obj.prop + obj.prop;
}

var length = 10000;
var i = 0;
var a = { prop: 'a' };
var b = { prop: 1 };

for (i = 0; i < length; i++) { add(i ! = =8000 ? a : b);

}Copy the code

Run:

d8 --trace-opt --trace-deopt add-of-mixed-dep.js or node --trace-opt --trace-deopt add-of-mixed-dep.jsCopy the code

The result is:

The V8 engine uses Hidden Classes internally to represent objects, and there have been many articles about Hidden Classes that I won’t bother to cover.

Run d8 –help to view all d8 command-line arguments. If you are using node, run node –help to print the node command-line arguments. If you want to view V8, use node –v8-options.

The following sections cover THE V8 GC (command line parameter — trace-GC) and most interestingly –allow-natives-syntax.

We recommend reading the source code for V8 ubiquitum-reason. h, which is a C++ header file with almost no code logic, defining the reasons why all javascript code cannot be optimized by the V8 engine. For example:

"Array index constant value too big"
"eval"
"ForOfStatement"
"Too many parameters"
"WithStatement"...Copy the code

The –allow-natives-syntax C++ header described in the following sections is runtime.h, and the V8 runtime functions can be used in javascript with the –allow-natives-syntax parameter. We have already used this in previous articles, such as HasFastProperties.

Reference article:

  • V8 – A Tale of Two Compilers
  • Performance Tips for JavaScript in V8
  • Ignition: V8 Interpreter