Preload attribute
Frederic Parain
frederic.parain at oracle.com
Thu Jun 8 17:14:58 UTC 2023
Hi Dan,
I've looked at your exploration of the Preload attribute. The LoaderTest
test loads class A but it doesn't link it. HotSpot looks at the PreLoad
attribute at class link time, not class load time (yes, the name is
misleading), this is why class B is not loaded.
Replacing the call to loadClass() with a call to Class.forName() to
force the linking of the class will trigger the processing of the
PreLoad attribute.
public static void main(String[] args) throws Throwable {
ARGS = args;
ClassLoader cl = new LoaderTest2();
Class<?> c = Class.forName(args[0], true, cl);
System.out.println(""+c+"::loader="+c.getClassLoader());
}
Fred
On 6/8/23 12:01 PM, Dan Heidinga wrote:
> Thanks Dan and Fred for the clarification on the current spec and
> Hotspot behaviour and John for suggesting we remove the attribute.
>
> I think the problem with the current status quo for the preload
> attribute is that we're trying to treat it like an optimization - a
> "we can have our cake" (know which classes to load at some
> indeterminate point) and "eat it too" (not promise users anything
> about when or if those classes will be loaded).
>
> As it stands, based just on the spec, it's hard for users to know what
> the preload attribute will do for them. There's nothing they can
> depend on in the spec and are at the mercy of whatever behaviour VM
> implementers pick on a given day. Which means they will depend on the
> current Hotspot behaviour (defacto standardization - yuck!) or expect
> the behaviour to change all the time.
>
> If we decouple the list of preloadable classes from the classfile, how
> would non-jdk classes be handled? Many applications are a mix of
> multiple jar files from different maintenance domains which would make
> having a combined list difficult. We'd also need to think through the
> classloader implications vs today's approach which attempts to load on
> the same loader as the class with the preload attribute.
>
> What if instead of ditching the attribute, or treating it like an
> optimization, we firmed up the contract and treated it as a guarantee
> similar to those of superclasses and superinterfaces as in the first
> line in section 5.4 "Linking"? The new text would read something like:
> > Linking a class or interface involves verifying and preparing
> that class or interface, its direct superclass, its direct
> superinterfaces, and its element type (if it is an array type), if
> necessary. Any classes listed in the preload attribute will be loaded
> at this point.
>
> We don't need to say in the JVMS why the classes are in the attribute,
> but we should be explicit about where the attempt to load them occurs
> and that errors are ignored. This provides stability to the users and
> allows for independent implementation while avoiding de
> facto standardization of today's behaviour.
>
> Before responding, I built the latest lworld branch of the Valhalla
> repo and played with the preload attribute to try and force a
> classloader-related deadlock. I was surprised to find that the
> attribute doesn't seem to have an effect on user-defined loaders and
> with the current spec, I can't even say if that's a bug or not.
> Example classfiles for this exploration are in
> https://github.com/DanHeidinga/valhalla-preload-example
>
> --Dan
>
> On Mon, Jun 5, 2023 at 9:52 PM John Rose <john.r.rose at oracle.com> wrote:
>
> Overall, as we look at Preload, it is looking more and more like a
> no-op, as far as the JLS and JVMS is concerned. Perhaps that is a
> signal that it should be placed somewhere outside of the JVMS,
> such as in a Leyden-specific mechanism (a preload list) produced
> in a way decoupled from any transactions between the JLS and JVMS.
>
> On 1 Jun 2023, at 11:24, Dan Smith wrote:
>
> On Jun 1, 2023, at 10:53 AM, Dan Heidinga
> <heidinga at redhat.com> wrote:
>
> A couple of questions about the spec for the Preload
> attribute[0]. The current spec says it indicates "certain
> classes contain information that may be of interest during
> linkage."
>
> The Preload attribute removes one need for Q modifiers
> while allowing calling convention optimizations and layout
> decisions to be made early.
>
> The current spec is quite vague on what classes should be
> included in the attribute and on when / what the VM will
> do with those classes (or even if it does anything).
>
> FWIW, the JEP has more detail about when javac is expected to
> include classes in Preload.
>
> I think it's time to tighten up the spec for Preload
> attribute and specify:
> * what the VM will do with classes listed in the attribute
>
> It is intentional that the VM may choose to do nothing. So
> anything it does is purely an optimization.
>
> Looks like a nop…
>
> (In particular, it should not /reject/ any inputs, because that
> would destabilize separate compilability in unpredictable ways.)
>
> * when those classes will be loaded (ie: somewhere in JVMS
> 5.3)
>
> If the VM chooses to load Preload classes, then our thinking
> was that JVMS 5.4 already describes the details of timing:
>
> https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-5.html#jvms-5.4
>
> So, for example, "Alternatively, an implementation may choose
> an "eager" linkage strategy, where all symbolic references are
> resolved at once when the class or interface is being
> verified." That is, the Preload classes could all be loaded
> during verification, or at some other stage of linking.
>
> My expectation is that the natural point for processing
> Preload is during preparation as vtables are set up, but
> sometimes I get these things wrong. :-)
>
> Sometimes you want them early (for instance layout) and sometimes
> you need to wait (vtable layout or even just before <clinit>).
>
> * how invalid cases are handled, including circularities
> (Class A's Preload mentions B <: A)
>
> Silent supression of errors, if any. Again, like a nop…
>
> "Errors detected during linkage are thrown at a point in the
> program where some action is taken by the program that might,
> directly or indirectly, require linkage to the class or
> interface involved in the error."
>
> I've always found this rule super vague, but I think "require"
> is the key word, and implies that errors caused by Preload
> resolution should just be ignored. (Because Preload isn't
> "required" to be processed at all.)
>
> * what types of classes can be listed (any? only values?)
>
> Definitely intend to support any classes of interest. Say a
> future optimization wants to know about a sealed
> superinterface, for example—it would be fine to tweak javac to
> add that interface to Preload, and then use the information to
> facilitate the optimization.
>
> There's a lot of nondeterminism here—can a compliant system
> trigger changes to class loading timing, but just on my
> birthday?—but I think it's within the scope of JVMS 5.4, which
> provides a lot of latitude for loading classes whenever it's
> convenient.
>
> It probably makes sense to start from the current Hotspot
> handling of the attribute and fine tune that into the spec?
>
> So I've outlined our hands-off stake in the ground above. The
> spec would definitely benefit, at least, from a non-normative
> cross-reference to 5.4 and short explanation. Beyond that, I
> think we'd be open to specifying more if we can agree
> something more is needed...
>
> I think we could get the benefits in Fred’s prototype (as he
> describes) with a list that is decoupled from any particular class
> file, and Leyden could deliver this list.
>
> As you see, I’m kind of sour on a Preload attribute these days.
>
More information about the valhalla-spec-observers
mailing list