Hi folks,

I was talking to some of the HS team at JavaOne, and they encouraged
me to send some of the patches that we are working on at Google back
to Sun.  (Everyone at Google is covered under a blanket SCA, so we can
contribute back anything done by any Googler).

To get started and test the waters, and because I have never tried to
contribute to OpenJDK before, I thought I would send on a
nearly-trivial fix that I made last year in response to a user
complaint.  The issue was that when the user specifies
-XX:OnOutOfMemoryError, and the OOM is thrown because a single memory
allocation was too close to Integer.MAX_VALUE, the OnOutOfMemoryError
command would not be executed.  I've attached the patch.  Let me know
what I should do to proceed.

Thanks!

Jeremy
# HG changeset patch
# User [email protected]
# Date 1244235210 25200
# Node ID cf2fd9253952b92e24b982f83ba1bc2faf584e8b
# Parent  aa0c48844632739a1efa8ff78f24ff4017fda89f
JVMTI does not execute post_resource_exhausted when allocating arrays close to 
Integer.MAX_VALUE.

diff -r aa0c48844632 -r cf2fd9253952 
src/share/vm/gc_interface/collectedHeap.inline.hpp
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp        Thu May 14 
10:57:58 2009 -0700
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp        Fri Jun 05 
13:53:30 2009 -0700
@@ -135,28 +135,14 @@ HeapWord* CollectedHeap::common_mem_allo
   }
 
 
-  if (!gc_overhead_limit_was_exceeded) {
-    // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
-    report_java_out_of_memory("Java heap space");
-
-    if (JvmtiExport::should_post_resource_exhausted()) {
-      JvmtiExport::post_resource_exhausted(
-        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
-        "Java heap space");
-    }
-
-    THROW_OOP_0(Universe::out_of_memory_error_java_heap());
+ if (!gc_overhead_limit_was_exceeded) {
+    THROW_OOM("Java heap space",
+              JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
+              Universe::out_of_memory_error_java_heap());
   } else {
-    // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
-    report_java_out_of_memory("GC overhead limit exceeded");
-
-    if (JvmtiExport::should_post_resource_exhausted()) {
-      JvmtiExport::post_resource_exhausted(
-        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
-        "GC overhead limit exceeded");
-    }
-
-    THROW_OOP_0(Universe::out_of_memory_error_gc_overhead_limit());
+    THROW_OOM("GC overhead limit exceeded",
+              JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
+              Universe::out_of_memory_error_gc_overhead_limit());
   }
 }
 
@@ -191,16 +177,10 @@ HeapWord* CollectedHeap::common_permanen
            "Unexpected exception, will result in uninitialized storage");
     return result;
   }
-  // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
-  report_java_out_of_memory("PermGen space");
 
-  if (JvmtiExport::should_post_resource_exhausted()) {
-    JvmtiExport::post_resource_exhausted(
-        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
-        "PermGen space");
-  }
-
-  THROW_OOP_0(Universe::out_of_memory_error_perm_gen());
+  THROW_OOM("PermGen space",
+            JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR,
+            Universe::out_of_memory_error_perm_gen());
 }
 
 HeapWord* CollectedHeap::common_permanent_mem_allocate_init(size_t size, 
TRAPS) {
diff -r aa0c48844632 -r cf2fd9253952 src/share/vm/oops/arrayKlass.cpp
--- a/src/share/vm/oops/arrayKlass.cpp  Thu May 14 10:57:58 2009 -0700
+++ b/src/share/vm/oops/arrayKlass.cpp  Fri Jun 05 13:53:30 2009 -0700
@@ -140,7 +140,10 @@ objArrayOop arrayKlass::allocate_arrayAr
     THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
   }
   if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
-    THROW_OOP_0(Universe::out_of_memory_error_array_size());
+    THROW_OOM("Java heap space",
+              JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR |
+                  JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
+              Universe::out_of_memory_error_array_size());
   }
   int size = objArrayOopDesc::object_size(length);
   klassOop k = array_klass(n+dimension(), CHECK_0);
diff -r aa0c48844632 -r cf2fd9253952 src/share/vm/oops/instanceKlass.cpp
--- a/src/share/vm/oops/instanceKlass.cpp       Thu May 14 10:57:58 2009 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp       Fri Jun 05 13:53:30 2009 -0700
@@ -497,7 +497,10 @@ objArrayOop instanceKlass::allocate_objA
 objArrayOop instanceKlass::allocate_objArray(int n, int length, TRAPS) {
   if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
   if (length > arrayOopDesc::max_array_length(T_OBJECT)) {
-    THROW_OOP_0(Universe::out_of_memory_error_array_size());
+    THROW_OOM("Java heap space",
+              JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR |
+                  JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
+              Universe::out_of_memory_error_array_size());
   }
   int size = objArrayOopDesc::object_size(length);
   klassOop ak = array_klass(n, CHECK_NULL);
diff -r aa0c48844632 -r cf2fd9253952 src/share/vm/oops/objArrayKlass.cpp
--- a/src/share/vm/oops/objArrayKlass.cpp       Thu May 14 10:57:58 2009 -0700
+++ b/src/share/vm/oops/objArrayKlass.cpp       Fri Jun 05 13:53:30 2009 -0700
@@ -39,7 +39,10 @@ objArrayOop objArrayKlass::allocate(int 
       assert(a->is_parsable(), "Can't publish unless parsable");
       return a;
     } else {
-      THROW_OOP_0(Universe::out_of_memory_error_array_size());
+      THROW_OOM("Java heap space",
+                JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR |
+                    JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
+                Universe::out_of_memory_error_array_size());
     }
   } else {
     THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
diff -r aa0c48844632 -r cf2fd9253952 src/share/vm/oops/typeArrayKlass.cpp
--- a/src/share/vm/oops/typeArrayKlass.cpp      Thu May 14 10:57:58 2009 -0700
+++ b/src/share/vm/oops/typeArrayKlass.cpp      Fri Jun 05 13:53:30 2009 -0700
@@ -80,7 +80,10 @@ typeArrayOop typeArrayKlass::allocate(in
       assert(t->is_parsable(), "Don't publish unless parsable");
       return t;
     } else {
-      THROW_OOP_0(Universe::out_of_memory_error_array_size());
+      THROW_OOM("Java heap space",
+                JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR |
+                    JVMTI_RESOURCE_EXHAUSTED_JAVA_HEAP,
+                Universe::out_of_memory_error_array_size());
     }
   } else {
     THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
diff -r aa0c48844632 -r cf2fd9253952 src/share/vm/utilities/exceptions.hpp
--- a/src/share/vm/utilities/exceptions.hpp     Thu May 14 10:57:58 2009 -0700
+++ b/src/share/vm/utilities/exceptions.hpp     Fri Jun 05 13:53:30 2009 -0700
@@ -240,6 +240,15 @@ class Exceptions {
 #define THROW_NULL(name)                    THROW_(name, NULL)
 #define THROW_MSG_NULL(name, message)       THROW_MSG_(name, message, NULL)
 
+#define THROW_OOM(message, flags, exception)                    \
+  do {                                                          \
+    report_java_out_of_memory((message));                       \
+    if (JvmtiExport::should_post_resource_exhausted()) {        \
+      JvmtiExport::post_resource_exhausted((flags), (message)); \
+    }                                                           \
+    THROW_OOP_0((exception));                                   \
+  } while (0)
+
 // The CATCH macro checks that no exception has been thrown by a function; it 
is used at
 // call sites about which is statically known that the callee cannot throw an 
exception
 // even though it is declared with TRAPS.

Reply via email to