Portability of compiled code

Brian Goetz brian.goetz at oracle.com
Fri Dec 23 19:12:50 UTC 2022


You identify a problem (generated code has environmental dependencies which may not carry into other environments) and a solution (detune the generated code to something generic.)  I agree with the problem, but there are many other possible solutions, and we shouldn’t prematurely snap to one of them.

Moving some work from runtime to earlier phases (whether through a Leyden condenser, a classfile rewriter, etc) always creates the possibility that this work depends on some environmental characteristic of the early execution environment.  The list is endless: hardware, operating system, environment variables, time and time zone, JDK and other dependency versions, etc.

Strategies for dealing with this include:

 - Record environmental dependencies, and fail if the code is restarted when the dependencies are not met.  This is entirely reasonable when applied to things like “you ran your checkpoint on Intel/Windows, but you’re resuming on ARM/MacOS”; it is merely a matter of judgment how fine-grained to record and enforce.

 - Generate perfectly portable everything, even if that means generating worse everything.  This is the route you are suggesting, but obviously this has limits that will be reached pretty quickly anyway.  Nothing is going to save you from trying to resume on a different architecture / OS / incompatible JVM version / wrong class path / etc.

 - Record environmental dependencies, but be willing to toss them if they don’t match the runtime environment.  For things like an AOT’ed code cache, the code cache could be flushed and we could fall back to dynamic code generation.

 - Train on a variety of architectures and include multiple versions of the AOT’ed code in the binary.

… and plenty of others.

A key aspect of Leyden is not only ahead-of-time condensation, but recording constraints that capture assumptions inherent in those condensations, and prevent operations that would contradict those assumptions (e.g., prohibit redefinition of classes that have been used to generate AOT’ed code.)


On Dec 23, 2022, at 12:46 PM, Ashutosh Mehra <asmehra at redhat.com<mailto:asmehra at redhat.com>> wrote:

Hello,

Early this year we were doing some experiments on portability of checkpoints under project CRaC and prepared a document [0] on our findings.
We feel parts of it would be relevant under Project Leyden as well, as it may enable ahead-of-time compilation in future (I know we are not there yet!)

For the CRaC checkpoints, we found the code generated by C1/C2 compiler is not always portable due to the use of architecture specific instructions.
The same would hold true in the context of AoT compilations as well.
To make the code portable C1/C2 compilers should be provided with a minimal set of cpu features that they are allowed to exploit during codegen phase.
However, this can also negatively impact the performance of the generated code as it would now not be utilizing all the features of the underlying architecture.
So the performance may have to be traded for gaining portability.

If anyone has thoughts on this aspect of the problem, please share them.

[0] http://cr.openjdk.java.net/~heidinga/crac/Portability_of_checkpoints.pdf

- Ashutosh Mehra

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20221223/6aefa28b/attachment.htm>


More information about the leyden-dev mailing list