RegExpTestInline extends to quantifiers, alternation, and unicode flags
Component: JavaScriptCore DFG/FTL JIT | 83683ab
Yarr는 WebKit의 regex engine입니다. Yarr JIT가 생성하는 matching 코드는 quantifier나 alternation이 포함된 pattern을 처리할 때 backtracking 상태를 담을 scratch frame을 필요로 합니다. 어느 branch를 탔는지, group이 몇 번 반복되었는지 같은 정보가 여기에 기록됩니다. 한편 RegExpTestInline은 Yarr를 호출하는 대신 regex match를 JIT 컴파일된 JavaScript 안으로 직접 inline하는 DFG/FTL 최적화입니다. 이전에는 이 frame이 필요한 pattern이라면 inline을 거부했습니다. frame의 주소를 frame pointer 기준으로 잡고 있었고, 이 방식은 Yarr 자체 call frame 안에서만 동작하기 때문입니다.
이 commit은 DFG/FTL frame 최하단의 outgoing-argument 영역을 Yarr frame 용도로 전환했습니다. inline된 matcher는 아무것도 호출하지 않으므로 이 영역은 원래 사용되지 않습니다. 주소 계산도 frame pointer가 아니라 stack pointer를 기준으로 수행됩니다. 이때 늘어난 공간에 대해 별도의 stack check를 수행하지는 않고, 바깥 함수가 이미 수행한 stack check가 이를 함께 덮는다는 전제에 의존합니다. 이 변경으로 quantifier와 alternation, 그리고 u/v unicode flag가 포함된 pattern까지 inline 대상이 되었습니다.
Significance
실제 코드에 등장하는 regex literal은 대부분 quantifier나 alternation을 사용합니다. 그동안 RegExpTestInline은 단순한 pattern에서만 동작했는데, 이번 변경으로 그 간극이 메워졌습니다. benchmark에서는 .test() 호출이 약 1.7배 빨라진 것으로 나타납니다. 수치와는 별개로 동작 방식 자체도 눈여겨볼 만합니다. JIT가 생성한 코드가 backtracking 상태를 stack 영역에 기록하는데, 이 영역의 크기는 다른 목적으로 emit된 stack check가 대신 보장합니다. 접근 역시 frame pointer가 아닌 stack pointer를 통해 이루어집니다.