Open
Bug 1164389
Opened 10 years ago
Updated 2 years ago
Allow certified applications to load XDR bytecode
Categories
(Core :: Networking: Cache, defect, P5)
Core
Networking: Cache
Tracking
()
NEW
People
(Reporter: vingtetun, Unassigned)
References
(Blocks 1 open bug)
Details
(Whiteboard: [necko-would-take])
Attachments
(8 files, 9 obsolete files)
3.51 KB,
text/x-log
|
Details | |
7.49 KB,
patch
|
bzbarsky
:
review-
|
Details | Diff | Splinter Review |
4.95 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
1.97 KB,
patch
|
jandem
:
review+
|
Details | Diff | Splinter Review |
3.76 KB,
patch
|
bzbarsky
:
review-
|
Details | Diff | Splinter Review |
3.89 KB,
patch
|
bzbarsky
:
review+
|
Details | Diff | Splinter Review |
4.99 KB,
patch
|
bzbarsky
:
review-
|
Details | Diff | Splinter Review |
10.28 KB,
patch
|
Details | Diff | Splinter Review |
This bug is about caching XDR'ed bytecode of JS files that has already been encountered into Necko Cache. So the next time the user is visiting a web site it should spend less time in the js engine.
I have opened this bug under Networking:Cache as I believe this is more a matter of where to save the bytecode than fixing the JS engine so it works (in fact most of the necessary code is already there).
Reporter | ||
Comment 1•10 years ago
|
||
Reporter | ||
Comment 2•10 years ago
|
||
Reporter | ||
Comment 3•10 years ago
|
||
Reporter | ||
Comment 4•10 years ago
|
||
Reporter | ||
Comment 5•10 years ago
|
||
Reporter | ||
Comment 6•10 years ago
|
||
Reporter | ||
Comment 7•10 years ago
|
||
Reporter | ||
Comment 8•10 years ago
|
||
Reporter | ||
Comment 9•10 years ago
|
||
This is hard for me to get performance infos of this patch for the general Firefox navigation use case.
It seems like most of the scripts pages are not cached, which is a bit weird when I compare the caching results with Chrome. Also nsICacheInfoChannel.isFromCache always returns false, even if I can access the mCacheEntry of the related http channel. I wonder if something is broken here.
In order to have some results for Gaia I fix the build system to emit bytecode directly and use that into the apps.
I also fix the build system to wrap all the code into a 'function foo() { ...code... }' so nothing is executed and we should benefit from lazy parsing in the case of the non-bytecode version.
I made a few changes again to have non-bytecode script version that are not jsminified, and to have bytecode that is not-compressed, compressed using speed compression, and compressed using best compression.
On desktop the results are (time is expressed in ms and the time is the result of the delta of afterexecute and beforeexecute which may miss some of the optimization in the bytecode case where we can avoid the calling ConvertToUTF16 onto all the source).
system.nojsmin.js: 82.63578299999998"
system.js: 52.64361299999999"
system.bytecode.no.compression.js: 11.779291999999998
system.bytecode.best.compression.js: 10.19159400000001
system.bytecode.speed.compression.js: 11.729264000000057
On device the results are similar except that the device is obviously slower that the desktop.
Content JS LOG: system.nojsmin.js: 617.3321880000001
system.bytecode.no.compression.js: 157.42744800000014
system.bytecode.best.compression.js: 99.32276000000002
system.bytecode.speed.compression.js: 83.63124999999968
No code is executed. This is just loading the content of the scripts files.
Also the bytecode generation is very dumb for now, it just takes all the script content and generate all the bytecode. I believe that a smarter approach with lazy bytecode generation for what is really used at startup could bring better results.
Reporter | ||
Comment 10•10 years ago
|
||
Seems like I forgot the result for the minified version of system.js running on the device in the previous comment:
system.js: 410.60885399999984
Comment 11•10 years ago
|
||
Hi Vivien! It's exciting to see all this progress on caching. This is something we've been talking about and wanting for a while.
For the benefit of people less familiar all the parts you're touching in the patches, can you explain the high-level strategy used here and is it for all content or just b2g app content?
Comment 12•10 years ago
|
||
Comment on attachment 8605167 [details] [diff] [review]
Part 3 - Add a JS_IsXDRBytecode to the jsapi.
Review of attachment 8605167 [details] [diff] [review]:
-----------------------------------------------------------------
This patch sounds good, still I wonder how we handle it for XUL caches.
::: js/src/jsapi.cpp
@@ +5926,5 @@
> return funobj;
> }
>
> +JS_PUBLIC_API(bool)
> +JS_IsXDRBytecode(const void* data, uint32_t length)
Rename this function JS_CanDecodeBytecode, and use XDRDecoder with VersionCheck instead of duplicating the code.
To remove the error message produced by CheckVersion, use "cx->clearPendingException();".
Reporter | ||
Comment 13•10 years ago
|
||
(In reply to Luke Wagner [:luke] from comment #11)
> For the benefit of people less familiar all the parts you're touching in the
> patches, can you explain the high-level strategy used here and is it for all
> content or just b2g app content?
Hi Luke.
The patches are divided in 2 sets (Part 1-5 and Part 6-8):
1. Load build time generated bytecode instead of the raw source file for js scripts.
Benefits:
- No additional IO.
- No need to convert the script data to utf-16
Downsides:
- Whole bytecode generated at build time.
- No recovery mechanism, so bytecode datas needs to be valid.
- Potential security issues. The bytecode should only be loaded by a source of trust (certified app).
2. Generate bytecode on the fly and store it into the HTTP cache as binary metadata. Re-use the previously generated bytecode when navigating if any.
Benefits:
- Easy recovery mechanism. The original source if available as raw data if the bytecode is incorrect.
- Bytecode can be generated during navigation.
Downsides:
- Additional IO to read/write the metadatas
The first set works only for Gaia certified apps *bytecode generated at build time).
The second set works for all script content that is retrieved into an HTML document (bytecode generated during navigation).
One of the goal would be to accumulate the benefits of the 2 approaches when there is a Service Worker installed.
When a new file will is saved into the Service Worker cache, then Gecko can generate the bytecode for the targeted file into a custom cache. When there is a XDR update, this cache could be invalidated.
The custom cache would be used as the content of the script instead of the raw source file.
Then we could have the best of both worlds. None of the necessary code is here for that, but it would be nice.
Also one thing I don't particularly like at the moment, is the fact that the whole bytecode is generated and saved. I assume that it implies that all the JS objects will be regenerated when the bytecode is decoded, even if those are never used.
I think that at some point it would be nice to save only the necessary bytecode that the page needs. It would means that the script needs to run at some point.
While I think this will be more efficient, I also believe this is out of the scope of this bug and can be done as an enhancement (the patch also contains a pref to enable/disable bytecode caching until it is ready).
Also the things that does not work with those patches:
- <script async>. I'm not sure JS_DecodeScript can be called out of the main thread ?
- scripts loaded into a web workers (should be easy to fix in dom/workers/nsScriptLoader.cpp)
- The http cache seems to work but I'm pretty sure I broke a few things with the addition of binary metadata
Comment 14•10 years ago
|
||
Thanks for the explanation! A few comments/questions:
- Have you considered building on the existing 'precompile' FFOS manifest option (https://developer.mozilla.org/en-US/Apps/Build/Manifest#precompile)? This would allow each app (not just certified apps) to opt in on a file-by-file basis (which could give a coarse-granularity solution to the problem you stated of cold code). 'precompile' also allows the first run experience to be a guaranteed a cache hit. Also, iiuc, we re-do precompilation upon Gecko upgrade. For asm.js, the cached machine code goes into persistent storage, so it won't be evicted until the app is uninstalled so the cache hit is guaranteed; we could do the same for the bytecode cache.
- Have you measured the size difference between gzipped source and gzipped XDR bytecode? IIRC, gzipped XDR bytecode was bigger which raises I/O throughput concerns. This is what suggested the hybrid approach nbp and I had discussed (but is harder and requires JS engine support).
- For web content, how does function.toSource() work?
Reporter | ||
Comment 15•10 years ago
|
||
(In reply to Luke Wagner [:luke] from comment #14)
> Thanks for the explanation! A few comments/questions:
>
> - Have you considered building on the existing 'precompile' FFOS manifest
> option (https://developer.mozilla.org/en-US/Apps/Build/Manifest#precompile)?
> This would allow each app (not just certified apps) to opt in on a
> file-by-file basis (which could give a coarse-granularity solution to the
> problem you stated of cold code). 'precompile' also allows the first run
> experience to be a guaranteed a cache hit. Also, iiuc, we re-do
> precompilation upon Gecko upgrade. For asm.js, the cached machine code goes
> into persistent storage, so it won't be evicted until the app is uninstalled
> so the cache hit is guaranteed; we could do the same for the bytecode cache.
>
I looked at the precompile options and considered it. But it would mean the bytecode cache is install time related. This seems still a valid options instead of generating bytecode at build time for Gaia, but it seems a bit more work and maybe a bit less efficient since the source file (containing the bytecode) will not be contained into the original zip anymore and there will be a few more file pointer to pass from the parent process to the child process. (maybe this is an invalid concern from my side ?).
But I admit that it would works for non-Gaia apps as well, which is cool.
On the other side betting on binding the bytecode cache logic to ServiceWorker cache updates seems to have more advantages to me.
Service Worker will likely be the new AppCache of apps. It will work for non packaged content as well as packaged content and even websites which want to install some content offline.
It will also let us experiment (from the app side) with generating js files optimized for startup at runtime. Those js files will then be saved in the ServiceWorker cache, which may then generate the appropriate bytecode for those custom js files.
I realize that this explanation may be unclear. Please let me know if it is.
> - Have you measured the size difference between gzipped source and gzipped
> XDR bytecode? IIRC, gzipped XDR bytecode was bigger which raises I/O
> throughput concerns. This is what suggested the hybrid approach nbp and I
> had discussed (but is harder and requires JS engine support).
I have some raw numbers from the Gaia build system (attached).
Format is: filename ( bytecode_size_in_bytes / original_size_in_bytes) = %
The numbers shows clearly that gzipped XDR bytecode is bigger for the Gaia case.
>
> - For web content, how does function.toSource() work?
Per http://mxr.mozilla.org/mozilla-central/source/js/src/jsscript.cpp#1927 my understanding is that the source part living in the XDR bytecode is used as the compressed source data.
Calling func.toSource() by hand seems to work too.
Comment 16•10 years ago
|
||
Just a note that storing large data to metadata of an http cache entry may be highly inefficient. What you do sounds more like a stream based stuff. Also, this will be held in memory until the entry is released from memory. We keep entries for some time and have a limit for them (based on memory consumption.) You'll completely break efficiency with this. Michal Novotny may also know more.
Comment 17•10 years ago
|
||
(In reply to Vivien Nicolas (:vingtetun) (:21) - (NOT reading bugmails, needinfo? please) from comment #15)
> I looked at the precompile options and considered it. But it would mean the
> bytecode cache is install time related. This seems still a valid options
> instead of generating bytecode at build time for Gaia, but it seems a bit
> more work and maybe a bit less efficient since the source file (containing
> the bytecode) will not be contained into the original zip anymore and there
> will be a few more file pointer to pass from the parent process to the child
> process. (maybe this is an invalid concern from my side ?).
Ahhh, I missed that you're talking about serializing the XDR at build time. Since the XDR format will change subtly with every Gecko build, that means that every Gecko update would necessarily need a lockstep Gaia build (but perhaps this is the case already?). You're right that build-time XDR can be more efficient by design, but I wonder by how much.
> But I admit that it would works for non-Gaia apps as well, which is cool.
I was wondering if this could be unified with caching of normal web content as well: rather than integrating at the HTTP cache level (which it sounds like has some issues in comment 16), we could put the cache in front of the network. This would also be good since, iiuc, services workers will use the Cache API to service requests and thus there is no HTTP request. Is this what you were also getting at in your discussion of service workers?
> I have some raw numbers from the Gaia build system (attached).
> Format is: filename ( bytecode_size_in_bytes / original_size_in_bytes) = %
> The numbers shows clearly that gzipped XDR bytecode is bigger for the Gaia
> case.
Thanks! It'd be good to get some comparison of the speedup (from avoiding parsing) compared to slowdown (from extra file i/o). The hard thing is that i/o speed is going to be highly variable, so it'd be good to measure on different mobile devices and also in different context (e.g., right after phone boot, there might be a lot of competing I/O). This is what Taras Glek was worried about and why he had a little campaign to remove the Firefox (desktop) fastload/startup cache (which XDRs chrome JS files). Ultimately, I don't think he found the numbers to justify it, but that was desktop I/O performance.
> > - For web content, how does function.toSource() work?
>
> Per http://mxr.mozilla.org/mozilla-central/source/js/src/jsscript.cpp#1927
> my understanding is that the source part living in the XDR bytecode is used
> as the compressed source data.
>
> Calling func.toSource() by hand seems to work too.
Ah hah, I didn't know we had the option to embed compressed source in XDR! Looks like we only do this if (hasSource && !sourceRetrievable_) so I'm guessing you're setting !sourceRetrievable here.
Reporter | ||
Comment 18•10 years ago
|
||
(In reply to Luke Wagner [:luke] from comment #17)
> (In reply to Vivien Nicolas (:vingtetun) (:21) - (NOT reading bugmails,
> needinfo? please) from comment #15)
> > I looked at the precompile options and considered it. But it would mean the
> > bytecode cache is install time related. This seems still a valid options
> > instead of generating bytecode at build time for Gaia, but it seems a bit
> > more work and maybe a bit less efficient since the source file (containing
> > the bytecode) will not be contained into the original zip anymore and there
> > will be a few more file pointer to pass from the parent process to the child
> > process. (maybe this is an invalid concern from my side ?).
>
> Ahhh, I missed that you're talking about serializing the XDR at build time.
> Since the XDR format will change subtly with every Gecko build, that means
> that every Gecko update would necessarily need a lockstep Gaia build (but
> perhaps this is the case already?). You're right that build-time XDR can be
> more efficient by design, but I wonder by how much.
>
As you guess Gecko and Gaia build steps are deeply linked for the moment. This is mostly because of the b2g update mechanism where everything is updated at the same time.
This is something I would like to break by moving Gaia to use Service Workers. So this is not an assumption that would always be true.
> > But I admit that it would works for non-Gaia apps as well, which is cool.
>
> I was wondering if this could be unified with caching of normal web content
> as well: rather than integrating at the HTTP cache level (which it sounds
> like has some issues in comment 16), we could put the cache in front of the
> network. This would also be good since, iiuc, services workers will use the
> Cache API to service requests and thus there is no HTTP request. Is this
> what you were also getting at in your discussion of service workers?
>
I was thinking of a custom code path for Service Worker based on their current storage backend mechanism (which may change for performance reasons if I have understood things correctly).
But if normal web content and Service Worker could benefit from a single implementation that may be better.
The things that worries me is having to rewrite some of the http cache mechanism related to update/ eviction of entries. Seems a lot of work and bugs.
> > I have some raw numbers from the Gaia build system (attached).
> > Format is: filename ( bytecode_size_in_bytes / original_size_in_bytes) = %
> > The numbers shows clearly that gzipped XDR bytecode is bigger for the Gaia
> > case.
>
> Thanks! It'd be good to get some comparison of the speedup (from avoiding
> parsing) compared to slowdown (from extra file i/o). The hard thing is that
> i/o speed is going to be highly variable, so it'd be good to measure on
> different mobile devices and also in different context (e.g., right after
> phone boot, there might be a lot of competing I/O). This is what Taras Glek
> was worried about and why he had a little campaign to remove the Firefox
> (desktop) fastload/startup cache (which XDRs chrome JS files). Ultimately,
> I don't think he found the numbers to justify it, but that was desktop I/O
> performance.
>
Agreed that having such numbers would be definitively useful. Is it OK to have a JS file similar to:
function foo() {
// 1 line of comment
// 2 lines of comment
...
// n lines of comment
}
and have |n| a variable number ? Or do we need real JS code to measure the parser ?
My current understanding of how the JS engine works, is that even with lazy parsing there is a need to do a pass on every character to ensure there is no syntax errors. Is it correct ?
> > > - For web content, how does function.toSource() work?
> >
> > Per http://mxr.mozilla.org/mozilla-central/source/js/src/jsscript.cpp#1927
> > my understanding is that the source part living in the XDR bytecode is used
> > as the compressed source data.
> >
> > Calling func.toSource() by hand seems to work too.
>
> Ah hah, I didn't know we had the option to embed compressed source in XDR!
> Looks like we only do this if (hasSource && !sourceRetrievable_) so I'm
> guessing you're setting !sourceRetrievable here.
Likely. But to be honest it was pure luck :)
Comment 19•10 years ago
|
||
(In reply to Vivien Nicolas (:vingtetun) (:21) - (NOT reading bugmails, needinfo? please) from comment #18)
> My current understanding of how the JS engine works, is that even with lazy
> parsing there is a need to do a pass on every character to ensure there is
> no syntax errors. Is it correct ?
I believe so, though I'm no expert. But I wanted to mention bug 1154987 and related work - it might be good to coordinate with Kannan to some degree.
Comment 20•10 years ago
|
||
(In reply to Vivien Nicolas (:vingtetun) (:21) - from comment #18)
> My current understanding of how the JS engine works, is that even with lazy
> parsing there is a need to do a pass on every character to ensure there is
> no syntax errors. Is it correct ?
Well, the cost is highly variable, depending on what is being parsed so, e.g., comments are going to parse a whole lot faster than normal JS code full of identifiers. The best thing would be to use real Gaia code (I was guessing from your posted patch queue that you already had a working prototype so it'd mostly be a matter of instrumenting what you have).
Reporter | ||
Updated•10 years ago
|
Blocks: nga-performance
Comment 21•9 years ago
|
||
Finally spent a bit of time to get some numbers here.
The datas are formatted in such a way:
App Title
- Result 1 for a run with GAIA_OPTIMIZE=1 (basically jsmin on all scripts)
- Result 2 for a run with GAIA_OPTIMIZE=3 (all scripts are encoded in bytecode. The resulting file does not contain the original source code).
- Delta between R1 and R2 expressed in ms
- Delta between R1 and R2 expressed in %
The results cames from raptor (https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Automated_testing/Raptor) which is what B2G use to see app performances data.
What it means is that the values expressed in those results are not pure JS but real page load with html,css, images and JS.
Also the results here are only with the set of patches part 1-5. No HTTP Cache involved here. Which basically correspond to how I would like this to land at first until Necko is ready to share a unique identifier for cached resources.
fm
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.navigationLoaded | 255.900 | 254.000 | 226.000 | 299.000 | 23.300 | 299.000 |
| coldlaunch.navigationInteractive | 337.500 | 333.000 | 300.000 | 392.000 | 26.352 | 392.000 |
| coldlaunch.visuallyLoaded | 337.600 | 333.000 | 300.000 | 392.000 | 26.269 | 392.000 |
| coldlaunch.contentInteractive | 337.600 | 333.000 | 300.000 | 392.000 | 26.269 | 392.000 |
| coldlaunch.beforefirstpaint | 379.300 | 374.000 | 340.000 | 436.000 | 28.313 | 436.000 |
| coldlaunch.fullyLoaded | 417.200 | 409.500 | 373.000 | 461.000 | 25.055 | 461.000 |
| coldlaunch.uss | 9.900 | 9.900 | 9.900 | 9.900 | 0.000 | 9.900 |
| coldlaunch.pss | 13.900 | 13.900 | 13.900 | 13.900 | 0.000 | 13.900 |
| coldlaunch.rss | 28.340 | 28.300 | 28.300 | 28.400 | 0.049 | 28.400 |
| coldlaunch.firstpaint | 453.000 | 453.000 | 453.000 | 453.000 | 0.000 | n/a |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.navigationLoaded | 214.700 | 209.000 | 191.000 | 311.000 | 33.100 | 311.000 |
| coldlaunch.beforefirstpaint | 338.400 | 333.500 | 318.000 | 362.000 | 14.465 | 362.000 |
| coldlaunch.navigationInteractive | 304.300 | 289.000 | 276.000 | 441.000 | 46.297 | 441.000 |
| coldlaunch.visuallyLoaded | 304.300 | 289.000 | 276.000 | 441.000 | 46.297 | 441.000 |
| coldlaunch.contentInteractive | 304.500 | 289.500 | 276.000 | 441.000 | 46.246 | 441.000 |
| coldlaunch.firstpaint | 387.000 | 374.000 | 355.000 | 450.000 | 32.729 | n/a |
| coldlaunch.fullyLoaded | 434.500 | 392.500 | 355.000 | 612.000 | 80.211 | 612.000 |
| coldlaunch.uss | 9.900 | 9.900 | 9.900 | 9.900 | 0.000 | 9.900 |
| coldlaunch.pss | 13.900 | 13.900 | 13.900 | 13.900 | 0.000 | 13.900 |
| coldlaunch.rss | 28.360 | 28.400 | 28.300 | 28.400 | 0.049 | 28.400 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.beforefirstpaint | -40.90 | -40.50 | -22.00 | -74.00 | -13.85 | -74.00 |
| coldlaunch.contentInteractive | -33.10 | -43.50 | -24.00 | 49.00 | 19.98 | 49.00 |
| coldlaunch.firstpaint | -66.00 | -79.00 | -98.00 | -3.00 | 32.73 | NaN |
| coldlaunch.fullyLoaded | 17.30 | -17.00 | -18.00 | 151.00 | 55.16 | 151.00 |
| coldlaunch.navigationInteractive | -33.20 | -44.00 | -24.00 | 49.00 | 19.94 | 49.00 |
| coldlaunch.navigationLoaded | -41.20 | -45.00 | -35.00 | 12.00 | 9.80 | 12.00 |
| coldlaunch.pss | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
| coldlaunch.rss | 0.02 | 0.10 | 0.00 | 0.00 | 0.00 | 0.00 |
| coldlaunch.uss | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 |
| coldlaunch.visuallyLoaded | -33.30 | -44.00 | -24.00 | 49.00 | 20.03 | 49.00 |
| coldlaunch.beforefirstpaint | -12.09% | -12.14% | -6.92% | -20.44% |-95.73% | -20.44% |
| coldlaunch.contentInteractive | -10.87% | -15.03% | -8.70% | 11.11% | 43.20% | 11.11% |
| coldlaunch.firstpaint | -17.05% | -21.12% | -27.61% | -0.67% |100.00% | NaN% |
| coldlaunch.fullyLoaded | 3.98% | -4.33% | -5.07% | 24.67% | 68.76% | 24.67% |
| coldlaunch.navigationInteractive | -10.91% | -15.22% | -8.70% | 11.11% | 43.08% | 11.11% |
| coldlaunch.navigationLoaded | -19.19% | -21.53% | -18.32% | 3.86% | 29.61% | 3.86% |
| coldlaunch.pss | 0.00% | 0.00% | 0.00% | 0.00% | NaN% | 0.00% |
| coldlaunch.rss | 0.07% | 0.35% | 0.00% | 0.00% | 0.00% | 0.00% |
| coldlaunch.uss | 0.00% | 0.00% | 0.00% | 0.00% | NaN% | 0.00% |
| coldlaunch.visuallyLoaded | -10.94% | -15.22% | -8.70% | 11.11% | 43.26% | 11.11% |
camera
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.navigationLoaded | 654.300 | 641.000 | 615.000 | 724.000 | 36.128 | 724.000 |
| coldlaunch.navigationInteractive | 654.400 | 641.000 | 615.000 | 724.000 | 36.172 | 724.000 |
| coldlaunch.beforefirstpaint | 624.300 | 668.500 | 424.000 | 703.000 | 99.077 | 703.000 |
| coldlaunch.visuallyLoaded | 768.800 | 750.500 | 739.000 | 842.000 | 35.603 | 842.000 |
| coldlaunch.firstpaint | 793.200 | 791.000 | 714.000 | 853.000 | 33.929 | 853.000 |
| coldlaunch.contentInteractive | 1341.100 | 1335.000 | 1280.000 | 1410.000 | 39.856 | 1410.000 |
| coldlaunch.fullyLoaded | 1341.200 | 1335.000 | 1280.000 | 1410.000 | 39.802 | 1410.000 |
| coldlaunch.uss | 13.170 | 13.200 | 13.100 | 13.200 | 0.046 | 13.200 |
| coldlaunch.pss | 17.670 | 17.700 | 17.600 | 17.700 | 0.046 | 17.700 |
| coldlaunch.rss | 33.210 | 33.200 | 33.200 | 33.300 | 0.030 | 33.300 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------- | -------- |
| coldlaunch.beforefirstpaint | 501.200 | 610.000 | 291.000 | 641.000 | 151.576 | 641.000 |
| coldlaunch.navigationLoaded | 617.000 | 604.500 | 567.000 | 686.000 | 43.662 | 686.000 |
| coldlaunch.navigationInteractive | 617.100 | 604.500 | 567.000 | 686.000 | 43.585 | 686.000 |
| coldlaunch.firstpaint | 745.800 | 740.000 | 685.000 | 787.000 | 29.322 | 787.000 |
| coldlaunch.visuallyLoaded | 725.800 | 709.000 | 660.000 | 805.000 | 43.813 | 805.000 |
| coldlaunch.contentInteractive | 1166.200 | 1146.500 | 1110.000 | 1253.000 | 49.364 | 1253.000 |
| coldlaunch.fullyLoaded | 1166.400 | 1147.000 | 1110.000 | 1254.000 | 49.490 | 1254.000 |
| coldlaunch.uss | 12.660 | 12.700 | 12.500 | 12.800 | 0.080 | 12.800 |
| coldlaunch.rss | 32.740 | 32.750 | 32.600 | 32.900 | 0.092 | 32.900 |
| coldlaunch.pss | 17.200 | 17.200 | 17.100 | 17.400 | 0.089 | 17.400 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.beforefirstpaint | -123.10 | -58.50 | -133.00 | -62.00 | 52.50 | -62.00 |
| coldlaunch.contentInteractive | -174.90 | -188.50 | -170.00 | -157.00 | 9.51 | -157.00 |
| coldlaunch.firstpaint | -47.40 | -51.00 | -29.00 | -66.00 | -4.61 | -66.00 |
| coldlaunch.fullyLoaded | -174.80 | -188.00 | -170.00 | -156.00 | 9.69 | -156.00 |
| coldlaunch.navigationInteractive | -37.30 | -36.50 | -48.00 | -38.00 | 7.41 | -38.00 |
| coldlaunch.navigationLoaded | -37.30 | -36.50 | -48.00 | -38.00 | 7.53 | -38.00 |
| coldlaunch.pss | -0.47 | -0.50 | -0.50 | -0.30 | 0.04 | -0.30 |
| coldlaunch.rss | -0.47 | -0.45 | -0.60 | -0.40 | 0.06 | -0.40 |
| coldlaunch.uss | -0.51 | -0.50 | -0.60 | -0.40 | 0.03 | -0.40 |
| coldlaunch.visuallyLoaded | -43.00 | -41.50 | -79.00 | -37.00 | 8.21 | -37.00 |
| coldlaunch.beforefirstpaint | -24.56% | -9.59% | -45.70% | -9.67% | 34.64% | -9.67% |
| coldlaunch.contentInteractive | -15.00% | -16.44% | -15.32% | -12.53% | 19.26% | -12.53% |
| coldlaunch.firstpaint | -6.36% | -6.89% | -4.23% | -8.39% |-15.71% | -8.39% |
| coldlaunch.fullyLoaded | -14.99% | -16.39% | -15.32% | -12.44% | 19.58% | -12.44% |
| coldlaunch.navigationInteractive | -6.04% | -6.04% | -8.47% | -5.54% | 17.01% | -5.54% |
| coldlaunch.navigationLoaded | -6.05% | -6.04% | -8.47% | -5.54% | 17.26% | -5.54% |
| coldlaunch.pss | -2.73% | -2.91% | -2.92% | -1.72% | 48.31% | -1.72% |
| coldlaunch.rss | -1.44% | -1.37% | -1.84% | -1.22% | 67.39% | -1.22% |
| coldlaunch.uss | -4.03% | -3.94% | -4.80% | -3.12% | 42.50% | -3.12% |
| coldlaunch.visuallyLoaded | -5.92% | -5.85% | -11.97% | -4.60% | 18.74% | -4.60% |
video
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.navigationLoaded | 370.900 | 370.000 | 341.000 | 394.000 | 14.467 | 394.000 |
| coldlaunch.navigationInteractive | 377.200 | 376.500 | 348.000 | 400.000 | 14.400 | 400.000 |
| coldlaunch.beforefirstpaint | 383.300 | 382.500 | 353.000 | 406.000 | 14.622 | 406.000 |
| coldlaunch.firstpaint | 410.600 | 413.500 | 376.000 | 437.000 | 16.865 | 437.000 |
| coldlaunch.visuallyLoaded | 604.300 | 615.500 | 476.000 | 647.000 | 46.312 | 647.000 |
| coldlaunch.contentInteractive | 604.400 | 615.500 | 476.000 | 648.000 | 46.405 | 648.000 |
| coldlaunch.fullyLoaded | 1169.200 | 1173.000 | 1082.000 | 1198.000 | 32.674 | 1198.000 |
| coldlaunch.pss | 23.700 | 23.700 | 23.700 | 23.700 | 0.000 | 23.700 |
| coldlaunch.rss | 38.500 | 38.500 | 38.500 | 38.500 | 0.000 | 38.500 |
| coldlaunch.uss | 19.500 | 19.500 | 19.500 | 19.500 | 0.000 | 19.500 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.navigationLoaded | 330.400 | 335.500 | 292.000 | 362.000 | 22.150 | 362.000 |
| coldlaunch.navigationInteractive | 336.400 | 341.500 | 298.000 | 368.000 | 22.258 | 368.000 |
| coldlaunch.beforefirstpaint | 343.600 | 347.000 | 304.000 | 377.000 | 23.005 | 377.000 |
| coldlaunch.firstpaint | 371.800 | 367.500 | 333.000 | 411.000 | 24.351 | 411.000 |
| coldlaunch.visuallyLoaded | 585.000 | 605.000 | 461.000 | 657.000 | 55.281 | 657.000 |
| coldlaunch.contentInteractive | 585.100 | 605.000 | 461.000 | 657.000 | 55.334 | 657.000 |
| coldlaunch.fullyLoaded | 1173.400 | 1200.500 | 1008.000 | 1261.000 | 72.607 | 1261.000 |
| coldlaunch.uss | 19.430 | 19.400 | 19.400 | 19.500 | 0.046 | 19.500 |
| coldlaunch.rss | 38.460 | 38.500 | 38.400 | 38.500 | 0.049 | 38.500 |
| coldlaunch.pss | 23.650 | 23.650 | 23.600 | 23.700 | 0.050 | 23.700 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.beforefirstpaint | -39.70 | -35.50 | -49.00 | -29.00 | 8.38 | -29.00 |
| coldlaunch.contentInteractive | -19.30 | -10.50 | -15.00 | 9.00 | 8.93 | 9.00 |
| coldlaunch.firstpaint | -38.80 | -46.00 | -43.00 | -26.00 | 7.49 | -26.00 |
| coldlaunch.fullyLoaded | 4.20 | 27.50 | -74.00 | 63.00 | 39.93 | 63.00 |
| coldlaunch.navigationInteractive | -40.80 | -35.00 | -50.00 | -32.00 | 7.86 | -32.00 |
| coldlaunch.navigationLoaded | -40.50 | -34.50 | -49.00 | -32.00 | 7.68 | -32.00 |
| coldlaunch.pss | -0.05 | -0.05 | -0.10 | 0.00 | 0.05 | 0.00 |
| coldlaunch.rss | -0.04 | 0.00 | -0.10 | 0.00 | 0.05 | 0.00 |
| coldlaunch.uss | -0.07 | -0.10 | -0.10 | 0.00 | 0.05 | 0.00 |
| coldlaunch.visuallyLoaded | -19.30 | -10.50 | -15.00 | 10.00 | 8.97 | 10.00 |
| coldlaunch.beforefirstpaint | -11.55% | -10.23% | -16.12% | -7.69% | 36.44% | -7.69% |
| coldlaunch.contentInteractive | -3.30% | -1.74% | -3.25% | 1.37% | 16.14% | 1.37% |
| coldlaunch.firstpaint | -10.44% | -12.52% | -12.91% | -6.33% | 30.74% | -6.33% |
| coldlaunch.fullyLoaded | 0.36% | 2.29% | -7.34% | 5.00% | 55.00% | 5.00% |
| coldlaunch.navigationInteractive | -12.13% | -10.25% | -16.78% | -8.70% | 35.30% | -8.70% |
| coldlaunch.navigationLoaded | -12.26% | -10.28% | -16.78% | -8.84% | 34.69% | -8.84% |
| coldlaunch.pss | -0.21% | -0.21% | -0.42% | 0.00% |100.00% | 0.00% |
| coldlaunch.rss | -0.10% | 0.00% | -0.26% | 0.00% |100.00% | 0.00% |
| coldlaunch.uss | -0.36% | -0.52% | -0.52% | 0.00% |100.00% | 0.00% |
| coldlaunch.visuallyLoaded | -3.30% | -1.74% | -3.25% | 1.52% | 16.22% | 1.52% |
music
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.navigationLoaded | 338.100 | 346.500 | 286.000 | 365.000 | 25.610 | 365.000 |
| coldlaunch.navigationInteractive | 424.600 | 435.500 | 347.000 | 459.000 | 33.548 | 459.000 |
| coldlaunch.beforefirstpaint | 467.000 | 474.000 | 421.000 | 500.000 | 26.382 | 500.000 |
| coldlaunch.visuallyLoaded | 550.000 | 550.500 | 502.000 | 589.000 | 23.971 | 589.000 |
| coldlaunch.contentInteractive | 550.000 | 550.500 | 502.000 | 589.000 | 23.971 | 589.000 |
| coldlaunch.firstpaint | 584.700 | 603.500 | 492.000 | 643.000 | 42.853 | 643.000 |
| coldlaunch.fullyLoaded | 1308.800 | 1314.000 | 1193.000 | 1398.000 | 60.249 | 1398.000 |
| coldlaunch.pss | 20.070 | 20.100 | 20.000 | 20.200 | 0.064 | 20.200 |
| coldlaunch.uss | 15.650 | 15.650 | 15.600 | 15.700 | 0.050 | 15.700 |
| coldlaunch.rss | 35.210 | 35.200 | 35.100 | 35.300 | 0.070 | 35.300 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------- | -------- |
| coldlaunch.navigationLoaded | 308.700 | 308.500 | 267.000 | 361.000 | 28.450 | 361.000 |
| coldlaunch.navigationInteractive | 400.700 | 393.500 | 328.000 | 467.000 | 37.797 | 467.000 |
| coldlaunch.beforefirstpaint | 447.000 | 441.500 | 396.000 | 504.000 | 35.262 | 504.000 |
| coldlaunch.visuallyLoaded | 528.900 | 524.000 | 478.000 | 591.000 | 33.513 | 591.000 |
| coldlaunch.contentInteractive | 529.000 | 524.500 | 478.000 | 591.000 | 33.502 | 591.000 |
| coldlaunch.firstpaint | 548.500 | 556.500 | 447.000 | 657.000 | 67.030 | 657.000 |
| coldlaunch.fullyLoaded | 1314.300 | 1277.000 | 1122.000 | 1599.000 | 123.337 | 1599.000 |
| coldlaunch.uss | 15.670 | 15.700 | 15.500 | 15.800 | 0.090 | 15.800 |
| coldlaunch.pss | 20.070 | 20.100 | 19.900 | 20.200 | 0.090 | 20.200 |
| coldlaunch.rss | 35.170 | 35.200 | 35.000 | 35.300 | 0.090 | 35.300 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.beforefirstpaint | -20.00 | -32.50 | -25.00 | 4.00 | 8.88 | 4.00 |
| coldlaunch.contentInteractive | -21.00 | -26.00 | -24.00 | 2.00 | 9.53 | 2.00 |
| coldlaunch.firstpaint | -36.20 | -47.00 | -45.00 | 14.00 | 24.18 | 14.00 |
| coldlaunch.fullyLoaded | 5.50 | -37.00 | -71.00 | 201.00 | 63.09 | 201.00 |
| coldlaunch.navigationInteractive | -23.90 | -42.00 | -19.00 | 8.00 | 4.25 | 8.00 |
| coldlaunch.navigationLoaded | -29.40 | -38.00 | -19.00 | -4.00 | 2.84 | -4.00 |
| coldlaunch.pss | 0.00 | 0.00 | -0.10 | 0.00 | 0.03 | 0.00 |
| coldlaunch.rss | -0.04 | 0.00 | -0.10 | 0.00 | 0.02 | 0.00 |
| coldlaunch.uss | 0.02 | 0.05 | -0.10 | 0.10 | 0.04 | 0.10 |
| coldlaunch.visuallyLoaded | -21.10 | -26.50 | -24.00 | 2.00 | 9.54 | 2.00 |
| coldlaunch.beforefirstpaint | -4.47% | -7.36% | -6.31% | 0.79% | 25.18% | 0.79% |
| coldlaunch.contentInteractive | -3.97% | -4.96% | -5.02% | 0.34% | 28.45% | 0.34% |
| coldlaunch.firstpaint | -6.60% | -8.45% | -10.07% | 2.13% | 36.07% | 2.13% |
| coldlaunch.fullyLoaded | 0.42% | -2.90% | -6.33% | 12.57% | 51.15% | 12.57% |
| coldlaunch.navigationInteractive | -5.96% | -10.67% | -5.79% | 1.71% | 11.24% | 1.71% |
| coldlaunch.navigationLoaded | -9.52% | -12.32% | -7.12% | -1.11% | 9.98% | -1.11% |
| coldlaunch.pss | 0.00% | 0.00% | -0.50% | 0.00% | 28.89% | 0.00% |
| coldlaunch.rss | -0.11% | 0.00% | -0.29% | 0.00% | 22.22% | 0.00% |
| coldlaunch.uss | 0.13% | 0.32% | -0.65% | 0.63% | 44.44% | 0.63% |
| coldlaunch.visuallyLoaded | -3.99% | -5.06% | -5.02% | 0.34% | 28.47% | 0.34% |
clock
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.beforefirstpaint | 415.900 | 409.000 | 367.000 | 535.000 | 44.033 | 535.000 |
| coldlaunch.navigationLoaded | 417.600 | 423.000 | 383.000 | 444.000 | 19.216 | 444.000 |
| coldlaunch.navigationInteractive | 459.000 | 465.000 | 428.000 | 482.000 | 17.844 | 482.000 |
| coldlaunch.firstpaint | 509.556 | 518.000 | 470.000 | 535.000 | 20.651 | n/a |
| coldlaunch.visuallyLoaded | 598.500 | 599.000 | 532.000 | 683.000 | 43.360 | 683.000 |
| coldlaunch.contentInteractive | 598.500 | 599.000 | 532.000 | 683.000 | 43.360 | 683.000 |
| coldlaunch.fullyLoaded | 599.000 | 599.000 | 534.000 | 684.000 | 43.188 | 684.000 |
| coldlaunch.uss | 15.470 | 15.500 | 15.400 | 15.500 | 0.046 | 15.500 |
| coldlaunch.rss | 34.210 | 34.200 | 34.200 | 34.300 | 0.030 | 34.300 |
| coldlaunch.pss | 19.560 | 19.600 | 19.500 | 19.600 | 0.049 | 19.600 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.navigationLoaded | 336.400 | 322.000 | 303.000 | 399.000 | 30.533 | 399.000 |
| coldlaunch.navigationInteractive | 378.500 | 363.000 | 348.000 | 447.000 | 31.398 | 447.000 |
| coldlaunch.beforefirstpaint | 438.100 | 424.500 | 407.000 | 501.000 | 28.194 | 501.000 |
| coldlaunch.firstpaint | 483.000 | 483.000 | 434.000 | 532.000 | 49.000 | n/a |
| coldlaunch.visuallyLoaded | 472.800 | 456.500 | 435.000 | 539.000 | 34.298 | 539.000 |
| coldlaunch.contentInteractive | 473.400 | 456.500 | 436.000 | 540.000 | 34.549 | 540.000 |
| coldlaunch.fullyLoaded | 473.500 | 456.500 | 436.000 | 540.000 | 34.474 | 540.000 |
| coldlaunch.uss | 15.400 | 15.400 | 15.400 | 15.400 | 0.000 | 15.400 |
| coldlaunch.pss | 19.500 | 19.500 | 19.500 | 19.500 | 0.000 | 19.500 |
| coldlaunch.rss | 34.200 | 34.200 | 34.200 | 34.200 | 0.000 | 34.200 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.beforefirstpaint | 22.20 | 15.50 | 40.00 | -34.00 | -15.84 | -34.00 |
| coldlaunch.contentInteractive | -125.10 | -142.50 | -96.00 | -143.00 | -8.81 | -143.00 |
| coldlaunch.firstpaint | -26.56 | -35.00 | -36.00 | -3.00 | 28.35 | NaN |
| coldlaunch.fullyLoaded | -125.50 | -142.50 | -98.00 | -144.00 | -8.71 | -144.00 |
| coldlaunch.navigationInteractive | -80.50 | -102.00 | -80.00 | -35.00 | 13.55 | -35.00 |
| coldlaunch.navigationLoaded | -81.20 | -101.00 | -80.00 | -45.00 | 11.32 | -45.00 |
| coldlaunch.pss | -0.06 | -0.10 | 0.00 | -0.10 | -0.05 | -0.10 |
| coldlaunch.rss | -0.01 | 0.00 | 0.00 | -0.10 | -0.03 | -0.10 |
| coldlaunch.uss | -0.07 | -0.10 | 0.00 | -0.10 | -0.05 | -0.10 |
| coldlaunch.visuallyLoaded | -125.70 | -142.50 | -97.00 | -144.00 | -9.06 | -144.00 |
| coldlaunch.beforefirstpaint | 5.07% | 3.65% | 9.83% | -6.79% |-56.18% | -6.79% |
| coldlaunch.contentInteractive | -26.43% | -31.22% | -22.02% | -26.48% |-25.50% | -26.48% |
| coldlaunch.firstpaint | -5.50% | -7.25% | -8.29% | -0.56% | 57.86% | NaN% |
| coldlaunch.fullyLoaded | -26.50% | -31.22% | -22.48% | -26.67% |-25.28% | -26.67% |
| coldlaunch.navigationInteractive | -21.27% | -28.10% | -22.99% | -7.83% | 43.17% | -7.83% |
| coldlaunch.navigationLoaded | -24.14% | -31.37% | -26.40% | -11.28% | 37.06% | -11.28% |
| coldlaunch.pss | -0.31% | -0.51% | 0.00% | -0.51% |-Infinity% | -0.51% |
| coldlaunch.rss | -0.03% | 0.00% | 0.00% | -0.29% |-Infinity% | -0.29% |
| coldlaunch.uss | -0.45% | -0.65% | 0.00% | -0.65% |-Infinity% | -0.65% |
| coldlaunch.visuallyLoaded | -26.59% | -31.22% | -22.30% | -26.72% |-26.42% | -26.72% |
gallery
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.navigationLoaded | 336.600 | 347.000 | 288.000 | 372.000 | 25.228 | 372.000 |
| coldlaunch.navigationInteractive | 337.200 | 347.500 | 289.000 | 372.000 | 24.975 | 372.000 |
| coldlaunch.beforefirstpaint | 405.200 | 410.500 | 358.000 | 437.000 | 23.314 | 437.000 |
| coldlaunch.firstpaint | 446.700 | 443.500 | 410.000 | 503.000 | 24.063 | 503.000 |
| coldlaunch.visuallyLoaded | 519.500 | 524.500 | 470.000 | 554.000 | 23.943 | 554.000 |
| coldlaunch.contentInteractive | 519.600 | 524.500 | 470.000 | 554.000 | 23.984 | 554.000 |
| coldlaunch.mediaEnumerated | 1188.800 | 1179.500 | 1151.000 | 1260.000 | 33.534 | 1260.000 |
| coldlaunch.fullyLoaded | 1637.500 | 1622.000 | 1574.000 | 1728.000 | 54.102 | 1728.000 |
| coldlaunch.uss | 39.760 | 39.600 | 38.800 | 40.800 | 0.674 | 40.800 |
| coldlaunch.pss | 44.260 | 44.100 | 43.300 | 45.300 | 0.674 | 45.300 |
| coldlaunch.rss | 59.380 | 59.250 | 58.500 | 60.400 | 0.652 | 60.400 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.navigationLoaded | 281.600 | 286.000 | 247.000 | 305.000 | 20.377 | 305.000 |
| coldlaunch.navigationInteractive | 282.500 | 287.000 | 247.000 | 306.000 | 20.549 | 306.000 |
| coldlaunch.beforefirstpaint | 351.500 | 356.500 | 313.000 | 382.000 | 23.863 | 382.000 |
| coldlaunch.firstpaint | 378.700 | 380.000 | 334.000 | 411.000 | 26.612 | 411.000 |
| coldlaunch.visuallyLoaded | 461.400 | 464.500 | 421.000 | 501.000 | 27.325 | 501.000 |
| coldlaunch.contentInteractive | 461.600 | 464.500 | 421.000 | 501.000 | 27.328 | 501.000 |
| coldlaunch.mediaEnumerated | 1125.600 | 1122.000 | 1077.000 | 1182.000 | 33.568 | 1182.000 |
| coldlaunch.fullyLoaded | 1584.500 | 1580.000 | 1531.000 | 1686.000 | 39.523 | 1686.000 |
| coldlaunch.uss | 39.970 | 40.300 | 39.100 | 40.700 | 0.520 | 40.700 |
| coldlaunch.rss | 59.570 | 59.900 | 58.700 | 60.300 | 0.520 | 60.300 |
| coldlaunch.pss | 44.460 | 44.800 | 43.600 | 45.200 | 0.528 | 45.200 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.beforefirstpaint | -53.70 | -54.00 | -45.00 | -55.00 | 0.55 | -55.00 |
| coldlaunch.contentInteractive | -58.00 | -60.00 | -49.00 | -53.00 | 3.34 | -53.00 |
| coldlaunch.firstpaint | -68.00 | -63.50 | -76.00 | -92.00 | 2.55 | -92.00 |
| coldlaunch.fullyLoaded | -53.00 | -42.00 | -43.00 | -42.00 | -14.58 | -42.00 |
| coldlaunch.mediaEnumerated | -63.20 | -57.50 | -74.00 | -78.00 | 0.03 | -78.00 |
| coldlaunch.navigationInteractive | -54.70 | -60.50 | -42.00 | -66.00 | -4.43 | -66.00 |
| coldlaunch.navigationLoaded | -55.00 | -61.00 | -41.00 | -67.00 | -4.85 | -67.00 |
| coldlaunch.pss | 0.20 | 0.70 | 0.30 | -0.10 | -0.15 | -0.10 |
| coldlaunch.rss | 0.19 | 0.65 | 0.20 | -0.10 | -0.13 | -0.10 |
| coldlaunch.uss | 0.21 | 0.70 | 0.30 | -0.10 | -0.15 | -0.10 |
| coldlaunch.visuallyLoaded | -58.10 | -60.00 | -49.00 | -53.00 | 3.38 | -53.00 |
| coldlaunch.beforefirstpaint | -15.28% | -15.15% | -14.38% | -14.40% | 2.30% | -14.40% |
| coldlaunch.contentInteractive | -12.56% | -12.92% | -11.64% | -10.58% | 12.24% | -10.58% |
| coldlaunch.firstpaint | -17.96% | -16.71% | -22.75% | -22.38% | 9.58% | -22.38% |
| coldlaunch.fullyLoaded | -3.34% | -2.66% | -2.81% | -2.49% |-36.89% | -2.49% |
| coldlaunch.mediaEnumerated | -5.61% | -5.12% | -6.87% | -6.60% | 0.10% | -6.60% |
| coldlaunch.navigationInteractive | -19.36% | -21.08% | -17.00% | -21.57% |-21.54% | -21.57% |
| coldlaunch.navigationLoaded | -19.53% | -21.33% | -16.60% | -21.97% |-23.81% | -21.97% |
| coldlaunch.pss | 0.45% | 1.56% | 0.69% | -0.22% |-27.65% | -0.22% |
| coldlaunch.rss | 0.32% | 1.09% | 0.34% | -0.17% |-25.38% | -0.17% |
| coldlaunch.uss | 0.53% | 1.74% | 0.77% | -0.25% |-29.62% | -0.25% |
| coldlaunch.visuallyLoaded | -12.59% | -12.92% | -11.64% | -10.58% | 12.38% | -10.58% |
dialer
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.navigationLoaded | 402.500 | 402.000 | 376.000 | 431.000 | 17.397 | 431.000 |
| coldlaunch.visuallyLoaded | 402.800 | 402.000 | 376.000 | 431.000 | 17.532 | 431.000 |
| coldlaunch.contentInteractive | 423.000 | 420.500 | 387.000 | 468.000 | 23.104 | 468.000 |
| coldlaunch.navigationInteractive | 435.000 | 430.500 | 396.000 | 482.000 | 24.775 | 482.000 |
| coldlaunch.beforefirstpaint | 440.000 | 435.500 | 400.000 | 486.000 | 25.036 | 486.000 |
| coldlaunch.firstpaint | 571.400 | 569.500 | 522.000 | 623.000 | 30.044 | 623.000 |
| coldlaunch.fullyLoaded | 662.200 | 672.500 | 621.000 | 709.000 | 28.329 | 709.000 |
| coldlaunch.pss | 16.470 | 16.500 | 16.400 | 16.500 | 0.046 | 16.500 |
| coldlaunch.uss | 12.380 | 12.400 | 12.300 | 12.400 | 0.040 | 12.400 |
| coldlaunch.rss | 31.000 | 31.000 | 30.900 | 31.100 | 0.063 | 31.100 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.navigationLoaded | 371.800 | 370.000 | 344.000 | 421.000 | 19.879 | 421.000 |
| coldlaunch.visuallyLoaded | 371.800 | 370.000 | 344.000 | 421.000 | 19.879 | 421.000 |
| coldlaunch.contentInteractive | 390.500 | 387.500 | 362.000 | 433.000 | 22.322 | 433.000 |
| coldlaunch.navigationInteractive | 401.400 | 399.000 | 373.000 | 445.000 | 23.062 | 445.000 |
| coldlaunch.beforefirstpaint | 405.400 | 403.500 | 377.000 | 449.000 | 23.517 | 449.000 |
| coldlaunch.firstpaint | 518.200 | 511.500 | 482.000 | 579.000 | 30.854 | 579.000 |
| coldlaunch.fullyLoaded | 596.600 | 585.000 | 559.000 | 665.000 | 35.474 | 665.000 |
| coldlaunch.pss | 16.430 | 16.400 | 16.400 | 16.500 | 0.046 | 16.500 |
| coldlaunch.rss | 31.020 | 31.000 | 31.000 | 31.100 | 0.040 | 31.100 |
| coldlaunch.uss | 12.320 | 12.300 | 12.300 | 12.400 | 0.040 | 12.400 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | ------- | ------- | ------- | ------- | ------ | ------- |
| coldlaunch.beforefirstpaint | -34.60 | -32.00 | -23.00 | -37.00 | -1.52 | -37.00 |
| coldlaunch.contentInteractive | -32.50 | -33.00 | -25.00 | -35.00 | -0.78 | -35.00 |
| coldlaunch.firstpaint | -53.20 | -58.00 | -40.00 | -44.00 | 0.81 | -44.00 |
| coldlaunch.fullyLoaded | -65.60 | -87.50 | -62.00 | -44.00 | 7.14 | -44.00 |
| coldlaunch.navigationInteractive | -33.60 | -31.50 | -23.00 | -37.00 | -1.71 | -37.00 |
| coldlaunch.navigationLoaded | -30.70 | -32.00 | -32.00 | -10.00 | 2.48 | -10.00 |
| coldlaunch.pss | -0.04 | -0.10 | 0.00 | 0.00 | 0.00 | 0.00 |
| coldlaunch.rss | 0.02 | 0.00 | 0.10 | 0.00 | -0.02 | 0.00 |
| coldlaunch.uss | -0.06 | -0.10 | 0.00 | 0.00 | 0.00 | 0.00 |
| coldlaunch.visuallyLoaded | -31.00 | -32.00 | -32.00 | -10.00 | 2.35 | -10.00 |
| coldlaunch.beforefirstpaint | -8.53% | -7.93% | -6.10% | -8.24% | -6.46% | -8.24% |
| coldlaunch.contentInteractive | -8.32% | -8.52% | -6.91% | -8.08% | -3.50% | -8.08% |
| coldlaunch.firstpaint | -10.27% | -11.34% | -8.30% | -7.60% | 2.63% | -7.60% |
| coldlaunch.fullyLoaded | -11.00% | -14.96% | -11.09% | -6.62% | 20.14% | -6.62% |
| coldlaunch.navigationInteractive | -8.37% | -7.89% | -6.17% | -8.31% | -7.43% | -8.31% |
| coldlaunch.navigationLoaded | -8.26% | -8.65% | -9.30% | -2.38% | 12.49% | -2.38% |
| coldlaunch.pss | -0.24% | -0.61% | 0.00% | 0.00% | 0.00% | 0.00% |
| coldlaunch.rss | 0.06% | 0.00% | 0.32% | 0.00% |-57.50% | 0.00% |
| coldlaunch.uss | -0.49% | -0.81% | 0.00% | 0.00% | 0.00% | 0.00% |
| coldlaunch.visuallyLoaded | -8.34% | -8.65% | -9.30% | -2.38% | 11.81% | -2.38% |
settings
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------- | -------- |
| coldlaunch.contentInteractive | 655.400 | 607.500 | 555.000 | 1011.000 | 129.226 | 1011.000 |
| coldlaunch.navigationLoaded | 729.000 | 684.000 | 620.000 | 1085.000 | 129.763 | 1085.000 |
| coldlaunch.navigationInteractive | 729.400 | 684.000 | 620.000 | 1085.000 | 129.594 | 1085.000 |
| coldlaunch.beforefirstpaint | 827.700 | 777.000 | 717.000 | 1179.000 | 129.047 | 1179.000 |
| coldlaunch.firstpaint | 957.100 | 900.500 | 860.000 | 1297.000 | 133.274 | 1297.000 |
| coldlaunch.startupPathEnd | 1273.600 | 1239.500 | 1153.000 | 1569.000 | 118.739 | 1569.000 |
| coldlaunch.visuallyLoaded | 1590.700 | 1537.000 | 1481.000 | 1962.000 | 140.253 | 1962.000 |
| coldlaunch.fullyLoaded | 4377.300 | 4339.000 | 4261.000 | 4662.000 | 114.489 | 4662.000 |
| coldlaunch.uss | 16.250 | 16.250 | 16.100 | 16.400 | 0.081 | 16.400 |
| coldlaunch.pss | 20.360 | 20.400 | 20.200 | 20.500 | 0.080 | 20.500 |
| coldlaunch.rss | 35.710 | 35.700 | 35.500 | 35.800 | 0.094 | 35.800 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------ | -------- |
| coldlaunch.contentInteractive | 621.400 | 588.500 | 548.000 | 886.000 | 93.381 | 886.000 |
| coldlaunch.navigationLoaded | 690.000 | 659.500 | 615.000 | 962.000 | 96.178 | 962.000 |
| coldlaunch.navigationInteractive | 690.100 | 659.500 | 615.000 | 962.000 | 96.118 | 962.000 |
| coldlaunch.beforefirstpaint | 795.100 | 758.500 | 715.000 | 1058.000 | 97.135 | 1058.000 |
| coldlaunch.firstpaint | 928.400 | 886.000 | 854.000 | 1187.000 | 97.125 | 1187.000 |
| coldlaunch.startupPathEnd | 1168.000 | 1150.000 | 1046.000 | 1372.000 | 82.647 | 1372.000 |
| coldlaunch.visuallyLoaded | 1516.100 | 1493.000 | 1434.000 | 1704.000 | 72.052 | 1704.000 |
| coldlaunch.fullyLoaded | 4252.300 | 4236.500 | 4123.000 | 4467.000 | 87.593 | 4467.000 |
| coldlaunch.uss | 16.830 | 16.950 | 16.500 | 17.100 | 0.237 | 17.100 |
| coldlaunch.pss | 20.950 | 21.100 | 20.600 | 21.200 | 0.229 | 21.200 |
| coldlaunch.rss | 36.290 | 36.400 | 35.900 | 36.600 | 0.247 | 36.600 |
| Metric | Mean | Median | Min | Max | StdDev | p95 |
| -------------------------------- | -------- | -------- | -------- | -------- | ------- | -------- |
| coldlaunch.beforefirstpaint | -32.60 | -18.50 | -2.00 | -121.00 | -31.91 | -121.00 |
| coldlaunch.contentInteractive | -34.00 | -19.00 | -7.00 | -125.00 | -35.84 | -125.00 |
| coldlaunch.firstpaint | -28.70 | -14.50 | -6.00 | -110.00 | -36.15 | -110.00 |
| coldlaunch.fullyLoaded | -125.00 | -102.50 | -138.00 | -195.00 | -26.90 | -195.00 |
| coldlaunch.navigationInteractive | -39.30 | -24.50 | -5.00 | -123.00 | -33.48 | -123.00 |
| coldlaunch.navigationLoaded | -39.00 | -24.50 | -5.00 | -123.00 | -33.59 | -123.00 |
| coldlaunch.pss | 0.59 | 0.70 | 0.40 | 0.70 | 0.15 | 0.70 |
| coldlaunch.rss | 0.58 | 0.70 | 0.40 | 0.80 | 0.15 | 0.80 |
| coldlaunch.startupPathEnd | -105.60 | -89.50 | -107.00 | -197.00 | -36.09 | -197.00 |
| coldlaunch.uss | 0.58 | 0.70 | 0.40 | 0.70 | 0.16 | 0.70 |
| coldlaunch.visuallyLoaded | -74.60 | -44.00 | -47.00 | -258.00 | -68.20 | -258.00 |
| coldlaunch.beforefirstpaint | -4.10% | -2.44% | -0.28% | -11.44% | -32.85% | -11.44% |
| coldlaunch.contentInteractive | -5.47% | -3.23% | -1.28% | -14.11% | -38.39% | -14.11% |
| coldlaunch.firstpaint | -3.09% | -1.64% | -0.70% | -9.27% | -37.22% | -9.27% |
| coldlaunch.fullyLoaded | -2.94% | -2.42% | -3.35% | -4.37% | -30.71% | -4.37% |
| coldlaunch.navigationInteractive | -5.69% | -3.71% | -0.81% | -12.79% | -34.83% | -12.79% |
| coldlaunch.navigationLoaded | -5.65% | -3.71% | -0.81% | -12.79% | -34.92% | -12.79% |
| coldlaunch.pss | 2.82% | 3.32% | 1.94% | 3.30% | 65.07% | 3.30% |
| coldlaunch.rss | 1.60% | 1.92% | 1.11% | 2.19% | 61.94% | 2.19% |
| coldlaunch.startupPathEnd | -9.04% | -7.78% | -10.23% | -14.36% | -43.67% | -14.36% |
| coldlaunch.uss | 3.45% | 4.13% | 2.42% | 4.09% | 65.82% | 4.09% |
| coldlaunch.visuallyLoaded | -4.92% | -2.95% | -3.28% | -15.14% | -94.66% | -15.14% |
Comment 22•9 years ago
|
||
Attachment #8605165 -
Attachment is obsolete: true
Attachment #8605170 -
Attachment is obsolete: true
Attachment #8605172 -
Attachment is obsolete: true
Attachment #8605173 -
Attachment is obsolete: true
Attachment #8687945 -
Flags: review?(jdemooij)
Comment 23•9 years ago
|
||
Attachment #8605166 -
Attachment is obsolete: true
Attachment #8687946 -
Flags: review?(jdemooij)
Comment 24•9 years ago
|
||
Attachment #8605167 -
Attachment is obsolete: true
Attachment #8687947 -
Flags: review?(jdemooij)
Comment 25•9 years ago
|
||
Attachment #8605168 -
Attachment is obsolete: true
Attachment #8687948 -
Flags: review?(jdemooij)
Comment 26•9 years ago
|
||
Attachment #8687949 -
Flags: review?(jdemooij)
Comment 27•9 years ago
|
||
Attachment #8605169 -
Attachment is obsolete: true
Attachment #8687950 -
Flags: review?(jdemooij)
Comment 28•9 years ago
|
||
Jan, I'm asking for r? to you. I'm not sure who to ask for this patch, so feel free to redirect r? if you are not the right person.
Comment 29•9 years ago
|
||
Ideally to do this bug properly we would need Necko support. The idea afaict is that Necko will have a unique id for resources, and will share this uid with the rest of Gecko.
So js/ or image/ will be able to listen for this id and create their own cache. Those patches does not cover the caching part. For the moment there is no such thing in Necko. Also I have limited the scope of beeing able to load bytecode to certified applications only. This allow Gaia to emit bytecode at compile time, and we will switch to runtime once Service Worker will be ready - which should allow third party apps to benefit from bytecode compilation as well.
This is what the next patch will do: emit bytecode from the Gaia build system.
Comment 30•9 years ago
|
||
Attachment #8605186 -
Attachment is obsolete: true
Attachment #8687955 -
Flags: review?(rchien)
Comment 31•9 years ago
|
||
Bugmorphing as I believe the cache support will be done in a separate bug once Necko is ready (and Service Workers...).
Summary: Bytecode cache → Allow certified applications to load XDR bytecode
Comment 32•9 years ago
|
||
Thanks for your patches! Some initial questions I had:
(1) What do we want to do for Gecko security updates? Will all Gaia certified apps be updated as well? Are we already doing that atm? Although it's uncommon, security fixes could change the XDR format.
(2) How does this interact with (JS) debugging?
Flags: needinfo?(vnicolas)
Comment 33•9 years ago
|
||
(In reply to Jan de Mooij [:jandem] from comment #32)
> Thanks for your patches! Some initial questions I had:
>
> (1) What do we want to do for Gecko security updates? Will all Gaia
> certified apps be updated as well? Are we already doing that atm? Although
> it's uncommon, security fixes could change the XDR format.
>
So far Gaia and Gecko updates are glued. Thinks will be different in the future, and at this time I hope to have runtime generated bytecode instead of buildtime.
> (2) How does this interact with (JS) debugging?
func.toSource() returns [sourceless code] and it basically makes the WebIDE debugger unhappy.
So far I do not expect people to debug this directly. This is similar to our |GAIA_OPTIMIZE = 1| build time flag. People tends to turn it off while debugging. Bytecode will be hidden beside |GAIA_OPTIMIZE = 3|
Let me know if I miss the questions!
Flags: needinfo?(vnicolas)
Comment 34•9 years ago
|
||
Sorry for the delay. Almost all these patches are outside js/src and in Gecko territory, so you need a DOM peer to review them. Maybe bz? He's familiar with the JS API.
Comment 35•9 years ago
|
||
Comment on attachment 8687947 [details] [diff] [review]
Add a JS_IsXDRBytecode to the jsapi
Review of attachment 8687947 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/jsapi.cpp
@@ +6167,5 @@
> + const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
> + return bytes[0] == (XDR_BYTECODE_VERSION >> 0 & 0xFF) &&
> + bytes[1] == (XDR_BYTECODE_VERSION >> 8 & 0xFF) &&
> + bytes[2] == (XDR_BYTECODE_VERSION >> 16 & 0xFF) &&
> + bytes[3] == (XDR_BYTECODE_VERSION >> 24 & 0xFF);
Replace the last 4 lines with:
return mozilla::LittleEndian::readUint32(bytes) == XDR_BYTECODE_VERSION;
This also nicely matches the code in XDRState::codeUint32().
::: js/src/jsapi.h
@@ +5296,5 @@
> extern JS_PUBLIC_API(JSObject*)
> JS_DecodeInterpretedFunction(JSContext* cx, const void* data, uint32_t length);
>
> +extern JS_PUBLIC_API(bool)
> +JS_IsXDRBytecode(const void* data, uint32_t length);
Nit: remove the JS_ prefix and move this inside the "namespace JS {" block below. We're trying to avoid the JS_ prefix for new code.
Attachment #8687947 -
Flags: review?(jdemooij) → review+
Comment 36•9 years ago
|
||
(In reply to Jan de Mooij [:jandem] from comment #34)
> Sorry for the delay. Almost all these patches are outside js/src and in
> Gecko territory, so you need a DOM peer to review them. Maybe bz? He's
> familiar with the JS API.
No worries for the delay. To be honest it was unclear to me who will be a good reviewer for all the dom/ parts so I asked you a bit randomly.
Let's ask bz. I assume he will redirect the r? if needed.
Thanks.
Comment 37•9 years ago
|
||
Jan, do you want to keep the r? for the one touching js/xpconnect or should I redirect it as well ?
Comment 38•9 years ago
|
||
Comment on attachment 8687946 [details] [diff] [review]
Add a isBytecode flag to evalOptions and use it if set
Boris, I'm not sure who is the right candidate to review those patches. Your name has been suggested, but feel free to redirect the r? if you are too busy or if this is a mistake.
Attachment #8687946 -
Flags: review?(jdemooij) → review?(bzbarsky)
Attachment #8687948 -
Flags: review?(jdemooij) → review?(bzbarsky)
Attachment #8687949 -
Flags: review?(jdemooij) → review?(bzbarsky)
Attachment #8687950 -
Flags: review?(jdemooij) → review?(bzbarsky)
Comment 39•9 years ago
|
||
Comment on attachment 8687945 [details] [diff] [review]
get_load_bytecode_methods.patch
(In reply to vnicolas from comment #37)
> Jan, do you want to keep the r? for the one touching js/xpconnect or should
> I redirect it as well ?
I'll redirect it as well as XPConnect is also above my paygrade ;)
Attachment #8687945 -
Flags: review?(jdemooij) → review?(bzbarsky)
Comment 40•9 years ago
|
||
I have to admit to being a bit lost after reading all that. What is the actual thing we are trying to implement in the end? It sounds like we're not storing bytecode in the necko cache, right? Are we just spitting out bytecode during the Gaia build process somehow and then just reading it in raw?
Also, have you checked whether the bytecode setup here leaves things runonce when they should be runonce?
Updated•9 years ago
|
Flags: needinfo?(21)
Comment 41•9 years ago
|
||
Comment on attachment 8687945 [details] [diff] [review]
get_load_bytecode_methods.patch
This patch really needs documentation describing the methods. Without that, I don't even know what they're _trying_ to do, much less whether they do it correctly...
Attachment #8687945 -
Flags: review?(bzbarsky) → review-
Comment 42•9 years ago
|
||
Comment on attachment 8687955 [details] [diff] [review]
Emit bytecode from the Gaia build system if supported.
Hi vnicolas,
I haven't look into this patch carefully and find out why this feature is going to modify Gaia build yet. However, there are some news [1] we must take care recently. We've an ongoing plan of moving build system from xpcshell to node and many Gaia people have wanted to embrace node ecosystem for a long time, so we wouldn't land any patch if it includes features are unsupported on node.
And could you point out which comment should I watch? Or an overview of this topic because there are so many comments... lol
[1] https://groups.google.com/forum/#!searchin/mozilla.dev.fxos/xpcshell$20for$20build$20script$2C$20or....just$20use$20node/mozilla.dev.fxos/RS7YVDb9SHE/asFLAT2SBAAJ
Attachment #8687955 -
Flags: review?(rchien)
Comment 43•9 years ago
|
||
Or if gecko APIs are unable to support on node.js platform, it would be a special feature making build system cannot move to node.
Please feel free to post any of your concerns on [1] if it's really a special case that would block node refactoring plan, thanks :)
[1] https://groups.google.com/forum/#!searchin/mozilla.dev.fxos/xpcshell$20for$20build$20script$2C$20or....just$20use$20node/mozilla.dev.fxos/RS7YVDb9SHE/asFLAT2SBAAJ
Comment 44•9 years ago
|
||
(In reply to Ricky Chien [:rickychien] from comment #42)
> Comment on attachment 8687955 [details] [diff] [review]
> Emit bytecode from the Gaia build system if supported.
>
> Hi vnicolas,
>
> I haven't look into this patch carefully and find out why this feature is
> going to modify Gaia build yet. However, there are some news [1] we must
> take care recently. We've an ongoing plan of moving build system from
> xpcshell to node and many Gaia people have wanted to embrace node ecosystem
> for a long time, so we wouldn't land any patch if it includes features are
> unsupported on node.
>
The build system patch is about converting JS source to raw JS spidermonkey bytecode. You need Spidermonkey for that afaik. So in the future, you may need to spawn a Xulrunner process from your node build system - which is already something you may need to do if you still want to validate CSS from Gecko.
If this is impossible, and the future new build system will cost us hundred (or hundreds) of milliseconds of cold launch time for apps on our reference device, I would say there is an issue here :)
Now, the idea here is also to move from build time generated bytecode to runtime generated bytecode in the future. Which will remove the need for this particular dependency on Xulrunner at build time.
In the time you will take to convert all the build system I hope it will be done...
Comment 45•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #40)
> I have to admit to being a bit lost after reading all that. What is the
> actual thing we are trying to implement in the end? It sounds like we're
> not storing bytecode in the necko cache, right? Are we just spitting out
> bytecode during the Gaia build process somehow and then just reading it in
> raw?
>
Your guess is correct. Those patches just emit bytecode during the Gaia build process and read them raw.
So, nothing in the Necko cache.
In the end and afaik the goal is:
1. Receive some new js source, paired with a unique identifier for the resource
2. Parse it, runs it, and save some of its associated bytecode
3. Use this bytecode directly a script with the same unique identifier is encountered
If my understanding of the discussion between Necko and JS folks is correct, the database will not be part of the Necko Cache (this is what some of the obsoletes patches of this bug does), but will be the responsibility of the JS engine based on the unique id associated with a resource in the Necko Cache. Necko will then inform when such a resource is evicted.
Also the stored bytecode will be generated at runtime, possibly based on what has been really used by a page at startup. (While the whole script bytecode is generated by the getBytecode method of those patches).
At least that's how I have understood things.
But realistically I don't think all of this will happen before next summer.
And because Gaia/Gecko updates are tied together at the moment, and so won't have bytecode versioning issues, I don't think we need to wait for all this plumbing to start playing with that.
So this is what is reflected in this bug. I took a shortcut and bugmorph the bug to start landing what you have described: emitting bytecode from the Gaia build process and using it raw.
Hope it makes sense.
> Also, have you checked whether the bytecode setup here leaves things runonce
> when they should be runonce?
Really not. The reason beeing that I have no idea what runonce means in this context :/
Comment 46•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #41)
> Comment on attachment 8687945 [details] [diff] [review]
> get_load_bytecode_methods.patch
>
> This patch really needs documentation describing the methods. Without that,
> I don't even know what they're _trying_ to do, much less whether they do it
> correctly...
I have added loadBytecode for testing if getBytecode works correctly. I can remove it if needed as its was mostly debugging purpose.
For getBytecode, it is clearly unclear to me that I'm doing things properly. The main goal of this method is to get the bytecode for a given source file. Most of the code has been stolen from other parts of this file and I won't be surprised to have done mistakes...
For getBytecode, does something like the following with help:
/*
* Convert a whole JS script to XDR bytecode and returns the result as an
* ArrayBuffer.
*
* @param uri the uri of the script to load.
* @param principal the principal from which we get the app id if any.
* @param charset optionally specifies the character encoding of
* the file. If absent, the file is interpreted
* as ASCII.
*/
Flags: needinfo?(21)
Comment 47•9 years ago
|
||
> Really not. The reason beeing that I have no idea what runonce means in this context :/
http://hg.mozilla.org/mozilla-central/file/3f5afaf4e6b7/js/src/jsapi.h#l3690
It's a flag used when compiling scripts that guarantees that they will only be executed once and allows the JS engine to make certain optimizations.
I _think_ we made it work with XDR, but if we're seriously going to use XDR for run-once things as here we should double-check it.
> For getBytecode, does something like the following with help:
Yes, that helps, thanks.
Updated•9 years ago
|
Attachment #8687945 -
Flags: review- → review?(bzbarsky)
Comment 48•9 years ago
|
||
(In reply to Boris Zbarsky [:bz] from comment #47)
> > Really not. The reason beeing that I have no idea what runonce means in this context :/
>
> http://hg.mozilla.org/mozilla-central/file/3f5afaf4e6b7/js/src/jsapi.h#l3690
>
> It's a flag used when compiling scripts that guarantees that they will only
> be executed once and allows the JS engine to make certain optimizations.
>
> I _think_ we made it work with XDR, but if we're seriously going to use XDR
> for run-once things as here we should double-check it.
I asked nbp a sec ago. His answer is: "It should be fine as your code is never run (directly compiled to bytecode). And even if it was set, XDR will ignore it."
As nbp is following this bug closely I believe he will correct me if I misunderstood!
Comment 49•9 years ago
|
||
Comment on attachment 8687945 [details] [diff] [review]
get_load_bytecode_methods.patch
>+++ b/js/xpconnect/idl/mozIJSSubScriptLoader.idl
Needs docs, as discussed.
>+mozJSSubScriptLoader::GetBytecode(nsIURI* aURI,
>+ options.discardSource = true;
>+ options.cloneSingletons = true;
>+ options.disableLazyParsing = true;
Please document very clearly why these are desirable. The latter two definitely hurt performance in some ways, and the former makes some things (like toSource() on functions) not work, so it's odd to me that we want them here, but maybe there's some good reason that I'm missing....
In general, I would think we would want exactly the same compilation options here as we normally use for web scripts.
>+ rv = loader->FindTargetObject(cx, &targetObj);
That that what we really want here? In practice, will this get called from JS components or something else with the weird backstage pass setup, and if so, will mReuseLoaderGlobal be true? If not, this seems like a fancy and unclear way of doing:
targetObj = js::UncheckedUnwrap(&v.toObject());
If we _do_ get called from JS components, do we actually want the sharing stuff that FindTargetObject() will do? Seems to me like we in fact want to always use the sandbox global here, so we take the JS_IsGlobalObject fast paths in PrepareScript.
>+ targetObj = JS_FindCompilationScope(cx, targetObj);
Not relevant if targetObj is just the sandbox global.
>+ static_cast<const char*>(uriStr.get()), serv,
Why is that cast needed? I don't think it should be needed.
>+ void* buffer = JS_EncodeScript(cx, script, &length);
If this returns null, need to bail out, right?
>+ arrayBuffer = JS_NewArrayBufferWithContents(originalCx, length, buffer);
If this returns null, free(buffer), and return NS_ERROR_OUT_OF_MEMORY.
That said, the compartment handling here is a bit odd. originalCx and cx could well be the same JSContext here; you just don't know. In that case, you're creating the arraybuffer in the sandbox global. Wouldn't you want to exit the sandbox compartment before doing this? Probably you want to scope the JSAutoCompartment you have to just until after the JS_EncodeScript has happened or something.
>+mozJSSubScriptLoader::LoadBytecode(JS::Handle<JS::Value> aBuffer,
>+ JS::AutoCheckCannotGC nogc;
How can it possibly make sense, given that JS_DecodeScript can gc?
You probably want GetArrayBufferLengthAndData here, which will give you the length and data in one call and not require the nogc shenanigans.
>+ retval.set(JS::BooleanValue(JS_ExecuteScript(cx, script)));
This function should probably be called "ExecuteBytecodeInCurrentGlobal" or something, no?
Attachment #8687945 -
Flags: review?(bzbarsky) → review-
Comment 50•9 years ago
|
||
Comment on attachment 8687946 [details] [diff] [review]
Add a isBytecode flag to evalOptions and use it if set
r=me
Attachment #8687946 -
Flags: review?(bzbarsky) → review+
Comment 51•9 years ago
|
||
Comment on attachment 8687948 [details] [diff] [review]
Mark script as bytecode in dom/base/nsScriptLoader.cpp
This is horribly terribly insecure without the "certified apps only" part. Please squash that into this changeset.
The version of nsJSUtils::EvaluateString that takes an offthread token but not an EvaluateOptions is dead code after this change. Please remove it.
>@@ -1489,17 +1503,17 @@ nsScriptLoader::OnStreamComplete(nsIStre
I don't understand this hunk. It doesn't seem to be against anything like m-c tip (in particular, the block you're changing doesn't seem to exist there). Marking r- pending understanding what's really going to land here.
Attachment #8687948 -
Flags: review?(bzbarsky) → review-
Comment 52•9 years ago
|
||
Comment on attachment 8687949 [details] [diff] [review]
Mark script as bytecode in dom/workers/ScriptLoader.cpp
r=me
Attachment #8687949 -
Flags: review?(bzbarsky) → review+
Comment 53•9 years ago
|
||
Comment on attachment 8687950 [details] [diff] [review]
Allow bytecode for certified apps only
>+nsScriptLoader::CanUseBytecode()
Calling this from worker threads is pretty questionable. Yes, it happens to work, probably, because we always run it on main thread before we manage to set up a worker... but I'd rather we explicitly added the bool var cache during layout module startup, not lazily the first time this is called.
Attachment #8687950 -
Flags: review?(bzbarsky) → review-
Updated•9 years ago
|
Whiteboard: [necko-would-take]
Comment 54•7 years ago
|
||
Bulk change to priority: https://bugzilla.mozilla.org/show_bug.cgi?id=1399258
Priority: -- → P5
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•