> From: Mark Thomas [mailto:ma...@apache.org] 
> Subject: Re: RV-Predict bugs

> To re-cap. The assertion is that
> ===
> String foo;
> doSomething() {
>   if (foo == null) {
>     foo = calculateNewValue();
>   }
>   return foo;
> }
> ===
> can be transformed (by the complier?) to
> ===
> String foo;
> String bar;
> doSomething() {
>   bar = foo;
>   if (foo == null) {
>     foo = calculateNewValue();
>     bar = foo;
>   }
>   return bar;
> }
> ===

> Ignoring re-ordering this transformation creates an obvious concurrency
> issue (foo is changed from null to non-null after its value is copied to
> bar and before foo is tested for null).

Correct.  That changed the original logic of the method, creating a timing 
window that wasn't there before.  In compiler language (see below), it 
rematerialized a load for a shared memory location.

> The questions I have are:

> 1. Is such a transformation legal? I assume the answer is yes but I've
> been struggling to find the language in the JLS that permits this. Is it
> 17.4 "An implementation is free to produce any code it likes, as long as
> all resulting executions of a program produce a result that can be
> predicted by the memory model."?

> 2. Why would something make a transformation like this? This brings us
> back to the question of theoretical issues vs. practical issues which
> helps us judge the severity of any given issue.

1. No (at least not in the real world).

2. Compiler bug.  An analogous example is the one-time gcc error that 
transformed
    if (a == 0) a = 1;
into
    temp = a;
    if (temp == 0) temp = 1;
    a = temp;
This caused immense havoc, besides being a performance killer.

For reference, read the LLVM spec for concurrency handling:
http://llvm.org/docs/Atomics.html
In particular, this section on instruction ordering:
http://llvm.org/docs/Atomics.html#atomic-orderings
Note the difference in implementation between handling shared variables in 
C/C++ (NotAtomic) and shared variables in Java (Unordered).

(For those not familiar with LLVM, it's the compilation tool chain used for OS 
X, iOS, Android, PS4, and many other platforms.)

The key bit of information pertinent to Java is this:

"In terms of the optimizer, this prohibits any transformation that transforms a 
single load into multiple loads, transforms a store into multiple stores, 
narrows a store, or stores a value which would not be stored otherwise. Some 
examples of unsafe optimizations are narrowing an assignment into a bitfield, 
*rematerializing a load*, and turning loads and stores into a memcpy call. 
Reordering unordered operations is safe, though, and optimizers should take 
advantage of that because unordered operations are common in languages that 
need them."

The above may go beyond the theoretical limitations of the memory model, but is 
representative of what compilers must do in order to generate workable programs 
in the real world.  This isn't academia, it's business.

I think I'm done here.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY 
MATERIAL and is thus for use only by the intended recipient. If you received 
this in error, please contact the sender and delete the e-mail and its 
attachments from all computers.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to