Compartments

Heap

We have implemented a major change to the way Firefox manages JavaScript objects. JavaScript objects include script-instantiated objects such as Arrays or Date objects, but also include JavaScript representations of Document Object Model (DOM) elements, such as input fields or DIV elements. In the past, Firefox held all JavaScript objects in a single JavaScript heap. This heap is occasionally garbage collected, which means the browser walks the entire object graph in the heap and determines which objects are still reachable and which are not. Unreachable objects are de-allocated and space is reclaimed.

Firefox 3.6 single heap model.

Having all JavaScript objects in the browser congregate in a single heap is suboptimal for a number of reasons. If a user has multiple windows (or tabs) open, and one of these windows (or tabs) created a lot of objects, it is likely that many of these objects are no longer reachable (garbage). When the browser detects such a state, it will initiate a garbage collection. Unfortunately though, since objects from different windows (or tabs) are intermixed in the heap, the browser has to walk the entire heap. If a number of idle windows are open, this can be quite wasteful, since those windows haven’t really created any garbage, so whenever a window with heavy activity triggers a garbage collection, much of the garbage collection time is spent walking unrelated parts of the global object graph.

In Firefox this problem is even more pronounced than in other browsers, because our UI code (also called chrome code, not to be confused with Google Chrome) is implemented in JavaScript, and there are a lot of chrome (UI) objects alive at any given moment. These UI objects tend to stick around and every time a web content window causes a garbage collection, Firefox spends a lot of time figuring out whether chrome objects are still alive instead of being able to focus on the active web content window.

FIrefox 4 Compartmentalized JavaScript Heaps

Compartments

For Firefox 4 we changed the way JavaScript objects are managed. Our JavaScript engine SpiderMonkey (sometimes also called TraceMonkey and JägerMonkey, which are SpiderMonkey’s trace-compilation and baseline Just-in-Time compilers) now supports multiple JavaScript heaps, which we also call compartments. All objects that belong to a certain origin (such as “http://mail.google.com/” or “http://www.bank.com/”) are placed into a separate compartment. This has a couple very important implications.

  • All objects created by a website reside within the same compartment and hence are located in the same memory region. This improves cache utilization by reducing false sharing of cache lines. False sharing occurs when we are trying to operate on an object and we have to read an entire cache line of data into the CPU cache. In the old model JavaScript objects could be co-located with arbitrary other JavaScript objects from other origins. Such cross origin objects are used together very infrequently, which reduces the number of cache hits we get. In the new model most objects touched by a website are tightly packed next to each other in memory, with no cross origin objects in between.
  • JavaScript objects (including JavaScript functions, which are objects as well) are only allowed to touch objects in the same compartment. This invariant is very useful for security purposes. The JavaScript engine enforces this requirement at a very low level. It means that a “google.com” object can never accidentally leak into an untrusted website such as “evil.com”. Only a special object type can cross compartment boundaries. We call these objects cross compartment wrappers. We track the creation of these cross compartment wrappers, and thus the JavaScript engine knows at all times what objects from a compartment are kept alive by outside references (through cross compartment wrappers). This allows us to garbage collect individual compartments, in addition to a global collection. We simply assume all objects referenced from outside the compartment to be live, and then walk the object graph inside the compartment. Objects that are found to be disconnected from the graph are discarded. With this new per-compartment garbage collection we shortcut having to walk unrelated heap areas of a window (or tab) that triggered a garbage collection.

Wrappers

Wrappers are not a new concept in Firefox, or browsers in general. In the past we have already used them to regulate how windows (or tabs) pass objects to each other. In the past, when another window (or tab or iframe) tried to touch an object that belongs to a different window, we handed it a wrapper object instead. That wrapper object dynamically checks at access time whether the accessor window (also called the subject) is permitted to access the target object. If one Google Mail window is trying to access another Google Mail window, the access is permitted, because these two windows (or tabs or iframes) are same origin and hence its safe to permit this access. If an untrusted website obtains a reference to a Google Mail DOM element, we hand it the same wrapper, and if it ever tries to access the Google Mail DOM Element the wrapper will at access time deny the property access because the untrusted website “evil.com” is cross origin with “google.com”.

Firefox 3.6 Shared Wrappers

A disadvantage of the Firefox 3.6 wrapper approach (which is similar to the way other browsers utilize wrappers) was the fact that these wrappers had to be injected manually at the right places in the C++ browser implementation, and each wrapper had to do a dynamic security check at access time. With compartments we can do a lot better:

  • Since all objects belonging to the same origin are within the same compartment, and no object from a different origin is in that compartment, we can let all objects within a compartment touch other objects in the same compartment without a wrapper in between. Keep in mind that this doesn’t just apply to windows but also to iframes. A single Google Mail session often uses dozens of iframes that all heavily exchange objects with each other. In the past we had to inject wrappers in between that kept performing dynamic security checks. This is no longer necessary, and there is an observable speedup when using iframe heavy web applications such as Google Mail.
  • Since all cross origin objects are in a different compartment, any cross origin access that needs to perform a security check can only happen through a cross compartment wrapper. Such a cross compartment wrapper always lives in a source compartment, and accesses a single destination object. When we create a cross compartment wrapper, we consult with the wrapper factory to see what kind of security policy should be applied. When “evil.com” obtains a reference to a “google.com” object, for example, we have to create a wrapper to that object in the “evil.com” compartment. When that wrapper is created the wrapper factory will tell us to apply a stringent cross origin security policy, which makes it impossible for “evil.com” to glean information from the “google.com” window. In contrast to our old wrappers, this security policy is static. Since only “evil.com” objects ever see this wrapper, and it only points to one single DOM element in the destination compartment, the policy doesn’t have to be re-checked at access time. Instead, every time “evil.com” attempts to read information from the DOM element, the access is denied without even comparing the two origins.

Firefox 4 Cross Compartment Wrapper

Brain Transplants

A particularly interesting oddity of the JavaScript DOM representation is the existence of two objects for each DOM window (or tab or iframe), the inner window and the outer window. This split was implemented by web browsers a few years ago to securely deal with windows being navigated to a new URL. When such a navigation occurs, the inner window object inside the outer window is replaced with a new object, whereas the actual reference to window (which is the outer window) remains unchanged. If such a navigation takes the window to a new origin, we allocate the inner window in the appropriate new compartment. This of course creates now the problem that the outer window can possibly no longer directly point to the new inner window, because it is in a different compartment.

We solve this problem through brain transplants. Whenever an outer window navigates, we copy it into the new destination compartment. The object in the old compartment is transformed into a cross compartment wrapper that points to the newly created object in the destination compartment. So the term brain transplants is very appropriate here. We are essentially transplanting the guts of the outer window object into a new object hull in the same compartment we allocated the inner object in.

Processes

Some readers might wonder how compartments compare to per-tab processes as they are used by Google Chrome and Internet Explorer. Compartments are similar in many ways, but also very different. Both processes and compartments shield JavaScript objects against each other. The most important distinction is that processes offer a stronger separation enforced by the processor hardware, while compartments offer a pure software guarantee. However, on the upside compartments allow much more efficient cross compartment communication that processes code. With compartments cross origin websites can still communicate with each other with a small overhead (governed by certain cross origin access policy), while with processes cross-process JavaScript object access is either impossible or extremely expensive. In a modern browser you will likely see both forms of separation being applied. Two web sites that never have to talk to each other can live in separate processes, while cross origin websites that do want to communicate can use compartments to enhance security and performance.

Future

We have landed the main compartments patch and current nightly builds (and Beta 7) are running with per-origin compartment JavaScript heaps. Some of the functionality described above will not ship until Beta 8, most importantly per-compartment garbage collections. Those currently still happen for all compartments at once. The foundation we laid with the compartments work will also enable a number of future extensions. Since we now cleanly separate objects belonging to different tabs, future changes to our JavaScript engine will permit us to not only perform JavaScript garbage collection for individual compartments, but we will also be able to do so in the background on a different thread for tabs with inactive content (i.e. no event handler is firing at the moment).

129 thoughts on “Compartments

    • The overall impact on a browser session is negligible. We are using a bit more memory because objects from different origin’s don’t share 4k memory pages. At the same time we use a bit less memory because we inject much fewer wrappers. So its mostly a wash. We will do a more detailed analysis over the next few weeks as we decide whether we want to use more fine grained compartments (i.e. one compartment per iframe or window).

  1. It sounds like the bulk of this code has just recently landed or will be landing with beta 8. Should we expect a noticeable speedup when Beta 7 is released? Or will a speedup be more significant with the GC for beta 8?

    I’m also curious if these changes set us up nicely in the future for process isolation of tabs and the like? This, I suppose, is with the assumption that that’s where we’re going?

    • Beta 7 contains all the wrapper changes, and there is a noticeable speedup (compartments improved our Dromaeo score by 21%, for example). There will be additional changes for Beta 8 for reduced GC pause times.

      Electrolysis is still very much happening. Its currently mostly targeting splitting chrome from content, and inside the content process we will use compartments, but over time we will likely also have multiple content processes.

      • Awesome.
        Will these changes likely also improve speed scores on other JS benchmarks as well? Or does only Dromaeo test in a way that shows this speed benefit?

  2. It is a testament to your skill – both as a coder and a writer – that I was able to follow this from beginning to end. Thanks, Andreas, for this fantastic post.

      • Ok, I see your previous post about process separation of compartments eventually and separate from chrome, which is what I guess I was trying to ask.

  3. Interesting reading. I don’t understand however what these inner and outer windows are. It there some good resource out there that explains what these are?

  4. Does this also help with performance by behaving as pool-allocation, i.e. discarding the whole compartment when a tab/page is closed?
    And similar for memory that would otherwise leak for various reasons, will that still be collected when (if) the whole compartment is this way?

  5. Pingback: Top Posts — WordPress.com

  6. Is it not possible to get reference cycles that cross compartments? Is there a separate GC not described here that can cross compartments?

  7. This post is explained very well and I enjoyed it, it was quite interesting.

    Correct me if I’m wrong but sounds like the summary is: compartment-per-origin with per-compartment garbage collection which results in faster and more secure javascript objects in various ways.

    Boy, just wait until it hits the trunks. I’ll be checking out arewefastyet.com as well.

  8. Since JS is isolated into compartments would it be possible to have 1 javascript thread per group of compartments that won’t touch (e.g. window objects that don’t have references to each other)? Currently having single-threaded javascript for everything is a major bottleneck, especially since it can also block the UI thread.

  9. I’ve noticed that Firefox uses a lot of CPU when idle (on average 10-15%) – is this likely to improve with Compartment GC or is this an unrelated issue?

  10. “If an untrusted website obtains a reference to a Google Mail DOM element, we hand it the same wrapper, and if it ever tries to access the Google Mail DOM Element the wrapper will at access time deny the property access because the untrusted website “evil.com” is cross origin with “google.com”.”

    What’s the point of handing a wrapper to a subject which does not has an access to the wrapped object in the first place?

  11. Thanks for great news! Already played a bit with the fresh Beta 7 and was impressed with the performance gain!
    Then I read this post and got even more excited, thanks for super-clear explanation!

  12. Pingback: Mozilla Firefox 4.0 Bêta 9

  13. Pingback: Firefox 4 Beta 9 – a huge pile of awesome ✩ Mozilla Hacks – the Web developer blog

  14. Pingback: MozillaES la comunidad de Mozilla en español

  15. Pingback: Firefox 4 beta 9 now available to download | La Leccion de Hoy

  16. Pingback: Startup speeds up in Firefox 4 beta 9 | 3 Technology

  17. Pingback: Firefox 4 beta 9 now available to download | Technoloby.com

  18. Pingback: Code Retard: Anything Geeky Goes

  19. Pingback: Вышла девятая бета-версия Firefox 4 | AllUNIX.ru – Всероссийский портал о UNIX-системах

  20. Pingback: Mozilla Italia » Archivio » Disponibile Firefox 4 beta 9

  21. Pingback: Download Mozilla Firefox 4 Beta 9 / JAUHARI

  22. Pingback: Browser start-up speeds up in Firefox 4 beta 9 | Games 4 Downloading

  23. Pingback: Vote My Story, Browser start-up speeds up in Firefox 4 beta 9 | Vote My Story

  24. Pingback: Firefox 4 Beta 9 Released | Firefox Extension Guru's Blog

  25. Pingback: MozillaZine.jp » Blog Archive » Firefox 4 Beta 9 がリリースされた

  26. Pingback: Browser start-up speeds up in Firefox 4 beta 9 Truman Consulting Group - Tekpedia.Net - Truman Consulting Group

  27. Pingback: Firefox 4 beta 9 now available to download | Best GPS Technology News

  28. Pingback: Browser start-up speeds up in the Firefox 4 beta 9 ( Latest Updates) | Top Practical Ethical Hacking Tutorials And Blogging Tips

  29. Pingback: Browser start-up speeds up in Firefox 4 beta 9 « Mohinder's Blog

  30. Pingback: Browers start-up speeds up in Firefox 4 beta 9 | Vanisle Networks

  31. Pingback: Browser start-up speeds up in Firefox 4 beta 9 | Vanisle Networks

  32. Pingback: Firefox 4 beta 9 now available to download | Technology News

  33. Thanks for the clear explanation – was really well written. (Nice to see other people use Balsamiq Mockups too!)

    One quick suggestion:
    I only came across this post by chance – as it wasn’t on Planet Firefox. Thought of adding this as a contributing blog to it?

  34. Pingback: Firefox 4 release creeps ever closer as Mozilla rolls out beta 9

  35. Pingback: Firefox 4 beta 9 now available to download | Designer Wear Live

  36. Pingback: Firefox 4 beta 9 now available to download | esenters43

  37. Pingback: Firefox 4 beta 9 now available to download | Nine T Design

  38. Pingback: Firefox 4 beta 9 now available to download — The Stock Market

  39. Pingback: Firefox 4.0 Beta 9 is available for download now!

  40. Pingback: Firefox 4 beta 9 now available to download | WSM

  41. Pingback: First Look: Firefox 4 Beta 9 | ZDNet

  42. Pingback: The PC Doctor's blog » Blog Archive » First Look: Firefox 4 Beta 9

  43. Pingback: Download Firefox 4 Beta 9

  44. Pingback: Firefox 4 beta 9 now available to download | waynefixtro

  45. Pingback: Frugal Tek-International TV station now streams on Internet

  46. Pingback: SilentDefender.co.uk » Blog Archive » Browser start-up speeds up in Firefox 4 beta 9

  47. Pingback: Firefox 4 beta 9 now available to download « Chiet's Tech News

  48. Pingback: Firefox 4 beta 9 now available to download | Everheartz15's Tech Blog

  49. Pingback: Firefox 4 kommt als neunte Testversion –

  50. Pingback: Browser start-up speeds up in Firefox 4 beta 9 – Which Browser – whichbrowser.org -Updates on new open source browser technologies, updates and add ons. « Which Browser?

  51. Pingback: Firefox 4 beta 9 now available to download | ashlykoehl

  52. Pingback: Firefox 4 beta 9 now available to download | rocymadsen

  53. Pingback: Firefox 4 beta 9 now available to download | cccharleskrace34

  54. Pingback: Firefox 4 beta 9 now available to download | Guydz Guides

  55. Pingback: Firefox 4 beta 9 now available to download | analog7931

  56. Pingback: Firefox 4 beta 9 now available to download | albertoholm

  57. Pingback: Firefox 4 beta 9 now available to download | Dress Juice

  58. Pingback: Deals of the Day [Dealzmodo] | La Leccion de Hoy

  59. Pingback: Here’s the Chair of My 1960s Sci-Fi Dreams [Furniture] | Gadget & Electronics Tips by Alfredo Trabulsi

  60. Pingback: Firefox 4 beta 9 now available to download | dollykerman

  61. Pingback: Firefox 4 beta 9 now available to download | Science and Technology News

  62. Pingback: Firefox 4 beta 9 now available to download | Digital Technology News

  63. Pingback: Firefox 4 beta 9 now available to download | Gadget & Electronics Tips by Alfredo Trabulsi

  64. Pingback: Firefox 4 beta 9 now available to download | 0845numbersonline.com

  65. Pingback: Firefox 4 beta 9 now available to download « Teal Blue Thoughts

  66. Pingback: Firefox 4 beta 9 now available to download | Techo Gossip

  67. Pingback: Firefox 4 beta 9 now available to download | The News 4 You

  68. Pingback: Firefox 4 beta 9 now available to download | Software Blog Updates

  69. Pingback: Firefox 4 beta 9 now available to download | teklehabte

  70. Pingback: Firefox 4 beta 9 now available to download | Technology News & Updates

  71. Pingback: Firefox 4 beta 9 now available to download | my-very-cool-gadgets.info

  72. Pingback: Firefox 4 beta 9 now available to download | Puvh Technological News

  73. Pingback: Firefox 4 beta 9 now available to download | Zopatropic

  74. Pingback: Firefox 4 beta 9 now available to download

  75. Pingback: Firefox 4 beta 9 now available to download | Alice in Wonderworld

  76. Pingback: Firefox 4 beta 9 now available to download | My Tech Blog

  77. Pingback: Firefox 4 beta 9 now available to download | Real Search Engine Marketing

  78. Pingback: Firefox 4 beta 9 now available to download | Self Hosted WordPress Blog

  79. Pingback: Firefox 4 beta 9 now available to download | Safe Brain News

  80. Pingback: Browser start-up speeds up in the Firefox 4 beta 9 ( Latest Updates) - - How To Hack | Online Ethical Hacking Classes On Hackersfind.com

  81. Pingback: Download Mozilla Firefox 4 Release Candidate RC Version now

  82. Pingback: Firefox 4.0: Erster Release Candidate steht bereit » Gadgefobia.de

  83. Pingback: Anonymous

  84. I’ve noticed more pauses in Firefox 4 than in Firefox 3.x while, evidently, GC is doing its job. So, I am not confident that the changes talked about here are a good thing.

  85. Pingback: Долгожданный Firefox 4 =) | Dan Tyan — web developer blog

  86. Pingback: Firefox 4 Released! » 笨師拉 – BenZilla

  87. Pingback: Download Firefox 4 final version | Mozilla

  88. Pingback: fstube.org « Firefox 4.0 Released!

  89. Pingback: Download Mozilla Firefox 4

  90. Pingback: Download Mozilla Firefox 4 : Adsensefeed.com

  91. Pingback: Релиз Firefox 4.0 | AllUNIX.ru – Всероссийский портал о UNIX-системах

  92. Pingback: Gauge » Вышел Firefox 4.0

  93. Pingback: Mozilla Firefox 4.0 | CooLXviD

  94. Pingback: Wydano Firefoksa i Firefoksa Portable 4.0 | OSnews.pl

  95. Pingback: What’s New in Firefox 4 (Part 2) | Samson's Weblog

  96. Pingback: RadioTux GNU/Linux » » RadioTux Talk 125: verseuchte zombie Aliens klauen die letzten IPv4-Adressen

  97. Pingback: Firefox 4 final… I like it, but… | Sretenović Homepage

  98. Pingback: Download Mozilla Firefox 4 : The best niche blog!

  99. Pingback: soser8 » Blog Archive » Grzglo: Wydano Firefoksa i Firefoksa Portable 4.0

  100. Pingback: What’s new in Firefox 4

  101. Pingback: New Update For Mozilla FireFox (4.0) Is Now Available To Download « The Computer Savvy Weblog

  102. Pingback: Quora

    • We are working on a multi-process architecture. Due to our vast extension architecture its a bit more involved than in browsers that have a very limited extension model.

  103. Pingback: Apple expands patent complaint against Samsung to include more devices | kaishaft

  104. Pingback: What’s new in Firefox 6 from the GC side? | Garbage Collection stats and thesis updates

  105. Pingback: Scalability | Garbage Collection stats and thesis updates

  106. Pingback: Scalability | Garbage Collection stats and thesis updates

  107. Pingback: Firefox performance annihilate Chrome when you have many tabs open | n33ch

  108. The page is not fully readable on iPad because some problems with scrolling near the end of story. But the design is great!

  109. Pingback: Old Dijkstra Essays Considered | Luke Wagner's Blog

  110. Pingback: Part I: A how to for performance testing on Firefox OS. « onecyrenus

Leave a comment