Re: Effects of JSM Compartments on Performance and Development Practices

2013-02-07 Thread Nicholas Nethercote
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

2013-01-22 Thread Boris Zbarsky

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

2013-01-22 Thread Boris Zbarsky

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

2013-01-22 Thread Nicholas Nethercote
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

2013-01-20 Thread Gregory Szorc
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

2013-01-20 Thread Justin Lebar
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

2013-01-20 Thread David Rajchenbach-Teller
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