<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">On 9 Jun 2023, at 12:41, Dan Heidinga wrote:</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">On Thu, Jun 8, 2023 at 4:51 PM John Rose <john.r.rose@oracle.com> wrote:</p>
<blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">On 8 Jun 2023, at 9:52, Dan Heidinga wrote:</p>
<p dir="auto">On Thu, Jun 8, 2023 at 12:44 PM John Rose <john.r.rose@oracle.com> wrote:</p>
<p dir="auto">On 8 Jun 2023, at 9:01, Dan Heidinga wrote:</p>
<p dir="auto">If we decouple the list of preloadable classes from the classfile, how
<br>
would non-jdk classes be handled?> What if instead of ditching the</p>
<p dir="auto">attribute, or treating it like an</p>
<p dir="auto">optimization, we firmed up the contract and treated it as a guarantee…</p>
<p dir="auto">If we go down this route, let’s consider putting the control information
<br>
into a module file (only) for starters. (Maybe class file later if
<br>
needed.) There would be fewer states to document and test, since (by
<br>
definition) class files could not get out of sync.</p>
<p dir="auto">A module would document, in one mplace, which types it would “prefer” to
<br>
preload in order to optimize its APIs (internal or external).</p>
<p dir="auto">This might lead to more class loading than intended. The current approach
<br>
has each classfile register the list of classes it wants preloaded to get
<br>
the best linkage which means we only have to load those classes if we link
<br>
the original class. There's a natural trigger for the preload and a
<br>
limited set of classes to load.</p>
<p dir="auto">There’s a spectrum of tradeoffs here: We could put preload attributes on
<br>
every method and field, to get the maximum amount of fine-grained lazy
<br>
(pre-)loading, or put them in a global file per JVM instance. The more
<br>
fine-grained, the harder it will be to write compliance testing, I think.</p>
</blockquote><p dir="auto">Agreed.  There's a sweet spot between expressiveness and overheads
<br>
(testing, metadata, etc).  Classfiles have historically been the place
<br>
where the JVM tracks this kind of information as that fits well with
<br>
separate compilation and avoids the "external metadata" problems of ie:
<br>
GraalVM's extra-linguistic configuration files.</p>
<p dir="auto">When compiling the current class, javac already requires directly
<br>
referenced classes to be findable and thus has the info required to write a
<br>
preload attribute.  Does javac necessarily have the same info when
<br>
compiling the module-info classfile?  Maybe when finding the non-exported
<br>
packages for the module javac (or jlink? or jmod?) could also find the
<br>
value classes that need preloading?</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">That is what I am assuming.  The module file would be edited by those guys.  Or (maybe better) a plain flat textual list is put somewhere the JVM can find it.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">Moving it into a separate pass like this doesn't feel like quite the right
<br>
fit though as it excludes the classpath and complicates the other tools
<br>
processing of the modules.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">I think it’s better than that.  When we are assembling a program (jlink or a Leyden condenser), the responsibility of publicizing value classes (for Preload) surely belongs to the declaration, not collectively on all the uses.</p>
<p dir="auto">So every module (jmod or whatever) that declares 1 or more value classes (if they are exported, at least) should list them on a publicized watch list.</p>
<p dir="auto">There is no need to replicate these watch lists across all potential API clients of a value class.  There are reasons <em>not</em> to do this, since the clients have only partial, provisional information about the values.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">Moving to a single per-module list loses the natural trigger and may
<br>
pre-load more classes than the application will use. If Module A has
<br>
classes {A, B, C} and each one preloads 5 separate classes, with a
<br>
per-module list that's forcing the loading of 15 additional classes (plus
<br>
supers, etc). With a per-class list, we only preload the classes on a
<br>
per-use basis. More of a pay for what you use model.</p>
<p dir="auto">Is there a natural trigger or way to limit the preloads to what I might
<br>
use
<br>
with the per-module file?</p>
<p dir="auto">That’s a very good question. I think what Preload *really is* is a list
<br>
of “names that may require special handling before using in APIs”. They
<br>
don’t need to be loaded when the preload attribute is parsed; they are
<br>
simply put in a “watch list” to trigger additional loading *when
<br>
necessary*. (This is already true.) So I think if we move the preload
<br>
list to (say) the module level (if not a global file), then the JVM will
<br>
have its watch list. (And, in fewer chunks than if we put all the stuff all
<br>
the time redundantly in all class files that might need them: That requires
<br>
frequent repetition.) The JVM can use its watch list as it does today, with
<br>
watch lists populated separately for each class file.</p>
</blockquote><p dir="auto">I initially thought a global list would lead to issues if two different
<br>
classloaders defined classes of the same name but since this is a "go and
<br>
look" signal, early loading based on name should be fine even in that case
<br>
as each loader that mentions the name would be asked to be asked to load
<br>
their version of the named class.  So I think a per-JVM list would be OK
<br>
from that perspective (though I still don't like it).</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">Agreed.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">To emphasize: A watch list does not require loading. It means, “if you see
<br>
this name at a point where you could use extra class info, then I encourage
<br>
you to load sooner rather than later”. The only reason it is “a thing” at
<br>
all is that the default behavior (of loading either as late as possible, or
<br>
as part of a CDS-like thingy) should be changed only on an explicit signal.</p>
</blockquote><p dir="auto">While true for what the JVM needs, this is hard behaviour to explain to
<br>
users and challenging for compliance test writers (or maybe not if we
<br>
continue to treat preload as an optimization).</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">I’m trying to reduce this to a pure optimization.  In that case, “watch lists” are just helpers, which are allowed to fail, and allowed to be garbage.</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">Is this where we want to
<br>
spend our complexity budget?</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">(No, hence it should be an optimization.)</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><p dir="auto">Part of why I'm circling back to treating
<br>
preload as a per-classfile attribute that forms a requirement on the VM
<br>
rather than as an optimization is that the model becomes clearer for users,
<br>
developers and testers.</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">I think it’s still going to be murky.  Why is putting the watch list on the API clients better than putting it on (or near) the value class definitions?</p>
</div><div class="plaintext" style="white-space: normal;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; color: #777777;"><blockquote style="margin: 0 0 5px; padding-left: 5px; border-left: 2px solid #777777; border-left-color: #999999; color: #999999;"><p dir="auto">And, hey, maybe CDS is all the primitive we need here: Just run -Xdump
<br>
with all of your class path loaded. Et voila, no Preload at all.</p>
</blockquote><p dir="auto"> Users may find this behaviour surprising - I ran with a CDS archive and my
<br>
JVM loaded classes earlier than it would have otherwise?</p>
</blockquote></div>
<div class="markdown" style="white-space: normal;">
<p dir="auto">CDS has the effect of making class loading in a more timely fashion, and (under Leyden) will almost certainly trigger reordering of loading as well.  So promulgating a “watch list” has goals which align with CDS.</p>
<p dir="auto">I’m starting to think that the right “level” to pull for optimizing value-based APIs is to put the value classes in a CDS archive.  That is a defacto watch list.  The jlink guy should just make a table of all value classes.  That’s the best form of Preload I can imagine, frankly.</p>

</div></div></body>

</html>