RFR(S): 8200466: Revisit the setting of _transitive_interfaces in InstanceKlass

coleen.phillimore at oracle.com coleen.phillimore at oracle.com
Mon Apr 30 21:20:01 UTC 2018



On 4/30/18 4:58 PM, Calvin Cheung wrote:
> Hi Coleen,
>
> Thanks for your review.
>
> On 4/30/18, 10:23 AM, coleen.phillimore at oracle.com wrote:
>>
>> This sharing of metadata has been prone to bugs.  Can you have the 
>> same bug with the _secondary_super field? 
>> InstanceKlass::deallocate_contents() checks:
>>
>>       secondary_supers() != transitive_interfaces() &&
>>
>> and will free the field possibly from the super class if 
>> transitive_interfaces() is still NULL.  (If I understand this 
>> correctly).
> If it passes the conditions check in the 'if' block, it will 
> deallocate the _secondary_supers.
> It maybe fine because the crash was in visit_all_interfaces() where it 
> doesn't dereference the _secondary_supers.

It seems like it would deallocate _secondary_supers if an OOM occurred 
after it's set to the super's transitive_interfaces and before 
_transitive_interfaces is set.  There could be a state that could cause 
this to happen.  I would have to trace through to see what sort of crash 
would happen.

>>
>> Wouldn't it be easier just to eagerly set the super class, and keep 
>> the call to initialize_supers() where it is?
> Do you mean adding the following in 
> ClassFileParser::apply_parsed_class_metadata() and reverting the rest 
> of the changes?
>
> this_klass->set_super(const_cast<Klass*>(_super_klass));
>

Yes, can you try this?  This line with a comment would be less 
complicated than passing NULL to initialize_supers() for the arrayKlass 
versions.


> BTW, I think the first arg to initialize_supers() should be casted to 
> Klass* like above because the _super_klass is already an InstanceKlass*.
>
> ik->initialize_supers(const_cast<InstanceKlass*>(_super_klass) ...
>
>
I think we still need some cast here and above because _super_klass is 
defined as const, and this function and set_super are both not 
const-safe, which is a bigger change.   Or you could make 
ClassFileParser::_super_klass not const since const is cast away.

>>
>> http://cr.openjdk.java.net/~ccheung/8200466/webrev.00/src/hotspot/share/classfile/classFileParser.cpp.udiff.html 
>>
>>
>> **** 5884,5893 *****
>> *--- 5889,5899 ----*
>> *Annotations::free_contents(_loader_data, _fields_annotations);*
>> *Annotations::free_contents(_loader_data, _fields_type_annotations);*
>> *}*
>> **
>> *clear_class_metadata();*
>> *+ _transitive_interfaces = NULL;*
>> **
>>
>> clear_class_metadata() already sets the _transitive_interfaces to 
>> NULL, so this shouldn't be needed.
> The current change does not set the _trasitive_interfaces to NULL in 
> clear_class_metadata().
>
> From the udiff above:
>
> **** 5832,5842 *****
> *--- 5838,5847 ----*
> *     _cp = NULL;*
> *     _fields = NULL;*
> *     _methods = NULL;*
> *     _inner_classes = NULL;*
> *     _local_interfaces = NULL;*
> *     _transitive_interfaces = NULL;*
> *     _combined_annotations = NULL;*
> *     _annotations = _type_annotations = NULL;*
> *     _fields_annotations = _fields_type_annotations = NULL;*
> *   }*

Oh I see it now and why you changed it.  Can you see if setting the 
Klass::_super ahead of setting _transitive_interfaces would work better?

thanks,
Coleen

>
> thanks,
> Calvin
>>
>> thanks,
>> Coleen
>>
>> On 4/27/18 12:46 AM, Calvin Cheung wrote:
>>> JBS: https://bugs.openjdk.java.net/browse/JDK-8200466
>>>
>>> webrev: http://cr.openjdk.java.net/~ccheung/8200466/webrev.00/
>>>
>>> This bug was discovered during the investigation of JDK-8200078 
>>> <https://bugs.openjdk.java.net/browse/JDK-8200078>.
>>>
>>> I've included the following comment in classFileParser.cpp to 
>>> summarize the change:
>>>
>>> // Delay the setting of _transitive_interfaces until after 
>>> initialize_supers() in
>>> // fill_instance_klass(). It is because the _transitive_interfaces 
>>> may be shared with
>>> // its _super. If an OOM occurs while loading the current klass, its 
>>> _super field
>>> // may not have been set. When GC tries to free the klass, the 
>>> _transitive_interfaces
>>> // may be deallocated mistakenly in 
>>> InstanceKlass::deallocate_interfaces(). Subsequent
>>> // dereferences to the deallocated _transitive_interfaces will 
>>> result in a crash.
>>>
>>> Testing: (on Oracle platforms)
>>>     hs-tier{1,2,3}
>>>     closed (soon will be open) PCL (parallel class loading) tests
>>>
>>> thanks,
>>> Calvin
>>



More information about the hotspot-runtime-dev mailing list