RFR (M): 8184334: Generalizing Atomic with templates
Andrew Haley
aph at redhat.com
Fri Jul 21 13:43:43 UTC 2017
Hi,
On 20/07/17 14:45, Erik Österlund wrote:
> It seems like the aliasing problem has multiple levels at which we can
> debate. I will try to put my thoughts down in a reasonably structured
> way... let's see how that goes.
>
> These are the core questions we are debating (and I will answer them in
> order):
>
> 1) What does the standard say about aliasing rules?
> 2) What did concrete implementations like GCC implement the aliasing rules?
> 3) What are the implications of those aliasing rules being violated?
> Does it matter?
> 4) Have these changes actually changed anything relating to those
> aliasing rules?
> 5) How do we proceed?
>
> Regarding #1: We seem to agree that there are various possible
> interpretations of the standard (wouldn't be the first time...); at
> least one interpretation that violates treating intptr_t as
> compatible with A* and at least one interpretation that permits
> it. I do not know if there is any one true interpretation of the C++
> standard, so I will assume the possibility that either one of us
> could be right here, and hence that a compiler writer might write a
> compiler in which it is either permitted aliasing or not.
>
> Regarding #2: While the simplest most contrived example of what we
> are arguing about being a strict aliasing violation is not caught as
> a strict aliasing violation using the strictest strict aliasing
> checks available in GCC, I feel dubious, but will take your word for
> it that intptr_t and A* are not compatible types. So for the rest of
> the discussion, I will assume this is true.
OK. For the sake of the discussion I'll go along with this.
> Regarding #3: We already inherently rely on passed in intptr_t or even
> jlong aliasing A*, possibly today enforced through -fno-strict-aliasing.
> I do not think the JVM will ever be able to turn such optimizations on.
I completely agree. However, if we are using -fno-strict-aliasing,
then I do not believe that there is any need for the complexity of the
casting that your patch does. We should be able to do the operations
that we need with no type casting at all, with suitable use of
template functions.
> Our C++ runtime lives in the border lands between Java and C++ that I
> will refer to as "shady land".
Yep.
> Regarding #4: I have made changes in the connection between the
> frontend and the backend. But I would like to maintain that the
> backends retain the same behaviour as they did before. For example,
> your xchg_ptr for void* casts (C-style) the exchange_value to
> intptr_t and use the intptr_t variant of xchg_ptr that passes
> intptr_t (a.k.a. int64_t on your architecture) into
> _sync_lock_test_and_set. So whatever hypothetical aliasing problem
> the new Atomic implementation class were still there before these
> changes. I have not introduced any of those aliasing issues, only
> improved the mediation between the frontend to the platform
> dependent backend.
True. But this is new code, and IMO should do better, and also IMO
does not need to be significantly more complex than the already
complex code we have. I assume that the complexity is due to some
compilers I don't know about, though, so I admit that I am at
something of a disadvantage. I suspect that none of it is necessary
for a complete and correct implementation on GCC. By "the complexity"
I am referring to a 4k line patch. I fear that not only is it
complex, it may also inhibit useful compiler optimizations.
> Regarding #5: Now as for how to move on with this, I hope we can
> agree that for code in "shady land", the compiler simply has to
> treat intptr_t as possible aliases to A* and that if it does not,
> then we need to tame it to do so. Because the C++ compiler simply
> does not know the full story of what is going on in our program and
> can not safely make any meaningful points-to analysis and data flow
> optimizations crossing dynamically generated JIT-compiled machine
> code of a different language.
>
> I propose three different solutions that we can discuss:
>
> Solution A: Do nothing. With this solution we recognize that a) we
> have actually not introduced any undefined behaviour that was not
> already there - the backend used intptr_t before and continues to do
> so, and b) doing so is safe (and inherently has to be safe) due to
> other levels of safeguarding such as turning off strict aliasing and
> using volatile.
>
> Solution B: If intptr_t does indeed not alias A*, we could find a
> pointer sized type, let's call it CanonicalPointer, that does indeed
> alias a generic A*, and pass pointer types from the frontend as
> CanonicalPointer to the backend. For example char* is explicitly
> described in the standard as an exception of the rules that is
> explicitly aliased to a generic A* (hopefully we agree about
> that).
We don't. A char* can point to the bytes of any type, but this rule
does not mean that an object of type char* can be accessed by an
lvalue of some other pointer type. They aren't the same thing at all.
The questions "what can a char* point to?" and "what can point to a
char* ?" are quite different. An int** can't point to a char*. The
only permission we have is that any pointer can be cast to a character
pointer, and that character pointer points to the first byte of the
object.
With regard to a solution, I feel there may be a much simpler answer.
But in order to sketch out that simpler answer, I need to know exactly
what problem is being solved. I presume that there is a need to turn
a call to a generalized function such as
template <typename T, typename U>
inline static void store(T store_value, volatile U* dest);
into a call to one of a number of specialized functions such as
template <>
inline void Atomic::specialized_store<int64_t>(int64_t store_value, volatile int64_t* dest) {
_Atomic_move_long(&store_value, dest);
}
and also perform some suitable magic for floating-point types. But do
we ever use atomic floats for anything? Will we ever?
--
Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
More information about the hotspot-runtime-dev
mailing list