On Fri, 4 Nov 2022 02:07:25 GMT, David Holmes <dhol...@openjdk.org> wrote:

>> This change adds an option **EnableWaitForParallelLoad** to enable the 
>> legacy behavior where the VM will manage synchronization for multiple 
>> threads loading the same class using a non-parallel capable class loader 
>> that have released the class loader lock.  The VM will break the class 
>> loader lock for parallel threads trying to load the class, and wait for the 
>> first thread that initiated loading the class to complete.  The subsequent 
>> threads will use the result of the first thread, rather than get a 
>> LinkageError: duplicate class definition for loading the class without 
>> synchronization.
>> Releasing the class loader lock was a common workaround for class loaders 
>> that used a non-hierarchical delegation scheme to avoid deadlock, before 
>> parallel capable class loading was added. 
>> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#registerAsParallelCapable()
>> 
>> Tested with tier1-6 and internal applications.
>
> src/hotspot/share/classfile/placeholders.cpp line 137:
> 
>> 135:   assert(action != PlaceholderTable::LOAD_INSTANCE || seen == NULL,
>> 136:          "Only one LOAD_INSTANCE allowed at a time");
>> 137: 
> 
> Unclear why this is removed? If disabling the new flag causes this fail then 
> shouldn't the new flag form part of the condition?

If you want, it seemed unnecessary clutter for the assert.

> src/hotspot/share/classfile/systemDictionary.cpp line 597:
> 
>> 595:           double_lock_wait(current, lockObject);
>> 596:         } else {
>> 597:           return NULL;
> 
> Not clear why we return NULL here rather than just falling through and 
> retrying?

If we don't return we'll actually do a wait and will hang.  Worse, we'll be in 
a tight loop holding both the ClassLoader and SystemDictionary_lock, that the 
other thread can't get.

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

PR: https://git.openjdk.org/jdk/pull/10832

Reply via email to