Mon, 31 Oct 2011 08:01:20 +0100
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
1.1 --- a/make/jprt.properties Fri Oct 28 13:04:10 2011 -0400 1.2 +++ b/make/jprt.properties Mon Oct 31 08:01:20 2011 +0100 1.3 @@ -541,9 +541,20 @@ 1.4 ${jprt.my.windows.i586}-*-c2-servertest, \ 1.5 ${jprt.my.windows.x64}-*-c2-servertest 1.6 1.7 +jprt.make.rule.test.targets.standard.internalvmtests = \ 1.8 + ${jprt.my.solaris.sparc}-fastdebug-c2-internalvmtests, \ 1.9 + ${jprt.my.solaris.sparcv9}-fastdebug-c2-internalvmtests, \ 1.10 + ${jprt.my.solaris.i586}-fastdebug-c2-internalvmtests, \ 1.11 + ${jprt.my.solaris.x64}-fastdebug-c2-internalvmtests, \ 1.12 + ${jprt.my.linux.i586}-fastdebug-c2-internalvmtests, \ 1.13 + ${jprt.my.linux.x64}-fastdebug-c2-internalvmtests, \ 1.14 + ${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \ 1.15 + ${jprt.my.windows.x64}-fastdebug-c2-internalvmtests 1.16 + 1.17 jprt.make.rule.test.targets.standard = \ 1.18 ${jprt.make.rule.test.targets.standard.client}, \ 1.19 - ${jprt.make.rule.test.targets.standard.server} 1.20 + ${jprt.make.rule.test.targets.standard.server}, \ 1.21 + ${jprt.make.rule.test.targets.standard.internalvmtests} 1.22 1.23 jprt.make.rule.test.targets.embedded = \ 1.24 ${jprt.make.rule.test.targets.standard.client}
2.1 --- a/src/share/vm/oops/arrayOop.cpp Fri Oct 28 13:04:10 2011 -0400 2.2 +++ b/src/share/vm/oops/arrayOop.cpp Mon Oct 31 08:01:20 2011 +0100 2.3 @@ -23,9 +23,40 @@ 2.4 */ 2.5 2.6 #include "precompiled.hpp" 2.7 + 2.8 +/////////////// Unit tests /////////////// 2.9 + 2.10 +#ifndef PRODUCT 2.11 + 2.12 #include "oops/arrayOop.hpp" 2.13 -#include "oops/objArrayOop.hpp" 2.14 -#include "oops/oop.inline.hpp" 2.15 -#include "oops/symbol.hpp" 2.16 +#include "utilities/globalDefinitions.hpp" 2.17 2.18 -// <<this page is intentionally left blank>> 2.19 +bool arrayOopDesc::check_max_length_overflow(BasicType type) { 2.20 + julong length = max_array_length(type); 2.21 + julong bytes_per_element = type2aelembytes(type); 2.22 + julong bytes = length * bytes_per_element + header_size_in_bytes(); 2.23 + return (julong)(size_t)bytes == bytes; 2.24 +} 2.25 + 2.26 +bool arrayOopDesc::test_max_array_length() { 2.27 + tty->print_cr("test_max_array_length"); 2.28 + 2.29 + assert(check_max_length_overflow(T_BOOLEAN), "size_t overflow for boolean array"); 2.30 + assert(check_max_length_overflow(T_CHAR), "size_t overflow for char array"); 2.31 + assert(check_max_length_overflow(T_FLOAT), "size_t overflow for float array"); 2.32 + assert(check_max_length_overflow(T_DOUBLE), "size_t overflow for double array"); 2.33 + assert(check_max_length_overflow(T_BYTE), "size_t overflow for byte array"); 2.34 + assert(check_max_length_overflow(T_SHORT), "size_t overflow for short array"); 2.35 + assert(check_max_length_overflow(T_INT), "size_t overflow for int array"); 2.36 + assert(check_max_length_overflow(T_LONG), "size_t overflow for long array"); 2.37 + assert(check_max_length_overflow(T_OBJECT), "size_t overflow for object array"); 2.38 + assert(check_max_length_overflow(T_ARRAY), "size_t overflow for array array"); 2.39 + assert(check_max_length_overflow(T_NARROWOOP), "size_t overflow for narrowOop array"); 2.40 + 2.41 + // T_VOID and T_ADDRESS are not supported by max_array_length() 2.42 + 2.43 + return true; 2.44 +} 2.45 + 2.46 + 2.47 +#endif //PRODUCT
3.1 --- a/src/share/vm/oops/arrayOop.hpp Fri Oct 28 13:04:10 2011 -0400 3.2 +++ b/src/share/vm/oops/arrayOop.hpp Mon Oct 31 08:01:20 2011 +0100 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -104,20 +104,26 @@ 3.11 3.12 // Return the maximum length of an array of BasicType. The length can passed 3.13 // to typeArrayOop::object_size(scale, length, header_size) without causing an 3.14 - // overflow. 3.15 + // overflow. We also need to make sure that this will not overflow a size_t on 3.16 + // 32 bit platforms when we convert it to a byte size. 3.17 static int32_t max_array_length(BasicType type) { 3.18 assert(type >= 0 && type < T_CONFLICT, "wrong type"); 3.19 assert(type2aelembytes(type) != 0, "wrong type"); 3.20 - const int bytes_per_element = type2aelembytes(type); 3.21 - if (bytes_per_element < HeapWordSize) { 3.22 + 3.23 + const size_t max_element_words_per_size_t = align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment); 3.24 + const size_t max_elements_per_size_t = HeapWordSize * max_element_words_per_size_t / type2aelembytes(type); 3.25 + if ((size_t)max_jint < max_elements_per_size_t) { 3.26 return max_jint; 3.27 } 3.28 + return (int32_t)max_elements_per_size_t; 3.29 + } 3.30 3.31 - const int32_t max_words = align_size_down(max_jint, MinObjAlignment); 3.32 - const int32_t max_element_words = max_words - header_size(type); 3.33 - const int32_t words_per_element = bytes_per_element >> LogHeapWordSize; 3.34 - return max_element_words / words_per_element; 3.35 - } 3.36 +// for unit testing 3.37 +#ifndef PRODUCT 3.38 + static bool check_max_length_overflow(BasicType type); 3.39 + static int32_t old_max_array_length(BasicType type); 3.40 + static bool test_max_array_length(); 3.41 +#endif 3.42 }; 3.43 3.44 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP
4.1 --- a/src/share/vm/prims/jni.cpp Fri Oct 28 13:04:10 2011 -0400 4.2 +++ b/src/share/vm/prims/jni.cpp Mon Oct 31 08:01:20 2011 +0100 4.3 @@ -5042,7 +5042,8 @@ 4.4 void execute_internal_vm_tests() { 4.5 if (ExecuteInternalVMTests) { 4.6 assert(QuickSort::test_quick_sort(), "test_quick_sort failed"); 4.7 - tty->print_cr("All tests passed"); 4.8 + assert(arrayOopDesc::test_max_array_length(), "test_max_array_length failed"); 4.9 + tty->print_cr("All internal VM tests passed"); 4.10 } 4.11 } 4.12
5.1 --- a/src/share/vm/utilities/quickSort.cpp Fri Oct 28 13:04:10 2011 -0400 5.2 +++ b/src/share/vm/utilities/quickSort.cpp Mon Oct 31 08:01:20 2011 +0100 5.3 @@ -23,13 +23,13 @@ 5.4 */ 5.5 5.6 #include "precompiled.hpp" 5.7 -#include "utilities/quickSort.hpp" 5.8 + 5.9 +/////////////// Unit tests /////////////// 5.10 5.11 #ifndef PRODUCT 5.12 5.13 -// Unit tests 5.14 - 5.15 #include "runtime/os.hpp" 5.16 +#include "utilities/quickSort.hpp" 5.17 #include <stdlib.h> 5.18 5.19 static int test_comparator(int a, int b) { 5.20 @@ -94,7 +94,7 @@ 5.21 } 5.22 5.23 bool QuickSort::test_quick_sort() { 5.24 - tty->print_cr("test_quick_sort\n"); 5.25 + tty->print_cr("test_quick_sort"); 5.26 { 5.27 int* test_array = NULL; 5.28 int* expected_array = NULL;
6.1 --- a/test/Makefile Fri Oct 28 13:04:10 2011 -0400 6.2 +++ b/test/Makefile Mon Oct 31 08:01:20 2011 +0100 6.3 @@ -1,5 +1,5 @@ 6.4 # 6.5 -# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. 6.6 +# Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. 6.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 # 6.9 # This code is free software; you can redistribute it and/or modify it 6.10 @@ -219,6 +219,15 @@ 6.11 6.12 ################################################################ 6.13 6.14 +# internalvmtests (run internal unit tests inside the VM) 6.15 + 6.16 +internalvmtests: prep $(PRODUCT_HOME) 6.17 + $(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -XX:+ExecuteInternalVMTests -version 6.18 + 6.19 +PHONY_LIST += internalvmtests 6.20 + 6.21 +################################################################ 6.22 + 6.23 # packtest 6.24 6.25 # Expect JPRT to set JPRT_PACKTEST_HOME.