JavaMemoryModel: JMM, escape analysis, lock elision

From: David Detlefs - Sun Microsystems Labs BOS (david.detlefs@sun.com)
Date: Mon Apr 25 2005 - 11:41:49 EDT


I'm a little confused by the following example, and wondered if I
could get some expert opinions.

class Bar {
  private int i;
  public synchronized void blah() {
    assert((i % 2) == 0);
    i++; i++; // Two separate increments deliberate.
  }

  public static Bar bbb;
}

Thread 1: Thread 2:

1| Bar b = new Bar(); 5| Bar b = Bar.bbb;
2| b.blah(); 6| if (b != null) b.blah();
3| Bar.bbb = b;

Here's my difficulty: the Bar allocated at line 1 is thread-local
until line 3; in particular, it is thread-local at the invocation at
line 2 of a synchronized method. The JMM (version I downloaded today
from the JSR-133 web site) has

6.6 Useless Synchronization can be Ignored

   A synchronization action is useless in a number of situations,
   including lock acquisition on thread-local objects...
   The old JMM did not allow useless synchronization to be completely
   removed, the new JMM does.

What's weird here is that whether the Bar object in question is
thread-local is affected by re-orderings allowed (or not) by the JMM.
In particular, if we removed the synchronization for "2| b.blah()",
then allowed Thread 2 to observe the effects of line 3 before those of
line 2 were complete, then line 6 might assert that b.i is even
between two of the updates of line 2, causing it to fail.

One possible conclusion is the the sentence is subtly wrong: that we
can't *completely* remove the synchronization: we have to keep "enough
of it around" to prevent reorderings that would undermine the
justification that made the object thread-local. To say this another
way, if we're going to perform an optimization that assumes that b is
thread local, we'd better make sure that it actually is when we say it
is, by delaying the action that makes it escape.

Does this seem right? I asked a pretty knowledgeable colleague about
this, and his take was completely different: that "thread-local" in
the JMM's usage meant "thread-local for the object's entire lifetime",
not the "thread-local at a given program point" that I had taken.

Thanks in advance for any comments...!

-- 
=============================================================================
Dave Detlefs                           http://www.sunlabs.com/people/detlefs/
Sun Microsystems Laboratories                           david.detlefs@sun.com
1 Network Drive, Burlington, MA 01803-0902                     (781)-442-0841

------------------------------- JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:09 EDT