However we hear of three different potential performance problems:
1) no caching of compiled JS,
2) overhead from creating and preparing each sandbox with its own JS
stuff,
3) run-time overhead from calls between functions defined in
different sandboxes.
The first two are easily solved by moving the loading off the startup
event. The third one concerns me since I don't know how to measure it
in a meaningful way. I suppose we could load all of our modules in to
one sandbox to workaround this, but I don't want to do that unless we
are really solving a problem. Any other information or ideas?
jjb
Andreas
> _______________________________________________
> dev-platform mailing list
> dev-pl...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-platform
Any idea on how much memory? Is it fixed or variable size?
It would be helpful if I had some model for what a compartment is.
Or is there any way to erase the global state in a sandbox? Here is what
I am imagining:
create sandbox object,
add some special properties, <------------------------+
run some code, which creates some more properties |
clean ---------------------------------------------- +
Could it be as simple as iterating the sandbox and deleting properties?
jjb
sizeof(JSCompartments) is 4660 bytes on 32-bit and 8496 bytes on
64-bit, so that's the baseline cost. I don't know about the
variable-sized overheads.
> It would be helpful if I had some model for what a compartment is.
http://andreasgal.wordpress.com/2010/10/13/compartments/ is a nice
write-up on compartments.
Nick
The top properties we need is ability to control loading and to
understand the result of loading so we can debug code. Next comes code
isolation so we can use the same technology for content. Then comes
runtime performance. At the bottom is internal scope isolation and
startup performance.
Cu.import has the opposite characteristics for the most part. It has
great startup and runtime performance, but we can't use it for content
and the scope of imported code is funky (maybe the second arg helps I
don't know). But the caching means we can't reload so it's out unless we
could be 100% dead sure there was a way to avoid it.
I'm beginning to think we should have stuck with <script> tags. Our
total investment in this minor module thing is threatening our project.
jjb
Cu.import is not exactly as you described. a) the second argument
provided can be used as the global, something like this:
var glob = {};
Cu.import("path-to-script", glob);
All the properties in the script that are exported are then accessible
on glob. Otherwise (e.g. without the second argument) it is imported
into the global object of the running context and is accessible
globally (like any global object).
b) Cu.import caching doesn't work like you seem to think. It caches
the script so that all scripts get it and it only has to compile it
once. Past that, properties changed on the cached script will be
visible to all imports of that script (see the docs for exactly how
this works in general).
I'm not sure why you need to reload scripts so I obviously can't
comment on that. But, if you could use Cu.import just for the chrome
scripts and evalInSandbox for the content scripts I'm sure it would
help some...
But what does the outer most scope look like in the debugger? glob? Hey
it could be simple, but do you know?
>
> b) Cu.import caching doesn't work like you seem to think. It caches
> the script so that all scripts get it and it only has to compile it
> once. Past that, properties changed on the cached script will be
> visible to all imports of that script (see the docs for exactly how
> this works in general).
Actually we replaced all our uses of XPCOM components with Cu.imports
last year some time, so I'm familiar with it. (The docs don't include
the entire story, see https://bugzilla.mozilla.org/show_bug.cgi?id=531886)
>
> I'm not sure why you need to reload scripts so I obviously can't
> comment on that.
So edits on source can be loaded without restarting the browser.
> But, if you could use Cu.import just for the chrome
> scripts and evalInSandbox for the content scripts I'm sure it would
> help some...
Yes, thanks, I appreciate all the information we can get about this
stuff. So I want to explain why I'm listening but not taking action ;-)
Optimization, by it nature, needs to focus on the most critical
resource. In our case it's developer time. So if something works, the
alternative needs to be really compelling. There are more issue with
evalInSandbox than I knew about, so the case is stronger. If someone
else wants to work through the issues and show Cu.import is better in
Firebug, great, I'm all for it. But if we can't get Firebug up on
multiprocess, being a bit faster on startup or a smaller memory won't
matter.
jjb
> Cu.import has the opposite characteristics for the most part. It has
> great startup and runtime performance, but we can't use it for content
> and the scope of imported code is funky
Not sure what you mean there. Cu.import simply copies the exported
symbols from the scope in which the module was compiled into the scope
passed as the second parameter (or the scope in which Components was
defined if no scope was provided). It's like a website with a frame in
it and script in the frame has var foo = parent.foo; foo(); to call a
function defined in the parent frame.
--
Warning: May contain traces of nuts.
What I find 'funky' is the result of:
var scope = frame.scope;
while(scope.jsParent)
scope = scope.jsParent;
for the stack frame of Cu.import compiles. For script tags, evals, and
such in an nsIDOMWindow, the |scope| will be the nsIDOMWindow. In the
Cu.imports case it looks like some kind of dumping ground. (If you run
Chromebug, it's the content of the DOM panel for the BackstagePass
context. To be sure I'm a little unclear whether this |scope| is related
to the Cu.import or perhaps it's from an xpcom component that issues
Cu.import?
If I set a breakpoint in a function compiled in browser.xul and single
step into a Cu.import which does not use the second argument, the outer
most scope (BackstagePass Scope) looks like the file-scope for the
imported file. This makes sense to me. I don't understand how to get
this object at the compile point.
jjb
There is a bugzilla entry for that (though not the one you posted). So yeah, Cu.import wouldn't be ideal while developing. Now I understand. Still, end users are not editing firebug code, so I don't think we need them to go through slowness. But the two different environments does mean testing two times. Maybe the fix will be in by the time we ship 1.8, and the point will be moot. In the mean time we use evalInSandbox. It will be nice to change the firebug code and not have to restart Firefox!
> for the stack frame of Cu.import compiles. For script tags, evals, and
> such in an nsIDOMWindow, the |scope| will be the nsIDOMWindow.
Wouldn't this be the same:
Cu.import(sciptfile, |window|);
?
Or better (but untested):
var scope = {window: |window|};
Cu.import(scriptfile, scope);
So now I think we ought to keep the evalInSandbox until Cu.import is improved to do what we want it to do. Do we have bugzilla entries for what we want out of Cu.import? Do we want something like import(file, scope, topwindow, reload?)? Something else?
-steve--
> What I find 'funky' is the result of:
> var scope = frame.scope;
> while(scope.jsParent)
> scope = scope.jsParent;
> for the stack frame of Cu.import compiles. For script tags, evals, and
> such in an nsIDOMWindow, the |scope| will be the nsIDOMWindow. In the
> Cu.imports case it looks like some kind of dumping ground. (If you run
> Chromebug, it's the content of the DOM panel for the BackstagePass
> context. To be sure I'm a little unclear whether this |scope| is
> related to the Cu.import or perhaps it's from an xpcom component that
> issues Cu.import?
Just as each JS-based XPCOM component has its own BackstagePass global
scope, so does each JS module. The only difference lies in the way that
the code is accessed from other script; in the case of a module, you
import the exported symbols; in the case of a component, you get a
service/create an instance of it.
So in the end there are two differences between Cu.import and XPCOM
components on the one side and Cu.sandbox/evalInSandbox on the other:
1) A new set of JavaScript globals is created for each sandbox,
2) Unless you turn off wrappers, evalInSandbox wraps everything.
(The first one isn't in the docs as I recall, the second one is in the
docs "backwards", the description makes me think the result is opposite
of what it actually is.
jjb