7102044: G1: VM crashes with assert(old_end != new_end) failed: don't call this otherwise

Mon, 31 Oct 2011 08:01:20 +0100

author
brutisso
date
Mon, 31 Oct 2011 08:01:20 +0100
changeset 3266
6fd81579526f
parent 3265
59519b7d7b9d
child 3267
ed80554efa25

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

make/jprt.properties file | annotate | diff | comparison | revisions
src/share/vm/oops/arrayOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/arrayOop.hpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/quickSort.cpp file | annotate | diff | comparison | revisions
test/Makefile file | annotate | diff | comparison | revisions
     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.

mercurial