New issue
Advanced search Search tips

Issue 661979 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner:
Closed: Nov 7
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Feature

Blocking:
issue 726626



Sign in to add a comment

Cold optimisations for streams

Project Member Reported by ricea@chromium.org, Nov 3 2016

Issue description

It is my understanding that V8Extras are compiled into Chrome without optimisation. I need to confirm that.

The implication is that ReadableStream and WritableStream performance will initially be poor until V8 identifies the hot paths. Unlike performance in the hot case, which is easy to benchmark and profile, the impact of the cold case is hard to measure.

A related issue is that the entire source code (minus comments) is compiled into the binary. Even after the Ignition project replaces that with bytecode, the bytecode will have a very close correspondence to the original source, and so it will be proportional in size.

Where this is leading is that it would be good to have some general optimisations applied to the Javascript that is compiled in, such as inlining, constant folding and variable and function renaming. But it's not necessarily desirable to have these changes in the source code that is checked in, because it should be maintainable and easy to cross-check against the standard.

Ideally we could use the Closure compiler to produce optimised Javascript to compile in. Unfortunately, Closure cannot currently output ES6, and can't be used during the build process due to the Java dependency.

So this issue exists to discuss other options.
 

Comment 1 by ricea@chromium.org, Nov 4 2016

Components: Blink>Network>StreamsAPI

Comment 2 by ricea@chromium.org, Nov 11 2016

My understanding was partially incorrect. V8Extras are not "compiled in" at all. The snapshot contains enough information to make the symbols available with no startup overhead, but compilation is very lazy indeed. Even the unoptimised full-codegen pass doesn't happen until each function is actually called.

The rest still applies.
See also:  https://crbug.com/614367 

Comment 4 by ricea@chromium.org, Jan 10 2017

It looks like we may have a solution sooner than expected:

https://docs.google.com/document/d/1G3JLn-BM-fItuJVUiILIz7X2qAv4eta5DljSSdQ94Fg/edit

This would also enable us to use ESLint in the presubmit to find typos.

Comment 5 by ricea@chromium.org, Mar 14 2017

uglifyjs is also available in the Chromium tree (and in use by Web UI). It might have ES6 output support sooner than Closure (https://github.com/mishoo/UglifyJS2/issues/448) but its optimisations are less sophisticated (eg. no constant or function inlining).

Comment 6 by ricea@chromium.org, Jun 1 2017

Blocking: 726626

Comment 7 by adamk@chromium.org, Jul 5 2017

Cc: domenic@chromium.org yangguo@chromium.org
+yangguo for v8 snapshotting expertise

How hard would it be to at least include the generated bytecode in the v8 extras snapshot?
We already have a way to include "warmed up" bytecode in the snapshot, but for Chrome this is not being used, to reduce snapshot size and GC pressure.

I'm not actually convinced including pre-generated code in the snapshot is the right thing to do. If yes, we should consider this for all other builtins as well.

If the cold start performance is that big of a problem, we should consider changing the optimizing compiler's tier up strategy/heuristic instead of an ad-hoc solution like including pre-generated code for particular builtins. Especially for builtins that is not on critical path of every V8 instance.

Comment 9 by ricea@chromium.org, Jul 28 2017

#8: Is the bytecode larger than the original source? If we could eliminate the source from the snapshot it would be big help as we haven't got a working minimiser solution.
For minified V8 internal natives, the bytecode array is roughly 4x the size of the source. Not sure how well that applies to the non-minified sources.

Comment 11 by ricea@chromium.org, Aug 23 2017

Owner: ricea@chromium.org
Status: Assigned (was: Available)
I did some preliminary investigation with uglifyjs (actually uglify-es).

After processing all the core/streams *.js files with the following invocation:

../../../../node/node_modules/uglify-es/bin/uglifyjs WritableStream.js -m -c ecma=6,expression=true -o $file.new -- $file && mv $file.new $file

all the tests still pass. However, visible constructor names change. For example

CountQueuingStrategy.name === 'r'.

This can be prevented by supplying an appropriate list to the "reserved" option to -m.

The size improvements justify this by itself: WritableStream.js goes from 37K to 8K. It would be nice to see if there are also measurable performance improvements.
Nice. In V8 we use a primitive minifier that ignores top-level identifiers to work around this issue. It has some severe drawbacks though, since it doesn't actually parse JavaScript.
What's the status on adding Node.js-based tools to the build process? Or were you thinking just manually building it and committing it?

Also it might be worth comparing ugly-es and babili: https://github.com/babel/minify however based on the stats in the readme they seem fairly similar.
Chromium already includes Node.js. I think for some build step.
I thought I had noted the results of my attempts to use uglifyjs here, but apparently not.

There's a big dependency mess which makes it difficult to run uglifyjs at build time. The Streams extras are compiled into the V8 snapshot, which means they are included in the V8 build despite being part of Blink. This is why the list of files to build ends up in //.gn. I don't think the V8 build will ever be able to run Node.js because it would be a circular dependency.

Because the v8 -> Blink dependency is not explicitly declared (and cannot be), there's no way to express the idea that a Blink build step needs to be run before building v8.

If //tools/v8_context_snapshot started to be used everywhere this might make things  easier. Currently there's a large blacklist of platforms that don't use it.

If we reached "crisis" point we could check-in the minified versions alongside the unminified versions with a manually-run script to generate them and a presubmit check that they were up-to-date, but I don't think we are in crisis yet.
A compromise idea I had was to add a v8.compileNow(f) function, and use it to compile CreateReadableStream and all its dependencies to bytecode at snapshot-creation time.
Status: WontFix (was: Assigned)
Closing in favour of issue 902633 (C++ port).

Sign in to add a comment