changeset 1936:8d88c9ac9247

Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Thu, 23 Dec 2010 18:13:28 +0100
parents 98dbef29f10b
children 4853c5cad3aa
files c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java c1x4hotspotsrc/hotspot/hotspot jtt.launch runscimark.sh src/os/linux/vm/os_linux.cpp src/os_cpu/linux_x86/vm/os_linux_x86.cpp src/share/vm/c1/c1_globals.hpp src/share/vm/c1x/c1x_CodeInstaller.cpp src/share/vm/c1x/c1x_CodeInstaller.hpp src/share/vm/c1x/c1x_VMEntries.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/vframeArray.cpp
diffstat 14 files changed, 87 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java	Wed Dec 22 19:47:39 2010 +0100
+++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotVMConfig.java	Thu Dec 23 18:13:28 2010 +0100
@@ -67,6 +67,7 @@
     public long inlineCacheMissStub;
     public long unwindExceptionStub;
     public long handleExceptionStub;
+    public long handleDeoptStub;
     public long throwClassCastException;
     public long throwArrayStoreException;
     public long throwArrayIndexException;
--- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java	Wed Dec 22 19:47:39 2010 +0100
+++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java	Thu Dec 23 18:13:28 2010 +0100
@@ -51,6 +51,7 @@
     private static final Integer MARK_OSR_ENTRY                 = 0x0003;
     private static final Integer MARK_UNWIND_ENTRY              = 0x0004;
     private static final Integer MARK_EXCEPTION_HANDLER_ENTRY   = 0x0005;
+    private static final Integer MARK_DEOPT_HANDLER_ENTRY       = 0x0006;
 
     private static final Integer MARK_STATIC_CALL_STUB          = 0x1000;
 
@@ -128,6 +129,11 @@
             asm.callRuntime(config.handleExceptionStub, null);
             asm.shouldNotReachHere();
 
+            asm.nop(1);
+            asm.mark(MARK_DEOPT_HANDLER_ENTRY);
+            asm.callRuntime(config.handleDeoptStub, null);
+            asm.shouldNotReachHere();
+
             if (!is(STATIC_METHOD, flags)) {
                 asm.bindOutOfLine(unverifiedStub);
                 asm.jmpRuntime(config.inlineCacheMissStub);
@@ -663,11 +669,10 @@
                 } else {
                     length = asm.createTemp("length", CiKind.Int);
                     if (implicitNullException) {
-                        asm.nop(1);
+                        //asm.nop(1);
                         asm.mark(MARK_IMPLICIT_NULL);
                     }
                     asm.pload(CiKind.Int, length, array, asm.i(config.arrayLengthOffset), implicitNullException);
-                    implicitNullException = false;
                 }
                 asm.jugteq(failBoundsCheck, index, length);
                 implicitNullException = false;
@@ -1088,6 +1093,8 @@
             asm.callRuntime(config.accessFieldStub, null);
             asm.jmp(patchSite);
 
+            // Check if we need NOP instructions like in C1 to "not destroy the world".
+
             state = State.Finished;
         }
     }
--- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java	Wed Dec 22 19:47:39 2010 +0100
+++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java	Thu Dec 23 18:13:28 2010 +0100
@@ -51,6 +51,8 @@
         C1XOptions.UseDeopt = false;
         C1XOptions.IRChecking = false;
         C1XOptions.DetailedAsserts = false;
+        C1XOptions.CommentedAssembly = true;
+        C1XOptions.MethodEndBreakpointGuards = 10;
     }
 
     @Override
--- a/c1x4hotspotsrc/hotspot/hotspot jtt.launch	Wed Dec 22 19:47:39 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB" value="true"/>
-<listAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB_LIST"/>
-<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="gdb"/>
-<stringAttribute key="org.eclipse.cdt.dsf.gdb.GDB_INIT" value=".gdbinit"/>
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REVERSE" value="false"/>
-<listAttribute key="org.eclipse.cdt.dsf.gdb.SOLIB_PATH"/>
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
-<booleanAttribute key="org.eclipse.cdt.dsf.gdb.internal.ui.launching.LocalApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
-<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
-<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="gdb"/>
-<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
-<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
-<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_ARGUMENTS" value="-client -XX:+UseC1X -Xcomp -XX:CompileOnly=jtt -XX:+PrintCompilation -Xbootclasspath/p:${workspace_loc:hotspot}/../../../maxine/C1X/bin:${workspace_loc:hotspot}/../../../maxine/CRI/bin:${workspace_loc:hotspot}/../../../maxine/Base/bin:${workspace_loc:hotspot}/../../../maxine/Assembler/bin:${workspace_loc:hotspot}/../HotSpotVM/bin -classpath ${workspace_loc:hotspot}/../../../maxine/VM/bin:${workspace_loc:hotspot}/../HotSpotTest/bin -C1X:+PrintCompilation JavaTester"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="java"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="hotspot"/>
-<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="cdt.managedbuild.toolchain.gnu.solaris.base.945602881"/>
-<booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="true"/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/hotspot"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;/&gt;&#10;"/>
-</launchConfiguration>
--- a/runscimark.sh	Wed Dec 22 19:47:39 2010 +0100
+++ b/runscimark.sh	Thu Dec 23 18:13:28 2010 +0100
@@ -7,10 +7,6 @@
   echo "MAXINE is not defined. It must point to a maxine repository directory."
   exit 1;
 fi
-if [ -z "${C1X}" ]; then
-  echo "C1X is not defined. It must point to a c1x4hotspot directory."
-  exit 1;
-fi
 if [ -z "${SCIMARK}" ]; then
   echo "SCIMARK is not defined. It must point to a SciMark benchmark directory."
   exit 1;
@@ -18,5 +14,5 @@
 for (( i = 1; i <= 5000; i++ ))      ### Outer for loop ###
 do
   echo "$i "
-  ${JDK7}/jre/bin/java -client -esa -ea -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+PrintCompilation -XX:+UseC1X -Xms32m -Xmx100m -Xbootclasspath/p:${MAXINE}/C1X/bin:${MAXINE}/CRI/bin:${MAXINE}/Base/bin:${MAXINE}/Assembler/bin:${C1X}/c1x4hotspotsrc/HotSpotVM/bin -Xbootclasspath/a:${SCIMARK} -C1X:+PrintTimers  jnt.scimark2.commandline -large
+  ${JDK7}/jre/bin/java -client -graal -esa -ea -Xms32m -Xmx100m -Xbootclasspath/a:${SCIMARK} -C1X:+PrintTimers  jnt.scimark2.commandline -large
 done
--- a/src/os/linux/vm/os_linux.cpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/os/linux/vm/os_linux.cpp	Thu Dec 23 18:13:28 2010 +0100
@@ -3408,7 +3408,13 @@
 
 void signalHandler(int sig, siginfo_t* info, void* uc) {
   assert(info != NULL && uc != NULL, "it must be old kernel");
+  if (TraceSignals) {
+    tty->print_cr(err_msg("signal received: code=%d errno=%d signo=%d thread=%s address=%x", info->si_code, info->si_errno, info->si_signo, Thread::current()->name(), info->si_addr));
+  }
   JVM_handle_linux_signal(sig, info, uc, true);
+  if (TraceSignals) {
+    tty->print_cr("signal handled");
+  }
 }
 
 
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Dec 23 18:13:28 2010 +0100
@@ -255,6 +255,17 @@
     }
 #endif // AMD64
 
+    if (TraceSignals) {
+    CodeBlob* cb = CodeCache::find_blob(pc);
+      if (cb != NULL && cb->is_nmethod()) {
+        nmethod* nm = (nmethod*)cb;
+        int rel = pc - nm->code_begin();
+        tty->print_cr("Implicit exception at %d of method %s", rel, nm->method()->name()->as_C_string());
+      } else {
+        tty->print_cr("No code blob found for %x", pc);
+      }
+    }
+
     // Handle ALL stack overflow variations here
     if (sig == SIGSEGV) {
       address addr = (address) info->si_addr;
@@ -354,8 +365,15 @@
 #endif // AMD64
       } else if (sig == SIGSEGV &&
                !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
+          if (TraceSignals) {
+            tty->print_cr("Implicit exception continuation");
+          }
           // Determination of interpreter/vtable stub/compiled code null exception
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
+      } else if (sig == SIGSEGV) {
+        if (TraceSignals) {
+          tty->print_cr("would have needed explicit null check %d", (intptr_t)info->si_addr);
+        }
       }
     } else if (thread->thread_state() == _thread_in_vm &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
--- a/src/share/vm/c1/c1_globals.hpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/c1/c1_globals.hpp	Thu Dec 23 18:13:28 2010 +0100
@@ -33,6 +33,8 @@
           "Bootstrap C1X before running Java main method")                  \
   product(intx, TraceC1X, 0,                                                \
           "Trace level for C1X")                                            \
+  product(bool, TraceSignals, false,                                        \
+          "Trace signals and implicit exception handling")                  \
   /* Printing */                                                            \
   notproduct(bool, PrintC1Statistics, false,                                \
           "Print Compiler1 statistics" )                                    \
--- a/src/share/vm/c1x/c1x_CodeInstaller.cpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/c1x/c1x_CodeInstaller.cpp	Thu Dec 23 18:13:28 2010 +0100
@@ -162,10 +162,6 @@
     assert(_hotspot_method != NULL && _name == NULL, "installMethod needs NON-NULL method and NULL name");
     assert(_hotspot_method->is_a(HotSpotMethodResolved::klass()), "installMethod needs a HotSpotMethodResolved");
 
-    // TODO: This is a hack.. Produce correct entries.
-    _offsets.set_value(CodeOffsets::Exceptions, 0);
-    _offsets.set_value(CodeOffsets::Deopt, 0);
-
     methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(_hotspot_method));
     ciMethodObject = (ciMethod *) _env->get_object(method);
     _parameter_count = method->size_of_parameters();
@@ -366,6 +362,11 @@
     GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*> ();
     GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*> ();
 
+    if (TraceC1X >= 2) {
+      tty->print_cr("Scope at bci %d with %d values", bci, values->length());
+      tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
+    }
+
     for (jint i = 0; i < values->length(); i++) {
       ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size);
 
@@ -600,6 +601,9 @@
       case MARK_EXCEPTION_HANDLER_ENTRY:
         _offsets.set_value(CodeOffsets::Exceptions, pc_offset);
         break;
+      case MARK_DEOPT_HANDLER_ENTRY:
+        _offsets.set_value(CodeOffsets::Deopt, pc_offset);
+        break;
       case MARK_STATIC_CALL_STUB: {
         assert(references->length() == 1, "static call stub needs one reference");
         oop ref = ((oop*) references->base(T_OBJECT))[0];
--- a/src/share/vm/c1x/c1x_CodeInstaller.hpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/c1x/c1x_CodeInstaller.hpp	Thu Dec 23 18:13:28 2010 +0100
@@ -34,6 +34,7 @@
     MARK_OSR_ENTRY                  = 0x0003,
     MARK_UNWIND_ENTRY               = 0x0004,
     MARK_EXCEPTION_HANDLER_ENTRY    = 0x0005,
+    MARK_DEOPT_HANDLER_ENTRY        = 0x0006,
     MARK_STATIC_CALL_STUB           = 0x1000,
     MARK_INVOKE_INVALID             = 0x2000,
     MARK_INVOKEINTERFACE            = 0x2001,
--- a/src/share/vm/c1x/c1x_VMEntries.cpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/c1x/c1x_VMEntries.cpp	Thu Dec 23 18:13:28 2010 +0100
@@ -459,6 +459,7 @@
   set_long(env, config, "inlineCacheMissStub", VmIds::addStub(SharedRuntime::get_ic_miss_stub()));
   set_long(env, config, "unwindExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::c1x_unwind_exception_call_id)));
   set_long(env, config, "handleExceptionStub", VmIds::addStub(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
+  set_long(env, config, "handleDeoptStub", VmIds::addStub(SharedRuntime::deopt_blob()->unpack()));
   set_long(env, config, "throwClassCastException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_class_cast_exception_id)));
   set_long(env, config, "throwArrayStoreException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_array_store_exception_id)));
   set_long(env, config, "throwArrayIndexException", VmIds::addStub(Runtime1::entry_for(Runtime1::throw_range_check_failed_id)));
@@ -516,7 +517,7 @@
 
 // public void recordBailout(String reason);
 JNIEXPORT void JNICALL Java_com_sun_hotspot_c1x_VMEntries_recordBailout(JNIEnv *jniEnv, jobject) {
-  fatal("Bailout in C1X");
+  //fatal("Bailout in C1X");
 }
 
 
--- a/src/share/vm/runtime/globals.hpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/runtime/globals.hpp	Thu Dec 23 18:13:28 2010 +0100
@@ -1149,7 +1149,7 @@
   develop(bool, TraceClassInitialization, false,                            \
           "Trace class initialization")                                     \
                                                                             \
-  develop(bool, TraceExceptions, false,                                     \
+  product(bool, TraceExceptions, false,                                     \
           "Trace exceptions")                                               \
                                                                             \
   develop(bool, TraceICs, false,                                            \
--- a/src/share/vm/runtime/sharedRuntime.cpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Thu Dec 23 18:13:28 2010 +0100
@@ -730,6 +730,9 @@
           _implicit_null_throws++;
 #endif
           if (UseC1X) {
+            if (TraceSignals) {
+              tty->print_cr("calling implicit call stub relative pc=%d method name = %s", pc - nm->entry_point(), nm->method()->name()->as_C_string());
+            }
             target_pc = Runtime1::entry_for(Runtime1::c1x_global_implicit_null_id);
           } else {
             target_pc = nm->continuation_for_implicit_exception(pc);
@@ -750,6 +753,7 @@
         _implicit_div0_throws++;
 #endif
         if (UseC1X) {
+          tty->print_cr("c1x implicit div0");
           target_pc = Runtime1::entry_for(Runtime1::c1x_throw_div0_exception_id);
         } else {
           target_pc = nm->continuation_for_implicit_exception(pc);
--- a/src/share/vm/runtime/vframeArray.cpp	Wed Dec 22 19:47:39 2010 +0100
+++ b/src/share/vm/runtime/vframeArray.cpp	Thu Dec 23 18:13:28 2010 +0100
@@ -300,9 +300,25 @@
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (TraceDeoptimization) {
+          tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (TraceDeoptimization) {
+          tty->print("Reconstructed expression %d (OBJECT): ", i);
+          oop o = (oop)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            tty->print_cr(err_msg("%s", o->blueprint()->name()->as_C_string()));
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead stack slot.  Initialize to null in case it is an oop.
@@ -321,9 +337,25 @@
     switch(value->type()) {
       case T_INT:
         *addr = value->get_int();
+#ifndef PRODUCT
+        if (TraceDeoptimization) {
+          tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr));
+        }
+#endif
         break;
       case T_OBJECT:
         *addr = value->get_int(T_OBJECT);
+#ifndef PRODUCT
+        if (TraceDeoptimization) {
+          tty->print("Reconstructed local %d (OBJECT): ", i);
+          oop o = (oop)(*addr);
+          if (o == NULL) {
+            tty->print_cr("NULL");
+          } else {
+            tty->print_cr(err_msg("%s", o->blueprint()->name()->as_C_string()));
+          }
+        }
+#endif
         break;
       case T_CONFLICT:
         // A dead location. If it is an oop then we need a NULL to prevent GC from following it