changeset 9820:1b60f639ac4b

implemented alternative implementation for loading the exception object from the thread at the start of an exception dispatcher
author Doug Simon <doug.simon@oracle.com>
date Sat, 25 May 2013 23:42:11 +0200
parents 8aea948c522b
children 32d8115dade8
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalRuntime.cpp src/share/vm/graal/graalRuntime.hpp
diffstat 7 files changed, 35 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat May 25 23:33:03 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Sat May 25 23:42:11 2013 +0200
@@ -411,6 +411,7 @@
     public long arithmeticSinAddress;
     public long arithmeticCosAddress;
     public long arithmeticTanAddress;
+    public long loadAndClearExceptionAddress;
 
     public int deoptReasonNone;
     public int deoptReasonNullCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sat May 25 23:33:03 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sat May 25 23:42:11 2013 +0200
@@ -97,6 +97,7 @@
     public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
     public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
     public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class);
+    public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class);
 
     public final HotSpotVMConfig config;
 
@@ -263,6 +264,7 @@
         registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
         registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
         registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
 
         registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
         registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Sat May 25 23:33:03 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Sat May 25 23:42:11 2013 +0200
@@ -22,11 +22,15 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
+import static com.oracle.graal.hotspot.meta.HotSpotRuntime.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.nodes.extended.UnsafeCastNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -34,6 +38,7 @@
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
 import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
+import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.word.*;
 
 /**
@@ -41,6 +46,11 @@
  */
 public class LoadExceptionObjectSnippets implements Snippets {
 
+    /**
+     * Alternative way to implement exception object loading.
+     */
+    private static final boolean USE_C_RUNTIME = Boolean.getBoolean("graal.loadExceptionObject.useCRuntime");
+
     @Snippet
     public static Object loadException() {
         Word thread = thread();
@@ -59,8 +69,18 @@
         }
 
         public void lower(LoadExceptionObjectNode loadExceptionObject) {
-            Arguments args = new Arguments(loadException);
-            template(args).instantiate(runtime, loadExceptionObject, DEFAULT_REPLACER, args);
+            if (USE_C_RUNTIME) {
+                StructuredGraph graph = loadExceptionObject.graph();
+                HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime;
+                ReadRegisterNode thread = graph.add(new ReadRegisterNode(hsRuntime.threadRegister(), true, false));
+                graph.addBeforeFixed(loadExceptionObject, thread);
+                ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(runtime, LOAD_AND_CLEAR_EXCEPTION, thread));
+                loadExceptionC.setStateAfter(loadExceptionObject.stateAfter());
+                graph.replaceFixedWithFixed(loadExceptionObject, loadExceptionC);
+            } else {
+                Arguments args = new Arguments(loadException);
+                template(args).instantiate(runtime, loadExceptionObject, DEFAULT_REPLACER, args);
+            }
         }
     }
 }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java	Sat May 25 23:33:03 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java	Sat May 25 23:42:11 2013 +0200
@@ -72,7 +72,7 @@
             try {
                 raiseException(message);
             } catch (Exception e) {
-                return message;
+                return message + e.getMessage();
             }
         }
         return null;
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Sat May 25 23:33:03 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Sat May 25 23:42:11 2013 +0200
@@ -795,6 +795,7 @@
   set_address("logObjectAddress", GraalRuntime::log_object);
   set_address("logPrintfAddress", GraalRuntime::log_printf);
   set_address("vmErrorAddress", GraalRuntime::vm_error);
+  set_address("loadAndClearExceptionAddress", GraalRuntime::load_and_clear_exception);
   set_address("writeBarrierPreAddress", GraalRuntime::write_barrier_pre);
   set_address("writeBarrierPostAddress", GraalRuntime::write_barrier_post);
   set_address("javaTimeMillisAddress", CAST_FROM_FN_PTR(address, os::javaTimeMillis));
--- a/src/share/vm/graal/graalRuntime.cpp	Sat May 25 23:33:03 2013 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Sat May 25 23:42:11 2013 +0200
@@ -380,6 +380,13 @@
   report_vm_error(__FILE__, __LINE__, error_msg, detail_msg);
 JRT_END
 
+JRT_LEAF(oop, GraalRuntime::load_and_clear_exception(JavaThread* thread))
+  oop exception = thread->exception_oop();
+  assert(exception != NULL, "npe");
+  thread->set_exception_oop(NULL);
+  thread->set_exception_pc(0);
+  return exception;
+JRT_END
 
 JRT_LEAF(void, GraalRuntime::log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3))
   ResourceMark rm;
--- a/src/share/vm/graal/graalRuntime.hpp	Sat May 25 23:33:03 2013 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Sat May 25 23:42:11 2013 +0200
@@ -42,6 +42,7 @@
   static void create_null_exception(JavaThread* thread);
   static void create_out_of_bounds_exception(JavaThread* thread, jint index);
   static void vm_error(JavaThread* thread, oop where, oop format, jlong value);
+  static oop load_and_clear_exception(JavaThread* thread);
   static void log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3);
   static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
   // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log