src/hotspot/share/jvmci/jvmciRuntime.hpp
changeset 52033 d6aa9ea2405d
parent 50858 2d3e99a72541
child 53244 9807daeb47c4
--- a/src/hotspot/share/jvmci/jvmciRuntime.hpp	Fri Oct 05 18:25:15 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp	Fri Oct 05 20:03:14 2018 +0200
@@ -121,13 +121,35 @@
 
   static BasicType kindToBasicType(Handle kind, TRAPS);
 
-  // The following routines are all called from compiled JVMCI code
+  static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail);
+  static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail);
+  static void new_multi_array_common(JavaThread* thread, Klass* klass, int rank, jint* dims, bool null_on_fail);
+  static void dynamic_new_array_common(JavaThread* thread, oopDesc* element_mirror, jint length, bool null_on_fail);
+  static void dynamic_new_instance_common(JavaThread* thread, oopDesc* type_mirror, bool null_on_fail);
+
+  // The following routines are called from compiled JVMCI code
 
-  static void new_instance(JavaThread* thread, Klass* klass);
-  static void new_array(JavaThread* thread, Klass* klass, jint length);
-  static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
-  static void dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length);
-  static void dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror);
+  // When allocation fails, these stubs:
+  // 1. Exercise -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError handling and also
+  //    post a JVMTI_EVENT_RESOURCE_EXHAUSTED event if the failure is an OutOfMemroyError
+  // 2. Return NULL with a pending exception.
+  // Compiled code must ensure these stubs are not called twice for the same allocation
+  // site due to the non-repeatable side effects in the case of OOME.
+  static void new_instance(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, false); }
+  static void new_array(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, false); }
+  static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, false); }
+  static void dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, false); }
+  static void dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, false); }
+
+  // When allocation fails, these stubs return NULL and have no pending exception. Compiled code
+  // can use these stubs if a failed allocation will be retried (e.g., by deoptimizing and
+  // re-executing in the interpreter).
+  static void new_instance_or_null(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, true); }
+  static void new_array_or_null(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, true); }
+  static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, true); }
+  static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, true); }
+  static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, true); }
+
   static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupted);
   static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3);
   static jint identity_hash_code(JavaThread* thread, oopDesc* obj);