RFR: 8353225: Add a way to iterate Klass inside the loaded CDS archive

Thomas Stuefe stuefe at openjdk.org
Wed Apr 2 12:16:03 UTC 2025


On Tue, 1 Apr 2025 18:05:57 GMT, Ioi Lam <iklam at openjdk.org> wrote:

>> If we want this PR to proceed we should restructure the CDS code to use a different mechanism to iterate over the unloaded proxy classes.
>
> However, I still don't understand why this API is necessary for "KLUT" -- why do you need to look at all the classes in the CDS archive, including those that are not yet loaded?
> 
> Not all classes in the CDS archive are destined to be loaded. So of them are never referenced by the app so they are not loaded. Others can be substituted by JVMTI ClassFileLoadHook. So if you see some of these unloaded classes, what can you do with them?

KLUT changes some of the basic operations on oops; for example, oop->isObjArray() retrieves the class kind from the KLUT table, not the class. For that, the entry for that Klass must have been added to the KLUT table. For dynamic class loading, this is not a problem: before an oop is ever born, we need to load the class first, so there is always a path where the Klass is created, and that is where I populate the entry in the table.

For CDS, this does not work. CDS uses methods on oops in the mapped heap regions before ever loading the associated class. For example, by calling oop->isObjArray() or similar. Traditionally this works because oop->isObjArray does not need much, just narrow Klass pointer decoding, which we set up beforehand. For KLUT, it does not work since the KLUT entry is not there yet.

Example: in ArchiveHeapLoader::finish_initialization()  (archiveHeapLoader.cpp:396). There are other examples.

I can workaround this by reverting to dynamic initialization for the KLUT entry (if entry missing, calculate it and store it), but that is undesirable for real oop iteration during GCs. We execute that condition a bazillion times because a few classes need it on the CDS initialization path. Well, maybe branch prediction would be smart enough to minimize the negative effect of this additional branch. But it is somewhat baffling that such a simple thing as iterating all Klass structures in a CDS archive is so complex.

Could one just iterate through the shared class space portion? Hop from Klass to Klass, as one would iterate through the heap? But I doubt that this always works either - there may be holes between Klass structures, or there may other things that live in there, too. 

About the "may never be loaded": That is fine. I rather unnecessarily calculate the KLUT token for a class that will never be used than to pay for "Is this entry initialized?" branch in every use of the KLUT table. The latter is worse, performance-wise.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/24311#discussion_r2024698540


More information about the hotspot-runtime-dev mailing list