Call for Discussion: New Project: Leyden
Ioi Lam
ioi.lam at oracle.com
Thu May 21 18:59:09 UTC 2020
On 5/19/20 7:07 AM, Mike Hearn wrote:
> Although this may be veering into an unwanted "what will it be" discussion,
> I'm curious how fundamental it is that an image must be either static or
> dynamic.
>
> HotSpot already does some speculative optimisations on the assumption that
> new code isn't loaded e.g. the class hierarchy analysis. Speculative
> optimisations do a great job of removing costs of dynamic language features
> like class redefinition. Leyden seems to be proposed as a new 'mode' of the
> Java language, but could it also be envisioned as a new set of
> optimisations that optimistically assume no dynamic code loading? For
> instance, could a module be marked as "available to dynamically loaded
> code" and then the points-to analysis / dead code elimination would pin the
> public API of the module before running, and if it's not marked as such,
> then DCE runs across the boundaries too?
>
> A big part of the SubstrateVM startup time win appears to come from a more
> aggressive version of the AppCDS heap serialisation feature, and a general
> focus on startup time to the exclusion of other factors (e.g. there's no
> notion of module layers or module boundary enforcement). To what extent is
> the closed-world assumption contributing to the footprint/startup time wins
> vs other spec changes - is that known?
>
> These questions aren't rhetorical, I don't have any view on the answers.
> After playing around with native-image and seeing mixed results (e.g.
> smaller wins than I thought for GUI JavaFX apps), and looking at the work
> being done on AppCDS, I started to wonder if HotSpot can eventually match
> the startup time and footprint wins of native-image without the
> compatibility breaking changes SVM makes to get there, just through
> doubling down on current optimisation techniques like jlink and speculation.
>
> Thanks for any insight offered!
Hi Mike,
Thanks for mentioning AppCDS. As someone working primarily on AppCDS, I
am happy to hear that you have a good impression on its current state
and potentials. Over the past few years, we have done many start-up
optimizations, in AppCDS and many other parts of the JDK (core libs,
jlink, hotspot, etc). You can see Claes Redestat's excellent
presentation here:
https://cl4es.github.io/2019/11/20/OpenJDK-Startup-Update.html
Since JDK9, we have cut down the HelloWorld start-up time from about
120ms in JDK 9 to less than 40ms in JDK 14. We will be eking out a few
more ms in JDK 15.
A large part of the improvement is due to archiving heap objects into
CDS -- mostly related module information. In JDK 16, I hope to finish
JDK-8244778 (Archive complete module graph in CDS). My prototype shows
about 7~10ms improvement in start-up time.
The problem with archiving heap objects, though, is currently it
requires a lot of manual work and knowledge about the code. I am
spending a lot of effort to take out 7~10ms for JDK-8244778. To be
useful in general applications, we need to make it much easier to use.
A key assumption of archiving heap objects is -- part of my program will
always produce the same set of objects, so I can execute it ahead of
time and save the results for later use. Maybe "closed world" sounds too
strong, but at least I need to have a "stable world", where I am
guaranteed to always see the exact same bytecodes in the exact set of
classes, so I can analyze them to see if they will indeed always produce
the same results.
The problem is Java classes are loosely coupled, and the linking happens
only at execution time. A reference to "Foo" can give you a completely
different class (an app can even define classes dynamically). I hope we
can introduce a new "linking" concept in the JLS, so Java classes can be
more strongly combined together into a bigger execution unit.
For example, a "linked" app will already have Foo in the VM's dictionary
before any bytecodes are executed. So the app won't be able to
substitute an different Foo. I think this will help not only AppCDS but
also AOT compilation.
I don't think speculation can help here -- if we have archived a set of
objects that involves Foo, and have used these objects part away during
execution, and (assuming we have not yet touched any archived Foo
objects yet) the app defines a new Foo class, we are stuck. It would
take tremendous effort to look at the archived objects to patch the new
version of the Foo objects, and this won't be possible if you add or
remove fields in Foo. We would also need to add a lot of run time checks
at every step to guarantee that we indeed load the same classes. All
these checks will be counterproductive to start-up.
Thanks
- Ioi
More information about the discuss
mailing list