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

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

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

V8 javascript engineがjavascriptをどのように処理しているかの解説。

More Decks by Taketoshi Aono(青野健利 a.k.a brn)

Other Decks in Programming

Transcript

  1. V8
 javascript engine

  2. せ⵸: @brn (ꫬꅿ⨳ⵃ) 耵噟: ؿٗٝزؒٝسؒٝآص،٥ط؎ذ؍ـؒٝآص، ⠓爡: Cyberagent ،سذؙأةآؔRightSegment٥AI Messenger ـؚٗ:

    http://abcdef.gets.b6n.ch/ Twitter: https://twitter.com/brn227
  3. V8הכ V8הכGoogleָ㹋鄲׃׋javascriptؒٝآٝדծ Google Chromeךjavascriptؒٝآٝח䱰欽ׁ׸גְתׅկ

  4. V8הכ V8ך暴䗙 •  넝鸞 •  Hidden Classהְֲⰻ鿇㘗ءأذي •  Inline Caching

    •  ⚅➿ⴽך؝ٖٝؕٝز٥؎ًؙٝٔٝةٕGC •  غ؎ز؝٦س؎ٝة٦فٔة׾ⰻ詿2016䎃劣 •  㼎䘔CPUכMipsծArmծX64ծX86٥7
  5. V8הכ 劤傈כծ javascriptָا٦أ؝٦سַ׵㹋遤ׁ׸׷תדך麣ך׶׾ծד ֹ׷׌ֽ铡僇׃תׅկ ׋׌ծ♧א♧אך갪湡ָ׉׸׌ֽדꞿְ儗꟦ֶ鑧דֹג׃ת ֲ״ֲזⰻ㺁ךזךדծ➙㔐כ謬ֻ䎢ֻ鑧׃״ֲה䙼ְתׅկ ⰻ㺁ָ崮ְַ׮׃׸תׇ׿ָ׀㺁饘ֻ׌ְׁկ⯜顑✲갪

  6. V8 Code base V8ך؝٦سك٦أך遤侧כծا٦أؿ؋؎ٕך׫דծ 秈108♰遤،٦ؗذؙثٍ㔿剣ך؝٦سろ׬֮׶תׅկ 鎉铂כC++ד鎸鶢ׁ׸גֶ׶ծوؙٗ׮㿊קו֮׶תׅկ 铣׬ך鳞ְ…

  7. V8ך㹋遤ך崧׸ Source AST Bytecode Graph Assembly

  8. Parsing ת׆ծV8כا٦أ؝٦س׾ػ٦أ׃גASTח㢌䳔׃תׅկ ASTהכAbstractSyntaxTreeך殛ד䬄韋圓俑加הㄎל׸תׅկ

  9. Abstract Syntax Tree if (x) { x = 100 }

  10. Abstract Syntax Tree IF CONDITION THEN BLOCK EXPRESSION STATEMENT ASSIGN

    VAR PROXY (X) LITERAL (100) if  (x)  {  x = 100 
  11. Parsing ׃ַ׃ծWebل٦آ׾Ꟛְ׋ة؎ىؚٝדjavascript׾Ⰻ鿇 ػ٦أ׃גخٔ٦׾⡲׷ךכ鹼ֻזְד׃׳ֲַ

  12. Parsing 鹼ְדׅկ זךדծV8כ鹼䒀ػ٦أ׾遤ְתׅկ

  13. Lazy Parsing function x() {return 1;} FUNCTION(X)

  14. Lazy Parsing function x() {return 1;} x() FUNCTION NAME (x)

    RETURN LITERAL(1)
  15. Lazy Parsing ֿך״ֲחծV8כ㹋ꥷחㄎן⳿ׁ׸׷תדػ٦أ׾鹼䒀׃תׅկ ֿך鹼䒀כꟼ侧⽃⡘ד遤׻׸תׅկ

  16. PreParsing ׋׌׃ծ㸣Ⰻחׅץג׾鹼䒀ػ٦أׅ׷׻ֽדכ֮׶תׇ׿կ v8::internal::PreParserؙٓأָ♧䏝ꟼ侧ך،ؐزٓ؎ٝ׾ػ٦ أ׃תׅկ ֿ׸ח״׏גծ •  ✲⵸ך俑岀ؒٓ٦ثؑحؙ •  ꟼ侧ךأ؝٦ف欰䧭 瘝׾遤ְתׅկ

  17. Dive into Parsing V8ךParsingחאְגכ׉׸׌ֽד涪邌דֹ׷ֻ׵ְ帾ְ㉏겗דծ https://docs.google.com/presentation/d/1b- ALt6W01nIxutFVFmXMOyd_6ou_6qqP6S0Prmb1iDs/present? slide=id.p חꟚ涪罏ךأٓ؎سָ֮׶תׅךדծ׉׍׵׾⿫撑կ

  18. Abstract Syntax Tree ׁגծֿ׸ד㹋ꥷחػ٦أ׾遤׏גְֹתׅկ ׍ז׫חծV8כ䩛剅ֹדػ٦؟٦׾鎸鶢׃גֶ׶ծyaccװlexהְ׏׋ ؝ٝػ؎ٓ؝ٝػ؎ٓ׾ⵃ欽׃גְתׇ׿կ ⱄ䌓♴꣬圓俑鍑匿岀דػ٦أ׃גְתׅկ

  19. AST Rewriter V8ךASTחꟼ׃ג׍׳׏ה꬗涯ְ㹋鄲׾鋅אֽ׋ךדծ 腜麣דָׅծ铡僇׃תׅկ

  20. AST Rewriter javascriptך圓俑דծSpreadؔلٖ٦ة٦הְֲ圓俑ָ֮׶ת ׅկ var x = [1,2,3]; var y

    = […x]; V8כֿך圓俑׾AltJSךزٓٝأػ؎ٓך圫חⰋֻⴽך圓俑ח 剅ֹ䳔ִג׃תְתׅկ
  21. AST Rewriter do { $R = []; for ($i of

    x) %AppendElement($R, $i); $R } // src/parsing/parser.cc ֿך״ֲחծ瘝⣣ךdo圓俑הfor-of圓俑ח剅ֹ䳔ִ ג׃תְתׅկ
  22. Abstract Syntax Tree ׁגծػ٦أָ㸣✪׃ծASTך欰䧭ָ㸣✪׃ת׃׋կ V8ךASTד暴䗙涸זךכծ 㹋ꥷך鎉铂圓鸡הوحث׃זְAST׾欰䧭ׅ׷挿דׅկ וְֲֲֿהַהְֲה…

  23. Abstract Syntax Tree var x = 100

  24. Abstract Syntax Tree var EXPRESSION STATEMENT CALL RUNTIME [IniOalizeVarGlobal] LITERAL

    (x) LITERAL (100) x 100 ?
  25. Abstract Syntax Tree V8כRuntimeㄎן⳿׃瘝ךC++ךㄎן⳿׃׾ծ ⟎䟝ךASTה׃גAST欰䧭儗挿ד欰䧭׃ג׃תְתׅկ

  26. AST to Bytecode ASTך欰䧭ָ㸣✪׃׋֮הכծ 欰䧭׃׋ASTַ׵Bytecode׾欰䧭׃תׅկ V8ךBytecodeכ劤䔲ח1Byteד邌植ׁ׸׷⟎䟝ㄏ⟀דׅկ ׉׃גծ׉ךBytecode׾㹋遤ׅ׷VM׾Ignitionהㄎןתׅկ

  27. Igniton V8חכIgnitionהㄎל׸׷Bytecode؎ٝة٦فٔةָ㹋鄲ׁ׸ גְתׅկ 㹋כֿך؎ٝة٦فٔةכ剑鵚㹋鄲ׁ׸׋לַ׶ך׮ךדծ ׍׳׏ה⵸תדכASTַ׵،إٝـٔ׾湫ח⳿⸂׃גְת׃ ׋կ

  28. Igniton Ignitionכٖآأةك٦أךغ؎ز؝٦س؎ٝة٦فٔةדծCPUךٖآ أةח㹋ꥷח⦼׾ⶴ׶➰ֽג㹋遤׃תׅկ  IgnitionכBytecodeHandlerהㄎל׸׷غ؎ز؝٦سⳢ椚ꟼ侧׾✮׭欰䧭 ׃גֶֹծغ؎ز؝٦سַ׵ꂁ⴨ך؎ٝرحؙأ׾《䖤ծ ׉ך؎ٝرحؙأח欰䧭ׁ׸׋،إٝـٓ׾ⶴ׶䔲גגծBytecodeךꂁ ⴨׾如ղ䊡㔐׃זָ׵ծ㼎䘔ׅ׷؎ٝرحؙأך،إٝـٓ׾ㄎן⳿׃ ؝٦س׾㹋遤׃תׅկ

  29. Igniton ז׷קוծ׻ַ׵׿

  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. Igniton Dispatch Table 00 01 02 04 08 0f 10

    10 Node Node Node MachineCode MachineCode IGNITION_HANDLER Entry Function(Machine Code) グラフからコードを生成 生成したコードを、 DispatchTableの対応する バイトコードのインデックスへ 登録
  32. Igniton Ignitionכغ؎ز؝٦سך欰䧭׾ASTַ׵遤ְתׅկ V8כAST׾䊡㔐ׅ׷倯岀ה׃גծv8::internal::AstVisitor<Subclass> הְֲ㛇䎿ؙٓأ׾欽䠐׃גְתׅկ AstVisitorךせך鸐׶ծVisitorػة٦ٝ׾ⵃ欽׃גAST׾䊡㔐׃ծⳢ 椚׾遤׏גְֹתׅկ

  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. Igniton 欰䧭ׁ׸׋BytecodeכBytecodeArrayהㄎל׸׷ꂁ⴨ח呓秛ׁ׸ת ׅկ 㹋遤儗חכֿךBytecodeArray׾׋ו׏ג㹋遤ׅ׷ֿהחז׶תׅկ

  35. Igniton Dispatch Table Entry Function(Machine Code) BytecodeArray Dispatch Tableから対応するHandlerを取り出して実行 0

    1 3 4 5 6 7 8 8 6 1
  36. Code Generation V8חכְֻאַך،إٝـٓ欰䧭皘䨽ָ֮׶תׅկ 㣐ⴽׅ׷ה⟃♴חז׶תׅկ CodeStub Builtins Runtime BytecodeHandler

  37. Code Generation Bytecodeַ׵،إٝـٓ׾㹋遤ׅ׷ךכ׻ַ׶ת׃׋ָծ Bytecodeַ׵㼎䘔ׅ׷،إٝـٓכוך״ֲח欰䧭׃גְ׷ךד׃׳ֲַ BytecodeHandlerהכוך״ֲז׮ךזךד׃׳ֲַ

  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. Code Generation ֿ׸ծ㹋כ㹋ꥷחכ㹋遤ׁ׸תׇ׿կ וְֲֲֿהַהְֲהծֿך؝٦سכ㹋遤ׁ׸׷הծ 㹋遤✮㹀ךGraph׾欰䧭ׅ׷׌ֽדׅկ

  40. Code Generation 㹋ꥷךC++؝٦سך崧׸הכ麩ֲDSL鎉铂דؚٓؿָ㹋鄲ׁ׸גְתׅկ

  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. Code Generation דכ㹋ꥷח،إٝـٓ׾⳿⸂ׅ׷ךכוֿזךַהְֲהծ MacroAssemblerהְֲؙٓأָ׉ך䕵ⶴ׾䬐׏גְתׅկ MacroAssemblerכ؎ٝة٦ؿؑ٦أכ،٦ؗذؙثٍ杝甧דָׅծ׉ך ⰻ鿇דㄎ׿דְ׷Assemblerؙٓأָぐ،٦ؗذؙثٍ㔿剣ך؝٦س׾ ⳿⸂׃תׅկ V8דכ㹋ꥷmasmהְֲفٗػذ؍せדMacroAssemblerָ걼⳿׃תׅկ

  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. Code Generation ׉׃ג剑穄涸חכծ GraphResolver׾㹋鄲׃׋CodeGeneratorؙٓأָGraph׾䊡㔐׃גծ MacroAssembler穗歋דAssembler׾ㄎן⳿׃ծ،إٝـٓ׾⳿⸂׃תׅկ

  45. Code Generation ׋׌׃ծMacroAssemblerכ剑穄涸ז؝٦س⳿⸂ד֮׏גծ Graphⰻח⯋חז׷䬄韋⻉ׁ׸׋ؔل؝٦سָ㙵׭鴥ת׸תׅկ ⟃♴ךꥡ㾴דծ،٦ؗذؙثٍ㔿剣ךGraphָ欰䧭ׁ׸תׅկ •  CodeStubAssembler •  CodeAssembler • 

    RawMachineAssembler •  MachineOperatorBuilder ♴ח遤ֻקוⰧ⡤涸זㄏ⟀חז׶תׅկ
  46. Code Generation e.x Load CodeStubAssembler::Load CodeAssembler::raw_assembler()->Load() RawMachineAssembler::Load AddNode(MachineAssembler::Load()) Graph Leaf

    Node
  47. Optimization ׁגծֿ׸דjavascript׾㹋遤ׅ׷彊⪒ָדֹת׃׋կ ׃ַ׃ֿ׸ד넝鸞זjavascript׾㹋遤ׅ׷ֿהָדֹ׷ד׃׳ֲַ 鸐䌢ծ⹛涸鎉铂ד֮׷javascriptכ㘗ח暴⻉׃׋Ⳣ椚׾遤ֲֿהָד ֹתׇ׿կ ׉ֿדծV8כ㹋遤儗ח暴ח걼籕ח㹋遤ׁ׸׷皘䨽ך㘗׾暴㹀ծ؝٦ س׾䊴׃剏ִתׅկֿ׸׾JIT(آٍأز٥؎ٝ٥ة؎ي)؝ٝػ؎ٓ הㄎןתׅկ

  48. Optimization V8ך剑黝⻉חכ㣐ֹֻⴓֽג3珏겲֮׶תׅկ •  Hidden Class •  Inline Caching •  TurboFan

  49. Hidden Class javascriptחכאְ剑鵚תדclassכ֮׶תׇ׿ד׃׋կ ׉ך➿׻׶prototypeהְֲ➬穈׫ד毟⡂ؙٓأ׾ⱄ植׃גְת׃׋կ ת׋ծ圓鸡⡤׮֮׶תׇ׿կ ׉׮׉׮㘗ָזְךדծ •  ؔـآؙؑزךًاحس׾ㄎן⳿ׅ •  فٗػذ؍ח،ؙإأׅ׷կ

    ֿ׸׵ךⳢ椚ך穠卓כ䌢ח♧㹀הכꣲ׶תׇ׿կ
  50. Hidden Class ׉ֿדV8כؔـآؙؑزךٖ؎،ؐزח岣湡׃ת׃׋կ ⢽ִלծ function Point(x, y) { this.x =

    x; this.y = y }; var point = new Point(1, 1); ֿ׸׾Point㘗ה׃ג钠陎ׅ׷׋׭חⰻ鿇ד㘗׾䭯׏גְתׅկ
  51. Map V8דכ •  ずׄفٗػذ؍せ •  ずׄ㘗 •  ずׄ갫䎷 ד㹀纏ׁ׸׋㜥さכずؙׄٓأה׫זׅ״ֲחׅ׷׋׭ծMapהְ ֲ嚊䙀׾䭯׍鴥׫ת׃׋կ

    ֿךMapכؔـآؙؑز欰䧭儗ծؙٓأד֮׸ל؝ٝأزؙٓة㹋 遤㸣✪儗ח欰䧭ׁ׸ծؔـآؙؑزךٖ؎،ؐز׾⥂䭯׃תׅկ ずׄ圓鸡ד֮׸לծずׄMapָⰟ剣ׁ׸תׅկ
  52. Map function Point(x, y) { this.x = x; this.y =

    y; } Map FixedArray [ {a: {offset: 0}}, {b: {offset: 1}} ]
  53. Map ׃ַ׃ծjavascriptדכفٗػذ؍ָ㢌⻉ׅ׷ֿהכ傈䌢蘠궢✲דׅկ ׉ך㜥さכוֲׅ׷ךד׃׳ֲַ

  54. Map Transition فٗػذ؍ך㟓幾ח״׏גؔـآؙؑزךٖ؎،ؐزָ㢌⻉׃׋㜥 さծV8כtransitionהְֲⳢ椚׾遤׏גծ麓⿠ךMap׾竰䪫׃׋倜׋ זMap׾欰䧭׃תׅկ

  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. Inline Caching Inline Cachingהכفٗػذ؍ٕحؙ،حف׾넝鸞⻉ׅ׷׋׭ך 剑黝⻉䩛岀דׅկ

  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. Inline Caching 初回 V8 add Receiver Map Cached address 1.

    Search 2. Check 4. Cache 3. Call
  59. Inline Caching 二回目以降 V8 add Receiver Map Cached address 1.

    Search and Call
  60. Inline Caching Inline Cachingחכ⟃♴ך4אך朐䡾ָ֮׶תׅկ •  Premonomorphic •  Monomorphic •  Polymorphic

    •  Megamorphic
  61. Premonomorphic Premonomorphicהכⴱ㔐ךICךة؎ىؚٝך朐䡾ד鏣㹀ׁ׸תׅկ ֿךة؎ىؚٝדכ剑鸞ךػأדכזֻ⡚鸞ךStubָ؝٦سח鏣㹀 ׁ׸תׅկ

  62. Monomorphic MonomorphicהכReceiverך㘗ָ♧㹀ך؛٦أך㜥さךICדׅկ ֿך㜥さכ♧אךٍؗحءُדׅ׬ךדծ剑鸞ך؛٦أחז׶תׅկ

  63. Polymorphic PolymorphicהכReceiverך珏겲ָ珏겲⟃♳ך؛٦أד鏣㹀ׁ׸ת ׅկPolymorphicכぐMapַ׵ٕ٦فדٍؗحءُ׾䱱׃⳿ׅךדծ Monomorphic״׶כ⡚鸞דָׅծICז׃״׶כ黓ַח넝鸞דׅկ

  64. Megamorphic Megamorphicכ֮ת׶חىأوحثָ㢳ְ㜥さך؛٦أדׅկ ٍؗحءׁُ׸׋؝٦س׾عحءُذ٦ـַٕ׵䱱稊׃תׅկ ֿך䱱稊כׅץג،إٝـٓד遤׻׸תׅկ

  65. (Load/Store)IC_Miss LoadIC_MissהStoreIC_MissכICחوحث׃זַ׏׋㜥さַծⴱ㔐ח ㄎל׸ծC++ךٓٝة؎ي׾穗歋׃גؔـآؙؑزךفٗػذ؍׾ 《䖤׃תׅկ

  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. Optimized Compilation V8כ䌢ח剑鸞ך؝٦س׾⳿⸂ׅ׷׻ֽדכ֮׶תׇ׿կ ⴱ㔐כ䗳׆ծBytecode穗歋ד㹋遤ׁ׸׷Genericז؝٦سָ㹋遤ׁ ׸׷׋׭ծRuntimeㄎן⳿׃׮㢳ֻ⡚鸞ז؝٦سָ㢳ְדׅկ ׉ך׋׭ծ㹋遤׾湊鋔׃ծقؽ٦ח㹋遤ׁ׸׷皘䨽׾剑黝⻉׃תׅկ

  68. Hot Spot V8ָ⚺ח湊鋔׃גְ׷ךָծ •  ٕ٦ف •  ꟼ侧ך㹋遤 דׅկ

  69. Loop Tracing قؽ٦זٕ٦ف׾鋅אֽ׷הծV8׾׉ך鿇ⴓ׾剑黝⻉׃׋؝٦سד 縧ֹ䳔ִתׅկ ֿךꥷծV8כOnStackReplacementהְֲ䩛岀׾ⵃ欽׃גٕ٦ف ؝٦س׾剑黝⻉׃תׅկ

  70. On Stack Replacement for (let i = 0; i <

    10000; i++) { doSomething(i); } JumpLoop LoopHeader SlowCode FastCode PC(فؚٗٓيؕؐٝة)׾縧ֹ䳔ִ׷
  71. Function Call Tracing ꟼ侧ㄎן⳿׃ך㜥さכծIgnitionָ欰䧭ׅ׷Return Bytecodeך BytecodeHandlerⰻדㄎן⳿׃㔐侧׾鎘庠׃ծ׃ְֹ⦼׾馄ִ׋㜥 さכInterrupt׾遤׏גծꟼ侧׾؝ٝػ؎ٕ׃ꟼ侧ךBody׾Ⰵ׸剏ִ תׅկ

  72. Function Interruption function Y() { … } RETURN OP Replace

    Body しきい値チェック
  73. TurboFan V8כ؝٦س׾Graphַ׵欰䧭׃תׅկ ׉ך׋׭ծׅץגך剑黝⻉׮Graphח㼎׃ג遤׻׸ծ خٔ٦ך協ⴘ׶瘝ךؚٓؿ剑黝⻉׮遤׻׸תׅկ ֿ׸׵ך剑黝⻉ػ؎فٓ؎ٝךֿה׾TurboFanהㄎןתׅկ

  74. TurboFan TurboFanך剑黝⻉ٔأزדׅկ •  Loop peeling / Loop elimination •  Escape

    analysis •  Lowering •  Effect and control linearize •  Dead code elimination •  Control flow optimization •  Memory optimization
  75. Deoptimization 剑黝⻉׃׋؝٦سָ䌢ח㹋遤〳腉הכꣲ׶תׇ׿կ Mapָ㢌׻׏׋׶ծ侧⦼ָoverlow׃׋׶ծ0ꤐ皾؝٦س㹋遤ׁ׸׋׶… ׉ך㜥さծV8כ膴剑黝⻉׾遤׏גծ剑黝⻉ׁ׸׷⵸ךBytecodeח䨱׶ תׅկ

  76. Pipeline OpOmize Assembler TurboFan Source AST Parser Bytecode Graph IgniOon

    Compile Optimization Deoptimization
  77. תה׭ ⟃♳ָV8ָا٦أ؝٦سַ׵堣唒铂׾欰䧭ׅ׷䊨玎הז׶תׅկ ➙㔐כGCחכ鍗׸׵׸גְזְדָׅծ V8חכGC׮䊨㣗ָ㢳ְךדծ莆㄂ך֮׷倯כ׈מ鋅ג׫גֻ׌ׁ ְկ ׀幠耮֮׶ָהֲ׀ְׂת׃׋կ