Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Disable V8's Optimizing Compiler

I'm writing a constant-time string comparison function (for node.js) and would like to disable V8's optimizing compiler for this single function; using command-line flags are out of the question.

I know that using a with{} (or try/catch) block will disable the optimizing compiler now, but I'm afraid this "feature" (bug) will be fixed in future versions.

Is there an immutable (and documented) way disabling V8's optimizing compiler?


Example function:

function constantTimeStringCompare( a, b ) {
    // By adding a `with` block here, we disable v8's optimizing compiler.
    // Using Object.create(null) ensures we don't have any object prototype properties getting in our way.our way.
    with ( Object.create( null ) ){
        var valid = true,
            length = Math.max( a.length, b.length );
        while ( length-- ) {
            valid &= a.charCodeAt( length ) === b.charCodeAt( length );
        }
        // returns true if valid == 1, false if valid == 0
        return !!valid;
    }
}

And a perf test just for fun.

like image 359
David Murdoch Avatar asked Aug 27 '13 22:08

David Murdoch


People also ask

What does an optimizing compiler does?

In computing, an optimizing compiler is a compiler that tries to minimize or maximize some attributes of an executable computer program. Common requirements are to minimize a program's execution time, memory footprint, storage size, and power consumption (the last three being popular for portable computers).

How is V8 so fast?

However, V8 does it incrementally, i.e., for each GC stop, V8 tries to mark as many objects as possible. It makes everything faster because there's no need to stop the entire execution until the collection finishes. In large applications, the performance improvement makes a lot of difference.

Does V8 optimize?

That's why it is so essential to implement objects with the same properties in the same order to have the same hidden class. Otherwise, V8 won't be able to optimize your code. In V8 words, you want to stay as much monomorphic as possible.

Does V8 use JIT?

Unlike other languages, The V8 engine uses both a compiler and an interpreter and follows Just in Time(JIT) Compilation for improved performance. Just in Time(JIT) Compilation: The V8 engine initially uses an interpreter, to interpret the code.


2 Answers

If you want solid way to do it, you need to run node with --allow-natives-syntax flag and call this:

%NeverOptimizeFunction(constantTimeStringCompare);

Note that you should call this before you have called constantTimeStringCompare, if the function is already optimized then this violates an assertion.

Otherwise with statement is your best bet as making it optimizable would be absolute lunacy whereas supporting try/catch would be reasonable. You don't need it to affect your code though, this will be sufficient:

function constantTimeStringCompare( a, b ) {
    with({});

    var valid = true,
        length = Math.max( a.length, b.length );
    while ( length-- ) {
        valid &= a.charCodeAt( length ) === b.charCodeAt( length );
    }
    // returns true if valid == 1, false if valid == 0
    return !!valid;

}

Merely mentioning with statement corrupts the entire containing function - the optimizations are done at function-level granularity, not per statement.

like image 147
Esailija Avatar answered Oct 04 '22 11:10

Esailija


To actually check is function optimized by particular Node.js version you can refer to Optimization Killers wiki of bluebird.
I've checked 3 solutions on Node 7.2:

  1. with({}) - Function is optimized by TurboFan
  2. try {} catch(e) {} - Function is optimized by TurboFan
  3. eval(''); - Function is not optimized

So to guarantee disable V8 optimization you should add eval('') to function body.

like image 40
vitalets Avatar answered Oct 04 '22 11:10

vitalets