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

Erroneous code range in exception table for synchronized statements

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.0
    • tools
    • merlin
    • generic
    • generic
    • Verified

      I am looking at a problem with the piece of code below:
      It has an exception handler for the sync. block, with a
      range [6, 35[ (i.e., excluding bytecode 35), and the
      exception handler starts at 35, for all exceptions
      (i.e., the exception class index is 0). I have compiled
      the method with the 1.3 javac and with 1.3 oldjavac
      and I get the same result regarding the exception
      range.

      java.lang.ref.Finalizer::add (41 bytes)
      -------------------------------------
      0 get_static 512
      3 store_local_object #1
      4 load_local_object #1
      5 monitor_enter
      6 get_static 256
      9 branch_if_null 26
      12 load_local_object #0
      13 get_static 256
      16 put_field 0 <next>
      19 get_static 256
      22 load_local_object #0
      23 put_field 1280 <prev>
      26 load_local_object #0
      27 set_static 256
      30 load_local_object #1
      31 monitor_exit
      32 branch 40
      35 store_local_object #2
      36 load_local_object #1
      37 monitor_exit
      38 load_local_object #2
      39 throw_exception
      40 return_void

      This exception range is wrong if am not mistaken
      (Todd concurs): if an exception happens after the
      monitorexit, e.g. at bytecode 32, the exception
      handler will try to unlock the monitor again
      (bytecode 37). This is currently a problem for
      C1 (what about C2?), since it assumes that a
      goto is a safepoint (even though this one is not
      a backward branch) and thus assumes that it
      may need to handle an asynchronous exception.
      As a consequence, it fails with an assertion when
      it tries to establish the fact that the monitor stacks
      at bytecode 32 and bytecode 35 correspond (they
      are off by one in this case). Anyway, this could
      probably be fixed with a "counter-hack" in the
      compiler...

      However, I am wondering now what the consequences
      are for the interpreter: potentially, an asynchronous
      exception may be delivered to the interpreter at that
      goto, in which case the exception handler would try
      to unlock the lock twice and die miserably. I am not
      100% sure anymore, how we deliver asynchronous
      exceptions to the interpreter, but I think we cause a
      safepoint and deliver the exception (need to check).

      The second question is: what did the Classic VM do?
      Could asynchronous exceptions be delivered at each
      bytecode? If so, wouldn't this cause a problem in
      this case?
      robert.griesemer@Eng 2000-04-03

      -------------------------------------------------------
      I have isolated the bug with a simple example:

      The following program:

      public class SyncTest {

        int _field;

        void access() {
          synchronized (this) {
            _field = 7;
          }
        }

        public static void main(String [] args) {
          SyncTest obj = new SyncTest();
          obj.access();
          System.out.println(obj._field);
        }

      }

      produces the following code for access with javac (newest version):
      (used javap -c SyncTest to decompile the code)

      Method void access()
         0 aload_0
         1 astore_1
         2 aload_1
         3 monitorenter
         4 aload_0
         5 bipush 7
         7 putfield #2 <Field int _field>
        10 aload_1
        11 monitorexit
        12 goto 20
        15 astore_2
        16 aload_1
        17 monitorexit
        18 aload_2
        19 athrow
        20 return
      Exception table:
         from to target type
           4 15 15 any <<<< WRONG EXCEPTION RANGE


      Code generated with oldjavac looks as follows:

      Method void access()
         0 aload_0
         1 astore_1
         2 aload_1
         3 monitorenter
         4 aload_0
         5 bipush 7
         7 putfield #7 <Field int _field>
        10 aload_1
        11 monitorexit
        12 goto 18
        15 aload_1
        16 monitorexit
        17 athrow
        18 return
      Exception table:
         from to target type
           4 10 15 any

      The exception range is wrong in the first case (see evaluation);
      this seems to be a problem only with javac; not with oldjavac.
      It is extremely important that this bug is fixed (see evaluation).
      robert.griesemer@Eng 2000-04-03

            gafter Neal Gafter (Inactive)
            wmaddoxsunw William Maddox (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: