RFR (XS) 8185160 -XX:DumpLoadedClassList omits graal classes
Ioi Lam
ioi.lam at oracle.com
Thu Oct 19 17:55:48 UTC 2017
On 10/19/17 9:47 AM, Jiangli Zhou wrote:
>
>> On Oct 18, 2017, at 9:50 PM, Ioi Lam <ioi.lam at oracle.com
>> <mailto:ioi.lam at oracle.com>> wrote:
>>
>>
>>
>> On 10/18/17 9:35 PM, Jiangli Zhou wrote:
>>> Hi Ioi,
>>>
>>>> On Oct 18, 2017, at 4:54 PM, Ioi Lam <ioi.lam at oracle.com
>>>> <mailto:ioi.lam at oracle.com>> wrote:
>>>>
>>>>
>>>>
>>>> On 10/17/17 9:04 PM, David Holmes wrote:
>>>>> Hi Ioi,
>>>>>
>>>>> On 18/10/2017 1:52 PM, Ioi Lam wrote:
>>>>>> http://cr.openjdk.java.net/~iklam/jdk10/8185160-dump-class-list-omits-graal.v01/
>>>>>> <http://cr.openjdk.java.net/%7Eiklam/jdk10/8185160-dump-class-list-omits-graal.v01/>
>>>>>>
>>>>>> https://bugs.openjdk.java.net/browse/JDK-8185160
>>>>>>
>>>>>> Summary:
>>>>>>
>>>>>> DumpLoadedClassList skips classes that can't be stored into the CDS
>>>>>> archive. For boot and platform loaders, only classes from the JRT
>>>>>> image
>>>>>> are listed.
>>>>>>
>>>>>> The test for "is this class from JRT image" was insufficient. It
>>>>>> checked only classes whose source ends with "...../modules". For the
>>>>>> platform loader, which loads the graal classes, the source is in the
>>>>>> form "jrt:/jdk.internal.vm.compiler".
>>>>>>
>>>>>> The fix is to also check for a "jrt:" prefix.
>>>>>
>>>>> So ./share/classfile/classLoader.hpp:
>>>>>
>>>>> static bool is_jrt(const char* name) { return
>>>>> string_ends_with(name, MODULES_IMAGE_NAME); }
>>>>>
>>>>> is a badly named function or just plain broken?
>>>>>
>>>>
>>>> I've renamed all the is_jrt() functions to is_modules_image(), so
>>>> it's clear as to what it does.
>>>>
>>>> See
>>>> http://cr.openjdk.java.net/~iklam/jdk10/8185160-dump-class-list-omits-graal.v02/
>>>> <http://cr.openjdk.java.net/%7Eiklam/jdk10/8185160-dump-class-list-omits-graal.v02/>
>>>
>>> The logic looks puzzling. For both NULL class loader and the
>>> PlatformClassLoader:
>>>
>>> The first if check at line 5938 excludes any classes not in the jimage.
>>>
>>> 5938 if (!ClassLoader::is_modules_image(stream->source()) &&
>>> strncmp(stream->source(), "jrt:", 4) != 0) {
>>> 5939 skip = true;
>>> 5940 }
>>> The second if check at line 5942 skips any classes from the boot
>>> append class path loaded by the NULL class loader. The second check
>>> skips a subset of the classes that’s already skipped by the first
>>> check. The second check is redundant.
>>>
>> You're right. The second check is redundant. I'll remove it.
>>
>>> 5942 if (class_loader == NULL &&
>>> ClassLoader::contains_append_entry(stream->source())) {
>>> 5943 // For the boot loader, also skip all classes that are loaded
>>> from the appended entries
>>> 5944 skip = true;
>>> 5945 }
>>> What about the classes from -Xbootclasspath/a (not in --patch-module
>>> and --upgrade-module-path)?
>>>
>> I am not sure what you mean here.
>
> This excludes all classes from the -Xbootclasspath/a. However, classes
> from -Xbootclasspath/a can be archived and used at runtime properly.
>
Hi Jiangli,
You're right. I misunderstood the original comments about the treatment
of the bootclasspath/a classes. Here's the updated code that should be
easier to understand:
bool skip = false;
if (class_loader == NULL ||
SystemDictionary::is_platform_class_loader(class_loader)) {
// For the boot and platform class loaders, skip classes that
are not found in the
// java runtime image, such as those found in the
--patch-module entries.
// These classes can't be loaded from the archive during runtime.
if (!ClassLoader::is_modules_image(stream->source()) &&
strncmp(stream->source(), "jrt:", 4) != 0) {
skip = true;
}
if (class_loader == NULL &&
ClassLoader::contains_append_entry(stream->source())) {
// .. but don't skip the boot classes that are loaded from
-Xbootclasspath/a
// as theycan be loaded from the archive during runtime.
skip = false;
}
}
Thanks
- Ioi
> Thanks,
> Jiangli
>
>>
>> Thanks
>> - Ioi
>>> Thanks,
>>> Jiangli
>>>
>>>>
>>>>
>>>>>> I also restructured the code to make it easier to read -- the
>>>>>> nesting of || and && is hard to follow.
>>>>>>
>>>>>> The original code had a subtle bug with the "!" operator:
>>>>>>
>>>>>> 5938 if (((class_loader == NULL &&
>>>>>> !ClassLoader::contains_append_entry(stream->source())) ||
>>>>>> 5939 SystemDictionary::is_platform_class_loader(class_loader)) &&
>>>>>> 5940 !ClassLoader::is_jrt(stream->source())) {
>>>>>>
>>>>>> So if (class_loader == NULL &&
>>>>>> ClassLoader::contains_append_entry(stream->source()) was true,
>>>>>> the class would NOT be skipped.
>>>>>>
>>>>>> The new version removes the "!".
>>>>>
>>>>> So there should be an updated test to trigger the original bug.
>>>>>
>>>>
>>>> I added a test case, but it's in the closed repo for now (since the
>>>> test case uses utilities in the closed AppCDS tests). This test
>>>> will be opened as part of JDK-8185996
>>>>
>>>> Thanks
>>>> - Ioi
>>>>
>>>>> Thanks,
>>>>> David
>>>>>
>>>>>> Thanks
>>>>>> - Ioi
>>>>
>>>
>>
>
More information about the hotspot-runtime-dev
mailing list