src/share/vm/oops/arrayOop.hpp

Print this page
rev 2779 : 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: stefank, kvn
   1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  87   int length() const {
  88     return *(int*)(((intptr_t)this) + length_offset_in_bytes());
  89   }
  90   void set_length(int length) {
  91     *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length;
  92   }
  93 
  94   // Should only be called with constants as argument
  95   // (will not constant fold otherwise)
  96   // Returns the header size in words aligned to the requirements of the
  97   // array object type.
  98   static int header_size(BasicType type) {
  99     size_t typesize_in_bytes = header_size_in_bytes();
 100     return (int)(Universe::element_type_should_be_aligned(type)
 101       ? align_object_offset(typesize_in_bytes/HeapWordSize)
 102       : typesize_in_bytes/HeapWordSize);
 103   }
 104 
 105   // Return the maximum length of an array of BasicType.  The length can passed
 106   // to typeArrayOop::object_size(scale, length, header_size) without causing an
 107   // overflow.

 108   static int32_t max_array_length(BasicType type) {
 109     assert(type >= 0 && type < T_CONFLICT, "wrong type");
 110     assert(type2aelembytes(type) != 0, "wrong type");
 111     const int bytes_per_element = type2aelembytes(type);
 112     if (bytes_per_element < HeapWordSize) {


 113       return max_jint;
 114     }
 115 
 116     const int32_t max_words = align_size_down(max_jint, MinObjAlignment);
 117     const int32_t max_element_words = max_words - header_size(type);
 118     const int32_t words_per_element = bytes_per_element >> LogHeapWordSize;
 119     return max_element_words / words_per_element;
 120   }







 121 };
 122 
 123 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP
   1 /*
   2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  87   int length() const {
  88     return *(int*)(((intptr_t)this) + length_offset_in_bytes());
  89   }
  90   void set_length(int length) {
  91     *(int*)(((intptr_t)this) + length_offset_in_bytes()) = length;
  92   }
  93 
  94   // Should only be called with constants as argument
  95   // (will not constant fold otherwise)
  96   // Returns the header size in words aligned to the requirements of the
  97   // array object type.
  98   static int header_size(BasicType type) {
  99     size_t typesize_in_bytes = header_size_in_bytes();
 100     return (int)(Universe::element_type_should_be_aligned(type)
 101       ? align_object_offset(typesize_in_bytes/HeapWordSize)
 102       : typesize_in_bytes/HeapWordSize);
 103   }
 104 
 105   // Return the maximum length of an array of BasicType.  The length can passed
 106   // to typeArrayOop::object_size(scale, length, header_size) without causing an
 107   // overflow. We also need to make sure that this will not overflow a size_t on
 108   // 32 bit platforms when we convert it to a byte size.
 109   static int32_t max_array_length(BasicType type) {
 110     assert(type >= 0 && type < T_CONFLICT, "wrong type");
 111     assert(type2aelembytes(type) != 0, "wrong type");
 112 
 113     const size_t max_words_per_size_t = align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
 114     const size_t max_elements_per_size_t = HeapWordSize * max_words_per_size_t / type2aelembytes(type);
 115     if ((size_t)max_jint < max_elements_per_size_t) {
 116       return max_jint;
 117     }
 118     return (int32_t)max_elements_per_size_t;




 119   }
 120   
 121 // for unit testing
 122 #ifndef PRODUCT
 123   static bool check_max_length_overflow(BasicType type);
 124   static int32_t old_max_array_length(BasicType type);
 125   static bool test_max_array_length();
 126 #endif
 127 };
 128 
 129 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP