News

Mozilla optimizes calls between JavaScript and WebAssembly in Firefox, making it almost as fast as JS to JS calls

3 min read

Yesterday, Mozilla announced that in the latest version of Firefox Beta, calls between JS and WebAssembly are faster than non-inlined JS to JS function calls. They have made these optimizations keeping two aspects of engine’s work in mind: reducing bookkeeping and cutting out intermediaries.

How they made WebAssembly function calls faster

They have optimized the calls in both directions, that is, from JavaScript to WebAssembly and WebAssembly to JavaScript with their recent work in Firefox. All these optimizations have been done to make the engine’s work easier.

The improvements fall into two groups:

  • Reducing bookkeeping: This means getting rid of unnecessary work to organize stack frames
  • Cutting out intermediaries: This means taking the most direct path between functions

How they optimized WebAssembly to JavaScript calls

The browser engine has to deal with two different kinds of languages while going through your code even if the code is all written in JavaScript: bytecode and machine code. The engine needs to be able to go back and forth between these two languages.

When it does these jumps, it needs to have some information in place, like the place from where it needs to resume. The engine also must separate the frames that it needs. To organize its work, the engine gets a folder and puts this information in it.

When the Firefox developers first added WebAssembly support, they had a different type of folder for it. So even though JIT-ed JavaScript code and WebAssembly code were both compiled and speaking machine language, it was treated as if they were speaking different languages.

This was unnecessarily costly in two ways:

  • An unnecessary folder is created which adds up setup and teardown costs
  • It requires trampolining through C++ to create the folder and do other setup

They fixed this by generalizing the code to use the same folder for both JIT-ed JavaScript and WebAssembly. This made calls from WebAssembly to JS almost as fast as JS to JS calls.

How they optimized JavaScript to WebAssembly calls

JavaScript and WebAssembly use different customs even if they are speaking the same language. For instance, to handle dynamic types, JavaScript uses something called boxing. As JavaScript doesn’t have explicit types, they need to be figured out at runtime.

To keep track of the types of values, the engine attaches a tag to the value. This turns one simple operation into four operations. This is the reason why WebAssembly expects parameters to be unboxed and doesn’t box its return values. Since it is statically typed, it doesn’t need to add this overhead.

So, before the engine gives the parameters to the WebAssembly function, the engine needs to unbox the values and put them in registers. It has to go through C++ again to prepare the values when going from JS to WebAssembly. Going to this intermediary step is a huge cost, especially for something that’s not that complicated.

To solve this, they took the code that C++ was running and made it directly callable from JIT code. So, when the engine goes from JavaScript to WebAssembly, the entry stub unboxes the values and places them in the right place.

Along with these calls, they have also optimized monomorphic and built-in calls.

To understand the optimizations well, check out Lin Clark’s official announcement on Mozilla’s website.

Read Next

Mozilla updates Firefox Focus for mobile with new features, revamped design, and Geckoview for Android

Mozilla releases Firefox 62.0 with better scrolling on Android, dark theme on macOS, and more

Mozilla, Internet Society, and web foundation wants G20 to address “techlash” fuelled by security and privacy concerns

Bhagyashree R

Share
Published by
Bhagyashree R

Recent Posts

Top life hacks for prepping for your IT certification exam

I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…

3 years ago

Learn Transformers for Natural Language Processing with Denis Rothman

Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…

3 years ago

Learning Essential Linux Commands for Navigating the Shell Effectively

Once we learn how to deploy an Ubuntu server, how to manage users, and how…

3 years ago

Clean Coding in Python with Mariano Anaya

Key-takeaways:   Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…

3 years ago

Exploring Forms in Angular – types, benefits and differences   

While developing a web application, or setting dynamic pages and meta tags we need to deal with…

3 years ago

Gain Practical Expertise with the Latest Edition of Software Architecture with C# 9 and .NET 5

Software architecture is one of the most discussed topics in the software industry today, and…

3 years ago