Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4640088

Volatile access incorrectly optimized away

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.4.0
    • tools
    • x86
    • windows_98



      Name: rmT116609 Date: 02/19/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

      DESCRIPTION OF THE PROBLEM :

      Javac incorrectly optimizes an access of a volatile variable. This is a bug, because according to JLS 17 and the upcoming JSR-133 (memory model), the use of a volatile variable should force a memory barrier in the VM. If the volatile variable is never accessed because the compiler optimizes it away, this memory barrier is no longer present, and a program may fail in a non-deterministic way unexpected by the programmer.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Compile the simple program listed below:

      $ javac Blah.java

      2. Check the bytecode produced - the access to b was mistakenly optimized away!

      $ javap -c Blah
      Compiled from Blah.java
      class Blah extends java.lang.Object {
          static volatile Blah b;
          static int i;
          Blah();
          void m();
      }

      Method Blah()
         0 aload_0
         1 invokespecial #1 <Method java.lang.Object()>
         4 return

      Method void m()
         0 getstatic #2 <Field int i>
         3 iconst_1
         4 iadd
         5 putstatic #2 <Field int i>
         8 return



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      The method should have decompiled like this:

      Method void m()
         0 getstatic #1 <Field Blah b>
         1 pop
         2 getstatic #2 <Field int i>
         5 iconst_1
         6 iadd
         7 putstatic #2 <Field int i>
        10 return


      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      //Blah.java
      class Blah {
        static volatile Blah b;
        static int i;
        void m() {
          b.i++; // accessing b should be a memory barrier
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :

      Do something else to get the desired memory barrier. For example, this will work:

      void m() {
        b.toString();
        i++;
      }
      (Review ID: 139898)
      ======================================================================

            gafter Neal Gafter (Inactive)
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: