RFR (L, but tedious) 8188220: Remove Atomic::*_ptr() uses and overloads from hotspot

coleen.phillimore at oracle.com coleen.phillimore at oracle.com
Thu Oct 12 17:23:33 UTC 2017


Here's the qseries in webrevs.

open webrev at http://cr.openjdk.java.net/~coleenp/8188220.add_ptr/webrev
open webrev at 
http://cr.openjdk.java.net/~coleenp/8188220.cmpxchg_ptr/webrev
open webrev at 
http://cr.openjdk.java.net/~coleenp/8188220.cmpxchg_if_null/webrev
open webrev at http://cr.openjdk.java.net/~coleenp/8188220.xchg_ptr/webrev
open webrev at http://cr.openjdk.java.net/~coleenp/8188220.store_ptr/webrev
open webrev at 
http://cr.openjdk.java.net/~coleenp/8188220.load_ptr_acquire/webrev
open webrev at 
http://cr.openjdk.java.net/~coleenp/8188220.assembler_cmpxchg/webrev
open webrev at http://cr.openjdk.java.net/~coleenp/8188220.casptr/webrev
open webrev at 
http://cr.openjdk.java.net/~coleenp/8188220.review-comments/webrev

assembler_cmpxchg should be release_store_ptr which got qrefreshed with 
trying to get the cmpxchg function pointer to compile.

Thanks,
Coleen

On 10/12/17 8:55 AM, coleen.phillimore at oracle.com wrote:
>
>
> On 10/12/17 8:21 AM, David Holmes wrote:
>> On 12/10/2017 9:52 PM, coleen.phillimore at oracle.com wrote:
>>> On 10/12/17 3:23 AM, David Holmes wrote:
>>>> Hi Coleen,
>>>>
>>>> Thanks for doing this tedious cleanup!
>>>>
>>>> It was good to see so many casts disappear; and sad to see so many 
>>>> have to now appear in the sync code. :(
>>>
>>> The sync code has _owner field as void* because it can be several 
>>> things.  I didn't try to
>>
>> Yeah I understood why this had to happen.
>>
>>>>
>>>> There were a few things that struck me ...
>>>>
>>>> Atomic::xchg_ptr turned into Atomic::xchg; yet for the stub 
>>>> generator routines atomic_xchg_ptr became atomic_xchg_long - but I 
>>>> can't see where that stub will now come into play?
>>>
>>> http://cr.openjdk.java.net/~coleenp/8188220.02/webrev/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp.udiff.html 
>>>
>>>
>>> I tried to remove it but windows x64 uses a stub for xchg (and others). 
>>
>> Ah so I think this is where it is used:
>>
>> ./os_cpu/windows_x86/atomic_windows_x86.hpp:DEFINE_STUB_XCHG(8, 
>> jlong, os::atomic_xchg_ptr_func)
>>
>> ie atomic_xchg_ptr is the stub for Atomic::xchg<8>
>>
>>> There was a preexisting stub for cmpxchg_long which I followed 
>>> naming convention.
>>>
>>>    static address _atomic_cmpxchg_entry;
>>>    static address _atomic_cmpxchg_byte_entry;
>>>    static address _atomic_cmpxchg_long_entry;
>>>
>>> Technically I think it should be long_long, as well as the 
>>> cmpxchg_long_entry as well.
>>
>> Or int64_t
>>
>>> I also missed renaming store_ptr_entry and add_ptr_entry.  What do 
>>> you suggest?
>>
>> store_ptr_entry actually seems unused.
>>
>> add_ptr_entry looks like it needs to be the 64-bit Atomic::add<8> 
>> implementation - so probably add_int64_t_entry.
>
> https://bugs.openjdk.java.net/browse/JDK-8186903
>
> I'm renaming to ptr => long for now to follow other code and fixing 
> the name with this RFE to what it really is, and what we decide.
>
> It was pretty ugly as:
>
>   static jint      (*atomic_add_func)           (jint, volatile jint*);
>   static intptr_t  (*atomic_add_ptr_func)       (intptr_t, volatile 
> intptr_t*);
>
> When the other uses jint as an argument.   Actually, I think add_ptr 
> makes more sense in this context than long.  I think I should leave 
> this name and not make it long.
>>
>>>>
>>>> ---
>>>>
>>>> src/hotspot/share/gc/shared/taskqueue.inline.hpp
>>>>
>>>> +  return (size_t) Atomic::cmpxchg((intptr_t)new_age._data,
>>>> +                                  (volatile intptr_t *)&_data,
>>>> +                                  (intptr_t)old_age._data);
>>>>
>>>> The actual types here should be size_t, can we now change it to use 
>>>> the real type?
>>>
>>> Yes, fixed.  Missed that one.
>>>>
>>>> ---
>>>>
>>>> src/hotspot/share/oops/cpCache.cpp
>>>>
>>>>  114 bool ConstantPoolCacheEntry::init_flags_atomic(intptr_t flags) {
>>>>  115   intptr_t result = Atomic::cmpxchg(flags, &_flags, (intptr_t)0);
>>>>  116   return (result == 0);
>>>>  117 }
>>>>
>>>> _flags is actually intx, yet above we treat it as intptr_t. But 
>>>> then later:
>>>>
>>>>  156   if (_flags == 0) {
>>>>  157     intx newflags = (value & parameter_size_mask);
>>>>  158     Atomic::cmpxchg(newflags, &_flags, (intx)0);
>>>>  159   }
>>>>
>>>> its intx again. This looks really odd to me.
>>>
>>> It's better as an intx, because that's what it's declared as. I'll 
>>> patch up some other uses but don't promise total consistency because 
>>> I don't want to pull on this particular sweater thread too much. 
>>> intx and intptr_t I believe are typedefed to each other.
>>>
>>> typedef intptr_t  intx;
>>>
>>> Should we not have intx and uintx and change all their uses? I've 
>>> sworn off large changes after this though.
>>
>> I don't know why we have intx/uintx other than someone not liking 
>> having to type intptr_t all the time.
>>
>>> ConstantPoolCacheEntry::make_flags returns an int.   I fixed 
>>> init_flags_atomic() because it's declared with an intx and defined 
>>> with intptr_t.
>>
>> Ok.
>>
>>>>
>>>> ---
>>>>
>>>> src/hotspot/share/runtime/objectMonitor.inline.hpp
>>>>
>>>> The addition of header_addr() made me a little nervous :) Can we 
>>>> add a sanity assert either inside it (or in synchronizer.cpp), to 
>>>> verify that this == &_header  (or monitor == monitor->header_addr())
>>>
>>> Where I introduced it, looked like undefined behavior because it 
>>> assumed that the header was the first field.
>>
>> Assumes and expects, I think. Not sure if it is undefined behaviour 
>> or not.
>
> Assumes without giving the static compiler a chance to check that what 
> you've done is correct or not.  Maybe that's not undefined behavior.
>>
>>> So I should sanity check that other places with undefined behavior 
>>> won't break?  Sure I'll do that.
>>
>> No only sanity check that your change actually didn't change 
>> anything. :)
>
> As well.
>>
>>>>
>>>> ---
>>>>
>>>> src/hotspot/share/runtime/synchronizer.cpp
>>>>
>>>>  // global list of blocks of monitors
>>>> -// gBlockList is really PaddedEnd<ObjectMonitor> *, but we don't
>>>> -// want to expose the PaddedEnd template more than necessary.
>>>> -ObjectMonitor * volatile ObjectSynchronizer::gBlockList = NULL;
>>>> +PaddedEnd<ObjectMonitor> * volatile ObjectSynchronizer::gBlockList 
>>>> = NULL;
>>>>
>>>> Did this have to change? I'm not sure why we didn't want to expose 
>>>> PaddedEnd, but it is now being exposed.
>>>
>>> I didn't see why not and it avoided a bunch of ugly casts.   I 
>>> tested that the SA was fine with it because the SA manually did the 
>>> address adjustment.  The SA could be fixed to know about PaddedEnd 
>>> if it's somehting they want to do.
>>
>> Glad you mentioned SA as I forgot to mention that with the vmStructs 
>> changes. :)
>>
>>> Thanks for going through and reviewing all of this.   Please answer 
>>> question about the stub function name and I'll include the change 
>>> with this patch.
>>
>> Would like to see an incremental webrev please. (Should be easy if 
>> you're using mq :) )
>
> Will do.
>
> Thanks,
> Coleen
>>
>> Thanks,
>> David
>>
>>> Coleen
>>>
>>>>
>>>> Thanks,
>>>> David
>>>> -----
>>>>
>>>>
>>>> On 11/10/2017 11:50 PM, coleen.phillimore at oracle.com wrote:
>>>>>
>>>>> Please review version .02 which removes use of replace_if_null, 
>>>>> but not the function.  A separate RFE can be filed to discuss that.
>>>>>
>>>>> open webrev at http://cr.openjdk.java.net/~coleenp/8188220.02/webrev
>>>>>
>>>>> Thanks,
>>>>> Coleen
>>>>>
>>>>> On 10/11/17 7:07 AM, coleen.phillimore at oracle.com wrote:
>>>>>>
>>>>>>
>>>>>> On 10/11/17 4:12 AM, Robbin Ehn wrote:
>>>>>>> On 10/11/2017 10:09 AM, David Holmes wrote:
>>>>>>>> On 11/10/2017 5:45 PM, Erik Österlund wrote:
>>>>>>>>
>>>>>>>> Removing the operation is a different argument to renaming it. 
>>>>>>>> Most of the above argues for removing it. :)
>>>>>>>
>>>>>>> +1 on removing
>>>>>>
>>>>>> Thank you for all your feedback.  Erik best described what I was 
>>>>>> thinking.  I will remove it then.  There were not that many 
>>>>>> instances and one instance that people thought would be useful, 
>>>>>> needed the old return value.
>>>>>>
>>>>>> Coleen
>>>>>>>
>>>>>>> Thanks, Robbin
>>>>>>>
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> David
>>>>>>>> -----
>>>>>>>>
>>>>>>>>> I have not reviewed this completely yet - thought I'd wait 
>>>>>>>>> with that until we agree about replace_if_null, if that is okay.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> /Erik
>>>>>>>>>
>>>>>>>>> On 2017-10-11 05:55, David Holmes wrote:
>>>>>>>>>> On 11/10/2017 1:43 PM, Kim Barrett wrote:
>>>>>>>>>>>> On Oct 10, 2017, at 6:01 PM, coleen.phillimore at oracle.com 
>>>>>>>>>>>> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> Summary: With the new template functions these are 
>>>>>>>>>>>> unnecessary.
>>>>>>>>>>>>
>>>>>>>>>>>> 2. renamed Atomic::replace_if_null to 
>>>>>>>>>>>> Atomic::cmpxchg_if_null. I disliked the first name because 
>>>>>>>>>>>> it's not explicit from the callers that there's an 
>>>>>>>>>>>> underlying cas. If people want to fight, I'll remove the 
>>>>>>>>>>>> function and use cmpxchg because there are only a couple 
>>>>>>>>>>>> places where this is a little nicer.
>>>>>>>>>>>
>>>>>>>>>>> I'm still looking at other parts, but I want to respond to 
>>>>>>>>>>> this now.
>>>>>>>>>>>
>>>>>>>>>>> I object to this change.  I think the proposed new name is 
>>>>>>>>>>> confusing,
>>>>>>>>>>> suggesting there are two different comparisons involved.
>>>>>>>>>>>
>>>>>>>>>>> I originally called it something else that I wasn't entirely 
>>>>>>>>>>> happy
>>>>>>>>>>> with.  When David suggested replace_if_null I quickly 
>>>>>>>>>>> adopted that as
>>>>>>>>>>> I think that name exactly describes what it does. In 
>>>>>>>>>>> particular, I
>>>>>>>>>>> think "atomic replace if" pretty clearly suggests a 
>>>>>>>>>>> test-and-set /
>>>>>>>>>>> compare-and-swap type of operation.
>>>>>>>>>>
>>>>>>>>>> I totally agree. It's an Atomic operation, the implementation 
>>>>>>>>>> will involve something atomic, it doesn't matter if it is 
>>>>>>>>>> cmpxchg or something else. The name replace_if_null describes 
>>>>>>>>>> exactly what the function does - it doesn't have to describe 
>>>>>>>>>> how it does it.
>>>>>>>>>>
>>>>>>>>>> David
>>>>>>>>>> -----
>>>>>>>>>>
>>>>>>>>>>> Further, I think any name involving "cmpxchg" is problematic 
>>>>>>>>>>> because
>>>>>>>>>>> the result of this operation is intentionally different from 
>>>>>>>>>>> cmpxchg,
>>>>>>>>>>> in order to better support the primary use-case, which is lazy
>>>>>>>>>>> initialization.
>>>>>>>>>>>
>>>>>>>>>>> I also object to your alternative suggestion of removing the 
>>>>>>>>>>> operation
>>>>>>>>>>> entirely and just using cmpxchg directly instead.  I don't 
>>>>>>>>>>> recall how
>>>>>>>>>>> many occurrences there presently are, but I suspect more 
>>>>>>>>>>> could easily
>>>>>>>>>>> be added; it's part of a lazy initialization pattern similar 
>>>>>>>>>>> to DCLP
>>>>>>>>>>> but without the locks.
>>>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>
>>>
>



More information about the hotspot-dev mailing list