7188911: nightly failures after JSR 292 lazy method handle update (round 2)
authortwisti
Tue, 07 Aug 2012 14:32:08 -0700
changeset 13396 1b2b5f740ee0
parent 13395 edf37d840190
child 13397 29369e94a65b
7188911: nightly failures after JSR 292 lazy method handle update (round 2) Reviewed-by: kvn, jrose
hotspot/src/share/vm/classfile/verifier.cpp
hotspot/src/share/vm/classfile/vmSymbols.hpp
hotspot/src/share/vm/interpreter/linkResolver.cpp
hotspot/src/share/vm/oops/methodOop.hpp
hotspot/src/share/vm/prims/jvm.cpp
hotspot/src/share/vm/prims/methodHandles.cpp
hotspot/src/share/vm/prims/nativeLookup.cpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/src/share/vm/runtime/sharedRuntime.hpp
hotspot/src/share/vm/utilities/exceptions.cpp
hotspot/src/share/vm/utilities/exceptions.hpp
--- a/hotspot/src/share/vm/classfile/verifier.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -327,7 +327,7 @@
 
   const char* bad_type_msg = "Bad type on operand stack in %s";
 
-  int32_t max_stack = m->max_stack();
+  int32_t max_stack = m->verifier_max_stack();
   int32_t max_locals = m->max_locals();
   constantPoolHandle cp(THREAD, m->constants());
 
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Tue Aug 07 14:32:08 2012 -0700
@@ -160,6 +160,7 @@
   template(java_lang_NoSuchMethodException,           "java/lang/NoSuchMethodException")          \
   template(java_lang_NullPointerException,            "java/lang/NullPointerException")           \
   template(java_lang_StringIndexOutOfBoundsException, "java/lang/StringIndexOutOfBoundsException")\
+  template(java_lang_UnsupportedOperationException,   "java/lang/UnsupportedOperationException")  \
   template(java_lang_InvalidClassException,           "java/lang/InvalidClassException")          \
   template(java_lang_reflect_InvocationTargetException, "java/lang/reflect/InvocationTargetException") \
   template(java_lang_Exception,                       "java/lang/Exception")                      \
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -1265,7 +1265,7 @@
                                                      bootstrap_specifier,
                                                      method_name, method_signature,
                                                      &resolved_appendix,
-                                                     CHECK);
+                                                     THREAD);
   if (HAS_PENDING_EXCEPTION) {
     if (TraceMethodHandles) {
       tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION);
@@ -1282,8 +1282,7 @@
     // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
     Handle nested_exception(THREAD, PENDING_EXCEPTION);
     CLEAR_PENDING_EXCEPTION;
-    THROW_MSG_CAUSE(vmSymbols::java_lang_BootstrapMethodError(),
-                    "BootstrapMethodError", nested_exception)
+    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
   }
   result.set_handle(resolved_method, resolved_appendix, CHECK);
 }
--- a/hotspot/src/share/vm/oops/methodOop.hpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.hpp	Tue Aug 07 14:32:08 2012 -0700
@@ -247,8 +247,10 @@
   void set_constants(constantPoolOop c)          { constMethod()->set_constants(c); }
 
   // max stack
-  int  max_stack() const                         { return _max_stack + extra_stack_entries(); }
-  void set_max_stack(int size)                   { _max_stack = size; }
+  // return original max stack size for method verification
+  int  verifier_max_stack() const                { return _max_stack; }
+  int           max_stack() const                { return _max_stack + extra_stack_entries(); }
+  void      set_max_stack(int size)              {        _max_stack = size; }
 
   // max locals
   int  max_locals() const                        { return _max_locals; }
--- a/hotspot/src/share/vm/prims/jvm.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -2241,7 +2241,7 @@
   klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
   k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
   oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
-  return methodOop(method)->max_stack();
+  return methodOop(method)->verifier_max_stack();
 JVM_END
 
 
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -1196,21 +1196,6 @@
 }
 JVM_END
 
-JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) {
-    TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL);
-    THROW_MSG_NULL(UOE_name, "MethodHandle.invoke cannot be invoked reflectively");
-    return NULL;
-}
-JVM_END
-
-JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) {
-    TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL);
-    THROW_MSG_NULL(UOE_name, "MethodHandle.invokeExact cannot be invoked reflectively");
-    return NULL;
-}
-JVM_END
-
-
 /// JVM_RegisterMethodHandleMethods
 
 #undef CS  // Solaris builds complain
@@ -1248,11 +1233,6 @@
   {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
 };
 
-static JNINativeMethod invoke_methods[] = {
-  {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
-  {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
-};
-
 // This one function is exported, used by NativeLookup.
 
 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
@@ -1278,9 +1258,6 @@
     ThreadToNativeFromVM ttnfv(thread);
 
     status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
-    if (status == JNI_OK && !env->ExceptionOccurred()) {
-      status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod));
-    }
     if (status != JNI_OK || env->ExceptionOccurred()) {
       warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
       enable_MH = false;
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -381,7 +381,10 @@
 
 address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
   if (!method->has_native_function()) {
-    address entry = lookup_base(method, in_base_library, CHECK_NULL);
+    address entry =
+        method->intrinsic_id() == vmIntrinsics::_invokeGeneric ?
+            SharedRuntime::native_method_throw_unsupported_operation_exception_entry() :
+            lookup_base(method, in_base_library, CHECK_NULL);
     method->set_native_function(entry,
       methodOopDesc::native_bind_event_is_interesting);
     // -verbose:jni printing
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -874,11 +874,20 @@
 }
 JNI_END
 
+JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...))
+{
+  THROW(vmSymbols::java_lang_UnsupportedOperationException());
+}
+JNI_END
 
 address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
   return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
 }
 
+address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() {
+  return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception);
+}
+
 
 #ifndef PRODUCT
 JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp	Tue Aug 07 14:32:08 2012 -0700
@@ -238,6 +238,7 @@
 
   // To be used as the entry point for unresolved native methods.
   static address native_method_throw_unsatisfied_link_error_entry();
+  static address native_method_throw_unsupported_operation_exception_entry();
 
   // bytecode tracing is only used by the TraceBytecodes
   static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0;
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Aug 07 14:32:08 2012 -0700
@@ -164,52 +164,58 @@
 }
 
 
-void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_loader, Handle h_protection_domain) {
+void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
+                            Handle h_loader, Handle h_protection_domain) {
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_name, message)) return;
+  if (special_exception(thread, file, line, name, message)) return;
   // Create and throw exception
   Handle h_cause(thread, NULL);
-  Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain);
+  Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
   _throw(thread, file, line, h_exception, message);
 }
 
-// Throw an exception with a message and a cause
-void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) {
+void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
+                                  Handle h_loader, Handle h_protection_domain) {
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_name, message)) return;
+  if (special_exception(thread, file, line, name, message)) return;
   // Create and throw exception and init cause
-  Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain);
+  Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
   _throw(thread, file, line, h_exception, message);
 }
 
-// This version already has a handle for name
-void Exceptions::_throw_msg(Thread* thread, const char* file, int line,
-                            Symbol* name, const char* message) {
-  Handle       h_loader(thread, NULL);
-  Handle       h_protection_domain(thread, NULL);
-  Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain);
+void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
+                              Handle h_loader, Handle h_protection_domain) {
+  // Check for special boot-strapping/vm-thread handling
+  if (special_exception(thread, file, line, h_cause)) return;
+  // Create and throw exception
+  Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain);
+  _throw(thread, file, line, h_exception, NULL);
 }
 
-// This version already has a handle for name
-void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line,
-                            Symbol* name, const char* message, Handle cause) {
-  Handle       h_loader(thread, NULL);
-  Handle       h_protection_domain(thread, NULL);
-  Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain);
-}
-
-void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* h_name, Symbol* h_signature, JavaCallArguments *args) {
+void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments *args) {
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_name, NULL)) return;
+  if (special_exception(thread, file, line, name, NULL)) return;
   // Create and throw exception
   Handle h_loader(thread, NULL);
   Handle h_prot(thread, NULL);
-  Handle h_cause(thread, NULL);
-  Handle exception = new_exception(thread, h_name, h_signature, args, h_cause, h_loader, h_prot);
+  Handle exception = new_exception(thread, name, signature, args, h_loader, h_prot);
   _throw(thread, file, line, exception);
 }
 
 
+// Methods for default parameters.
+// NOTE: These must be here (and not in the header file) because of include circularities.
+void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) {
+  _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, NULL), Handle(thread, NULL));
+}
+void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message) {
+  _throw_msg(thread, file, line, name, message, Handle(thread, NULL), Handle(thread, NULL));
+}
+void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause) {
+  _throw_cause(thread, file, line, name, h_cause, Handle(thread, NULL), Handle(thread, NULL));
+}
+
+
 void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) {
   Handle exception;
   if (!THREAD->has_pending_exception()) {
@@ -240,12 +246,9 @@
 
 // Creates an exception oop, calls the <init> method with the given signature.
 // and returns a Handle
-// Initializes the cause if cause non-null
-Handle Exceptions::new_exception(Thread *thread, Symbol* h_name,
-                                 Symbol* signature,
-                                 JavaCallArguments *args,
-                                 Handle h_cause, Handle h_loader,
-                                 Handle h_protection_domain) {
+Handle Exceptions::new_exception(Thread *thread, Symbol* name,
+                                 Symbol* signature, JavaCallArguments *args,
+                                 Handle h_loader, Handle h_protection_domain) {
   assert(Universe::is_fully_initialized(),
     "cannot be called during initialization");
   assert(thread->is_Java_thread(), "can only be called by a Java thread");
@@ -254,8 +257,8 @@
   Handle h_exception;
 
   // Resolve exception klass
-  klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread);
-  instanceKlassHandle klass (thread, ik);
+  klassOop ik = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread);
+  instanceKlassHandle klass(thread, ik);
 
   if (!thread->has_pending_exception()) {
     assert(klass.not_null(), "klass must exist");
@@ -273,24 +276,8 @@
                                          signature,
                                          args,
                                          thread);
-
       }
     }
-
-    // Future: object initializer should take a cause argument
-    if (h_cause() != NULL) {
-      assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
-          "exception cause is not a subclass of java/lang/Throwable");
-      JavaValue result1(T_OBJECT);
-      JavaCallArguments args1;
-      args1.set_receiver(h_exception);
-      args1.push_oop(h_cause);
-      JavaCalls::call_virtual(&result1, klass,
-                                     vmSymbols::initCause_name(),
-                                     vmSymbols::throwable_throwable_signature(),
-                                     &args1,
-                                     thread);
-    }
   }
 
   // Check if another exception was thrown in the process, if so rethrow that one
@@ -301,12 +288,60 @@
   return h_exception;
 }
 
+// Creates an exception oop, calls the <init> method with the given signature.
+// and returns a Handle
+// Initializes the cause if cause non-null
+Handle Exceptions::new_exception(Thread *thread, Symbol* name,
+                                 Symbol* signature, JavaCallArguments *args,
+                                 Handle h_cause,
+                                 Handle h_loader, Handle h_protection_domain) {
+  Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain);
+
+  // Future: object initializer should take a cause argument
+  if (h_cause.not_null()) {
+    assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
+        "exception cause is not a subclass of java/lang/Throwable");
+    JavaValue result1(T_OBJECT);
+    JavaCallArguments args1;
+    args1.set_receiver(h_exception);
+    args1.push_oop(h_cause);
+    JavaCalls::call_virtual(&result1, h_exception->klass(),
+                                      vmSymbols::initCause_name(),
+                                      vmSymbols::throwable_throwable_signature(),
+                                      &args1,
+                                      thread);
+  }
+
+  // Check if another exception was thrown in the process, if so rethrow that one
+  if (thread->has_pending_exception()) {
+    h_exception = Handle(thread, thread->pending_exception());
+    thread->clear_pending_exception();
+  }
+  return h_exception;
+}
+
+// Convenience method. Calls either the <init>() or <init>(Throwable) method when
+// creating a new exception
+Handle Exceptions::new_exception(Thread* thread, Symbol* name,
+                                 Handle h_cause,
+                                 Handle h_loader, Handle h_protection_domain,
+                                 ExceptionMsgToUtf8Mode to_utf8_safe) {
+  JavaCallArguments args;
+  Symbol* signature = NULL;
+  if (h_cause.is_null()) {
+    signature = vmSymbols::void_method_signature();
+  } else {
+    signature = vmSymbols::throwable_void_signature();
+    args.push_oop(h_cause);
+  }
+  return new_exception(thread, name, signature, &args, h_loader, h_protection_domain);
+}
+
 // Convenience method. Calls either the <init>() or <init>(String) method when
 // creating a new exception
-Handle Exceptions::new_exception(Thread* thread, Symbol* h_name,
+Handle Exceptions::new_exception(Thread* thread, Symbol* name,
                                  const char* message, Handle h_cause,
-                                 Handle h_loader,
-                                 Handle h_protection_domain,
+                                 Handle h_loader, Handle h_protection_domain,
                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
   JavaCallArguments args;
   Symbol* signature = NULL;
@@ -320,7 +355,7 @@
     // the exception we are trying to build, or the pending exception.
     // This is sort of like what PRESERVE_EXCEPTION_MARK does, except
     // for the preferencing and the early returns.
-    Handle incoming_exception (thread, NULL);
+    Handle incoming_exception(thread, NULL);
     if (thread->has_pending_exception()) {
       incoming_exception = Handle(thread, thread->pending_exception());
       thread->clear_pending_exception();
@@ -344,7 +379,7 @@
     args.push_oop(msg);
     signature = vmSymbols::string_void_signature();
   }
-  return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain);
+  return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain);
 }
 
 // Another convenience method that creates handles for null class loaders and
@@ -355,8 +390,7 @@
 // encoding scheme of the string into account. One thing we should do at some
 // point is to push this flag down to class java_lang_String since other
 // classes may need similar functionalities.
-Handle Exceptions::new_exception(Thread* thread,
-                                 Symbol* name,
+Handle Exceptions::new_exception(Thread* thread, Symbol* name,
                                  const char* message,
                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
 
--- a/hotspot/src/share/vm/utilities/exceptions.hpp	Wed Aug 01 14:44:26 2012 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp	Tue Aug 07 14:32:08 2012 -0700
@@ -112,19 +112,22 @@
   // Throw exceptions: w/o message, w/ message & with formatted message.
   static void _throw_oop(Thread* thread, const char* file, int line, oop exception);
   static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL);
-  static void _throw_msg(Thread* thread, const char* file, int line,
-                         Symbol* name, const char* message, Handle loader,
-                         Handle protection_domain);
-  static void _throw_msg(Thread* thread, const char* file, int line,
-                         Symbol* name, const char* message);
+
+  static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message);
+  static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
+                         Handle loader, Handle protection_domain);
+
+  static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause);
+  static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
+                               Handle h_loader, Handle h_protection_domain);
+
+  static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause);
+  static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
+                           Handle h_loader, Handle h_protection_domain);
+
   static void _throw_args(Thread* thread, const char* file, int line,
                           Symbol* name, Symbol* signature,
                           JavaCallArguments* args);
-  static void _throw_msg_cause(Thread* thread, const char* file,
-                         int line, Symbol* h_name, const char* message,
-                         Handle h_cause, Handle h_loader, Handle h_protection_domain);
-  static void _throw_msg_cause(Thread* thread, const char* file, int line,
-                            Symbol* name, const char* message, Handle cause);
 
   // There is no THROW... macro for this method. Caller should remember
   // to do a return after calling it.
@@ -134,17 +137,26 @@
   // Create and initialize a new exception
   static Handle new_exception(Thread* thread, Symbol* name,
                               Symbol* signature, JavaCallArguments* args,
-                              Handle cause, Handle loader,
-                              Handle protection_domain);
+                              Handle loader, Handle protection_domain);
+
+  static Handle new_exception(Thread* thread, Symbol* name,
+                              Symbol* signature, JavaCallArguments* args,
+                              Handle cause,
+                              Handle loader, Handle protection_domain);
 
   static Handle new_exception(Thread* thread, Symbol* name,
-                              const char* message, Handle cause, Handle loader,
-                              Handle protection_domain,
+                              Handle cause,
+                              Handle loader, Handle protection_domain,
                               ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
 
- static Handle new_exception(Thread* thread, Symbol* name,
-                             const char* message,
-                             ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
+  static Handle new_exception(Thread* thread, Symbol* name,
+                              const char* message, Handle cause,
+                              Handle loader, Handle protection_domain,
+                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
+
+  static Handle new_exception(Thread* thread, Symbol* name,
+                              const char* message,
+                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
 
   static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method);
 
@@ -214,15 +226,15 @@
 #define THROW_MSG(name, message)                    \
   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return;  }
 
+#define THROW_CAUSE(name, cause)   \
+  { Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; }
+
 #define THROW_MSG_LOADER(name, message, loader, protection_domain) \
   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return;  }
 
 #define THROW_ARG(name, signature, args) \
   { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args);   return; }
 
-#define THROW_MSG_CAUSE(name, message, cause) \
-  { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return; }
-
 #define THROW_OOP_(e, result)                       \
   { Exceptions::_throw_oop(THREAD_AND_LOCATION, e);                           return result; }