Using C++11+ in hotspot

Mikael Vidstedt mikael.vidstedt at oracle.com
Tue Aug 7 18:36:40 UTC 2018


In utilities/copy.[ch]pp there’s Copy::conjoint_copy and its close friends which does support different element sizes, and which promises to not tear the words/elements (if the underlying implementation doesn’t do the right thing it needs to be fixed). It doesn’t currently allow for configuring/customizing memory ordering requirements though, and If “extreme” performance is required there may well be some additional specialization needed as well.

Cheers,
Mikael

> On Aug 6, 2018, at 11:26 PM, Martin Buchholz <martinrb at google.com> wrote:
> 
> 
> 
> On Mon, Aug 6, 2018 at 11:12 AM, John Rose <john.r.rose at oracle.com <mailto:john.r.rose at oracle.com>> wrote:
> On Aug 5, 2018, at 8:30 AM, Martin Buchholz <martinrb at google.com <mailto:martinrb at google.com>> wrote:
>> 
>> Thanks to whoever added the comment long ago.
> 
> FTR I think it was Steffen Grarup.  We were just learning about MT safety at the time.
> The copy conjoint/disjoint APIs were not yet in existence.  I think they came around
> 2003, and Paul Hohensee's name is all over the SCCS history there.
> 
> s 00008/00002/00762
> d D 1.147 99/02/17 10:14:36 steffen 235 233
>> I 235
> static inline void copy_table(address* from, address* to, int size) {
>   // Copy non-overlapping tables. The copy has to occur word wise for MT safety.
>   while (size-- > 0) *to++ = *from++;
> }
> 
> Today, that loop should be recoded to use copy, and copy in turn needs to
> do whatever magic is required to force word-atomic access on non-atomic data.
> 
> 
> That loop copies address*, while  pd_disjoint_words_atomic copies HeapWord, so these are not compatible out of the box.
> 
> We could have atomic relaxed copies like below.  Using compiler builtins also avoids the problem of the underlying type not being declared atomic<>, and is ISA-independent.  OTOH maybe we always want that loop compiled to REP MOVSQ on x64.
> 
> 
> template <typename T>
> static ALWAYSINLINE void copy_atomic_relaxed(const T* from, T* to) {
>   T val;
>   __atomic_load(from, &val, __ATOMIC_RELAXED);
>   __atomic_store(to, &val, __ATOMIC_RELAXED);
> }
> 
> static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
> #ifdef AMD64
>   switch (count) {
>   case 8:  copy_atomic_relaxed(from + 7, to + 7);
>   case 7:  copy_atomic_relaxed(from + 6, to + 6);
>   case 6:  copy_atomic_relaxed(from + 5, to + 5);
>   case 5:  copy_atomic_relaxed(from + 4, to + 4);
>   case 4:  copy_atomic_relaxed(from + 3, to + 3);
>   case 3:  copy_atomic_relaxed(from + 2, to + 2);
>   case 2:  copy_atomic_relaxed(from + 1, to + 1);
>   case 1:  copy_atomic_relaxed(from + 0, to + 0);
>   case 0:  break;
>   default:
>     while (count-- > 0) {
>       copy_atomic_relaxed(from++, to++);
>     }
>     break;
>   }



More information about the workshop-discuss mailing list