V8 javascript engine for フロントエンドデベロッパー

180 views

Published on

V8 javascript engine がどうjavascriptを最適化し、実行するかの概要

Published in: Software
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
180
On SlideShare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

V8 javascript engine for フロントエンドデベロッパー

  1. 1. V8
 javascript engine
  2. 2. : @brn ( ) : : Cyberagent RightSegment AI Messenger : http://abcdef.gets.b6n.ch/ Twitter: https://twitter.com/brn227
  3. 3. V8 V8 Google javascript Google Chrome javascript
  4. 4. V8 V8 •  •  Hidden Class •  Inline Caching •  GC •  2016 •  CPU Mips Arm X64 X86 7
  5. 5. V8 javascript
  6. 6. V8 Code base V8 108 C++ …
  7. 7. V8 Source AST Bytecode Graph Assembly
  8. 8. Parsing V8 AST AST AbstractSyntaxTree
  9. 9. Abstract Syntax Tree if (x) { x = 100 }
  10. 10. Abstract Syntax Tree IF CONDITION THEN BLOCK EXPRESSION STATEMENT ASSIGN VAR PROXY (X) LITERAL (100) if (x) { x = 100
  11. 11. Parsing Web javascript
  12. 12. Parsing V8
  13. 13. Lazy Parsing function x() {return 1;} FUNCTION(X)
  14. 14. Lazy Parsing function x() {return 1;} x() FUNCTION NAME (x) RETURN LITERAL(1)
  15. 15. Lazy Parsing V8
  16. 16. PreParsing v8::internal::PreParser •  • 
  17. 17. Dive into Parsing V8 Parsing https://docs.google.com/presentation/d/1b- ALt6W01nIxutFVFmXMOyd_6ou_6qqP6S0Prmb1iDs/present? slide=id.p
  18. 18. Abstract Syntax Tree V8 yacc lex
  19. 19. AST Rewriter V8 AST
  20. 20. AST Rewriter javascript Spread var x = [1,2,3]; var y = […x]; V8 AltJS
  21. 21. AST Rewriter do { $R = []; for ($i of x) %AppendElement($R, $i); $R } // src/parsing/parser.cc do for-of
  22. 22. Abstract Syntax Tree AST V8 AST AST …
  23. 23. Abstract Syntax Tree var x = 100
  24. 24. Abstract Syntax Tree var EXPRESSION STATEMENT CALL RUNTIME [IniOalizeVarGlobal] LITERAL (x) LITERAL (100) x 100 ?
  25. 25. Abstract Syntax Tree V8 Runtime C++ AST AST
  26. 26. AST to Bytecode AST AST Bytecode V8 Bytecode 1Byte Bytecode VM Ignition
  27. 27. Igniton V8 Ignition Bytecode AST
  28. 28. Igniton Ignition CPU Ignition BytecodeHandler Bytecode
  29. 29. Igniton
  30. 30. // 擬似的なjavascriptコード        ! var Bytecodes = [0,1,2,3] var index = 0; function dispatch(next) { BytecodeHandlers[next](); } const BytecodeHandlers = { ['0']() {...; dispatch(Bytecodes[index++])}, ['1']() {...; dispatch(Bytecodes[index++])}, ['2']() {...; dispatch(Bytecodes[index++])}, ['3']() {...; dispatch(Bytecodes[index++])} } const firstBytecode = Bytecodes[index++]; BytecodeHandlers[firstBytecode](firstBytecode);
  31. 31. Igniton Dispatch Table 00 01 02 04 08 0f 10 10 Node Node Node MachineCode MachineCode IGNITION_HANDLER Entry Function(Machine Code) グラフからコードを生成 生成したコードを、 DispatchTableの対応する バイトコードのインデックスへ 登録
  32. 32. Igniton Ignition AST V8 AST v8::internal::AstVisitor<Subclass> AstVisitor Visitor AST
  33. 33. Visitor Pattern class Visitor { void Visit(Ast* ast) { ast->Accept(this); } void VisitXXX(XXX* ast) { ast->property->accept(this); } } class Ast(XXX) { void Accept(Visitor* visitor) { visitor->VisitXXX(this) } }
  34. 34. Igniton Bytecode BytecodeArray BytecodeArray
  35. 35. Igniton Dispatch Table Entry Function(Machine Code) BytecodeArray Dispatch Tableから対応するHandlerを取り出して実行 0 1 3 4 5 6 7 8 8 6 1
  36. 36. Code Generation V8 CodeStub Builtins Runtime BytecodeHandler
  37. 37. Code Generation Bytecode Bytecode BytecodeHandler
  38. 38. IGNITION_HANDLER(JumpIfToBooleanFalse, InterpreterAssembler) {! Node* value = GetAccumulator();! // Accumulatorの値を取得! Node* relative_jump = BytecodeOperandUImmWord(0);! // 引数のoperandを取得! Label if_true(this), if_false(this);! BranchIfToBooleanIsTrue(value, &if_true, &if_false);! // valueがtrueならif_true、falseならif_false! Bind(&if_true);! Dispatch();! Bind(&if_false);! // operandのbytecodeまでjump! Jump(relative_jump);! }!
  39. 39. Code Generation Graph
  40. 40. Code Generation C++ DSL
  41. 41. IGNITION_HANDLER(ForInContinue, InterpreterAssembler) {! ...! Branch(WordEqual(index, cache_length), &if_true, &if_false);! Bind(&if_true);! {! SetAccumulator(BooleanConstant(false));! Goto(&end);! }! Bind(&if_false);! {! SetAccumulator(BooleanConstant(true));! Goto(&end);! }! ...! }!
  42. 42. Code Generation MacroAssembler MacroAssembler Assembler V8 masm MacroAssembler
  43. 43. #define __ ACCESS_MASM(masm)! ! static void Generate_StackOverflowCheck(...) {! ! __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);! __ movp(scratch, rsp);! ! __ subp(scratch, kScratchRegister);! __ sarp(scratch, Immediate(kPointerSizeLog2));! ! __ cmpp(scratch, num_args);! ! __ j(less_equal, stack_overflow, stack_overflow_distance);! }!
  44. 44. Code Generation GraphResolver CodeGenerator Graph MacroAssembler Assembler
  45. 45. Code Generation MacroAssembler Graph Graph •  CodeStubAssembler •  CodeAssembler •  RawMachineAssembler •  MachineOperatorBuilder
  46. 46. Code Generation e.x Load CodeStubAssembler::Load CodeAssembler::raw_assembler()->Load() RawMachineAssembler::Load AddNode(MachineAssembler::Load()) Graph Leaf Node
  47. 47. Optimization javascript javascript javascript V8 JIT( )
  48. 48. Optimization V8 3 •  Hidden Class •  Inline Caching •  TurboFan
  49. 49. Hidden Class javascript class prototype •  • 
  50. 50. Hidden Class V8 function Point(x, y) { this.x = x; this.y = y }; var point = new Point(1, 1); Point
  51. 51. Map V8 •  •  •  Map Map Map
  52. 52. Map function Point(x, y) { this.x = x; this.y = y; } Map FixedArray [ {a: {offset: 0}}, {b: {offset: 1}} ]
  53. 53. Map javascript
  54. 54. Map Transition V8 transition Map Map
  55. 55. Map Transition function Point(x, y) { this.x = x; this.y = y; } Map FixedArray [ {x: {offset: 0}}, {y: {offset: 1}}, transiOon: {address: …} ] var x = new Point(1, 1); x.z = 1; Map FixedArray [ {x: {offset: 0}}, {y: {offset: 1}}, {z: {offset: 2}} ] transition
  56. 56. Inline Caching Inline Caching
  57. 57. class X {add() {return 1}}! class Y {add() {return 2}}! var m = [new X(), new X(), new Y()];! for (let i = 0; i < m.length; i++) {! m[i].add();! }! !
  58. 58. Inline Caching 初回 V8 add Receiver Map Cached address 1. Search 2. Check 4. Cache 3. Call
  59. 59. Inline Caching 二回目以降 V8 add Receiver Map Cached address 1. Search and Call
  60. 60. Inline Caching Inline Caching 4 •  Premonomorphic •  Monomorphic •  Polymorphic •  Megamorphic
  61. 61. Premonomorphic Premonomorphic IC Stub
  62. 62. Monomorphic Monomorphic Receiver IC
  63. 63. Polymorphic Polymorphic Receiver Polymorphic Map Monomorphic IC
  64. 64. Megamorphic Megamorphic
  65. 65. (Load/Store)IC_Miss LoadIC_Miss StoreIC_Miss IC C++
  66. 66. (Load/Store)IC_Miss 二回目以降 V8 add Receiver (y) Map Cached address (x) 1. Search 2. Compare Map x !== y 3. (Load/Store)IC_Miss
  67. 67. Optimized Compilation V8 Bytecode Generic Runtime
  68. 68. Hot Spot V8 •  • 
  69. 69. Loop Tracing V8 V8 OnStackReplacement
  70. 70. On Stack Replacement for (let i = 0; i < 10000; i++) { doSomething(i); } JumpLoop LoopHeader SlowCode FastCode PC( )
  71. 71. Function Call Tracing Ignition Return Bytecode BytecodeHandler Interrupt Body
  72. 72. Function Interruption function Y() { … } RETURN OP Replace Body しきい値チェック
  73. 73. TurboFan V8 Graph Graph TurboFan
  74. 74. TurboFan TurboFan •  Loop peeling / Loop elimination •  Escape analysis •  Lowering •  Effect and control linearize •  Dead code elimination •  Control flow optimization •  Memory optimization
  75. 75. Deoptimization Map overlow 0 … V8 Bytecode
  76. 76. Pipeline OpOmize Assembler TurboFan Source AST Parser Bytecode Graph IgniOon Compile Optimization Deoptimization
  77. 77. V8 GC V8 GC

×