< prev index next >

src/hotspot/share/classfile/classLoaderData.cpp

Print this page
rev 50866 : 8203826: Chain exception from initialization in later NoClassDefFoundErrors.

@@ -67,10 +67,11 @@
 #include "oops/oop.inline.hpp"
 #include "oops/oopHandle.inline.hpp"
 #include "oops/weakHandle.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
+#include "runtime/javaCalls.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/safepointVerifiers.hpp"
 #include "utilities/growableArray.hpp"

@@ -443,10 +444,74 @@
     // Added a potentially young gen oop to the ClassLoaderData
     record_modified_oops();
   }
 }
 
+void ClassLoaderData::record_init_exception(OopHandle cls, Handle exc, TRAPS) {
+  if (_exception_map.resolve() == NULL) {
+    Klass* ht = SystemDictionary::resolve_or_null(vmSymbols::java_util_Hashtable(), THREAD);
+
+    if (ht != NULL && !THREAD->has_pending_exception()) {
+      Handle h_ht = JavaCalls::construct_new_instance(InstanceKlass::cast(ht),
+                                                      vmSymbols::void_method_signature(),
+                                                      THREAD);
+      // construct_new_instance() returns NULL handle on error
+      _exception_map = add_handle(h_ht);
+    }
+  }
+  if (_exception_map.resolve() != NULL) {
+    assert(cls.resolve() != NULL && exc.not_null(), "Mirror and exception must be non-NULL");
+    JavaValue r(T_OBJECT);
+    Klass* ht = SystemDictionary::resolve_or_null(vmSymbols::java_util_Hashtable(), THREAD);
+    JavaCalls::call_virtual(&r,
+                            Handle(THREAD, _exception_map.resolve()),
+                            InstanceKlass::cast(ht),
+                            vmSymbols::put_name(),
+                            vmSymbols::object_object_object_signature(),
+                            Handle(THREAD, cls.resolve()),
+                            exc,
+                            THREAD);
+    if (!THREAD->has_pending_exception()) {
+      JavaValue v(T_VOID);
+      JavaCalls::call_static(&v,
+                             SystemDictionary::Throwable_klass(),
+                             vmSymbols::removeNativeBacktrace_name(),
+                             vmSymbols::throwable_void_signature(),
+                             exc,
+                             THREAD);
+    }
+  }
+  // Cleanup and ignore any exceptions because recording initialisation exceptions is optional
+  if (THREAD->has_pending_exception()) {
+    CLEAR_PENDING_EXCEPTION;
+  }
+}
+
+Handle ClassLoaderData::query_init_exception(OopHandle cls, TRAPS) {
+  if (_exception_map.resolve() != NULL) {
+    Klass* ht = SystemDictionary::resolve_or_null(vmSymbols::java_util_Hashtable(), THREAD);
+    if (ht != NULL && !THREAD->has_pending_exception()) {
+      assert(cls.resolve() != NULL, "Class mirror must exist");
+      JavaValue exc(T_OBJECT);
+      JavaCalls::call_virtual(&exc,
+                              Handle(THREAD, _exception_map.resolve()),
+                              InstanceKlass::cast(ht),
+                              vmSymbols::get_name(),
+                              vmSymbols::object_object_signature(),
+                              Handle(THREAD, cls.resolve()),
+                              THREAD);
+      if (exc.get_jobject() != NULL) {
+        return Handle(THREAD, (oop)exc.get_jobject());
+      }
+    }
+  }
+  // Cleanup and ignore any exceptions because querying initialisation exceptions is optional
+  if (THREAD->has_pending_exception()) {
+    CLEAR_PENDING_EXCEPTION;
+  }
+  return Handle();
+}
 
 void ClassLoaderDataGraph::clear_claimed_marks() {
   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
     cld->clear_claimed();
   }
< prev index next >