提交 18772701 编写于 作者: H hseigel

8000968: NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes...

8000968: NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes for > 32G CompressedOops
Summary: Pick a base that works for both CompressedOpps alignment and CompressedKlassPtrs alignment.
Reviewed-by: kvn, roland
上级 0f21aafb
...@@ -144,6 +144,7 @@ NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true }; ...@@ -144,6 +144,7 @@ NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true };
NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true }; NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true };
address Universe::_narrow_ptrs_base; address Universe::_narrow_ptrs_base;
size_t Universe::_class_metaspace_size;
void Universe::basic_type_classes_do(void f(Klass*)) { void Universe::basic_type_classes_do(void f(Klass*)) {
f(boolArrayKlassObj()); f(boolArrayKlassObj());
...@@ -689,8 +690,15 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) { ...@@ -689,8 +690,15 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
// Return specified base for the first request. // Return specified base for the first request.
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) { if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
base = HeapBaseMinAddress; base = HeapBaseMinAddress;
} else if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) {
if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) && // If the total size and the metaspace size are small enough to allow
// UnscaledNarrowOop then just use UnscaledNarrowOop.
} else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) &&
(!UseCompressedKlassPointers ||
(((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) {
// We don't need to check the metaspace size here because it is always smaller
// than total_size.
if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) &&
(Universe::narrow_oop_shift() == 0)) { (Universe::narrow_oop_shift() == 0)) {
// Use 32-bits oops without encoding and // Use 32-bits oops without encoding and
// place heap's top on the 4Gb boundary // place heap's top on the 4Gb boundary
...@@ -706,14 +714,24 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) { ...@@ -706,14 +714,24 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
base = (OopEncodingHeapMax - heap_size); base = (OopEncodingHeapMax - heap_size);
} }
} }
// See if ZeroBaseNarrowOop encoding will work for a heap based at
// (KlassEncodingMetaspaceMax - class_metaspace_size()).
} else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) &&
(Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) &&
(KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) {
base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size());
} else { } else {
// Can't reserve below 32Gb. // UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or
// HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb.
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
} }
// Set narrow_oop_base and narrow_oop_use_implicit_null_checks // Set narrow_oop_base and narrow_oop_use_implicit_null_checks
// used in ReservedHeapSpace() constructors. // used in ReservedHeapSpace() constructors.
// The final values will be set in initialize_heap() below. // The final values will be set in initialize_heap() below.
if (base != 0 && (base + heap_size) <= OopEncodingHeapMax) { if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) &&
(!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) {
// Use zero based compressed oops // Use zero based compressed oops
Universe::set_narrow_oop_base(NULL); Universe::set_narrow_oop_base(NULL);
// Don't need guard page for implicit checks in indexed // Don't need guard page for implicit checks in indexed
...@@ -796,7 +814,9 @@ jint Universe::initialize_heap() { ...@@ -796,7 +814,9 @@ jint Universe::initialize_heap() {
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M); Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
} }
if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) { if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) ||
(UseCompressedKlassPointers &&
((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) {
// Can't reserve heap below 32Gb. // Can't reserve heap below 32Gb.
// keep the Universe::narrow_oop_base() set in Universe::reserve_heap() // keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
...@@ -862,8 +882,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { ...@@ -862,8 +882,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
// be compressed the same as instances. // be compressed the same as instances.
// Need to round class space size up because it's below the heap and // Need to round class space size up because it's below the heap and
// the actual alignment depends on its size. // the actual alignment depends on its size.
size_t metaspace_size = align_size_up(ClassMetaspaceSize, alignment); Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
size_t total_reserved = align_size_up(heap_size + metaspace_size, alignment); size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr); ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);
...@@ -904,8 +924,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { ...@@ -904,8 +924,8 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
// compressed oops is greater than the one used for compressed klass // compressed oops is greater than the one used for compressed klass
// ptrs, a metadata space on top of the heap could become // ptrs, a metadata space on top of the heap could become
// unreachable. // unreachable.
ReservedSpace class_rs = total_rs.first_part(metaspace_size); ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size());
ReservedSpace heap_rs = total_rs.last_part(metaspace_size, alignment); ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment);
Metaspace::initialize_class_space(class_rs); Metaspace::initialize_class_space(class_rs);
if (UseCompressedOops) { if (UseCompressedOops) {
......
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -211,6 +211,9 @@ class Universe: AllStatic { ...@@ -211,6 +211,9 @@ class Universe: AllStatic {
static struct NarrowPtrStruct _narrow_klass; static struct NarrowPtrStruct _narrow_klass;
static address _narrow_ptrs_base; static address _narrow_ptrs_base;
// Aligned size of the metaspace.
static size_t _class_metaspace_size;
// array of dummy objects used with +FullGCAlot // array of dummy objects used with +FullGCAlot
debug_only(static objArrayOop _fullgc_alot_dummy_array;) debug_only(static objArrayOop _fullgc_alot_dummy_array;)
// index of next entry to clear // index of next entry to clear
...@@ -278,6 +281,13 @@ class Universe: AllStatic { ...@@ -278,6 +281,13 @@ class Universe: AllStatic {
static bool reserve_metaspace_helper(bool with_base = false); static bool reserve_metaspace_helper(bool with_base = false);
static ReservedHeapSpace reserve_heap_metaspace(size_t heap_size, size_t alignment, bool& contiguous); static ReservedHeapSpace reserve_heap_metaspace(size_t heap_size, size_t alignment, bool& contiguous);
static size_t class_metaspace_size() {
return _class_metaspace_size;
}
static void set_class_metaspace_size(size_t metaspace_size) {
_class_metaspace_size = metaspace_size;
}
// Debugging // Debugging
static int _verify_count; // number of verifies done static int _verify_count; // number of verifies done
// True during call to verify(). Should only be set/cleared in verify(). // True during call to verify(). Should only be set/cleared in verify().
......
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -227,12 +227,12 @@ inline oop oopDesc::decode_heap_oop(oop v) { return v; } ...@@ -227,12 +227,12 @@ inline oop oopDesc::decode_heap_oop(oop v) { return v; }
// might not be the same as oop. // might not be the same as oop.
inline narrowOop oopDesc::encode_klass_not_null(Klass* v) { inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
assert(!is_null(v), "oop value can never be zero"); assert(!is_null(v), "klass value can never be zero");
assert(check_klass_alignment(v), "Address not aligned"); assert(check_klass_alignment(v), "Address not aligned");
address base = Universe::narrow_klass_base(); address base = Universe::narrow_klass_base();
int shift = Universe::narrow_klass_shift(); int shift = Universe::narrow_klass_shift();
uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1)); uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
assert(OopEncodingHeapMax > pd, "change encoding max if new encoding"); assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
uint64_t result = pd >> shift; uint64_t result = pd >> shift;
assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow"); assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
assert(decode_klass(result) == v, "reversibility"); assert(decode_klass(result) == v, "reversibility");
......
...@@ -1446,7 +1446,11 @@ void Arguments::set_ergonomics_flags() { ...@@ -1446,7 +1446,11 @@ void Arguments::set_ergonomics_flags() {
} }
// Set the ClassMetaspaceSize to something that will not need to be // Set the ClassMetaspaceSize to something that will not need to be
// expanded, since it cannot be expanded. // expanded, since it cannot be expanded.
if (UseCompressedKlassPointers && FLAG_IS_DEFAULT(ClassMetaspaceSize)) { if (UseCompressedKlassPointers) {
if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
warning("Class metaspace size is too large for UseCompressedKlassPointers");
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
} else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
// 100,000 classes seems like a good size, so 100M assumes around 1K // 100,000 classes seems like a good size, so 100M assumes around 1K
// per klass. The vtable and oopMap is embedded so we don't have a fixed // per klass. The vtable and oopMap is embedded so we don't have a fixed
// size per klass. Eventually, this will be parameterized because it // size per klass. Eventually, this will be parameterized because it
...@@ -1455,6 +1459,7 @@ void Arguments::set_ergonomics_flags() { ...@@ -1455,6 +1459,7 @@ void Arguments::set_ergonomics_flags() {
FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M); FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
} }
} }
}
// Also checks that certain machines are slower with compressed oops // Also checks that certain machines are slower with compressed oops
// in vm_version initialization code. // in vm_version initialization code.
#endif // _LP64 #endif // _LP64
......
#
# Copyright (c) 2013, 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
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# @test Test8000968.sh
# @bug 8000968
# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
# @run shell Test8000968.sh
#
if [ "${TESTJAVA}" = "" ]
then
PARENT=`dirname \`which java\``
TESTJAVA=`dirname ${PARENT}`
printf "TESTJAVA not set, selecting " ${TESTJAVA}
printf " If this is incorrect, try setting the variable manually.\n"
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Windows_* )
FS="\\"
NULL=NUL
;;
* )
FS="/"
NULL=/dev/null
;;
esac
JAVA=${TESTJAVA}${FS}bin${FS}java
#
# See if platform has 64 bit java.
#
${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL}
if [ "$?" != "1" ]
then
printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n"
printf "Passed.\n"
exit 0
fi
#
# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops.
#
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n"
exit 1
fi
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n"
exit 1
fi
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n"
exit 1
fi
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n"
exit 1
fi
printf "Passed.\n"
exit 0
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册