[aarch32 jdk9 patch] bug fix: rethrow NegativeArraySizeException

Triple Yang triple.yang at linaro.org
Tue Dec 29 15:13:36 UTC 2015


Hi, all, the test following case should throw an NegativeArraySizeException
as JVM spec requires for the array size being -1, but right now, jvm
crashes when it runs the case:
///////////////// Test.java /////////////////////
public class Test {
  public static void main(String[] args)
  {
    try { (new byte[-1])[0] = 0; }
    catch (Exception e) { System.out.println(e); }
  }
}
///////////////// Test.java end /////////////////////

and its bytecodes:
////////////////////////////////////////////////////
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=2, args_size=1
         0: iconst_m1
         1: newarray       byte
         3: iconst_0
         4: iconst_0
         5: bastore
         6: goto          17
         9: astore_1
        10: getstatic     #3  // Field
java/lang/System.out:Ljava/io/PrintStream;
        13: aload_1
        14: invokevirtual #4  // Method
java/io/PrintStream.println:(Ljava/lang/Object;)V
        17: return
      Exception table:
         from    to  target type
            0     6     9   Class java/lang/Exception
////////////////////  end ////////////////////////

Analysis:
when interpreting the "newarray" bytecode, JVM calls
InterpreterRuntime::newarray() via call_VM template to allocate a byte
array and push a NegativeArraySizeException object at the top of stack for
array size being -1. And then at the end of call_VM template, JVM checks if
there is any pending exception to be handled. It calls
SharedRuntime::exception_handler_for_return_address() to determine the
proper handler. Current implementation leads to JVM crash because it finds
the handler in call stub frame, and passes the JVM control flow to
StubRoutines::catch_exception_entry().

It seems JVM should find the exception handler in the Java frame, and pass
as argument the real call site to
SharedRuntime::exception_handler_for_return_address(). Current
implementation uses lr register to hold the call site for
SharedRuntime::exception_handler_for_return_address(). I believe lr
register is assigned an improper value so I suppose the attached patch to
fix this bug:

////////////////////  patch ////////////////////////
diff -r f69a4ff3f0bb src/cpu/aarch32/vm/macroAssembler_aarch32.cpp
--- a/src/cpu/aarch32/vm/macroAssembler_aarch32.cpp Wed Dec 23 12:21:32
2015 +0000
+++ b/src/cpu/aarch32/vm/macroAssembler_aarch32.cpp Tue Dec 29 20:12:55
2015 +0800
@@ -591,7 +591,7 @@
     ldr(rscratch2, Address(java_thread,
in_bytes(Thread::pending_exception_offset())));
     Label ok;
     cbz(rscratch2, ok);
-    ldr(lr, Address(rfp, frame::return_addr_offset));
+    mov(lr, target(l));
     lea(rscratch2,
RuntimeAddress(StubRoutines::forward_exception_entry()));
     b(rscratch2);
     bind(ok);
//////////////////// end ////////////////////////

Thank you all.
Regards.
-------------- next part --------------
diff -r f69a4ff3f0bb src/cpu/aarch32/vm/macroAssembler_aarch32.cpp
--- a/src/cpu/aarch32/vm/macroAssembler_aarch32.cpp	Wed Dec 23 12:21:32 2015 +0000
+++ b/src/cpu/aarch32/vm/macroAssembler_aarch32.cpp	Tue Dec 29 20:12:55 2015 +0800
@@ -591,7 +591,7 @@
     ldr(rscratch2, Address(java_thread, in_bytes(Thread::pending_exception_offset())));
     Label ok;
     cbz(rscratch2, ok);
-    ldr(lr, Address(rfp, frame::return_addr_offset));
+    mov(lr, target(l));
     lea(rscratch2, RuntimeAddress(StubRoutines::forward_exception_entry()));
     b(rscratch2);
     bind(ok);


More information about the aarch32-port-dev mailing list