优化/功能运行时v8状态代码会发生什么?

时间:2017-10-14 21:59:22

标签: javascript node.js optimization v8

我看到了一个关于v8 Optimization的问题,这让我在v8优化方面发挥了一些作用。 我还看过关于v8 {蓝色Optimization killers的蓝鸟帖子。

根据v8 repo,优化状态代码的乘法为2:  1,2,4,8等等(见OptimizationStatus enum)

但是,下面的代码给了我奇怪的状态代码,如17和65,并且仅在这些特定情况下(参见最后几行代码)。 关于为什么会发生这种情况的任何想法?

function adder(a, b) {
    return new Function('a', 'b', 'return b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b')(a, b);
}
function addereval(a, b) {
    return eval('b%2 ? a + b : b%3 ? a - b : b%5 ? b / a : a * b');
}

function printStatus(fn) {
    var status = %GetOptimizationStatus(fn)
    switch (status) {
        case 1: console.log(fn.name, "function is optimized"); break;
        case 2: console.log(fn.name, "function is not optimized"); break;
        case 3: console.log(fn.name, "function is always optimized"); break;
        case 4: console.log(fn.name, "function is never optimized"); break;
        case 6: console.log(fn.name, "function is maybe deoptimized"); break;
        case 7: console.log(fn.name,"Function is optimized by TurboFan"); break;
        default: console.log(fn.name, "Unknown optimization status: ", status); break;
    }
}
printStatus(adder);
printStatus(addereval);


for(let i = 0; i < 263; i++) {
    adder(1, 2);
}
console.log('\n', '==== adder after invocation - result is on node v8.2.1 17 or 65 on node v8.7.0 ===');
printStatus(adder);

addereval(1, 2);
console.log('\n', '==== addereval after invocation - result is 65 ===');
printStatus(addereval);

使用以下命令运行此代码:

node --trace_deopt --allow-natives-syntax FILENAME.js

如果您觉得更舒服,可以使用my gist

2 个答案:

答案 0 :(得分:6)

Type input.txt 已更新为返回一组按位标志而不是单个值,文章Optimization Killers已过时。可用的状态信息也略有改变。

要访问新值,您需要获取返回值的二进制表示。现在,例如,如果返回%GetOptimizationStatus,则二进制表示如下:

65

每个二进制数字充当布尔值,具有以下含义:

65₁₀ = 000001000001₂

因此,0 0 0 0 0 1 0 0 0 0 0 1 ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ │ │ └─╸ is function │ │ │ │ │ │ │ │ │ │ └───╸ is never optimized │ │ │ │ │ │ │ │ │ └─────╸ is always optimized │ │ │ │ │ │ │ │ └───────╸ is maybe deoptimized │ │ │ │ │ │ │ └─────────╸ is optimized │ │ │ │ │ │ └───────────╸ is optimized by TurboFan │ │ │ │ │ └─────────────╸ is interpreted │ │ │ │ └───────────────╸ is marked for optimization │ │ │ └─────────────────╸ is marked for concurrent optimization │ │ └───────────────────╸ is optimizing concurrently │ └─────────────────────╸ is executing └───────────────────────╸ topmost frame is turbo fanned 表示函数是一个函数并被解释(这意味着它在查询其状态时优化)。

要在JavaScript中访问这些值,只需使用按位AND运算符并查看该值是否为非零:

65

等等。这里的关键方面是这些条件中不止一个可以评估为真。

答案 1 :(得分:3)

status按位标志值,代码看起来应该更像这样:

var status = GetOptimizationStatus(fn);
if ((status & (1 << 0)) {
  console.log(fn.name, "kIsFunction");
}
if ((status & (1 << 1)) {
  console.log(fn.name, "kNeverOptimize");
}
// etc .. can be 'true' for several different combinations;
// most notably, many different status will also include 'kIsFunction'

考虑一个&#34;状态代码&#34; 17〜或〜16 + 1〜或〜(1 << 4) | (1 << 0)〜这意味着〜&#34; kIsFunction&#34; &#34; kIsOptimized&#34;。

请参阅bit arrays进行一般操作 - 以及为什么在代码中显示的条件中使用&