src/hotspot/share/utilities/exceptions.cpp
changeset 48826 c4d9d1b08e2e
parent 47689 54b78d6243c5
child 49177 eebf559c9e0d
--- a/src/hotspot/share/utilities/exceptions.cpp	Wed Jan 31 10:55:49 2018 -0800
+++ b/src/hotspot/share/utilities/exceptions.cpp	Fri Sep 08 10:46:46 2017 -0700
@@ -403,6 +403,37 @@
                                    h_prot, to_utf8_safe);
 }
 
+// invokedynamic uses wrap_dynamic_exception for:
+//    - bootstrap method resolution
+//    - post call to MethodHandleNatives::linkCallSite
+// dynamically computed constant uses wrap_dynamic_exception for:
+//    - bootstrap method resolution
+//    - post call to MethodHandleNatives::linkDynamicConstant
+void Exceptions::wrap_dynamic_exception(Thread* THREAD) {
+  if (THREAD->has_pending_exception()) {
+    oop exception = THREAD->pending_exception();
+    // See the "Linking Exceptions" section for the invokedynamic instruction
+    // in JVMS 6.5.
+    if (exception->is_a(SystemDictionary::Error_klass())) {
+      // Pass through an Error, including BootstrapMethodError, any other form
+      // of linkage error, or say ThreadDeath/OutOfMemoryError
+      if (TraceMethodHandles) {
+        tty->print_cr("[constant/invoke]dynamic passes through an Error for " INTPTR_FORMAT, p2i((void *)exception));
+        exception->print();
+      }
+      return;
+    }
+
+    // Otherwise wrap the exception in a BootstrapMethodError
+    if (TraceMethodHandles) {
+      tty->print_cr("[constant/invoke]dynamic throws BSME for " INTPTR_FORMAT, p2i((void *)exception));
+      exception->print();
+    }
+    Handle nested_exception(THREAD, exception);
+    THREAD->clear_pending_exception();
+    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
+  }
+}
 
 // Exception counting for hs_err file
 volatile int Exceptions::_stack_overflow_errors = 0;