如果某个函数没有优化,是否意味着声明它的所有函数都没有优化?

use*_*860 2 javascript optimization v8

最近我遇到了这篇关于V8引擎优化JavaScript程序的优化杀手.但这篇文章对我来说并不完全清楚,所以我想问一下这个问题.

文章指出:

优化编译器编译的代码可以很容易地比通用编译器生成的代码快100倍......重要的是要注意导致优化救助的模式会影响整个包含函数.

这是否意味着,例如,如果一些大块代码,假设一个JavaScript库,它以IIFE(立即调用函数表达式)的形式包含一个包含try {} catch(e) {}在另一个函数声明中的语句,那么整个库未优化?

看起来是这样,因为我试图运行这个命令$ node --trace_opt --trace_deopt --allow-natives-syntax try_catch.js,try_catch.js如下:

//Function that contains the pattern to be inspected (using with statement)
function optimizeWhack() {
    foo();
    function foo() {
        try {} catch(e) {}
    }
    return 12
}

function printStatus(fn) {
    switch(%GetOptimizationStatus(fn)) {
        case 1: console.log("Function is optimized"); break;
        case 2: console.log("Function is not optimized"); break;
        case 3: console.log("Function is always optimized"); break;
        case 4: console.log("Function is never optimized"); break;
        case 6: console.log("Function is maybe deoptimized"); break;
    }
}

//Fill type-info
optimizeWhack();

%OptimizeFunctionOnNextCall(optimizeWhack);
//The next call
optimizeWhack();

//Check
printStatus(optimizeWhack);
Run Code Online (Sandbox Code Playgroud)

我得到的回应是这个,有function is not optimized:

$ node --trace_opt --trace_deopt --allow-natives-syntax try_catch.js 
[deoptimize context: ea2f6f14679]
[optimizing: optimizeWhack / ea2f6fc9c29 - took 0.033, 0.064, 0.000 ms]
**** DEOPT: optimizeWhack at bailout #1, address 0x0, frame size 8
[deoptimizing: begin 0xea2f6fc9c29 optimizeWhack @1]
  translating optimizeWhack => node=3, height=8
    0x7fff113fa238: [top + 40] <- 0xd7de9006c91 ; [sp + 40] 0xd7de9006c91 <JS Global Object>
    0x7fff113fa230: [top + 32] <- 0x1bca01a663fc ; caller's pc
    0x7fff113fa228: [top + 24] <- 0x7fff113fa268 ; caller's fp
    0x7fff113fa220: [top + 16] <- 0xea2f6f14679; context
    0x7fff113fa218: [top + 8] <- 0xea2f6fc9c29; function
    0x7fff113fa210: [top + 0] <- 0xea2f6fca051 ; rbx 0xea2f6fca051 <JS Function foo>
[deoptimizing: end 0xea2f6fc9c29 optimizeWhack => node=3, pc=0x1bca01a665ff, state=NO_REGISTERS, alignment=no padding, took 0.074 ms]
[removing optimized code for: optimizeWhack]
Function is not optimized
Run Code Online (Sandbox Code Playgroud)

一个更普遍的问题是指向我关于所有这些优化的东西的一些文献,来源等,如果那些存在的话.

先感谢您.

Vya*_*rov 5

V8的优化编译器是基于函数的,因此如果它无法优化某些不影响任何其他函数的函数 - 包括那些包含此不可优化函数声明的函数.

几乎所有优化编译器都不支持的语句也只具有本地效果 - 它们禁用包含它们的特定函数的优化,但不影响包含该函数的函数.但有一个例外:直接eval影响所有封闭函数.

function foo() {
  function bar() {
    function baz() {
      eval(str);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在上面没有一个例子foo,bar,baz是通过V8的曲轴优化的.

现在举例来说:从日志中可以看出,optimizeWhack在您重新调整优化后,它确实已经过优化

[optimizing: optimizeWhack / ea2f6fc9c29 - took 0.033, 0.064, 0.000 ms]
Run Code Online (Sandbox Code Playgroud)

但是,当执行进入优化功能时,它被去优化

*** DEOPT: optimizeWhack at bailout #1, address 0x0, frame size 8
[deoptimizing: begin 0xea2f6fc9c29 optimizeWhack @1]
Run Code Online (Sandbox Code Playgroud)

deopt的原因如下:因为您optimizeWhackfoo()进入的单态状态下执行了一次调用IC,而V8则调用了特定函数值的调用.但是,下次调用new时,会创建一个不再匹配上一次调用的预期值optimizeWack foo内容foo.这导致deopt.

如果optimizeWhack在请求优化之前重写样本以调用两次,那么您将看到optimizeWhack保持优化:

optimizeWhack();
optimizeWhack();

%OptimizeFunctionOnNextCall(optimizeWhack);
optimizeWhack();

printStatus(optimizeWhack);

// $ d8 --allow-natives-syntax test.js
// Function is optimized
Run Code Online (Sandbox Code Playgroud)