On Tuesday, 2011-07-19 at 22:51 , Nickolay Ponomarev wrote:
Hi all,
After seeing Irakli's work on Components.utils.import()-based loader <https://plus.google.com/106343137603240143566/posts/RdDGumbnLmf?hl=en> I've been thinking if maybe sandboxes were a better match for jetpack's modules and page-mods.
Here's a brief comparison of capabilities I put together: https://wiki.mozilla.org/User:Asqueella/Sandboxes
Run code with non-system principal
Multiple "instances" of the same code (page-mods, unit-test)
Unloadable
Many extra globals: atob, btoa, File, __LOCATION__, __URI__, EXPORTED_SYMBOLS
As far as I know, the main problem with sandboxes is that the code has to be read into a JS string and then passed to evalInSandbox() by the loader, with no caching of compiled code.So maybe adding sandbox.loadScript(url) with the necessary caching would be better than trying to use Cu.import? The loader could also take advantage of this method only when it exists, making older platform versions easier to support.
So maybe adding sandbox.loadScript(url) with the necessary caching would be better than trying to use Cu.import? The loader could also take advantage of this method only when it exists, making older platform versions easier to support.
BTW, it seems that for sandboxes with the system principal this functionality is already in Firefox 8:
https://bugzilla.mozilla.org/show_bug.cgi?id=648125
http://mxr.mozilla.org/mozilla-central/source/toolkit/mozapps/extensions/XPIProvider.jsm#3457
3461 Components.utils.evalInSandbox(
3462 "Components.classes['@mozilla.org/moz/jssubscript-loader;1'] \
3463 .createInstance(Components.interfaces.mozIJSSubScriptLoader) \
3464 .loadSubScript(__SCRIPT_URI_SPEC__);", .........);
Is there anything I'm missing? Does anyone know the performance/memory characteristics of Sandbox vs Cu.import modules?
Nickolay
--
You received this message because you are subscribed to the Google Groups "mozilla-labs-jetpack" group.
To post to this group, send email to mozilla-la...@googlegroups.com.
To unsubscribe from this group, send email to mozilla-labs-jet...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mozilla-labs-jetpack?hl=en.
On Tuesday, 2011-07-19 at 22:51 , Nickolay Ponomarev wrote:Run code with non-system principal
All jetpack modules run with system principal anyway.
Multiple "instances" of the same code (page-mods, unit-test)I guess we could create multiple modules instances, but as far as I know we don't do it.
UnloadableDo you suggest that sandboxes may be destroyed in some way ?
Many extra globals: atob, btoa, File, __LOCATION__, __URI__, EXPORTED_SYMBOLSActually having atob / boat is awesome, as we won't have to use hidden window for that :D (I did not knew they were there)!!!I agree that those globals are inconvenient, but they can be easily shadowed:
As far as I know, the main problem with sandboxes is that the code has to be read into a JS string and then passed to evalInSandbox() by the loader, with no caching of compiled code.So maybe adding sandbox.loadScript(url) with the necessary caching would be better than trying to use Cu.import? The loader could also take advantage of this method only when it exists, making older platform versions easier to support.So maybe adding sandbox.loadScript(url) with the necessary caching would be better than trying to use Cu.import? The loader could also take advantage of this method only when it exists, making older platform versions easier to support.I don't think compiled code cacheing is relevant, as module from the same url is never executed more than once. We cache module exports so that second require('foo') will return exports from the cache. Also note sure you're aware, SDK modules are bundled with each add-on and are mapped to a diff resource URIs, which means that exact same sdk module is executed per addon.
On Tuesday, 2011-07-19 at 22:51 , Nickolay Ponomarev wrote:Here's a brief comparison of capabilities I put together: https://wiki.mozilla.org/User:Asqueella/SandboxesHere is few comments on that:Run code with non-system principalAll jetpack modules run with system principal anyway.
Multiple "instances" of the same code (page-mods, unit-test)I guess we could create multiple modules instances, but as far as I know we don't do it.
UnloadableDo you suggest that sandboxes may be destroyed in some way ?
Many extra globals: atob, btoa, File, __LOCATION__, __URI__, EXPORTED_SYMBOLSActually having atob / boat is awesome, as we won't have to use hidden window for that :D (I did not knew they were there)!!!I agree that those globals are inconvenient, but they can be easily shadowed:
As far as I know, the main problem with sandboxes [...] no caching of compiled code.
I don't think compiled code cacheing is relevant, as module from the same url is never executed more than once.
We cache module exports so that second require('foo') will return exports from the cache. Also note sure you're aware, SDK modules are bundled with each add-on and are mapped to a diff resource URIs, which means that exact same sdk module is executed per addon.
Is there anything I'm missing? Does anyone know the performance/memory characteristics of Sandbox vs Cu.import modules?
Main reason I've started with this loader is to simplify complexity of the current loader and offloading as much to the platform as possible. So ideas is to replace all of this:
From my point of view, I think that the main drawback of Cu.import is the lack of control of the JS context. We can't set our custom principal, nor JS version.
So it is obvious that we have to improve our performances [...] Then, from what I know, we have only two options: Cu.import or loadSubScript.
[...]
Finally, I would say that the priority is to simplify our codebase with proposal like Irakli's loader, then improving performance is going to be wayyyy simplier!
On Wednesday, 2011-07-20 at 21:35 , Nickolay Ponomarev wrote:
Hi,
Thanks for your reply! I'll reply both to you and (indirectly) Dave here, since you raise similar points.
On Wed, Jul 20, 2011 at 4:52 AM, Irakli Gozalishvili <rfo...@gmail.com> wrote:On Tuesday, 2011-07-19 at 22:51 , Nickolay Ponomarev wrote:Here's a brief comparison of capabilities I put together: https://wiki.mozilla.org/User:Asqueella/SandboxesHere is few comments on that:Run code with non-system principalAll jetpack modules run with system principal anyway.At this time yes, but there have been plans to change that for a while (e.g. your own https://bugzilla.mozilla.org/show_bug.cgi?id=636145, mentioned by Alexandre in another post here).
Multiple "instances" of the same code (page-mods, unit-test)I guess we could create multiple modules instances, but as far as I know we don't do it.
We do in unit-tests, as I mentioned, and it's worth keeping in mind:
http://www.google.com/codesearch#search/&q=require%5C%28%22cuddlefish%22%5C%29%20package:git://github.com/mozilla/addon-sdk.git&type=cs
http://www.google.com/codesearch#search/&q=makesandboxedloader%20package:git://github.com/mozilla/addon-sdk.git&type=cs
Page-mods are essentially multiple copies of the same code running in different context. jsm modules cannot be used for that, while page-mods would most benefit from the caching, as discussed below.
UnloadableDo you suggest that sandboxes may be destroyed in some way ?
Sandboxes participate in GC (that's what makes uninstall-without-restart work), while Cu.import modules are rooted and the knob to unload them only appeared in a recent Firefox version.
Many extra globals: atob, btoa, File, __LOCATION__, __URI__, EXPORTED_SYMBOLSActually having atob / boat is awesome, as we won't have to use hidden window for that :D (I did not knew they were there)!!!I agree that those globals are inconvenient, but they can be easily shadowed:
Arguably, with the module system you want to have a clean slate with a bunch of modules you can import to get the necessary functionality. That reduces the amount of magic (c.f. your comment about atob), so it's easier to learn and understand.
As far as I know, the main problem with sandboxes [...] no caching of compiled code.I don't think compiled code cacheing is relevant, as module from the same url is never executed more than once....per startup. It's very much relevant. otherwise there would be no startup cache for Firefox code. See my earlier post http://groups.google.com/group/mozilla-labs-jetpack/browse_thread/thread/6d0b8401ba698f36/842af69769b09bcc , where I cite 25% loss (200ms on my old laptop) in startup performance for a simple add-on, of which 25% is spent compiling and evaluating the JS code. (This doesn't allow to estimate the exact wins from caching, but shows there's a room to improve.)
Also, please keep the page-mods in mind. Their code is re-evaluated for *every page load*.
We cache module exports so that second require('foo') will return exports from the cache. Also note sure you're aware, SDK modules are bundled with each add-on and are mapped to a diff resource URIs, which means that exact same sdk module is executed per addon.
Thanks, I know that.
Is there anything I'm missing? Does anyone know the performance/memory characteristics of Sandbox vs Cu.import modules?
Main reason I've started with this loader is to simplify complexity of the current loader and offloading as much to the platform as possible. So ideas is to replace all of this:
I'm very much on board with the simplification of the loader, since I had to read through that code a few times! Thanks for doing that, by the way!
It's just that seeing someone actually try changing sandboxes to jsm modules made me think about their pros and cons.
On 7/19/11 9:51 PM, Dave Townsend wrote:
>
> I think in general you want the system principal right now. Presumably
> you could also load a couple of small parts of code into a sandbox
> somehow should you require a non-system principal for a specific set
> of code.
As Alexandre has been working on in 636145, we'd really like for only
the lowest-level require("chrome")-using modules to have the system
principal, and for the rest to be denied XPCOM access. That's critical
to allow security reviews of non-chrome modules to rely upon their
dependencies list (the module-graph "manifest") as providing an upper
bound on the module's authority.
> I actually think that (with proper version handling) allowing multiple
> add-ons to essentially access the same SDK modules would be a great
> way to save the performance hit per add-on. Perhaps that doesn't make
> a difference once we're in an e10s world though.
It should still be an option, though: putting multiple add-ons in the
same process ought to save us memory on the shared components.
There's a security angle here too. Sharing module instances enables
communication: if your add-on and my add-on both do
require("something"), and something.js has set/get methods, we can send
information and objects through it. The common module must be a willing
participant (it may be possible to audit the code to prove it posesses a
property named "DeepFrozen", in which case it cannot act as a
communication channel, but that's a much bigger project[1]).
From a what-authority-does-require()-grant-you point of view, importing
a module that doesn't itself include any other dependencies shouldn't
give you any new powers: reviewers should be able to treat that just
like manually pasting in the contents of the included module, so no
difference between:
foo.js:
require("bar").blah()
bar.js:
exports.blah = function() {print("hello");}
and:
foo.js:
tmp.blah = function() {print("hello");}
blah()
But shared instances gives more power than that: it lets you collude
with other users. If bar.js looks like:
var shared;
exports.set = function(value) {shared=value;}
exports.get = function() {return shared;}
then there's a big difference between bar.js being interpolated/pasted
in, versus it living in a single shared instance.
That said, jetpack currently uses shared instances of modules within a
single add-on, because that's absolutely necessary to make most of our
APIs work, and we just all remember that shared nodes in the module
graph enable collusion.
cheers,
-Brian
[1]: http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.123.9021
http://wiki.erights.org/wiki/DeepFrozen