CSS JIT: Just-in-Time Compiled CSS Selectors in WebKit

CSS JIT: Just-in-Time Compiled CSS Selectors in WebKit

In this presentation, we'll show a little bit details of CSS Selector JIT.
Selector Matching is known as heavy CPU-intensive load and it consumes much time when rendering web pages.
Careful observations show that typical CSS Selectors can be compiled into state machines and the form of this is suitable for JIT-compiled code.
We develop CSS Selector JIT compiler that compiles CSS Selector predicates into machine code that represents state machines.
Evaluation using cssquery part of major benchmark Dromaeo exhibits that the performance of CSS JIT compiled selector matching is average 3.0x faster than one of existing highly tuned C++ implementation.

09b5a917b6ea8928e0d5bf8a432412fe?s=128

Yusuke SUZUKI

March 15, 2015
Tweet

Transcript

  1. CSS JIT: Just-in-Time Compiled CSS Selectors in WebKit Yusuke Suzuki

    Twitter: @Constellation <utatane.tea@gmail.com>
  2. Outline • Motivation & Goals • Existing CSS Selector Implementation

    • CSS Selector JIT • Evaluation • Conclusion
  3. Motivation • Web Browser is highly CPU intensive Application •

    CSS Selector is executed frequently – CSS Selector matching is one of the major bottleneck • Style Resolution / QuerySelector – For each node, check selector match/fail over node • Speed of selector matching is important for Rendering / JS (Selectors API) .rabbit.house { … } CSS StyleSheet
  4. Motivation • Web Browser is highly CPU intensive Application •

    CSS Selector is executed frequently – CSS Selector matching is one of the major bottleneck • Style Resolution / QuerySelector – For each node, check selector match/fail over node • Speed of selector matching is important for Rendering / JS (Selectors API) .rabbit.house { … } CSS StyleSheet Selector Matching
  5. QuerySelector implementation • root.querySelectorAll(/* selector */) 1. For each element

    under root 1. Do selector matching with selector and element (SelectorChecker in WebKit / Blink) 2. if matched 1. result.append(element) 2. Return result • querySelectorAll executes selector matching the number of elements times
  6. Goals • Provide faster selector matching – Make style resolution

    faster – Make JS code using QuerySelector faster
  7. Outline • Motivation & Goals • Existing CSS Selector Implementation

    • CSS Selector JIT • Evaluation • Conclusion
  8. Existing CSS Selector Implementation • Highly tuned C++ implementation (WebKit/Blink)

    • SelectorChecker::match • SelectorChecker::matchRecursively • SelectorChecker::checkOne • … recursively call markRecursively (backtracking is needed)
  9. CSS Selector Structure & Terminology • Composed of compound selectors

    – simple selector (e.g. div) + combinator (e.g. >) • Selector is evaluated from-right-to-left span div > div + div compound selectors (div+ div~ div div> span) div ~ descendant child following- sibling next- sibling rightmost http://dev.w3.org/csswg/selectors4/#structure
  10. Evaluation Example • body div span case span div body

    section div span p h3 section body section div div p span Matching starts with this span
  11. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  12. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  13. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  14. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  15. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  16. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  17. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  18. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  19. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  20. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  21. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  22. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  23. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div
  24. Evaluation Example: Matched • body div span case span div

    body section div span p h3 section body section div p span div Matched
  25. Evaluation Example: Failed • body div> span case span div>

    body section div span p h3 section body section div p span div
  26. Evaluation Example: Failed • body div> span case span div>

    body section div span p h3 section body section div p span div
  27. Evaluation Example: Failed • body div> span case span div>

    body section div span p h3 section body section div p span div
  28. Evaluation Example: Failed • body div> span case span div>

    body section div span p h3 section body section div p span div
  29. Evaluation Example: Failed • body div> span case span div>

    body section div span p h3 section body section div p span div
  30. Evaluation Example: Failed • body div> span case span div>

    body section div span p h3 section body section div p span div Failed
  31. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  32. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  33. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  34. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  35. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  36. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  37. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  38. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  39. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  40. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  41. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  42. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  43. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div
  44. Evaluation Example: Backtracking • body> div> div span case •

    When child(xxx>) is failed, backtracking with the closest descendant(xxx) span div> body> div div span body div div div Matched
  45. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  46. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  47. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  48. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  49. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  50. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  51. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  52. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  53. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  54. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  55. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  56. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  57. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  58. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  59. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div
  60. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div Failed Completely Because…
  61. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div Failed Completely Because…
  62. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div Failed Completely Because…
  63. Evaluation Example: Backtracking • section> div div span case •

    When descendant(xxx) is failed, selector matching completely failes. span div section> div div span body div div div Failed Completely Because… Candidates become less
  64. Outline • Motivation & Goals • Existing CSS Selector Implementation

    • CSS Selector JIT • Evaluation • Conclusion
  65. CSS Selector JIT • Just-in-Time compile Selector Matching predicate –

    Provide faster selector matching • Leverage selector’s static data to generate highly optimized machine code
  66. Observations • After moving to the next descendant selector, never

    return to the previous selector – Saving the current execution context over descendant selectors is not necessary • When child selector fails, always starts from the closest descendant selector – Information to perform backtracking is highly limited • DOM Node matching starts with
  67. Design • Compile CSS Selector into State Machine • Move

    over states by x86 jmp – In C++ implementation, recursive function call is used – Avoid functions calls • Store almost all data in registers – Current Element – Backtracking target Element – Others
  68. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span
  69. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL SUCCESS
  70. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL SUCCESS unmatch
  71. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL SUCCESS unmatch Parent
  72. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL SUCCESS unmatch no parent Parent
  73. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent Parent
  74. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent Parent unmatch
  75. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent Parent unmatch Parent
  76. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent no parent Parent unmatch Parent
  77. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent no parent Parent unmatch Parent div
  78. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent no parent Parent unmatch Parent div unmatch (current register is already suitable)
  79. Compiling machine code • Represent CSS Selector Matching with code

    & jumps – Avoid recursive function call (NO CALLS!) – Storing current element to register Example 1: div> div span span FAIL div SUCCESS unmatch no parent no parent Parent unmatch Parent div unmatch (current register is already suitable)
  80. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span
  81. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div P unmatch div P unmatch unmatch no parent
  82. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div P unmatch div P unmatch unmatch no parent save
  83. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div P unmatch div P unmatch unmatch no parent save P
  84. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div P unmatch div P unmatch unmatch no parent save P no parent
  85. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div P unmatch div P unmatch unmatch no parent save P div no parent
  86. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div P unmatch div P unmatch unmatch no parent save P div no parent unmatch backtrack with saved register
  87. Compiling machine code • Storing backtracking element to one register

    Example 2: div> div> div span span FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P div no parent unmatch backtrack with saved register
  88. Compiling machine code • Storing backtracking element to one register

    – Since only one descendant should be considered Example 3: div> div> div div> div> div span span FAIL div P div P unmatch save P div unmatch with saved
  89. Compiling machine code • Storing backtracking element to one register

    – Since only one descendant should be considered Example 3: div> div> div div> div> div span span FAIL div P div P unmatch save P div unmatch with saved div P div P save P div unmatch with saved SUCCESS
  90. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  91. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  92. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  93. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  94. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  95. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  96. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  97. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  98. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  99. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  100. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  101. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  102. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  103. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  104. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  105. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  106. Evaluation Flow Example Example 4: body> div> div span span

    FAIL div SUCCESS P unmatch div P unmatch unmatch no parent save P body no parent unmatch backtrack with saved register div div span body div div Element register Backtracking register Instruction pointer In JIT code
  107. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret
  108. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret span
  109. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret span FAIL
  110. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret span FAIL parent parent
  111. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret span FAIL div parent parent
  112. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret span FAIL div div parent parent
  113. div> div span Code Generated JIT code for CSS Selector

    JIT for "div > div span": Code at [0x7fd031187000, 0x7fd0311870a0): 0x7fd031187000: push %rbp 0x7fd031187001: mov 0x58(%rdi), %rax 0x7fd031187005: mov $0x7fd08c30ec50, %rcx 0x7fd03118700f: cmp %rcx, 0x18(%rax) 0x7fd031187013: jnz 0x7fd031187081 0x7fd031187019: mov 0x20(%rdi), %rdi 0x7fd03118701d: test %rdi, %rdi 0x7fd031187020: jz 0x7fd031187081 0x7fd031187026: test $0x4, 0x1c(%rdi) 0x7fd03118702a: jz 0x7fd031187081 0x7fd031187030: mov 0x58(%rdi), %rdx 0x7fd031187034: mov $0x7fd08c30f670, %rsi 0x7fd03118703e: cmp %rsi, 0x18(%rdx) 0x7fd031187042: jnz 0x7fd031187019 0x7fd031187048: mov 0x20(%rdi), %rdi 0x7fd03118704c: test %rdi, %rdi 0x7fd03118704f: jz 0x7fd031187081 0x7fd031187055: test $0x4, 0x1c(%rdi) 0x7fd031187059: jz 0x7fd031187081 0x7fd03118705f: mov 0x58(%rdi), %r8 0x7fd031187063: mov $0x7fd08c30f670, %r9 0x7fd03118706d: cmp %r9, 0x18(%r8) 0x7fd031187071: jnz 0x7fd031187019 0x7fd031187077: mov $0x1, %eax 0x7fd03118707c: jmp 0x7fd031187083 0x7fd031187081: xor %eax, %eax 0x7fd031187083: pop %rbp 0x7fd031187084: ret span FAIL div div parent parent SUCCESS
  114. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  115. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  116. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  117. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  118. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  119. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  120. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  121. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  122. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  123. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  124. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul
  125. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul Done
  126. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul But Ideal Backtracking is…
  127. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul But Ideal Backtracking is…
  128. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul But Ideal Backtracking is…
  129. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul But Ideal Backtracking is…
  130. More intelligent backtracking • Leveraging this static information, provide more

    intelligent backtracking – This is my largest contribution to WebKit CSS JIT Example 4: ul> li> p span span li> ul> p ol span li li p p ul But Ideal Backtracking is…
  131. Computing Backtracking height • Pre-compute appropriate backtracking height Example 4:

    ul> li> p span span li> ul> p pre-tag height 0 2 1 0 1 2 span FAIL p SUCCESS P unmatch li P unmatch unmatch no parent save P ul no parent unmatch backtrack with saved register
  132. Computing Backtracking height • Pre-compute appropriate backtracking height Example 4:

    ul> li> p span span li> ul> p pre-tag height 0 2 1 0 1 2 span FAIL p SUCCESS P unmatch li P unmatch unmatch no parent P ul no parent unmatch
  133. Implementation Status • Almost all selectors are already supported –

    Indirect/direct adjacent – ::pseudo-element – :visited – :matches(…, nested complex selector) (Selectors Level4) – :not(…, nested complex selectors) (ditto) • They are highly used in some user extensions – Etc.
  134. Outline • Motivation & Goals • Existing CSS Selector Implementation

    • CSS Selector JIT • Evaluation • Conclusion
  135. Experimental Setup • MacBook Pro Late 2011 – 4 cores

    Intel Core i7 2860QM CPU @ 2.50GHz – 8GB RAM • Softwares – OSX Yosemite 64bit – WebKit revision 181499 • Benchmarks – Dromaeo cssquery tests in WebKit PerformanceTests • Dromaeo/cssquery-dojo.html • Dromaeo/cssquery-jquery.html • Dromaeo/cssquery-prototype.html • Schemes – CSS JIT / baseline – To give a fair comparison, I’ve created the patch that enables some pruning paths in baseline • In the latest WebKit, there’s a little pruning path which is only enabled in CSS JIT enabled • https://bugs.webkit.org/show_bug.cgi?id=142703
  136. Evaluation – cssquery-dojo – Relative improvements • Except for fast-path

    case, 3.071x faster on average – This result is very early report, I’ll re-investigate carefully • Some selectors doesn’t show any improvement – They’re simple enough to use specialized (non-JIT) path 1.009 3.148 2.998 3.227 1.025 3.147 0.975 3.225 2.942 3.035 3.183 3.099 3.116 1.739 0.969 3.217 4.758 3.136 0.993 3.158 3.123 1.753 4.985 1.008 3.185 0.971 3.961 1.003 1.734 1.003 1.738 0.975 3.032 0.000 1.000 2.000 3.000 4.000 5.000 6.000 body div + div div > div div div div div .dialog div[class^=dia] div.character, div.dialog div[class=dialog] #scene1 #speech1 div[class] div[class*=sce] div div div[class~=dialog] div:nth-child(odd) div.scene div.dialog div:only-child div, div, div div[class$=log] .dialog div:last-child div ~ div div:nth-child(even) div:nth-child(n) div div:first-child #speech5 div, a, span div[class|=dialog] div:nth-child(2n+1) * div:nth-child(2n) div.dialog body div cssquery-dojo Relative Improvements
  137. Evaluation – cssquery-dojo – runs/s • CSS JIT shows significant

    improvements • Specialized (highly simple) non-JIT selectors show the same results 0 5000 10000 15000 20000 25000 30000 35000 40000 45000 50000 body div + div div > div div div div div .dialog div[class^=dia] div.character, div.dialog div[class=dialog] #scene1 #speech1 div[class] div[class*=sce] div div div[class~=dialog] div:nth-child(odd) div.scene div.dialog div:only-child div, div, div div[class$=log] .dialog div:last-child div ~ div div:nth-child(even) div:nth-child(n) div div:first-child #speech5 div, a, span div[class|=dialog] div:nth-child(2n+1) * div:nth-child(2n) div.dialog body div cssquery-dojo runs/s baseline CSSJIT
  138. Evaluation – cssquery-jquery – Relative improvements • Overall significant improvements

    3.965 4.064 3.541 1.862 1.807 1.005 3.650 0.949 3.929 3.692 3.571 3.980 3.926 3.567 4.046 0.972 3.850 3.935 3.892 1.809 3.945 4.228 3.716 5.594 3.976 0.967 3.947 3.660 3.616 1.802 3.955 3.939 4.004 5.471 6.118 0.987 0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 div[class|=dialog] div#scene1 div.dialog div body div div:nth-child(2n+1) div:nth-child(2n) * div #speech5 body div + div div > div div .dialog div div div div[class$=log] #scene1 #speech1 div[class=dialog] .dialog div[class*=sce] div.dialog div[class~=dialog] div:nth-child(odd) div:only-child div, a, span div div div, div, div div[class^=dia] #speech5 div:last-child div ~ div div[class] div:nth-child(even) div:first-child div#speech5 div.scene div.dialog div.character, div.dialog div:nth-child(n) div cssquery-jquery Relative Improvements
  139. Evaluation – cssquery-prototype – Relative improvements • Overall significant improvements

    3.989 5.438 4.017 4.033 1.810 0.996 1.804 4.038 3.604 3.950 4.032 3.900 6.501 3.846 3.802 1.009 1.810 3.588 4.017 1.808 3.648 3.892 4.006 3.950 5.838 3.921 1.017 4.062 3.658 3.703 4.029 3.956 3.857 4.715 1.009 3.932 0.000 1.000 2.000 3.000 4.000 5.000 6.000 7.000 div:first-child div.character, div.dialog div[class~=dialog] div div div div:nth-child(even) .dialog div:nth-child(2n+1) div.scene div.dialog div .dialog div:only-child div[class|=dialog] div + div div:nth-child(n) div ~ div div[class] div div:nth-child(odd) #scene1 #speech1 div[class^=dia] div:nth-child(2n) div #speech5 div div div[class=dialog] div[class*=sce] div, div, div div#speech5 * div#scene1 div.dialog div #speech5 body div div.dialog div:last-child div > div div, a, span body div[class$=log] cssquery-prototype Relative Improvements
  140. Outline • Motivation & Goals • Existing CSS Selector Implementation

    • CSS Selector JIT • Evaluation • Conclusion
  141. Shipment Status • x64 / ARMv7s / ARMv7 / ARM64

    backend • Already shipped in iOS8 – And more optimizations are coming in the next release
  142. Conclusion • Selector matching is crucial • CSS Selector JIT

    brings up to the next stage – Avoid function calls – Store almost all to the registers – Provide faster performance • Intelligent backtracking – Reduces register pressure – Avoid unnecessary backtraking