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

return instruction of a synchronized method does not throw Exception if the curr

XMLWordPrintable

    • sparc
    • solaris_2.5.1, solaris_7



      Name: dkC59003 Date: 08/04/99



      In The JVM Specification (2nd edition) chapter 6 (The JVM Instruction Set)
      on the page 353 it has been written:

      "...
      Runtime Exceptions

          If the current method is a synchronized method and the current thread is not the
          owner of the monitor acquired or reentered on invocation of the method, return
          throws an IllegalMonitorStateException. This can happen, for example, if a
          synchronized method contains a monitorexit instruction, but no monitorenter
          instruction, on the object on which the method is synchronized.
      ..."
      It is the new asssertion which is absent in the first edition of JVM Specification.

      In order to analyse this assertion the test
      has been written in JASM code as below:

      -------------------------------------- text of test1 -----------------------
      public class return006011
      extends java/lang/Object
      {

      static Field instr_sign:"I";

      Method free_object:"()V"
      stack 1 locals 1
      {
                      iconst_4;
                      putstatic Field instr_sign:"I";
      aload_0;
                      monitorexit; // may throw java/lang/IllegalMonitorStateException !!!
                      iconst_5;
                      putstatic Field instr_sign:"I";
      return; // may throw java/lang/IllegalMonitorStateException
      }

      synchronized Method test_body:"()V"
      stack 1 locals 1
      {
      aload_0;
      invokevirtual Method free_object:"()V";
                      bipush 6;
                      putstatic Field instr_sign:"I";
      return; // must throw java/lang/IllegalMonitorStateException
      }

      public static Method main:"([Ljava/lang/String;)V"
      stack 2 locals 2
      {
      aload_0;
      getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
      invokestatic Method run:"([Ljava/lang/String;Ljava/io/PrintStream;)I";
      bipush 95/*STATUS_TEMP*/;
      iadd;
      invokestatic Method java/lang/System.exit:"(I)V";
      return;
      }

      public static Method run:"([Ljava/lang/String;Ljava/io/PrintStream;)I"
      stack 2 locals 2
      {
      new class return006011;
      dup;
      invokespecial Method <init>:"()V";
                      try TRY2, TRY1;
      invokevirtual Method test_body:"()V";
                      iconst_2;
                      goto MRET;
                      endtry TRY1;
                      catch TRY1 java/lang/IllegalMonitorStateException;
                      pop;
                      getstatic Field instr_sign:"I";
                      goto MRET;
                      endtry TRY2;
                      catch TRY2 java/lang/Throwable; // unforeseen something has failed
                      pop;
      iconst_3;
      MRET: ireturn;
      }

      public Method <init>:"()V"
      stack 1 locals 1
      {
      aload_0;
      invokespecial Method java/lang/Object.<init>:"()V";
      return;
      }


      } // end Class return006011
      -------------------------------------- end of text of test1 -----------------------
         It is expected that this test may have three variants of results:
      a). Accordingly with the assertion for monitorexit instruction given on the page 337
      which is
      " Otherwise, if the virtual machine implementation enforces the rules on structured
        use of locks described in Section 8.13 and if the second of those rules is violated
        by the execution of this monitorexit instruction, then monitorexit throws an
        IllegalMonitorStateException. "
      the monitorexit instruction in "free_object" method may throw the
      IllegalMonitorStateException and in this case test must result the integer value 99.
      b). Otherwise, accordingly with the assertion for return instruction given on the page 353
      which is
      " Otherwise, if the virtual machine implementation enforces the rules on structured
        use of locks described in Section 8.13 and if the first of those rules is violated
        during invocation of the current method, then return throws an
        IllegalMonitorStateException. "
      the return instruction in "free_object" method may throw the
      IllegalMonitorStateException and in this case test must result the integer value 100.
      c). Otherwise, at last, accordingly with the considered assertion the return instruction
      in "test_body" method MUST throw the IllegalMonitorStateException and in this case test
      must result the integer value 101.
         But in reality the test does not throw any exception and its result is the integer
      value 97.
      The command lines for test execution are given below
      (it is assumed that JASM file name of the test1 is return006011.jasm and
      the current directory contains this file):

      & jasm return006011.jasm
      & java return006011
      & echo $status
      97

      The java version - Classic VM (build JDK-1.3-K, green threads, sunwjit)
      was used for the test execution.

      Notes.
           There are the same assertions for the folowing instructions:
           areturn, dreturn, freturn, ireturn, lreturn. Identical
           tests for these assertions have the same results.

      ==========================================================

      ======================================================================

      Name: dkC59003 Date: 09/01/99



      The classic VM (J2SDK 1.3beta) behaviour does not correspond to
      the considered assertion.

      The test example shown in description above is not a good one
      because it depends on the optional rules on structured use of locks
      described in Section 8.13.
      The new test in JASM code is proposed (see test source below).

      This test may have two variants of results:

      a). If the considered assertion is true then the return
          instruction (in the "test_body" method) must throw the
          IllegalMonitorStateException and in this case the test must result
          the integer value 0 (expected result - STATUS_PASSED).
       
      b). Otherwise, the test must return the integer value 2
          (unexpected result - STATUS_FAILED).


      The execution of this test under HotSpot Client VM mode produces 0 as
      result, ie the test is PASSED.

      But the execution of this test under Classic VM mode produces 2 as
      result, ie the test is FAILED.

      See logs and source below.

      For HotSpot Client VM mode:

      % java -version
      java version "1.3beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
      Java(TM) HotSpot Client VM (build 1.3beta-O-release, 1.3beta-O-release, interpreted mode)
      % java return006011
      % echo $status
      0

      For Classic VM mode:

      % java -green -version
      java version "1.3beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
      Classic VM (build 1.3beta-O, green threads, nojit)
      % java -green return006011
      % echo $status
      2

      or

      % java -native -version
      java version "1.3beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3beta-O)
      Classic VM (build 1.3beta-O, native threads, nojit)
      % java -native return006011
      % echo $status
      2

      NOTES
         Under JVM 1.1.8 the test produces expected result:

      % java -version
      java version "1.1.8"
      % java return006011
      % echo $status
      0


      ------------------------------ source text of test -----------------------
      public class return006011
      extends java/lang/Object
      {
      synchronized Method test_body:"()V"
      stack 1 locals 1
      {
      aload_0;
                      monitorexit;
      return; // must throw java/lang/IllegalMonitorStateException
      }
      public static Method main:"([Ljava/lang/String;)V"
      stack 2 locals 1
      {
      aload_0;
      getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
      invokestatic Method run:"([Ljava/lang/String;Ljava/io/PrintStream;)I";
      // in stack - test_result
      invokestatic Method java/lang/System.exit:"(I)V";
      return;
      }
      public static Method run:"([Ljava/lang/String;Ljava/io/PrintStream;)I"
      stack 2 locals 2
      {
      new class return006011;
      dup;
      invokespecial Method <init>:"()V";

      try TRY1;
      invokevirtual Method test_body:"()V";
                      iconst_2/*STATUS_FAILED*/;
                      ireturn;
                      endtry TRY1;

                      catch TRY1 java/lang/IllegalMonitorStateException;
                      pop;

                      iconst_0/*STATUS_PASSED*/;
      ireturn;
      }
      public Method <init>:"()V"
      stack 1 locals 1
      {
      aload_0;
      invokespecial Method java/lang/Object.<init>:"()V";
      return;
      }
      } // end Class return006011
      -------------------------------------- end of text of test -----------------------

      ======================================================================

            hongzh Hong Zhang
            dkhukhrosunw Dmitry Khukhro (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: