RFR(S): 8193434: [GRAAL] Graal classes are not loaded with -Xshare:dump

Calvin Cheung calvin.cheung at oracle.com
Thu Mar 1 17:33:07 UTC 2018



On 2/28/18, 12:56 PM, Ioi Lam wrote:
>
>
>
> On 2/28/18 10:42 AM, Jiangli Zhou wrote:
>> I vote for this solution. Although it is not perfect since classes 
>> not in the combined dictionary will still copied into the shared 
>> metaspaces, it is much cleaner than the conditional check in 
>> SystemDictionary::resolve_from_stream(). 
>
> We can change CollectClassesClosure to collect only boot classes if 
> UseAppCDS is false. That way, non-boot classes will not be copied into 
> the shared metaspaces.
I've made this additional change.
Updated webrev:
     http://cr.openjdk.java.net/~ccheung/8193434/webrev.03/

thanks,
Calvin
>
>
> class CollectClassesClosure : public KlassClosure {
>   void do_klass(Klass* k) {
>     if (!(k->is_instance_klass() && 
> InstanceKlass::cast(k)->is_in_error_state())) {
>       _global_klass_objects->append_if_missing(k);
>     }
>     if (k->is_array_klass()) {
>       // Add in the array classes too
>       ArrayKlass* ak = ArrayKlass::cast(k);
>       Klass* h = ak->higher_dimension();
>       if (h != NULL) {
>         h->array_klasses_do(collect_array_classes);
>       }
>     }
>   }
> };
>
> Thanks
> - Ioi
>> Removing the CDS specific if block 
>> in SystemDictionary::resolve_from_stream() makes normal code path 
>> cleaner.
>>
>> Thanks,
>> Jiangli
>>
>>
>>> On Feb 28, 2018, at 7:59 AM, Ioi Lam <ioi.lam at oracle.com 
>>> <mailto:ioi.lam at oracle.com>> wrote:
>>>
>>>
>>>
>>> On 2/27/18 5:38 PM, Calvin Cheung wrote:
>>>> Hi Ioi,
>>>>
>>>> Thanks for taking a look.
>>>>
>>>> On 2/27/18, 4:30 PM, Ioi Lam wrote:
>>>>> Hi Calvin,
>>>>>
>>>>> I think the CNFE is caused by this code (in the "before" version):
>>>>>
>>>>> 1054 InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* 
>>>>> class_name,
>>>>> 1055 Handle class_loader,
>>>>> 1056 Handle protection_domain,
>>>>> 1057 ClassFileStream* st,
>>>>> 1058 TRAPS) {
>>>>> 1059 #if INCLUDE_CDS
>>>>> 1060   ResourceMark rm(THREAD);
>>>>> 1061   if (DumpSharedSpaces && !class_loader.is_null() &&
>>>>> 1062       !UseAppCDS && strcmp(class_name->as_C_string(), 
>>>>> "Unnamed") != 0) {
>>>>> 1063     // If AppCDS is not enabled, don't define the class at 
>>>>> dump time (except for the "Unnamed"
>>>>> 1064     // class, which is used by MethodHandles).
>>>>> 1065 THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), 
>>>>> class_name->as_C_string());
>>>>> 1066   }
>>>>> 1067 #endif
>>>> Yes, I wrote a comment in the bug report yesterday.
>>>>>
>>>>> As far as I can tell, the intention is -- if UseAppCDS is not 
>>>>> enabled, load classes only for the boot loader.
>>>> Right.
>>>>>
>>>>> However, when -XX:+UseJVMCICompiler is enabled in the command-line 
>>>>> during dumping, we get this:
>>>>>
>>>>> $ java -Xshare:dump -Xlog:cds,cds+hashtables 
>>>>> -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=./test.jsa 
>>>>> -Xbatch -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI 
>>>>> -XX:+UseJVMCICompiler
>>>>>
>>>>> java.lang.ClassNotFoundException: 
>>>>> org/graalvm/compiler/hotspot/HotSpotGraalJVMCIServiceLocator
>>>>> at java.lang.ClassLoader.defineClass2(java.base at 11-internal/Native 
>>>>> Method)
>>>>> at 
>>>>> java.lang.ClassLoader.defineClass(java.base at 11-internal/ClassLoader.java:1086)
>>>>> at 
>>>>> java.security.SecureClassLoader.defineClass(java.base at 11-internal/SecureClassLoader.java:206)
>>>>> at 
>>>>> jdk.internal.loader.BuiltinClassLoader.defineClass(java.base at 11-internal/BuiltinClassLoader.java:760)
>>>>> at 
>>>>> jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(java.base at 11-internal/BuiltinClassLoader.java:681)
>>>>> at 
>>>>> jdk.internal.loader.BuiltinClassLoader.findClass(java.base at 11-internal/BuiltinClassLoader.java:562)
>>>>> at 
>>>>> java.lang.ClassLoader.loadClass(java.base at 11-internal/ClassLoader.java:611)
>>>>> at java.lang.Class.forName(java.base at 11-internal/Class.java:450)
>>>>> ...
>>>>>
>>>>>
>>>>> With "-XX+UseAppCDS -Xlog:class+load=debug", we can see this class 
>>>>> is loaded by the platform loader:
>>>>>
>>>>>
>>>>> [0.325s][info ][class,load] 
>>>>> org.graalvm.compiler.hotspot.HotSpotGraalJVMCIServiceLocator 
>>>>> source: jrt:/jdk.internal.vm.compiler
>>>>> [0.325s][debug][class,load]  klass: 0x00000008c0083c30 super: 
>>>>> 0x00000008c00734c8 loader: [class loader 0x00007f30344e5870 a 
>>>>> 'jdk/internal/loader/ClassLoaders$PlatformClassLoader'{0x000000041105cbf0}] 
>>>>> bytes: 1443 checksum: 8dae8ade
>>>>>
>>>>>
>>>>> I think instead of using the _force_init_jvmci_runtime, which 
>>>>> allows these classes to be loaded only during a portion of the 
>>>>> dump time, a better fix would be to remove the above "if" block 
>>>>> altogether. I think if UseAppCDS is not true, 
>>>>> SystemDictionary::combine_shared_dictionaries() won't be called, 
>>>>> so any non-boot classes will be left out from the CDS archive, 
>>>>> which is what you want.
>>>> I tried setting breakpoint in 
>>>> SystemDictionary::combine_shared_dictionaries() and the debugger 
>>>> stopped there without enabling UseAppCDS.
>>>
>>> How about adding a check like this:
>>>
>>> void SystemDictionary::combine_shared_dictionaries() {
>>>   assert(DumpSharedSpaces, "dump time only");
>>>   if (UseAppCDS) {
>>>     Dictionary* master_dictionary = 
>>> ClassLoaderData::the_null_class_loader_data()->dictionary();
>>>     CombineDictionariesClosure cdc(master_dictionary);
>>>     ClassLoaderDataGraph::cld_do(&cdc);
>>>   }
>>>
>>>
>>>> My current proposed change should have the least impact on CDS 
>>>> (without enabling UseAppCDS).
>>>> For getting rid of those "Preload Warning" noted by Vladimir, I 
>>>> think I can leave the _force_init_jvmci_runtime setting; i.e. not 
>>>> resetting it to false at the end of force JVMCI runtime init. This 
>>>> is what I had in my first version:
>>>> http://cr.openjdk.java.net/~ccheung/8193434/webrev.00/ 
>>>> <http://cr.openjdk.java.net/%7Eccheung/8193434/webrev.00/>
>>> I think the use of _force_init_jvmci_runtime feels like an ad-hoc 
>>> solution. The existing code is already hard to understand:
>>>
>>> 1061   if (DumpSharedSpaces && !class_loader.is_null() &&
>>> 1062       !UseAppCDS && strcmp(class_name->as_C_string(), 
>>> "Unnamed") != 0) {
>>>
>>> Our problem here is to make sure that the Java-based class loaders 
>>> runs correctly during dump time. In the future, if more non-boot 
>>> classes are loaded when running the Java-based class loaders, this 
>>> "if" condition will get more and more complicated.
>>>
>>> I think it's much cleaner to modify combine_shared_dictionaries(). 
>>> That way we can ensure that the Java-based loaders can run 
>>> correctly, and also make sure that only boot classes are archived 
>>> when UseAppCDS is false.
>>>
>>> Thanks
>>> - Ioi
>>>>>
>>>>> What do you think?
>>>> I think the current fix with the "Preload Warning" is ok; it means 
>>>> 170 classes won't be in the archive.
>>>>
>>>> thanks,
>>>> Calvin
>>>>>
>>>>> Thanks
>>>>> - Ioi
>>>>>
>>>>>
>>>>>
>>>>> On 2/27/18 11:01 AM, Calvin Cheung wrote:
>>>>>> bug: https://bugs.openjdk.java.net/browse/JDK-8193434
>>>>>>
>>>>>> webrev: http://cr.openjdk.java.net/~ccheung/8193434/webrev.01/ 
>>>>>> <http://cr.openjdk.java.net/%7Eccheung/8193434/webrev.01/>
>>>>>>
>>>>>> java -Xshare:dump -Xlog:cds,cds+hashtables 
>>>>>> -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=./test.jsa 
>>>>>> -Xbatch -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI 
>>>>>> -XX:+UseJVMCICompiler -Djvmci.Compiler=graal
>>>>>>
>>>>>> The above command causes the CNFE to be thrown in 
>>>>>> SystemDictionary::resolve_from_stream() during CDS dump time.
>>>>>> The proposed change is to add a _force_init_jvmci_runtime flag 
>>>>>> which is set at the beginning of 
>>>>>> JVMCIRuntime::force_initialization() and reset at the end of the 
>>>>>> initialization. The flag will be checked in 
>>>>>> SystemDictionary::resolve_from_stream() so that it will not throw 
>>>>>> CNFE during the eager initialization of JVMCI runtime during vm init.
>>>>>>
>>>>>> The proposed change passed hs-tier1 through hs-tier3 testing on 
>>>>>> linux-x64, windows-x64, sparcv9, and Mac OS X.
>>>>>>
>>>>>> thanks,
>>>>>> Calvin
>>
>


More information about the hotspot-runtime-dev mailing list