comparison src/share/vm/oops/arrayOop.hpp @ 2908: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
comparison
equal deleted inserted replaced
10:f626643895e1 11:560c922c1bec
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 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. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
102 : typesize_in_bytes/HeapWordSize); 102 : typesize_in_bytes/HeapWordSize);
103 } 103 }
104 104
105 // Return the maximum length of an array of BasicType. The length can passed 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 106 // to typeArrayOop::object_size(scale, length, header_size) without causing an
107 // overflow. 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.
108 static int32_t max_array_length(BasicType type) { 109 static int32_t max_array_length(BasicType type) {
109 assert(type >= 0 && type < T_CONFLICT, "wrong type"); 110 assert(type >= 0 && type < T_CONFLICT, "wrong type");
110 assert(type2aelembytes(type) != 0, "wrong type"); 111 assert(type2aelembytes(type) != 0, "wrong type");
111 const int bytes_per_element = type2aelembytes(type); 112
112 if (bytes_per_element < HeapWordSize) { 113 const size_t max_element_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_element_words_per_size_t / type2aelembytes(type);
115 if ((size_t)max_jint < max_elements_per_size_t) {
113 return max_jint; 116 return max_jint;
114 } 117 }
118 return (int32_t)max_elements_per_size_t;
119 }
115 120
116 const int32_t max_words = align_size_down(max_jint, MinObjAlignment); 121 // for unit testing
117 const int32_t max_element_words = max_words - header_size(type); 122 #ifndef PRODUCT
118 const int32_t words_per_element = bytes_per_element >> LogHeapWordSize; 123 static bool check_max_length_overflow(BasicType type);
119 return max_element_words / words_per_element; 124 static int32_t old_max_array_length(BasicType type);
120 } 125 static bool test_max_array_length();
126 #endif
121 }; 127 };
122 128
123 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP 129 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP