Source to Binary - journey of V8 javascript engine

Source to Binary - journey of V8 javascript engine

V8 javascript engineについて
パーサー、AST、Ignition/TurboFan、最適化周り等

Transcript

  1. None
  2. Name @brn (ꫬꅿ⨳ⵃ) Occupation ؿٗٝزؒٝسؒٝآص،٥ط؎ذ؍ـؒٝآص، Company Cyberagent ،سذؙأةآؔ AI Messenger

    Blog http://abcdef.gets.b6n.ch/ Twitter https://twitter.com/brn227 GitHub https://github.com/brn
  3. Agenda •  What is V8? •  Execution flow of V8

    •  Parsing •  Abstract Syntax Tree •  Ignition – BytecodeInterpreter •  CodeStubAssembler •  Builtins / Runtime •  Optimization / Hidden Class / Inline Caching •  TurboFan / Deoptimization
  4. What is V8? V8הכGoogle爡ָ㹋鄲׃׋javascriptؒٝآٝדծ Google Chrome/Node.JSךjavascriptؒٝآٝח䱰欽ׁ׸גְתׅկ

  5. Execution Flow

  6. Source AST Bytecode Graph Assembly first time hot code

  7. Parsing

  8. Basic parsing V8כا٦أ؝٦س׾ػ٦أ׃גASTח㢌䳔ׅ׷ ASTהכAbstractSyntaxTreeך殛獥 䬄韋圓俑加הㄎל׸׷ Parsing

  9. if (x) { x = 100 }

  10. IF CONDITION THEN BLOCK EXPRESSION STATEMENT ASSIGN VAR PROXY (X)

    LITERAL (100) if (x)  {  x = 100 
  11. Problems

  12. Parsing all functions - Slow ׅץגך؝٦س׾剑ⴱחػ٦أׅ׷ךכ֮ת׶״׹׃ֻזְ ׮׃ػ٦أ׃׋؝٦سָ㹋遤ׁ׸זֽ׸ל䠐㄂ָזְ Parsing

  13. Split parsing phase ػ٦أ׾鹼䒀׃ג遤ֲ׋׭חծػ٦أ׾✳媮ꥡחⴓֽ׷ Parsing

  14. PreParsing ✲⵸חׅץגךꟼ侧ךٖ؎،ؐز׾ ػ٦أ׃גֶֻ Parsing

  15. function x(a, b) { return a + b; } FUNCTION(X)

    parameter-count: 2 start-position: 1 end-position: 34 use-super-property: false …
  16. // when x is called x() FUNCTION NAME (x) RETURN

    LITERAL(1)
  17. Lazy Parsing V8כ㹋ꥷח״ן׌ׁ׸׷תדػ٦أ׾鹼䒀ׅ׷ ꟼ侧כㄎן⳿ׁ׸גⴱ׭ג؝ٝػ؎ׁٕ׸׷ Parsing

  18. More About https://docs.google.com/presentation/d/1b- ALt6W01nIxutFVFmXMOyd_6ou_6qqP6S0Prmb1iDs/present? slide=id.p Parsing

  19. Abstract Syntax Tree

  20. AST Rewriting Parserח״׏ג欰䧭ׁ׸׋AST׾㢌䕎ׅ׷ ְֻאַ稱➜ AbstractSyntaxTree

  21. Subsclass constructor return 竰䪫׃׋ؙٓأך؝ٝأزؙٓة׾㢌䕎ׅ׷ 崢欰ؙٓأך؝ٝأزؙٓةד䒭׾return׃גְ׷儗כծ 3갪怴皾㶨ח㢌䳔׃גծ 䒭ך穠卓ָundefined׌׏׋㜥さחכthis׾䨱ׅկ AbstractSyntaxTree

  22. constructor() {! super();! return expr! }! ! constructor() {! super();!

    var tmp;! return (temp = expr) === undefined?! this: temp;! }!
  23. for (let/const/var in/of e) for-in/ofךⴱ劍⻉דconst/let׾⢪ֲ׋׭חծⰋ⡤׾ـٗحؙד㔲 ׫㢌侧׾㹑鎉ׅ׷կ AbstractSyntaxTree

  24. for (const key of e) {! ...! }!

  25. {! var temp;! for (temp of e) {! const x

    = temp;! ...! }! let x! }!
  26. Spread operator doהfor-ofח縧ֹ䳔ִגⳢ椚 AbstractSyntaxTree

  27. const x = [1,2,3];! const y = [...x];!

  28. do {! $R = [];! for ($i of x)! %AppendElement($R,

    $i);! $R! }!
  29. Ecmascript? – Binary AST ➙תד鋅׋״ֲחASTך؟؎ؤכ穠圓㣐ְֹךדծ ׉׸׾㖇簭ׅ׷䲿周 Parsing

  30. Ignition

  31. Bytecode Interpreter V8כ欰䧭׃׋AST׾1~4byteךBytecodeח㢌䳔׃גַ׵㹋遤ׅ ׷ Ignition

  32. How does it work? ♧אך،ُؗيٖ٦ة٦׾⪒ִٖآأةك٦أד⹛⡲ׅ׷؎ٝ ة٦فٔة Ignition

  33. Pseudo javascript code Javascriptד圓鸡׾垷⦺ׅ׷הֿך״ֲחז׷ Ignition

  34. const Bytecodes = [0,1,2,3,4,5];! let index = 0;! function dispatch(next)

    {BytecodeHandlers[next] ();}! const BytecodeHandlers = [! () => {...; dispatch(Bytecodes[index++])},! () => {...; dispatch(Bytecodes[index++])},! () => {...; dispatch(Bytecodes[index++])},! () => {...; dispatch(Bytecodes[index++])},! () => {...; dispatch(Bytecodes[index++])},! () => {...; dispatch(Bytecodes[index++])},! ]! dispatch(Bytecodes[index++]);!
  35. How to create bytecode? BytecodeכASTַ׵AstVisitor׾ⵃ欽׃ג欰䧭ׁ׸׷ AstVisitorכVistorػة٦ٝ׾ⵃ欽׃׋ؙٓأדծ AST׾帾ׁ⮚⯓䱱稊׃זָ׵㼎䘔ׅ׷؝٦ٕغحؙꟼ侧׾ㄎן⳿ ׅ Ignition

  36. BytecodeArray 欰䧭ׁ׸׋BytecodeכBytecodeArrayח呓秛ׁ׸׷ BytecodeArrayכꟼ侧⽃⡘ד㶷㖈ׅ׷ Ignition

  37. Dispatch Table Stub(Machine Code) BytecodeArray Dispatch Tableから対応するHandlerを取り出して実行 0 1 3

    4 5 6 7 8 5 6 1
  38. InterpreterEntryTrampoline 剑穄涸ח欰䧭ׁ׸׋BytecodeכInterpreterEntrynTrampolineה ㄎל׸׷Builtin؝٦سַ׵㹋遤ׁ׸׷ InterpreterEntryTrampolineכAssemblyח؝ٝػ؎ׁٕ׸ծ 鸐䌢ךCךꟼ侧הㄎן⳿ׁ׸׷ Ignition

  39. InterpreterEntryTrampoline(Assembly) Script::Run Call as C function Ignition DispatchTable Dispatch First

    bytecode
  40. Ignition Handler ⯓玎亻⡂؝٦سד爙׃׋BytecodeHandlersכV8דכ Ignition Handlerהㄎל׸גְ׷ Ignition HandlerכCodeStubAssemblerהְֲDSLד鎸鶢ׁ׸ג ְ׷ Iginition

  41. CodeStub Assember

  42. What is CodeStubAssmber? CodeStubAssembler(CSA)כ؝٦س欰䧭׾ؚٓؿ欰䧭ח䬄韋⻉׃ ׋V8ⰻ鿇ךDSL 㹋遤✮㹀Node׾穈׫甧ג׷׌ֽדծCodeGeneratorח״׏גぐ ،٦ؗذؙثٍぢֽך؝٦سָ欰䧭ׁ׸׷׋׭ծ،إٝـٔ鎉铂 ׾ְ׍ְ׍倜׋ח剅ֻ䗳銲ָזְ CodeStubAssembler

  43. 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);! }!
  44. Graph based DSL ֿךCodeStubAssemblerךֶַ־ד㹋ꥷך،٦ؗذؙثٍぢֽ ך،إٝـٓ׾擾濼׃גְזֻג׮֮׵׋ח؝٦س׾鷄⸇ׅ׷ֿ הָ㺁僒חז׶ծ ת׋〳铣䚍׮ꬊ䌢ח넝ֻז׏גְ׷ CodeStubAssembler

  45. Dispatch Table 00 01 02 04 08 0f 10 10

    Node Node Node Operator Operator IGNITION_HANDLER Stub (Mahine Code Fragment) グラフからコードを生成 生成したコードを、 DispatchTableの対応する バイトコードのインデックスへ 登録 Assemble
  46. Assembler 㹋ꥷחぐ،٦ؗذؙثٍぢֽך؝٦س׾⳿⸂ׅ׷ X64ぢֽךjmpص٦ٌصحؙ׾׍׳׏ה׌ֽ鋖ְג׫״ֲ CodeStubAssembler

  47. void Assembler::jmp(! Handle<Code> target,! RelocInfo::Mode rmode! ) {! EnsureSpace ensure_space(this);!

    // 1110 1001 #32-bit disp.! // ここでメモリ上にアセンブラを書き出す! emit(0xE9);! emit_code_target(target, rmode);! }!
  48. Where to use BuiltinsכAssemblerؙٓأ׾ⵃ欽׃גぐ،٦ؗذؙثٍ嫣ך Stubָ鎸鶢ׁ׸גְ׷ ♧鿇CSA׾⢪ֲ皘䨽׮֮׷(*-gen.cc) Ignition HandlerכקרⰋגָCSAד鎸鶢ׁ׸גְ׷ CodeStubAssembler

  49. Builtins & Runtime

  50. Builtins BuiltinsכV8ך饯⹛儗ח؝ٝػ؎ׁٕ׸׷،إٝـٓך؝٦س晙 ꟼ侧ך״ֲחCallBuiltin穗歋דㄎן⳿ׁ׸׷ Stubה׮ㄎל׸׷ 㹋遤儗ך剑黝⻉כ遤׻׸זְ Builtins & Runtime

  51. Runtime RuntimeכBuiltinsװ׉ך➭ך،إٝـٓ؝٦سַ׵ㄎן⳿ֿׅ הָדֹ׷C++ך؝٦س Javascriptך⚅歲ַ׵C++ך⚅歲׾אזּ؝٦س晙 ずֻׄ㹋遤儗ך剑黝⻉כ遤׻׸זְ Builtins & Runtime

  52. Hidden Class

  53. What is Hidden Class? Javascriptחכ㘗ָזְךדؔـآؙؑز׾鋉㹀ׅ׷׮ךָ搀ְկ ׉ך׋׭ծV8כؔـآؙؑزך圓鸡荈⡤׾㘗ך״ֲח䪔׏גְ׷կ ֿ׸׾Hidden Classהㄎע Hidden Class

  54. •  Hidden Class const point1 = {x: 0, y: 0};!

    const point2 = {x: 0, y: 0};! Map FixedArray [ {x: {offset: 0}}, {y: {offset: 1}} ]
  55. Map ׋הִJavascript♳דכⴽךؔـآؙؑزד֮׏ג׮ծ ずׄ圓鸡׾䭯׏גְ׸לずׄHidden Class׾Ⱏ剣ׅ׷ ׉׃גֿךؔـآؙؑزך酅ח֮׷圓鸡׾Mapהㄎע Hidden Class

  56. const pointA = {x: 0, y: 0};! const pointB =

    {x: 0, y: 0};! // pointA.Map === pointB.Map;! ! const pointC = {y: 0, x: 0};! // pointA.Map !== pointC.Map! ! const point3D = {x: 0, y: 0, z: 0};! // point3D.Map !== pointA.Map!
  57. class PointA {! constructor() {! this.x = 0;! this.y =

    0;! }! }! const pointAInstance = new PointA();! ! class PointB {! constructor() {! this.y = 0;! this.x = 0;! }! }! const pointBInstance = new PointB();! // PointAInstance.Map !== PointBInstance.Map!
  58. Layout Mapؔـآؙؑزכַז׶⿑㺘חفٗػذ؍ךoffset׾ثؑحؙ ׅ׷׋׭ծٔذٕٓךⴱ劍⻉갫٥فٗػذ؍ךⴱ劍⻉갫٥فٗػ ذ؍ך侧ָ麩ֲהⴽךMapָⶴ׶䔲ג׵׸׷ Hidden Class

  59. Map Transition ׃ַ׃فٗػذ؍ך㟓幾ָ걼籕ח饯ֿ׷Javascriptדծ嫣㔐Map ׾欰䧭ׅ׷ה؝أزָ搀鋔דֹזְךדכ V8כفٗػذ؍ך㟓幾ָ֮׏׋㜥さחכMap׾Ⱏ剣׃זָ׵ծ 㟓ִ׋鿇ⴓך׫ך倜׃ְMap׾欰䧭ׅ׷ ֿ׸׾Map Transitionהㄎע Hidden Class

  60. function Point(x, y) { this.x = x; this.y = y;

    } Map FixedArray [ {x: {offset: 0}}, {y: {offset: 1}}, ] var x = new Point(1, 1); x.z = 1; Map FixedArray [ {z: {offset: 2}} ] transition {z: transi>on(address)}
  61. What's Happening? Hidden Classָ֮׷ה⡦ָ㴍׃ְַהְֲהծ ؔـآؙؑزךفٗػذ؍،ؙإأװ㘗ךثؑحؙ׾״׶넝鸞חծ ״׶㸜Ⰻח遤ִ׷״ֲחז׷ Hidden Class

  62. Inline Caching

  63. What is Inline Caching فٗػذ؍،ؙإأך넝鸞⻉ך׋׭ח麓⿠ך،ؙإأ׾ٍؗح ءُ׃גֶֻ Inline Caching

  64. function x(obj) {! return obj.x + obj.y;! }! ! x({x:

    0, y: 0});! x({x: 1, y: 1});! x({x: 2, y: 2});!
  65. Search Property ؔـآؙؑزַ׵فٗػذ؍׾䱱ׅ׋׭חכծ HashMapװFixedArrayַ׵فٗػذ؍׾ٗ٦سׅ׷ ׃ַ׃׉׸׾嫣㔐遤ֲךכꬊ䌢ח鹼ְ Inline Caching

  66. Reduce Property Access ֿך⢽דכxהyפך،ؙإأָずׄMap׾䭯אؔـآؙؑزח㼎 ׃ג⡦䏝׮㹋遤ׁ׸גְ׷ ׅדחobjכ{x, y}ךMapה׻ַ׏גְ׷ךד֮׸לծ 䔲搫ًٌٖٔ؎،ؐز׮׻ַ׏גְ׷ךדծ湫䱸offset׾䭷㹀׃ ג،ؙإأ׃׋קֲָ傍ְ Inline

    Caching
  67. Cache זךדծ暴㹀ךMapך،ؙإأ׾鎸䥉׃גֶֻ ֮׷فٗػذ؍פ،ؙإأ׃׋㜥さծ׉ךMapؔـآؙؑز׾鎸 䥉ׅ׷ֿהד2㔐湡⟃꣬ךفٗػذ؍،ؙإأָ넝鸞⻉ׁ׸׷ Inline Caching

  68. x({x: 0, y: 0});! // uninitialized! x({x: 1, y: 1});!

    // stub_call! x({x: 2, y: 2});! // found ic! x({x: 1, y: 1, z: 1})! // load ic miss! x({x: 1, y: 1, foo() {}});! // load ic miss!
  69. Cache Miss ׋׌׃ծMapָ㢌⻉׃׋㜥さחכ䔲搫CacheךMissؼحزָ饯ֹ ׷ךדծת׋فٗػذ؍׾ٗ٦س׃ג倜׋ח鎸䥉׃湫ׅ ׋׌׃ׅץג׾鎸ꐮׅ׷ךכ♶〳腉זךדծ4אתדMapؔـ آؙؑز׾鎸ꐮׅ׷ Inline Cache

  70. Cahce State ٍؗحءُך朐䡾כ⟃♴ך״ֲח鼂獳ׅ׷ PreMonomorphic Monomorphic Polymorphic Megamorphic Inline Caching

  71. Pre Monomorphic ؝٦س♳ך鿪さד劢ⴱ劍ַוֲַⴻ㹀ׅ׷׋׭ח㶷㖈ׅ׷ךדծ ֮ת׶䠐㄂כזְ Inline Caching

  72. Monomorphic ⽃♧ךMapפך،ؙإأ׃ַ㶷㖈׃זְ朐䡾 椚䟝涸ז朐䡾ה鎉ִ׷ Inline Caching

  73. Polymorphic MapָFixedArrayח呓秛ׁ׸גֶ׶醱侧ךMapַ׵嗚稊׃ג فٗػذ؍،ؙإأ׾㹋遤ׅ׷ ٍؗحءُ荈⡤כׁ׸גְ׷ךדת׌넝鸞 Inline Caching

  74. Megamorphic ֮ת׶חMissָ㢳ְךדծMapך鎸ꐮ׾⨡姺׃׋朐䡾 איחStubַ׵GetProperty׾ㄎן⳿׃גفٗػذ؍׾《䖤ׅ׷ 剑׮鹼ְ朐䡾 Inline Caching

  75. Optimization

  76. Hot or Small 䌢ח؝٦س׾剑黝⻉ׅ׷ךכꬊ䌢ח搀꼽 ⟃♴ך勴⟝ח䔲גכת׷؝٦س׾剑黝⻉ׅ׷ •  (ꟼ侧ךغ؎ز؝٦سꞿ/ 1200) + 2ך㔐侧ꟼ侧ָㄎן⳿ׁ׸

    גְ׷ •  ꟼ侧ָ㼭ְׁ(غ؎ز؝٦سךꞿָׁ90劢弫) Optimization
  77. Optimization Budget غ؎ز؝٦س㹋遤⚥חぐꟼ侧חכ剑黝⻉✮皾ָⶴ׶䮶׵׸גֶ׶ծ ׉ך⦼ָ0׾ⴖ׷ה؝٦س剑黝⻉⦪酡הז׷ Optimization

  78. For loop ٕ٦فדכJumpLoopהְֲغ؎ز؝٦سָ⳿⸂ׁ׸׷ ֿךJumpLoopך⚥ד䨱׶⯓ך،سٖأ⦼ךoffset׾ꅾ׫ח׃גծ ⯓玎ך✮皾ַ׵⦼׾䒷ֹծ׉׸ָ0׾ⶴ׏׋׵ٕ٦فⰻך剑黝⻉ ָ涪欰ׅ׷ Optimization

  79. function id(v) {return v;}! function x(v) {! for (var i

    = 0; i < 10000; i++) {! id(v + i);! }! }! x(1);!
  80. 0x1bb9e5e2935e LdaSmi.Wide [1000] 0x1bb9e5e2937e JumpLoop [32], [0] (0x1bb9e5e2935e @ 4)

    Bytecode length = 100 if (budget –= 100 < 0) { OptimizeAndOSR(); }
  81. OSR - OnStackReplacement ؝ٝػ؎ׁٕ׸גغ؎ز؝٦سַ׵堣唒铂ח㢌䳔ׁ׸׋؝٦سכծ ٕ٦فך鷿⚥ד굲ן⯓ָ剅ֹ䳔ִ׵׸ג倜׋ז堣唒铂ך؝٦سָ 㹋遤ׁ׸׷ Optimization

  82. For function ꟼ侧ך㜥さכReturnغ؎ز؝٦سָ䗳׆欰䧭ׁ׸׷ ׉ֿדInterruptָ遤׻׸ג✮皾ךثؑحָؙ涪欰ׅ׷ Optimization

  83. function x() {! const x = 1 + 1;! }!

    x();!
  84. 0x3d22953a917a StackCheck 0x3d22953a9180 Return Bytecode length 30 if (budget -=

    30 < 0) { OptimizeConcurrent(); }
  85. Concurrent Compilation ꟼ侧׾剑黝⻉ׅ׷㜥さכծ⚛⴨؝ٝػ؎ָٕꬊず劍ח遤׻׸׷ ׉ך׋׭如㔐⟃꣬ךꟼ侧ㄎן⳿׃ָ䗳׆剑黝⻉ׁ׸גְ׷׻ֽד כזְ Optimization

  86. CompilationQueue CompilationJob CompilationJob CompilationJob Hot Function Bytecode Called Hot Function(Queued)

    Bytecode Called Hot Function(Queued) Bytecode Called Optimized Function Assembly Called
  87. const x = x => x;! const y = ()

    => {! for (let i = 0; i < 1000; i++) {! x(i);! }! ! for (let i = 0; i < 1000; i++) {! x(i);! }! };! y();!
  88. 0x13b567fa924e LdaSmi.Wide [1000] 0x13b567fa9268 JumpLoop [26], [0] (0x13b567fa924e @ 4)

    Bytecode length 26 budget –= 26 0x13b567fa926e LdaSmi.Wide [1000] 0x13b567fa9288 JumpLoop [26], [0] (0x13b567fa926e @ 36) Bytecode length 26 budget –= 26 0x13b567fa928c Return budget –= all_bytecode_length
  89. Budget for function ׋הִٕ٦فָⴓⶴׁ׸גְג׮Ⰻ⡤ך✮皾׾Returnד׮鎘皾ׅ ׷ךד㉏겗זֻ剑黝⻉ָ遤׻׸׷ Optimization

  90. TurboFan

  91. What is TurboFan? TurboFanהכV8ך剑黝⻉أةحؙךֿה V8כBytecodeַ׵剑黝⻉؝ٝػ؎ٕ׾遤ֲ㜥さחծ ♧傉IR׾欰䧭ׅ׷ ֿךGraph欰䧭ה剑黝⻉׾遤ֲךָTurboFan TurboFan

  92. Bytecode IR TurboFan Optimization & CodeGeneration

  93. IR 䬄韋涸ז㹋遤ـٗحؙ Control Flow Graph TurboFan

  94. #22:Branch[None](#21:SpeculativeNumberLessThan, #9:Loop) #28:IfTrue(#22:Branch) #30:JSStackCheck(#11:Phi, #32:FrameState, #21:SpeculativeNumberLessThan, #28:IfTrue) #33:JSLoadGlobal[0x2f3e1c607881 <String[1]: a>,

    1] (#11:Phi, #34:FrameState, #30:JSStackCheck, #30:JSStackCheck) #2:HeapConstant[0x2f3e1c6022e1 <undefined>]() #39:FrameState #36:StateValues[sparse:^^](#12:Phi, #33:JSLoadGlobal) #37:FrameState#35:Checkpoint(#37:FrameState, #33:JSLoadGlobal, #33:JSLoadGlobal) #38:JSCall[2, 15256, NULL_OR_UNDEFINED] (#33:JSLoadGlobal, #2:HeapConstant, #11:Phi, #39:FrameState, #35:Checkpoint, #33:JSLoadGlobal) #9:Loop(#0:Start, #38:JSCall)
  95. Optimization TurboFanכGraphח㼎׃ג剑黝⻉׾遤ֲ TurboFan

  96. inline ꟼ侧ㄎן⳿׃ךInline⻉ trimming ⵋ麦׃זְNodeך⵴ꤐ type 㘗䱿锷 typed-lowering 㘗ח㛇בְג䒭װㄏ⟀׾״׶知⽃זⳢ椚ח縧ֹ䳔ִ׷ loop-peeling ٕ٦فⰻךⳢ椚׾㢩ח⳿ׅկ

  97. loop-exit-elimination LoopExit׾⵴ꤐ load-elimination 搀꼽ז⦼ך铣׫⳿׃װcheck׾⵴ꤐ simplified-lowering ״׶Ⱗ⡤涸ז⦼דㄏ⟀׾ءٝفٕח㢌䳔ׅ׷ generic-lowering JSفٖؿ؍حؙأך➰ֻㄏ⟀׾״׶ءٝفٕזㄎן⳿׃װ stubךㄎן⳿׃ח㢌䳔ׅ׷ dead-code-elimination

    ⵋ麦♶腉؝٦سך⵴ꤐ
  98. Code generation 剑穄涸חInstructionSelectorהְֲؙٓأָregisterךⶴ➰׾遤 ְծ ֿךؚٓؿַ׵CodeGeneratorָ堣唒铂׾欰䧭׃ג PC(ProgramCounter)ח،إٝـٔ׾剅ֹ⳿׃גְֻ Optimization

  99. Deoptimization

  100. What is Deoptimization? Deoptimization(膴剑黝⻉)הכ剑黝⻉׃׋Assembly؝٦سח✮劍 ׇט⦼ָ床׏׋㜥さחծⱄ䏝؝ٝػ؎ٕ׃湫ׅ堣腉 ׮׍׹׿㼰זְח馉׃׋ֿהכזְ Deoptimizationָ涪欰ׅ׷⢽׾然钠׃ג׫״ֲ Deoptimization

  101. 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});!
  102. Wrong Map ➙ך⢽דכ剑ⴱח{x}ךMapח㼎׃ג剑黝⻉ׁ׸׋Assembly׾⳿ ⸂׃׋ָծ ✳㔐湡ךㄎן⳿׃ָ{x,y}ךMap׌׏׋׋׭חծⱄ؝ٝػ؎ٕ׾⡭ ⭑זֻׁ׸ג׃ת׏׋ ׍׳׏ה׌ֽAssembly׾鋖ְג׫״ֲ Deoptimization

  103. 0x451eb30464c 8c 48b9f1c7d830391e0000 REX.W movq rcx, 0x1e3930d8c7f1 0x451eb304656 96 483bca

    REX.W cmpq rcx,rdx 0x451eb304659 99 0f8591000000 jnz 0x451eb3046f0 ;; Check Map!! ... 0x451eb3046f0 130 e81ff9cfff call 0x451eb004014 ;; deoptimization bailout 2
  104. Bailout ֿך״ֲח⳿⸂ׁ׸׋؝٦سחMap׾然钠ׅ׷؝٦س׮ろת׸ג ְ׷ Deoptimizationָ遤׻׸׷ה؝٦سכBytecode㹋遤ח䨱׷ָծ ֿ׸׾Bailoutהㄎע Deoptimization

  105. Summary ⟃♳ָV8ָJS׾㹋遤ׅ׷䊨玎ד֮׷ 儗꟦ך鿪さ♳GCכ満ְ׋ V8ך؝٦سٔ٦ر؍ؚٝך䪮遭瘝כת׋ـؚٗח剅ֻ✮㹀 http://abcdef.gets.b6n.ch/ ׀幠耮֮׶ָהֲ׀ְׂת׃׋