Project Leyden: Beginnings

John Rose john.r.rose at oracle.com
Tue May 24 18:00:21 UTC 2022


n 23 May 2022, at 9:10, Ioi Lam wrote:

> On 5/20/2022 9:16 AM, Volker Simonis wrote:
>> … It seems to me that "snapsafety" could be such a constraint and I 
>> hope
>> for a fruitful and successful cooperation between the two projects.

A snappy term indeed!  When applied to the existing Java platform, the 
concept (probably) leads to all sorts of complicated considerations 
about remote and hidden side effects and environmental queries.

As Ioi points out, the big new thing here, not possible outside of 
Leyden, is the option to *modify* the Java language specification (and 
standard libraries), if we think it helps clarify or simplify the 
(suitably modified) definition of snapsafety.

>
> I think we have an opportunity in Leyden to improve the language and 
> platform to support such concepts. I don't know the details of 
> "snapsafety", but in general we should have language support to 
> indicate some sort of "immutable" constraints. These constraints can 
> be validated (so that we can use pre-optimized snapshot (s)), or 
> invalidated (so we will go back to the old slow-but-correct 
> initialization).

The part of the language I like to think about changing is not so much 
assertions (maybe `assert`s) about past events (which are those 
“immutable constraints”?) but rather relaxation or modification for 
rules regarding order of evaluation, for suitably marked expressions and 
statements.

The small scale constant-folding rules which every JIT uses are really 
order of evaluation changes:  An expression like `1+2+x` folding to 
`3+x` takes the expression `1+2` and moves it “back in time” to JIT 
time.  This is safe because the JIT knows there is no way the program 
can give evidence of the difference (unless a debugger single-steps 
through bytecodes).  But I think we should chase after constant-folding 
this sort of thing:

```
Object lookup(String x) {
   // hey, can someone please do this just once, at jlink time?
   var mydata = readHashTable(findResourceFile("mydata.xml”));
   // this depends on x, so cannot be moved back in time:
   return var.get(x);
}
```

The standard technique is to put `mydata` in a static final variable.  
And now that’s easy to do inline as well:

```
Object lookup(String x) {
   // like a C++ static, the initializer is executed on first use:
   class Static {
     static final HashMap<String,Object>
     mydata = readHashTable(findResourceFile("mydata.xml”));
     // but still, can someone please do it just once, at jlink time?
   }
   // this depends on x, so cannot be moved back in time:
   return Static.mydata.get(x);
}
```

(Side note: Reading files throws a checked exception.  Does this mean 
that the above method should be amended to throw a possible checked 
exception, but marked as “somewhere in the past”?  If so, then 
time-shifted expressions would need to have associated time-shifted 
exception checking rules.)

This is a kind of time-shifting currently under programmer control.  It 
suggests to me that we can and should double down on supporting static 
final state (and also lazy statics as in JDK-8209964), by focusing some 
effort on time-shifting not so much arbitrary expressions and 
statements, but the initialization of classes.  If a programmer could 
mark a *whole class* as time-shiftable in its initialization, then the 
programmer could expect that jlink could make good provisioning 
decisions about that class, rather than the current standard policy of 
initializing a class on first use (of a static or of an instance 
creation).

One more bit of mental framework:  A Java class is initialized no 
earlier and no later than its first initializing use (static or instance 
creation).  Certainly there must be other events that the class 
initialization could be referred to.  “jlink time” is a hazy 
concept, but program startup is not:  A Java program starts just before 
its selected `main` entry point is run.  If a class C could be marked 
(by the programmer) as being initialized no earlier than entry to 
`main`, then the programmer could certify that the class is a candidate 
for pre-initialization, regardless of the change of semantics (relative 
to Java’s current order of class initialization).  And that would 
solve some (not all) of the problems around making valid jlink-time 
evaluations.  I guess I’m suggesting that a language-level proxy for 
“jlink time” is main method entry.

I suspect that time-shifted class initialization probably needs a 
concept of time-shifted dependency (as well as time-shifted exceptions, 
see above?) so that if class C is marked as “can initialize around 
main entry” C can also be marked as “but no earlier than 
initialization of D”, for some other class D that C’s initialization 
depends on.

(The work on lazies JDK-8209964 is sort of a complementary image of what 
Leyden is after, since a lazy variable is time-shifted *after* its 
containing class is initialized, another change from standard Java 
rules.  The two kinds of time shifting, backward and forward, probably 
deserve a combined treatment of some sort.)

>
> Also, in addition to a single snapshot of an app, perhaps we can also 
> consider multiple snapshots at a lower granularity.
>
> One parallel to draw from is the "constexpr" keyword in C++. However, 
> "constexpr" only deals with language-level constructs. For Java, 
> perhaps we need something that includes a wider set of environmental 
> dependencies. For example, many immutable tables in Java apps are 
> created from external XML files. Do we want a way to snapshot such 
> tables? Maybe we can do that if the XML files are statically stored 
> inside a jlink image?
>
> Again, I don't know what the answer is, but I am excited that we are 
> able to look for solutions at all levels of the language and platform.
>
>
> Thanks
> - Ioi
>
>
>>
>> Thank you and best regards,
>> Volker
>>
>>> We will lean heavily on existing components of the JDK including the
>>> HotSpot JVM, the C2 compiler, application class-data sharing (CDS), 
>>> and
>>> the `jlink` linking tool.
>>>
>>> In the long run we will likely embrace the full closed-world 
>>> constraint
>>> in order to produce fully-static images.  Between now and then, 
>>> however,
>>> we will develop and deliver incremental improvements which 
>>> developers
>>> can use sooner rather than later.
>>>
>>> Let us begin!
>>>
>>> - Mark
>>>
>>>
>>> [1] 
>>> https://mail.openjdk.java.net/pipermail/discuss/2020-April/005429.html
>>>
>>> // https://openjdk.java.net/projects/leyden/notes/01-beginnings


More information about the leyden-dev mailing list