mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8000968: NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes for > 32G CompressedOops
Pick a base that works for both CompressedOpps alignment and CompressedKlassPtrs alignment. Reviewed-by: kvn, roland
This commit is contained in:
parent
6c6a537471
commit
1831def9cc
5 changed files with 154 additions and 20 deletions
|
@ -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) {
|
||||||
// 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) {
|
||||||
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() {
|
||||||
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) {
|
||||||
// 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) {
|
||||||
// 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) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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 {
|
||||||
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 {
|
||||||
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().
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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; }
|
||||||
// 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,13 +1446,18 @@ 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) {
|
||||||
// 100,000 classes seems like a good size, so 100M assumes around 1K
|
if (ClassMetaspaceSize > KlassEncodingMetaspaceMax) {
|
||||||
// per klass. The vtable and oopMap is embedded so we don't have a fixed
|
warning("Class metaspace size is too large for UseCompressedKlassPointers");
|
||||||
// size per klass. Eventually, this will be parameterized because it
|
FLAG_SET_DEFAULT(UseCompressedKlassPointers, false);
|
||||||
// would also be useful to determine the optimal size of the
|
} else if (FLAG_IS_DEFAULT(ClassMetaspaceSize)) {
|
||||||
// systemDictionary.
|
// 100,000 classes seems like a good size, so 100M assumes around 1K
|
||||||
FLAG_SET_ERGO(uintx, ClassMetaspaceSize, 100*M);
|
// 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
|
||||||
|
// would also be useful to determine the optimal size of the
|
||||||
|
// systemDictionary.
|
||||||
|
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
|
||||||
|
|
99
hotspot/test/runtime/8000968/Test8000968.sh
Normal file
99
hotspot/test/runtime/8000968/Test8000968.sh
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
#
|
||||||
|
# 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
|
Loading…
Add table
Add a link
Reference in a new issue