RFR: 8154750: Add missing OrderAccess operations to ClassLoaderData lock-free data structures
Stefan Karlsson
stefan.karlsson at oracle.com
Fri May 27 05:30:42 UTC 2016
On 2016-05-27 00:36, David Holmes wrote:
> Hi Kim,
>
> Thanks for looking at this.
>
> On 27/05/2016 5:56 AM, Kim Barrett wrote:
>>> On May 24, 2016, at 4:03 AM, David Holmes <david.holmes at oracle.com>
>>> wrote:
>>>
>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8154750
>>>
>>> webrev: http://cr.openjdk.java.net/~dholmes/8154750/webrev/
>>
>> Thanks for fixing these uses of DCLP.
>>
>> ------------------------------------------------------------------------------
>>
>> src/share/vm/classfile/classLoaderData.cpp
>> 80 // helper function to avoid in-line casts
>> 81 template <typename T> static T load_ptr_acquire(volatile T* p) {
>> 82 return static_cast<T>(OrderAccess::load_ptr_acquire(p));
>> 83 }
>>
>> For better type safety, maybe this should instead be
>>
>> template<typename T> static T* load_ptr_acquire(T* volatile * p) {
>> return static_cast<T*>(OrderAccess::load_ptr_acquire(p));
>> }
>
> Can you explain to me what difference this makes please. The field
> types are all "Foo*" so I'm unclear what the difference is between
> writing this in a form where T is Foo* and T is Foo. ??
>
>> This also seems like it might be generally useful. Would it make
>> sense to add it to OrderAccess?
>
> I tried and could not get it to work. As I said earlier in the thread
> it either failed to compile or else became self-referential and hit an
> infinite loop at runtime. Trying to deal with that seemed out-of-scope
> for what I was trying to achieve here. I was also worried about
> silently changing other uses of load_ptr_acquire.
>
> That said, your formulation of it may work better than mine. So I will
> give it another try.
>
>> ------------------------------------------------------------------------------
>>
>> src/share/vm/classfile/classLoaderData.cpp
>> 197 void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
>> 209 void ClassLoaderData::packages_do(void f(PackageEntry*)) {
>>
>> Based on the RFR, I'm guessing these are only called at a safepoint or
>> while holding Module_lock? Maybe add assert_locked_or_safepoint to
>> these too?
>>
>> (Maybe these are only called from the corresponding
>> ClassLoaderDataGraph functions, which already have such an assertion.
>> But more local assertions in the CLD functions would make things
>> easier to understand.)
>
> AFAICS yes they are only called from the CLDG functions. I don't like
> adding redundant assertions but okay. (Even debug builds have time
> constraints!)
>
>> ------------------------------------------------------------------------------
>>
>> src/share/vm/classfile/classLoaderData.cpp
>> 352 // This is called by InstanceKlass::deallocate_contents() to
>> remove the
>> 353 // scratch_class for redefine classes. We need a lock because
>> there it may not
>> 354 // be called at a safepoint if there's an error.
>> 355 void ClassLoaderData::remove_class(Klass* scratch_class) {
>> ... and modifies _klasses list ...
>>
>> How are the unlocked iterators over the _klasses list protected from
>> the modifications performed here? The description is suggestive that
>> they might not be (e.g. need lock because might not be at a
>> safepoint).
>
> I'll have to check this but I think this deletion can only be done in
> a context where you can't be iterating the klasses. Lifecycle
> management is unclear to me (I'm not that familiar with the CLD code).
> May need the CLD experts to chime in.
It used to be the case that Klasses were deleted from the_klasses list
while other threads iterated over it. Coleen removed those instances with:
http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-March/013283.html
If we still cut Klasses out of the CLD::_klasses list outside of a GC
safepoint, then that's a bug.
Thanks,
StefanK
> Thanks,
> David
>
More information about the hotspot-runtime-dev
mailing list