Re: Effects of JSM Compartments on Performance and Development Practices
On Tue, Jan 22, 2013 at 6:13 PM, Nicholas Nethercote n.netherc...@gmail.com wrote: https://bugzilla.mozilla.org/show_bug.cgi?id=759585 proposes introducing zones. Compartments in the same zone could share arenas, which would fix (1) (for compartments in the same zone). This would also fix (3), because compartments in the same zone would be able to share strings. The zones approach is my preferred solution. Bill McCloskey is working actively on zones and has been making good progress, from what I hear. Enough so that I've WONTFIXed a couple of the other bugs (e.g. 807205) that suggested alternative fixes. Zones really are the right way to fix this problem! Nick ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Effects of JSM Compartments on Performance and Development Practices
On 1/20/13 4:01 PM, Joshua Cranmer wrote: If it were possible to have strings cross-compartments that don't require flattening and excessive copying, that would make the lives of add-on authors in a CPG world much easier. Please make sure bugs are filed? -Boris ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Effects of JSM Compartments on Performance and Development Practices
On 1/20/13 2:37 PM, Gregory Szorc wrote: * Have all or most of chrome-privileged JS share the same compartment (like on B2G). It's my understanding the CPG decision was largely driven by content/security requirements and chrome just got caught up in it. What's not clear to me is whether this is a proposal to keep separate globals per JSM but have them all in one compartment or whether this is a proposal to have a single global for all JSMs, or all JSMs that opt into having this single global or something. The latter is much simpler to do. * Eliminate excessive copying and other perf issues associated with sending objects across compartments. This would be a good idea, yes. * Allow JSMs to be imported into specific named compartments. As might this be. -Boris ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Effects of JSM Compartments on Performance and Development Practices
On Tue, Jan 22, 2013 at 2:15 PM, Boris Zbarsky bzbar...@mit.edu wrote: On 1/20/13 2:37 PM, Gregory Szorc wrote: * Have all or most of chrome-privileged JS share the same compartment (like on B2G). It's my understanding the CPG decision was largely driven by content/security requirements and chrome just got caught up in it. What's not clear to me is whether this is a proposal to keep separate globals per JSM but have them all in one compartment AIUI, the global-to-compartment mapping will always be 1-to-1, and changing this would be monstrously problematic. or whether this is a proposal to have a single global for all JSMs, or all JSMs that opt into having this single global or something. The compartment overhead has three components. (1) Wasted space within GC arenas (because compartments can't share arenas). This is a consistent, moderate-to-large overhead. (2) Space taken up by cross-compartment wrappers (both the objects and the CCW tables). This doesn't seem that much of a problem in practice. (3) Strings get copied between compartments. This is an irregular problem, but it can be terrible when it does occur. There are several possible fixes for this problem. https://bugzilla.mozilla.org/show_bug.cgi?id=759585 proposes introducing zones. Compartments in the same zone could share arenas, which would fix (1) (for compartments in the same zone). This would also fix (3), because compartments in the same zone would be able to share strings. https://bugzilla.mozilla.org/show_bug.cgi?id=807205 proposes a way to load multiple JS modules into the same compartment. This would also solve both (1) and (3), with the side-effect that separate modules would be sharing a global, which has some risk. https://bugzilla.mozilla.org/show_bug.cgi?id=833585 requests that strings not be copied between compartments, but if either of the previous two proposals were implemented it shouldn't be necessary. The zones approach is my preferred solution. Firefox has hundreds of compartments, and that won't change any time soon, and the separation that compartments provide gives lots of nice security/isolation benefits. Instead of finding ways to work around compartments, because they have memory overhead, it would be better to fix that memory overhead. Nick ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Effects of JSM Compartments on Performance and Development Practices
I'm writing to the Platform list as a developer that maintains a significant amount of JavaScript for Firefox. Much of the JavaScript I maintain is for large backend features, such as Sync and Firefox Health Report. These features are thousands of lines of code (mostly JavaScript) and interact with many systems in Firefox. These backend systems tend to perform many of the same tasks, so there is code shared between them in the form of JSMs. To reduce redundant code (therefore bugs) and development costs, there is obviously the incentive to share as much code as possible. I'd like to start a discussion about an issue that has been troubling me for a while: the performance overhead of separate compartments per JSM. I've previously brought this up in bugs and with a few individuals. I wanted to raise awareness by posting here. I apologize in advance if I make a few semantic mistakes on things like globals and compartments and the overhead of cross-compartment operations: I'm not a core platform hacker! Ever since Compartment per Global (CPG) landed, JS modules imported with Cu.import now get their own compartment (at least on desktop Firefox - I'm told they share a compartment on B2G for performance reasons). This is all nice in theory. You even get a line item in about:memory to see if your module is doing anything wonky! Unfortunately, this change has a few unfortunate side-effects: a) Memory overhead for each compartment b) Perf losses due to crossing compartments Assuming the about:memory compartment numbers are correct, each imported JS module seems to consume at *least* ~55kb (numbers are similar on both OS X and Windows Nightly builds). Furthermore, there appear to be some scenarios where crossing compartments has a horrible effect on performance. For example, it is my understanding that crossing compartments can sometimes copy data. I believe this always holds for strings. See bug 806087 for example. Hundreds of MBs of string-chars/huge are seemingly being copied between JSMs/compartments. While this specific bug number is resolved, the underlying copying issue remains AFAIK. Sadly, these two issues have a negative influence on how I write JavaScript code. I'm of the camp that tends to write many, small, standalone JSMs rather than large and monolithic ones. I find the resulting code is easier to comprehend and test. As an added bonus, anybody can come along later and reuse an individual module. This includes add-ons. Yay code reuse! The end result is less overall code being written and debugged and higher test coverage. I like to think this means the quality of the code base is higher and new features can be rolled out quicker (due to code reuse). I hold strong convictions that this code architecture is superior. With separate compartments per module, I've been put in a tough position. I have to weigh the code maintainability advantages of multiple modules against memory usage and performance overhead. If I create dozens of small, reusable, and specifically-targeted JSMs, I've got the Perf team giving me the stink eye for increasing memory usage and cross-compartment overhead. If I write JSMs that are thousands of lines long, I'm creating technical debt and increasing the barrier to change. This is a Kobayashi Maru (no win) scenario. Firefox and other Gecko apps suffer with both ends of the spectrum. Finding a compromise between the two extremes is difficult if not impossible in some scenarios. Furthermore, code is always changing thus the conditions influencing the decision are always changing. That's my problem. And, it's a problem that every large JavaScript feature faces. And, with groups like Jetpack talking about landing lots of reusable JSMs in the tree, I think it's a problem that will only get worse over time. Now, what can we do about it? I'd like to live in a world where you are not significantly penalized for creating multiple, loosely coupled JSMs. Here are some ideas: * Reduce the memory overhead of compartments (I believe this is already being worked on). * Have all or most of chrome-privileged JS share the same compartment (like on B2G). It's my understanding the CPG decision was largely driven by content/security requirements and chrome just got caught up in it. * Eliminate excessive copying and other perf issues associated with sending objects across compartments. * Allow JSMs to be imported into specific named compartments. * (Hacky) Build system magic to concatenate or merge multiple files together so they load as one module/compartment. This must be done with care because there could be things like file-level symbol collisions. I requested named compartments in bug 807205. In summary, there are some large JS services (like Sync and Firefox Health Report) that consist of a large number of JSMs. The memory overhead quickly amounts to several hundred kb, possibly into the MBs. All modules are used
Re: Effects of JSM Compartments on Performance and Development Practices
We've had bug 764220 open on the CPG memory regression for six months now. Although it's a MemShrink:P1, it hasn't gotten the attention it deserves. FWIW, I think part of this stems from the fact that the MemShrink team is often ineffective at getting others to fix bugs that we think are a priority, perhaps because we don't have an Important Person prodding other managers to worry about our bugs. So when we can't fix a bug ourselves, it often languishes. (Not to dismiss the heroic efforts of many people outside the core MemShrink group who have fixed memory bugs!) The CPG memory regression and bug 689623 are good examples of this. There are a lot of different approaches we could take to reducing the overhead from CPG. I'd think that a first step would be trying to apply bug 798491 (the B2G patch to load most chrome code into one compartment) to desktop Firefox, but I don't fully understand the trade-offs here. CPG resulted in a memory regression for both content and chrome JS, and we may need different techniques to address them. But ultimately, I think this is an eminently solvable problem; we just need to convince someone to look at it. And as engineers, the main way we have to effect that is to bring it up, like you did. So thanks. :) -Justin On Sun, Jan 20, 2013 at 2:37 PM, Gregory Szorc g...@mozilla.com wrote: I'm writing to the Platform list as a developer that maintains a significant amount of JavaScript for Firefox. Much of the JavaScript I maintain is for large backend features, such as Sync and Firefox Health Report. These features are thousands of lines of code (mostly JavaScript) and interact with many systems in Firefox. These backend systems tend to perform many of the same tasks, so there is code shared between them in the form of JSMs. To reduce redundant code (therefore bugs) and development costs, there is obviously the incentive to share as much code as possible. I'd like to start a discussion about an issue that has been troubling me for a while: the performance overhead of separate compartments per JSM. I've previously brought this up in bugs and with a few individuals. I wanted to raise awareness by posting here. I apologize in advance if I make a few semantic mistakes on things like globals and compartments and the overhead of cross-compartment operations: I'm not a core platform hacker! Ever since Compartment per Global (CPG) landed, JS modules imported with Cu.import now get their own compartment (at least on desktop Firefox - I'm told they share a compartment on B2G for performance reasons). This is all nice in theory. You even get a line item in about:memory to see if your module is doing anything wonky! Unfortunately, this change has a few unfortunate side-effects: a) Memory overhead for each compartment b) Perf losses due to crossing compartments Assuming the about:memory compartment numbers are correct, each imported JS module seems to consume at *least* ~55kb (numbers are similar on both OS X and Windows Nightly builds). Furthermore, there appear to be some scenarios where crossing compartments has a horrible effect on performance. For example, it is my understanding that crossing compartments can sometimes copy data. I believe this always holds for strings. See bug 806087 for example. Hundreds of MBs of string-chars/huge are seemingly being copied between JSMs/compartments. While this specific bug number is resolved, the underlying copying issue remains AFAIK. Sadly, these two issues have a negative influence on how I write JavaScript code. I'm of the camp that tends to write many, small, standalone JSMs rather than large and monolithic ones. I find the resulting code is easier to comprehend and test. As an added bonus, anybody can come along later and reuse an individual module. This includes add-ons. Yay code reuse! The end result is less overall code being written and debugged and higher test coverage. I like to think this means the quality of the code base is higher and new features can be rolled out quicker (due to code reuse). I hold strong convictions that this code architecture is superior. With separate compartments per module, I've been put in a tough position. I have to weigh the code maintainability advantages of multiple modules against memory usage and performance overhead. If I create dozens of small, reusable, and specifically-targeted JSMs, I've got the Perf team giving me the stink eye for increasing memory usage and cross-compartment overhead. If I write JSMs that are thousands of lines long, I'm creating technical debt and increasing the barrier to change. This is a Kobayashi Maru (no win) scenario. Firefox and other Gecko apps suffer with both ends of the spectrum. Finding a compromise between the two extremes is difficult if not impossible in some scenarios. Furthermore, code is always changing thus the conditions influencing the decision are always changing. That's my
Re: Effects of JSM Compartments on Performance and Development Practices
I have some shared concerns, given that I am one of the persons involved in the ongoing heavy refactoring on Session Restore, which for some users needs to deal with 50Mb+ strings sent across JSMs. At the moment, my main worry is not memory usage (yet) but string copying. Cheers, David signature.asc Description: OpenPGP digital signature ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform