Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Apple Speeds Up WebKit’s JS Engine with LLVM JIT

Apple Speeds Up WebKit’s JS Engine with LLVM JIT

This item in japanese


Apple has improved the speed of Nitro with 35% – Safari’s JavaScript engine – by converting JavaScript into LLVM IR code which is then subject to heavy optimization.

According to a blog post on, WebKit had in the past three levels of optimizations for its internal JavaScript bytecode, each one being used at run time by striking a balance between the time needed to optimize a section of code and the benefits resulting from doing it:

  • LLInt (Low Level Interpreter) – this is a bytecode interpreter not a compiler and it is doing very little in terms of optimization. Each function call goes through LLInt, and if it contains a statement which is invoked more than 100 times or the function itself is called more than 6 times then the function is handed to the next level of optimization, Baseline JIT.
  • Baseline JIT – this is a simple JIT creating code faster than LLInt, but it does not include heavy optimizations. Again, if a statement is found to be executed more than 1,000 times or a function is called more than 66 times, the compilation is passed to the following level, DFG JIT. It is possible to switch compilers right after executing a statement by using On-Stack Replacement (OSR).
  • DFG JIT (Data Flow Graph JIT) – Until now this compiler was responsible for Safari’s performance, but it is used only for sections of code that need more CPU because code optimizations take time.

To improve Nitro’s performance even more, Apple decided to introduce LLVM into the optimization chain. Chris Lattner, the original author and lead of LLVM Compiler Infrastructure, works for Apple leading the Developer Tools department, and perhaps is behind this move. This forth tier is called FTL JIT (Fourth Tier LLVM) and is a C++ module that ends up using LLVM low level optimizations. To do that, a function’s bytecode is converted into LLVM IR through two intermediary phases - Continuation-Passing Style (CPS) and Static Single Assignment (SSA) - which are meant to transform and optimize an originally dynamic code into a static one which is later processed by the LLVM compiler. This is the first time LLVM has been used for profile-directed compilation of a dynamic language and required some deep changes in LLVM, according to Filip Pizlo:

The WebKit FTL JIT is the first major project to use the LLVM JIT infrastructure for profile-directed compilation of a dynamic language. To make this work, we needed to make some big changes – in WebKit and LLVM. LLVM needs significantly more time to compile code compared to our existing JITs. WebKit uses a sophisticated generational garbage collector, but LLVM does not support intrusive GC algorithms. Profile-driven compilation implies that we might invoke an optimizing compiler while the function is running and we may want to transfer the function’s execution into optimized code in the middle of a loop; to our knowledge the FTL is the first compiler to do on-stack-replacement for hot-loop transfer into LLVM-compiled code. Finally, LLVM previously had no support for the self-modifying code and deoptimization tricks that we rely on to handle dynamic code.

What did Apple achieve working on this for one year? According to Pizlo, Safari is 38% faster than DFG JIT for the Richards benchmark and on average 35% faster on a number of asm.js benchmarks. It remains to be seen how it compares on Octane against Chrome or Firefox. And “work on the FTL is just beginning – we still need to increase the set of JavaScript operations that the FTL can compile and we still have unexplored performance opportunities,” ended Pizlo.

FTL JIT has been committed to the WebKit trunk as r167958 and can be tested with WebKit Nightly.

Rate this Article


Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • The Richards benchmark IS from Octane

    by Eric Aguiar,

    Your message is awaiting moderation. Thank you for participating in the discussion. is where the 35% perf increase measurements can be seen since the LLVM Jit is only for OSX 64-bit as of this time.
    Multiple other sub-benchmarks of Octane like DeltaBlue, EarleyBoyer, Mandreel, NavierStokes and RayTrace also benefit from the new Jit if anyone cares to read the graphs and see the results for themselves.

  • Re: The Richards benchmark IS from Octane

    by Abel Avram,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Yes, I knew that Richards is one of the many benchmarks included in Octane. Google insists on having a suite of benchmarks not just one, and it makes sense.

    Thanks for the link. It is not clear to me what version of Safari appears in the charts. Anyway, based on that site (, Safari has some 13,000 points for Octane, and assuming it is the stable version it means we need to add max. 35% to it, making it 17,550, still lower than 22,000 for Chrome. It seems that Safari is still behind both Chrome and Firefox (20,000).

  • Re: The Richards benchmark IS from Octane

    by Eric Aguiar,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Nono, you have to look at the link I gave which specifically filters out the benchmarks done on 64-bit OSX machines and are the sub-results of the Octane tests using the little expandable filter "Machines" & "Breakdown" link things on the left side of the page. You'll see the individual numbers there since the new Jit only works and is enabled on 64-bit OSX.
    The main front-page shows almost no change at all since it's averaged out over many architectures/chipsets and tests.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p