Skip to content

Instantly share code, notes, and snippets.

@justjavac
Last active March 31, 2024 06:30
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save justjavac/55699b0ba771187f812cb7995c12575f to your computer and use it in GitHub Desktop.
Save justjavac/55699b0ba771187f812cb7995c12575f to your computer and use it in GitHub Desktop.
V8 %GetOptimizationStatus

%GetOptimizationStatus return a set of bitwise flags instead of a single value, to access the 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).toString(2).padStart(12, '0');
// 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

test.js:

// Function that contains the pattern to be inspected (using an `with` statement)
function fn() {
    with ({ i: 0, v: 0 }) {
        return v;
    }
}

function printStatus(fn) {
    const status = %GetOptimizationStatus(fn);
    console.log(status.toString(2).padStart(12, '0'));

    if (status & (1 << 0)) {
        console.log("is function");
    }

    if (status & (1 << 1)) {
        console.log("is never optimized");
    }
    
    if (status & (1 << 2)) {
        console.log("is always optimized");
    }
    
    if (status & (1 << 3)) {
        console.log("is maybe deoptimized");
    }
    
    if (status & (1 << 4)) {
        console.log("is optimized");
    }
    
    if (status & (1 << 5)) {
        console.log("is optimized by TurboFan");
    }
    
    if (status & (1 << 6)) {
        console.log("is interpreted");
    }
    
    if (status & (1 << 7)) {
        console.log("is marked for optimization");
    }
    
    if (status & (1 << 8)) {
        console.log("is marked for concurrent optimization");
    }
    
    if (status & (1 << 9)) {
        console.log("is optimizing concurrently");
    }
    
    if (status & (1 << 10)) {
        console.log("is executing");
    }
    
    if (status & (1 << 11)) {
        console.log("topmost frame is turbo fanned");
    }
}

console.log('0. prepare function for optimization');
printStatus(fn);

console.log("1. fill type-info");
fn();

console.log('2. calls function to go from uninitialized -> pre-monomorphic -> monomorphic')
fn();
printStatus(fn);

%OptimizeFunctionOnNextCall(fn);

console.log('3. optimize function on next call')
printStatus(fn);

console.log('4. next call')
fn();

console.log('5. get optimization status')
printStatus(fn);

Run it:

node --allow-natives-syntax test.js

or with details:

node --trace_opt --trace_deopt --allow-natives-syntax test.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment