What happens to v8 status code on optimization / function run?

谁说我不能喝 提交于 2019-12-09 12:22:33

问题


I saw a question about v8 Optimization which led me to play a bit with v8 Optimization. I've also seen bluebird post about v8 Optimization killers.

According to v8 repo, optimization status codes are in multiplications of 2: 1,2,4 ,8 and so on (see OptimizationStatus enum )

However, the following code gave me strange status codes like 17 and 65, and only in these specific cases (see the last few lines of code). Any ideas about why this is happening?

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);

Run this code with:

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

You can use my gist if you find it more comfortable


回答1:


status is a bitwise flag value and the code should look more like this:

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'

Consider a "status code" of 17 ~or~ 16 + 1 ~or~ (1 << 4) | (1 << 0) ~which means~ "kIsFunction" and "kIsOptimized".

See the bit arrays for general manipulation - and why the use of & in the conditions shown in the code.




回答2:


%GetOptimizationStatus has been updated to return a set of bitwise flags instead of a single value, and the article Optimization Killers is outdated. The available status information has also been slightly changed.

To access the new value, you need to take the binary representation of the returned value. Now, for example, if 65 is returned, the binary representation is the following:

65₁₀ = 000001000001₂

Each binary digit acts as a boolean with the following meaning:

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

Thus, 65 means the function is a function and is interpreted (which means it is not optimized at the time of querying its status).

To access these values in JavaScript, simply use the bitwise AND operator and see if the value is non-zero:

var status = %GetOptimizationStatus(fn);

if (status & 1) console.log("function is function");
if (status & 2) console.log("function is never optimized");
if (status & 4) console.log("function is always optimized");
if (status & 8) console.log("function is maybe deoptimized");
if (status & 16) console.log("function is optimized");
if (status & 32) console.log("function is optimized by TurboFan");
if (status & 64) console.log("function is interpreted");
...

And so on. The key aspect here is that more than one of these conditions can evaluate to true.



来源:https://stackoverflow.com/questions/46749742/what-happens-to-v8-status-code-on-optimization-function-run

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!