8005173: assert(false) failed: DEBUG MESSAGE: exception oop must be empty (macroAssembler_x86.cpp:625)
authortwisti
Fri, 11 Oct 2013 10:14:02 -0700
changeset 20703 2de7fe0e9693
parent 20702 bbe0fcde6e13
child 20706 3f93b1f4fe71
child 20707 b3b658c6d1f8
8005173: assert(false) failed: DEBUG MESSAGE: exception oop must be empty (macroAssembler_x86.cpp:625) Reviewed-by: kvn, iveresov
hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp
hotspot/src/share/vm/c1/c1_Runtime1.cpp
hotspot/src/share/vm/opto/runtime.cpp
hotspot/src/share/vm/runtime/thread.hpp
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Wed Oct 09 16:32:21 2013 +0200
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Fri Oct 11 10:14:02 2013 -0700
@@ -1067,6 +1067,25 @@
 
   __ verify_not_null_oop(Oexception);
 
+#ifdef ASSERT
+  // check that fields in JavaThread for exception oop and issuing pc are
+  // empty before writing to them
+  Label oop_empty;
+  Register scratch = I7;  // We can use I7 here because it's overwritten later anyway.
+  __ ld_ptr(Address(G2_thread, JavaThread::exception_oop_offset()), scratch);
+  __ br_null(scratch, false, Assembler::pt, oop_empty);
+  __ delayed()->nop();
+  __ stop("exception oop already set");
+  __ bind(oop_empty);
+
+  Label pc_empty;
+  __ ld_ptr(Address(G2_thread, JavaThread::exception_pc_offset()), scratch);
+  __ br_null(scratch, false, Assembler::pt, pc_empty);
+  __ delayed()->nop();
+  __ stop("exception pc already set");
+  __ bind(pc_empty);
+#endif
+
   // save the exception and issuing pc in the thread
   __ st_ptr(Oexception,  G2_thread, in_bytes(JavaThread::exception_oop_offset()));
   __ st_ptr(Oissuing_pc, G2_thread, in_bytes(JavaThread::exception_pc_offset()));
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Wed Oct 09 16:32:21 2013 +0200
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Fri Oct 11 10:14:02 2013 -0700
@@ -542,8 +542,7 @@
     // exception handler can cause class loading, which might throw an
     // exception and those fields are expected to be clear during
     // normal bytecode execution.
-    thread->set_exception_oop(NULL);
-    thread->set_exception_pc(NULL);
+    thread->clear_exception_oop_and_pc();
 
     continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
     // If an exception was thrown during exception dispatch, the exception oop may have changed
--- a/hotspot/src/share/vm/opto/runtime.cpp	Wed Oct 09 16:32:21 2013 +0200
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Fri Oct 11 10:14:02 2013 -0700
@@ -976,30 +976,36 @@
   address handler_address = NULL;
 
   Handle exception(thread, thread->exception_oop());
+  address pc = thread->exception_pc();
+
+  // Clear out the exception oop and pc since looking up an
+  // exception handler can cause class loading, which might throw an
+  // exception and those fields are expected to be clear during
+  // normal bytecode execution.
+  thread->clear_exception_oop_and_pc();
 
   if (TraceExceptions) {
-    trace_exception(exception(), thread->exception_pc(), "");
+    trace_exception(exception(), pc, "");
   }
+
   // for AbortVMOnException flag
   NOT_PRODUCT(Exceptions::debug_check_abort(exception));
 
-  #ifdef ASSERT
-    if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
-      // should throw an exception here
-      ShouldNotReachHere();
-    }
-  #endif
-
+#ifdef ASSERT
+  if (!(exception->is_a(SystemDictionary::Throwable_klass()))) {
+    // should throw an exception here
+    ShouldNotReachHere();
+  }
+#endif
 
   // new exception handling: this method is entered only from adapters
   // exceptions from compiled java methods are handled in compiled code
   // using rethrow node
 
-  address pc = thread->exception_pc();
   nm = CodeCache::find_nmethod(pc);
   assert(nm != NULL, "No NMethod found");
   if (nm->is_native_method()) {
-    fatal("Native mathod should not have path to exception handling");
+    fatal("Native method should not have path to exception handling");
   } else {
     // we are switching to old paradigm: search for exception handler in caller_frame
     // instead in exception handler of caller_frame.sender()
@@ -1346,7 +1352,8 @@
   tty->print(" in ");
   CodeBlob* blob = CodeCache::find_blob(exception_pc);
   if (blob->is_nmethod()) {
-    ((nmethod*)blob)->method()->print_value();
+    nmethod* nm = blob->as_nmethod_or_null();
+    nm->method()->print_value();
   } else if (blob->is_runtime_stub()) {
     tty->print("<runtime-stub>");
   } else {
--- a/hotspot/src/share/vm/runtime/thread.hpp	Wed Oct 09 16:32:21 2013 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Fri Oct 11 10:14:02 2013 -0700
@@ -1283,6 +1283,11 @@
   void set_exception_handler_pc(address a)       { _exception_handler_pc = a; }
   void set_is_method_handle_return(bool value)   { _is_method_handle_return = value ? 1 : 0; }
 
+  void clear_exception_oop_and_pc() {
+    set_exception_oop(NULL);
+    set_exception_pc(NULL);
+  }
+
   // Stack overflow support
   inline size_t stack_available(address cur_sp);
   address stack_yellow_zone_base()