Upgrade to Pro — share decks privately, control downloads, hide ads and more …

V8 Presentation NodeConf

Tamar Twena-Stern
November 06, 2023
37

V8 Presentation NodeConf

Tamar Twena-Stern

November 06, 2023
Tweet

Transcript

  1. Compiler - Translates High level code to machine code in

    compilation process Interpreter - directly executes source code written in a high-level programming, translate to machine code line by line Dynamic Typed Languages - checks variable types at runtime Static Typed Languages - checks variable types at compile time
  2. Dynamic Type Languages Have Perform Those Techniques At Runtime •

    Runtime Type Checking • Dynamic Dispatch
  3. Compiler, static typed language == Interpreter, dynamic type language ==

    == Interpreter, dynamic type language So In Most Cases
  4. megamorohic(myNumber : number) : void; megamorohic(myString: String) : void; megamorohic(myPerson

    : Person) : void; megamorohic(myFirstAray: Array<String>) : void; megamorohic(mySecondArray: Array<number>) : void;
  5. De-Optimization - Example class Person { constructor(name, age) { this.name

    = name; this.age = age; } } function getAge(person) { return person.age; }
  6. De-Optimization - Example for (let i = 0 ; i

    < 1000000 ; i++ ) { // After X iterations the Turbofan binary will be created const p = new Person("Tamar", 30); getAge(p); }
  7. De-Optimization - Example const differentPerson = new Person("Tamar", 30);; //

    Adding dynamic property, hidden class changed differentPerson.salary = 3000; //binary released getAge(differentPerson);
  8. Optimized Code function concat_str(arg) { return arg + arg; }

    // Start for (let i = 0 ; i< 100000; i++) { concat_str("a"); } // End
  9. Code With DeOptimization function concat_str(arg) { return arg + arg;

    } // Start for (let i = 0 ; i< 100000; i++) { if (i == 10231) { concat_str(1); } else { concat_str("a"); } } // End
  10. De-optimizing After Transfering Different Type [marking 0x070b4aa60601 <JSFunction (sfi =

    0x3dc4dce32af9)> for optimization to TURBOFAN, ConcurrencyMode::kConcurrent, reason: hot and stable] [compiling method 0x070b4aa60601 <JSFunction (sfi = 0x3dc4dce32af9)> (target TURBOFAN) using Turbofan OSR] [optimizing 0x070b4aa60601 <JSFunction (sfi = 0x3dc4dce32af9)> (target TURBOFAN) - took 0.000, 0.625, 0.000 ms] [bailout (kind: deopt-eager, reason: Insufficient type feedback for call): begin. deoptimizing 0x070b4aa60601 <JSFunction (sfi = 0x3dc4dce32af9)>, opt id 0, bytecode offset 30, deopt exit 4, FP to SP delta 96, caller SP 0x00016bc4a310, pc 0x000128853144]
  11. const a = 1; const b = doStuff1(a); const c

    = doStuff2(a); for (let i=0; i<100000; i++) { doStuff1(a);//After X runs,run Machine Code (TurboFan) } Before Adding SparkPlug
  12. const a = 1; const b = doStuff1(a); // run

    Machine Code (SparkPlug) const c = doStuff2(a); // run Machine Code (SparkPlug) for (let i=0; i<100000; i++) { doStuff1(a); // After X runs, run Machine Code (TurboFan) } After Adding SparkPlug
  13. Ignition Does The Hard Work • variable resolution • parentheses

    or arrow functions • desugaring destructuring statements
  14. getX({ x: 3 }) // Cache size = 1 getX({

    x: 3, a: 1 }) // polymorphic getX({ x: 3, b: 1 }) // polymorphic getX({ x: 3, c: 1 }) // polymorphic, several cache entries getX({ x: 3, d: 1 }) // megamorphic - Entries are overwritten on collisions
  15. Until recent V8 versions - Inline Cache was not implemented

    for class fields and private methods
  16. const person = {}; person.age = 42; function getAge(p) {

    return p.age; } class Person { age; constructor(age) { this.age = age; } getAge() { return this.age; } }
  17. Benchmark Setup class Person { age; constructor(age) { this.age =

    age; } function getAge(p) { return p.age; } }
  18. Benchmark // Start for (let i = 0 ; i

    < 1000000 ; i++ ) { const p = new Person(30); p.getAge(p); } // End