RFR: 8186476: Generalize Atomic::add with templates

David Holmes david.holmes at oracle.com
Tue Aug 22 02:25:09 UTC 2017

Hi Kim,

On 20/08/2017 4:16 PM, Kim Barrett wrote:
> Please review this change to Atomic::add, making it a function
> template with a per-platform underlying implementation.
> This change is similar to 8186166: "Generalize Atomic::cmpxchg with
> templates", with similar goals and taking a similar approach.

So one thing I realized with this change is that the use of the 
templates now obscures the set of "overloads" that are available for a 
given operation. Before you could look at atomic.hpp and see that there 
was no add(jlong, jlong*), but now you only discover the absence of that 
API when you try to use it. It took me a while to figure out the 
machinations for PlatformAdd<8> only existing on 64-bit. :)

Aside: the 1 -> 1u changes are really irksome. I know you explained it 
before but it still seem crazy to me that the compiler can't handle this. :(

> This change deprecates add_ptr.  Followup changes will convert
> existing uses of cmpxchg_ptr and eventually remove it.  Followup
> changes will also update uses of cmpxchg that can be simplified
> because of the generalized API.  Only changes to usage that were
> required by the new implementation have been made so far.
> The add function calls private Atomic::AddImpl, to select among
> several cases, based on the argument types.  Each case performs some
> checking and possibly conversion to reach a standard form of the
> arguments (or fail and report a compile time error), which are then
> passed to private Atomic::PlatformAdd.
> Only safe conversions of the first (add_value) argument are made by
> the AddImpl layer.  add_value must be integral, and is never narrowed.
> dest's value type must be either integral or a pointer type.  When
> both are integral, they must be of the same signedness.  If smaller,
> add_value will be promited to the same size as dest's value type.
> The PlatformAdd class is provided by each platform, and performs
> additional case analysis to generate the appropriate code for the
> platform.  Most PlatformAdd implementations use one of two helper base
> classes, Atomic::FetchAndAdd and Atomic::AddAndFetch.  These provide
> common parts of the implementation in terms of a support function
> provided by the derived PlatformAdd, accessed using CRTP.
> This change involves modifications to all of the existing platform
> implementations of Atomic::add.  I've updated all of the platforms,
> but only tested those supported by Oracle.  I'll need help from the
> various platform maintainers to check and test my changes.
> Changes to files can be categorized as follows:
> [No new metaprogramming tools!]
> Change add to a template:
> atomic.hpp
> Oracle-supported platforms:
> atomic_bsd_x86.hpp - 64bit only
> atomic_linux_arm.hpp
> atomic_linux_x86.hpp
> atomic_solaris_sparc.hpp
> solaris_sparc.il
> atomic_solaris_x86.hpp
> atomic_windows_x86
> Non-Oracle platform changes:
> atomic_aix_ppc.hpp
> atomic_bsd_x86.hpp - 32bit
> atomic_bsd_zero.hpp
> atomic_linux_aarch.hpp
> atomic_linux_ppc.hpp
> atomic_linux_s390.hpp
> atomic_linux_sparc.hpp
> atomic_linux_zero.hpp
> Usage changes required by API change:
> g1CardLiveData.cpp
> g1ConcurrentMark.cpp
> g1HotCardCache.cpp
> g1HotCardCache.hpp
> g1RemSet.cpp
> symbol.cpp
> mallocTracker.hpp
> A few specific items:
> - atomic_linux_arm.hpp
> Neither add variant has "cc" in the clobbers list, even though the
> condition codes are modified.  That seems like a pre-existing bug.
> - atomic_linux_sparc.hpp
> Neither add variant has "cc" in the clobbers list, even though the
> condition codes are modified.  That seems like a pre-existing bug.
> The 32-bit add was using intptr_t as the rv type.  Probably a harmless
> copy-paste mistake.  Now using template parameter type.
> Uses hard-coded machine registers and assumes the inline-asm
> processing assigns the values to the corresponding machine registers,
> even though the given constraints are just generic register requests.
> I don't understand how this can work.
> - atomic_solaris_sparc.hpp
> Atomic::add was implemented using asm code in solaris_sparc.il.  I was
> going to change it to use gcc-style inline-asm, but the linux_sparc
> version wasn't helpful this time (unlike for cmpxchg) (see above).
> Instead, I wrote the CAS-loop in C++, using Atomic::cmpxchg; much
> simpler code, and should be no less efficient, assuming the compiler
> does it's job.

I was getting ready to object to this until I saw that the asm in the 
.il file is already a CAS-loop. :) Makes me wonder whether this version 
should not be in platform independent code ready to be inherited by a 
platform if needed?

> CR:
> https://bugs.openjdk.java.net/browse/JDK-8186476
> Webrev:
> http://cr.openjdk.java.net/~kbarrett/8186476/hotspot.00/

Nothing jumped out at me after a few readings :)


> Testing:
> Ad hoc hotspot nightly test.

More information about the hotspot-dev mailing list