diff src/share/vm/oops/arrayOop.hpp @ 4070:6fd81579526f

7102044: G1: VM crashes with assert(old_end != new_end) failed: don't call this otherwise Summary: arrayOopDesc::max_array_length() should return a value that does not overflow a size_t if it is converted to bytes. Reviewed-by: kvn, dholmes
author brutisso
date Mon, 31 Oct 2011 08:01:20 +0100
parents f95d63e2154a
children aa4c21b00f7f
line wrap: on
line diff
--- a/src/share/vm/oops/arrayOop.hpp	Fri Oct 28 13:04:10 2011 -0400
+++ b/src/share/vm/oops/arrayOop.hpp	Mon Oct 31 08:01:20 2011 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,20 +104,26 @@
 
   // Return the maximum length of an array of BasicType.  The length can passed
   // to typeArrayOop::object_size(scale, length, header_size) without causing an
-  // overflow.
+  // overflow. We also need to make sure that this will not overflow a size_t on
+  // 32 bit platforms when we convert it to a byte size.
   static int32_t max_array_length(BasicType type) {
     assert(type >= 0 && type < T_CONFLICT, "wrong type");
     assert(type2aelembytes(type) != 0, "wrong type");
-    const int bytes_per_element = type2aelembytes(type);
-    if (bytes_per_element < HeapWordSize) {
+
+    const size_t max_element_words_per_size_t  = align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
+    const size_t max_elements_per_size_t = HeapWordSize * max_element_words_per_size_t  / type2aelembytes(type);
+    if ((size_t)max_jint < max_elements_per_size_t) {
       return max_jint;
     }
+    return (int32_t)max_elements_per_size_t;
+  }
 
-    const int32_t max_words = align_size_down(max_jint, MinObjAlignment);
-    const int32_t max_element_words = max_words - header_size(type);
-    const int32_t words_per_element = bytes_per_element >> LogHeapWordSize;
-    return max_element_words / words_per_element;
-  }
+// for unit testing
+#ifndef PRODUCT
+  static bool check_max_length_overflow(BasicType type);
+  static int32_t old_max_array_length(BasicType type);
+  static bool test_max_array_length();
+#endif
 };
 
 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP