How javascript works?

How javascript works?

Javascript execution flow.


  1. How Javascript Works?


  3. Where we work on?

  4. Javascript Ruby Java Machine Language Assembler C/C++ Rust Go English

    Japanese etc… “High-level” “Low-level”
  5. Low-level language Low-level language mean “More hardware side” language. That

    mean we can control hardware behavior directly through programing languages. Low-level language has below pros & cons. • Pros) Very fast. Because Low-level language manipulate hardware directly. • Pros) Fun:) • Cons) Very dangerous. Because Low-level language has a least safety system. • Cons) Hard to write. Because Low-level language hasn’t any modern programing language features in many case.
  6. High-level language High-level language mean “More human side” language. That

    mean we can control hardware behavior indirectly through more human readable and understandable language. High-level language has below pros & cons • Pros) Human readable and easy to write. (Becuase High-level language has intermediate translator that translate from High-level to Low-level) • Pros) High productivity. Because we are’t need to think many hardwares. • Cons) Slower than Low-level in many case.
  7. Why we create High-level lang? Because Low-level language is very

    dangerous and difficult to cover many platforms. Programing history is efficient hardware - especially CPU - control history. But today, we have many CPU, so we can’t cover all CPU except a few people. And Low-level languages requires very complicated memory management and sometimes that cause memory leak which may difficult to solve and other dangerous bugs like buffer overflow. So to solve these problems, we have created some High-level programing languages.
  8. Javascript Javascript is High-level programing language that created by Brendan

    Eich. That work on mainly browser or server(Node.js). This language has relatively many engines, compared to the other programing languages. E.g, V8(Google), JavascriptCore(WebKIT), SpiderMonkey(Mozilla) Today I will describe major 3 javascript engines.
  9. Execution Steps

  10. Lifecycle of javascript “Sourcecode” “Abstract Syntax Tree” “Bytecode” “Binary”

  11. Parsing

  12. AbstractSyntaxTree if (flag) { x = 100; } *G $POEJUJPO

  13. Parsing First, javascript engine load source codes and convert it

    to Abstract Syntax Tree. Parsing is conversion which convert from flatten source code strings to structured model.
  14. Parser Generator Many languages are using ParserGenerrator like yacc. But

    almost javascript engines aren’t using ParserGenerator. They are mainly using Handwritten-Recursive-Descent-Parser. By using Handwritten-Recursive-Descent-Parser, engines can controll parsing process more flexibly.
  15. Efficient Parsing Many javascript engines has no any wasted time,

    so they want to parse only needed, they are not want to parse waste source codes. How to solve this issue? V8 solve this issues by using PreParser which parse only source code layout, which mean all function bodies will skip.
  16. PreParsing function someProcess(a, b, c) { ... } PreParsed Function

    information name : “someProcess” parameter-count : 3 start-position : 1 end-position : 34 use-super-property: false
  17. Problematic grammars Javascript has curious grammars. If you start writing

    parser of javascript, you'll see ECMA262 grammars and you’ll find Cover* grammars. CoverParenthesizedExpressionAndArrowParameterList This long name grammar was created for arrow function and parenthesized expression like below. (a, b, c) => {...} (a, b, c); Arrow function and parenthesized expression can’t distinct until find “=>” glyph. So ecma262 solve this problem by treat this two grammar as same grammar tree that has different meaning.
  18. Bytecode

  19. Bytecode Bytecode is relatively low-level operation for VirtualMachine but bytecode

    is not machine language. It’s defined by each javascript engine.
  20. Bytecode JumpIfToBooleanFalse LdaSmi StaGlobal Star r0 Ldar r0 0x260a7c81db19: [FixedArray]

    in OldSpace - map: 0x260aee2807a9 <Map> - length: 2 0: 0x260a7c81da59 <String[4]: flag> 1: 0x260a7c81da71 <String[1]: x> *G $POEJUJPO 5IFO (flag) 4UBUFNFOU "TTJHONFOU&YQSFTTJPO 7BS1SPYZ -JUFSBM x 100
  21. Bytecode generation Almost all javascript engines are generating bytecode from

  22. Interpreter

  23. Interpreter Interpreter is a execution engine, but not execute machine

    language, generally, interpreter execute AST directly or execute bytecode. Today, almost all javascript engines has executing bytecode, so it’s called Bytecode Interpreter.
  24. Optimizations

  25. Pipelines V8 Javascript Core SpiderMonkey Ignition (Interpreter + Baseline JIT)

    JIT Optimization (TurboFan) Deoptimization Interpreter Simple JIT Optimization Deoptimization Full JIT Interpreter (LL Int) Baseline JIT Optimization Deoptimization DFG JIT FTL JIT
  26. Pipelines Alomost all current javascript engines has implemented pipeline below.

    Bytecode => Baseline JIT => Optimized JIT
  27. Baseline JIT Baseline JIT is simple unoptimized “Baseline” assembler. “Baseline”

    mean optimization baseline. It’s fast than Bytecode but slower than native optimized codes.
  28. Optimized JIT Optimized JIT is fastest program in javascript engine.

    That is very fast, but cost many cpu cycles to generate and using large heap space to reserve.
  29. Deoptimization Deoptimization is convertion from optimized machine language to previous

    baseline JIT, if infered type become invalid. Generally this caused by unexpected type is passed to optimized function.
  30. Deoptimization const id = x => x; const test =

    obj => { for (let i = 0; i < 100000; i++) { id(obj.x); } } test({x: 1}); test({x: 1, y: 1}); This code will cause deoptimization.
  31. Optimization steps(V8) Find Hotspot Bytecode Create TurboFan IR OSR/Compile Function

    Consume optimization budget Deoptimization
  32. Optimization steps(JSC) OSR 100times statement or 6 times function called

    Deoptimization Bytecode “LL Int” Baseline JIT 1000times statement or 66 times function called DFG JIT FTL JIT Collect profiles
  33. Optimization steps(IonMonkey) Collect Profiles Deoptimization Bytecode “LL Int” Simple JIT

    Find Heaviely looped code Full JIT Create MIR Optimize
  34. Types & Inline Caches

  35. Types(V8 Map) const foo = { x: 1, y: 2

    } {x: {offset: 1}} {y: {offset: 3}} foo.z = 3 {transition: {x: {offset: 1}}, {y: {offset: 3}}} {z: {offset: 4}}
  36. Types(Others) Javascript engines has each Map like structure, E.g. JSC

    Shape. Each Type systems different from each other, but basic idea of these systems are that classificate javascript object by property layout.
  37. Inline Cache function x(obj) { return obj.x + obj.y; }

    x({x: 0, y: 0}); x({x: 1, y: 1}); x({x: 2, y: 2}); Search “x” and “y” Direct access to “x” and “y” x y 1st time 2nd time or later
  38. Inline Caches Inline cache is fast path for property access.

    Almost all case hasn’t any problem, but javascript is very dynamic language, so if property is updated, property cache will update too. Inline cache has below state. Monomorphic Polymorphic Megamorphic
  39. Inline Cache States(V8) “Monomorphic” Ideal state. Only one Map. “Polymorphic”

    Has some Maps, but still fast. “Megamorphic” Bad state, can’t create fast path.
  40. Appendix Garbage Collector

  41. GC Specs V8 Javascript Core SpiderMonkey Orinoco GC Concurrent Incremental

    Parallel MarkCompat Generational Copying Concise Riptide GC Concurrent Incremental Parallel MarkCompat Generational Conversative Copying ?