RFR (M): 8184334: Generalizing Atomic with templates

Kim Barrett kim.barrett at oracle.com
Sat Jul 22 20:55:41 UTC 2017


> On Jul 21, 2017, at 10:43 PM, Kim Barrett <kim.barrett at oracle.com> wrote:
> For example, I think something like the following
> (completely untested code) could work for linux_x64, and doesn't
> involve any casts between pointer types.  Instead, it relies on
> implicit type erasure at the interface between C++ and inline
> assembly.
> 
> […]
> template<>
> struct Atomic::SpecializedAdd<4> {
>  template<typename I, typename D>
>  D operator()(I i, D volatile* d) const {
>    I addend = i;
>    __asm__ volatile("lock xaddl %0,(%2)"
>                     : "=r" (addend)
>                     : "0" (addend), "r" (d)
>                     : "cc", "memory");
>    // For integer case, I == D, and cast is a nop. 
>    // For pointer case (D is P*), cast from I => P*. 
>    return reinterpret_cast<D>(addend + i);
>  }
> };
> […]

Sorry, I was in a hurry and forgot to fix the cast to a new pointer of the
result of arithmetic on the integer representation of an existing pointer.
That’s easily dealt with:

template<>
struct Atomic::SpecializedAdd<4> {
  template<typename I, typename D>
  D operator()(I i, I scaled_i, D volatile* d) const {
    I addend = scaled_i;
    __asm__ volatile("lock xaddl %0,(%2)"
                     : "=r" (addend)
                     : "0" (addend), "r" (d)
                     : "cc", "memory");
    // For integer case, I == D, and cast is a nop. 
    // For pointer case (D is P*), cast from I => P*.
    return reinterpret_cast<D>(addend) + i;
  }
};

and fix the callers to pass in the appropriately scaled value for scaled_i.



More information about the hotspot-runtime-dev mailing list