I agree that the fastest executing approach is the approach that does the
least amount of computation. And so yes, your suggestion to "keep a warm
version of the AST loaded in memory, and update that AST on the fly with
just new AST's of changed classes" is a fast design. But there are some
unconsidered questions: do you still have to retranslate the *entire* AST
to Javascript source (and is the resulting process still fast if you have
to do so)? Do the modified files need to trigger generator reruns? How do
you know which generators are/are not affected by the change? When
implementing this incremental generator support, how much duplication will
there be with existing generator logic in the main compile path?

If you follow this mutative/truly incremental approach in memory in
SuperDev mode, then it's unclear how to reuse this work to also speed up
normal compilation triggered by a build system or continuous integration
server (such as Maven or Jenkins).

The approach i'm working on is to make change normal compiles to be
incremental at the "per module" level. This should transparently speed up
not just build systems, but also SuperDev mode.

In a nutshell my approach (leaving out lots and lots of edge cases) is
this: run the GWT compiler on "Module A" with *just* the Java source for
"Module A" and the bytecode for its dependencies provided to the JDT
compiler. Take the results of this compilation and do all of the normal
transformations on it except for optimization (which are currently
inherently global) and write out the resulting Javascript (for just the
types that were provided as Java source) using a special namer that names
types/functions/variables in a globally stable way (so that cross modules
references will resolve at runtime) and write this Javascript into a
".gwtlib" file. Repeat this for every module in the dependency tree,
starting at the leaf nodes. When you get to the root of the tree, run
global generators and link these precompiled Javascript chunks (that you
pull out of the accumulated ".gwtlib" files) into one big chunk.

This (should be) fast for 2 reasons: the amount of IO and computation for
each stage is kept to the minimum, and the the global phase is never
analyzing/transforming/outputting a global size AST (it's just
concatenating together the previously compiled Javascript for each of the
dependent modules). It's basically the same process as normal Java
compilation with separate Jar files being constructed.

It can make cold compiles better by making it possible to parallelize the
compilation of different modules in the module tree, and it can of course
make warm compiles better by requiring only the recompilation of the
particular module that contains the changed file (as well as the rerun of
global generators and linking). User.gwt.xml registers 16 generators, but
I'm expecting that I'll be able to annotate some of them as "known to be
local" so that they can be kept out of the global phase and for the
remaining ones it should be possible to run them partially locally and
partially globally (so as to minimize the size of the global phase).
Eventually it would be nice to deprecate and replace all generators that
require some global phase.




On Wed, Aug 21, 2013 at 8:34 AM, Stephen Haberman
<step...@exigencecorp.com>wrote:

> Hey John,
>
> > it means having an optional compilation path that does not recompile
> > the entire world (as the current monolithic compile path does) and
> > instead tries to recompile just files (or or modules) that have
> > changed.
>
> Spiffy! Out of curiosity, would the API look something like:
>
>     theBackendCompile.recompile(List<File> filesThatChanged)
>
> Such that the existing ResourceOracle/TypeOracle instances are mutated
> with the updated state, instead of being rebuilt?
>
> AFAIK, historically most of the optimizations around "incremental"
> compiles have always required going back to building ResourceOracle,
> TypeOracle from scratch, but speeding it up with caching.
>
> ...IIRC. It's been a little while since I've poked at the code.
>
> I know I'm being a broken record, but I think the mutative/truly
> incremental approach, while a (large) PITA to build, in the long run is
> the only solution that would be fast enough to get SuperDevMode fast
> enough such that it's "hit save in Eclipse, the js file is updated,
> done!", just like Java (and web) developers are used to.
>
> (I know Brian really doesn't like solutions that require Eclipse, but I
> think the same mutative/incremental compiler API could just as well be
> called by an Eclipse plugin or an IDEA plugin or even a Java daemon
> polling the file system for changes. It's not IDE-specific.)
>
> Feel free to ignore my musings given I'm not actually contributing
> anything to the effort; just curious as to how things are going.
>
> - Stephen
>
> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors
> ---
> You received this message because you are subscribed to the Google Groups
> "GWT Contributors" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors
--- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to