RFR: 8259839 SystemDictionary exports too much implementation [v2]

David Holmes dholmes at openjdk.java.net
Wed Jan 27 06:13:44 UTC 2021


On Wed, 27 Jan 2021 02:04:54 GMT, Coleen Phillimore <coleenp at openjdk.org> wrote:

>> I apologize for the large change but it's really a bunch of little cleanups combined made while trying to understand the code.  Only number 8 below changes any behavior.  Tested with tier1-8 (24hr Dacapo is still running).
>> 
>> In systemDictionary.cpp:
>>  1. moved placeholder table and other table sizes into systemDictionary.cpp
>>  2. Made SystemDictionary::find_class() into a verification function called verify_dictionary_entry since that's what it was used for 
>>  3. Moved a resolve_or_fail() down and removed redundant checks before calling handle_resolution_exception
>>  4. Fixed some comments
>>  5. child_name confused me. class_name and super_name are more meaningful in these contexts
>>  6. callers of find_or_define_instance_class had to check for a different klass return (with AllowParallelDefineClass), or an exception in order to deallocate one of the classes, so I wrapped it into a function and renamed find_or_define_instance_class into find_or_define_helper.
>>  7. find_placeholder() is really used to verify_placeholder(). Actually the verification was a nop. Fixing it found a bug in that CDS was calling define_instance_class rather than find_or_define_instance_class for parallelCapable class loader's that it shares, so verify_placeholder() was failing.  Changed the CDS code to call find_or_define_instance_class instead.
>> 
>> In systemDictionary.hpp, I moved the static data members and moved declarations around to make private and have a single protected block for SystemDictionaryShared to use.
>
> Coleen Phillimore has updated the pull request incrementally with one additional commit since the last revision:
> 
>   return NULL for find_or_define_helper if pending exception

Hi Coleen,

I can't quite convince myself that the changes in relation to potentially parallel definition are right, but that is mainly because I can't fully reconcile the existing comments in that area. A number of comments below.

Thanks,
David

src/hotspot/share/classfile/systemDictionary.cpp line 241:

> 239: static Klass* handle_resolution_exception(Symbol* class_name, bool throw_error, Klass* klass, TRAPS) {
> 240:   if (HAS_PENDING_EXCEPTION) {
> 241:     assert(klass == NULL, "Should not have result with exception pending");

If klass is expected to be NULL why even bother passing it in to this function?

src/hotspot/share/classfile/systemDictionary.cpp line 240:

> 238: 
> 239: static Klass* handle_resolution_exception(Symbol* class_name, bool throw_error, Klass* klass, TRAPS) {
> 240:   if (HAS_PENDING_EXCEPTION) {

To me it would be clearer if the caller checked HAS_PENDING_EXCEPTION and only called handle_resolution_exception if there was one. As there are only a couple of calls this doesn't result in much code duplication.

src/hotspot/share/classfile/systemDictionary.cpp line 411:

> 409:     InstanceKlass* klassk = dictionary->find_class(name_hash, class_name);
> 410:     InstanceKlass* quicksuperk;
> 411:     // to support // loading: if klass done loading, just return superclass

I assume // is an approximation for || ie parallel loading? can we just say parallel please.

src/hotspot/share/classfile/systemDictionary.cpp line 414:

> 412:     // if super_name, & class_loader don't match:
> 413:     // if initial define, SD update will give LinkageError
> 414:     // if redefine: compare_class_versions will give HIERARCHY_CHANGED

Should these comment lines be indented because they describe what happens when super_name and loader don't match?
I find these comments are bit hard to parse in their existing form of psuedo-English.

src/hotspot/share/classfile/systemDictionary.cpp line 1588:

> 1586: 
> 1587:   // Bootstrap and other parallel classloaders don't acquire a lock,
> 1588:   // they use placeholder token.

Unclear to me what this existing text is referring to. Parallel-capable classloaders do acquire a lock in the Java code. If this pertains only to class resolution (and so potentially skips the Java loadClass call) then the only "other parallel classloader" would be the platform-loader - right?

src/hotspot/share/classfile/systemDictionary.cpp line 2032:

> 2030: // Verify that this placeholder exists since this class is in the middle of loading.
> 2031: void verify_placeholder(Symbol* class_name, ClassLoaderData* loader_data, bool is_parallel_capable) {
> 2032:   // Only parallel capable class loaders use placeholder table for define class (bizarre)

Is that really "Only parallel capable _built-in_ class loaders use ..."  as they by-pass the Java loadClass call that otherwise does the locking.

But don't you still need placeholder entries for class circularity errors, which can happen with non-parallel-capable classloaders too ??

src/hotspot/share/classfile/systemDictionary.cpp line 2083:

> 2081:     }
> 2082: 
> 2083:     DEBUG_ONLY(verify_placeholder(name, loader_data, is_parallelCapable(class_loader)));

I think this would be clearer as:
 (is_parallelCapable(class_loader) verify_placeholder(name, loader_data);)```

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

PR: https://git.openjdk.java.net/jdk/pull/2247


More information about the hotspot-runtime-dev mailing list