mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
Merge
This commit is contained in:
commit
80b2573b1c
875 changed files with 31883 additions and 13163 deletions
1
.hgtags
1
.hgtags
|
@ -228,3 +228,4 @@ bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102
|
|||
b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104
|
||||
589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105
|
||||
514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106
|
||||
892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107
|
||||
|
|
|
@ -228,3 +228,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
|
|||
96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
|
||||
5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105
|
||||
8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106
|
||||
0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107
|
||||
|
|
12
Makefile
12
Makefile
|
@ -404,7 +404,6 @@ COMPILER_PATH.desc = Compiler install directory
|
|||
CACERTS_FILE.desc = Location of certificates file
|
||||
DEVTOOLS_PATH.desc = Directory containing zip and gnumake
|
||||
CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files
|
||||
DXSDK_PATH.desc = Root directory of DirectX SDK
|
||||
|
||||
# Make variables to print out (description and value)
|
||||
VARIABLE_PRINTVAL_LIST += \
|
||||
|
@ -429,17 +428,6 @@ VARIABLE_CHECKDIR_LIST += \
|
|||
VARIABLE_CHECKFIL_LIST += \
|
||||
CACERTS_FILE
|
||||
|
||||
# Some are windows specific
|
||||
ifeq ($(PLATFORM), windows)
|
||||
|
||||
VARIABLE_PRINTVAL_LIST += \
|
||||
DXSDK_PATH
|
||||
|
||||
VARIABLE_CHECKDIR_LIST += \
|
||||
DXSDK_PATH
|
||||
|
||||
endif
|
||||
|
||||
# For pattern rules below, so all are treated the same
|
||||
DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval)
|
||||
DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir)
|
||||
|
|
|
@ -444,10 +444,6 @@
|
|||
Install
|
||||
<a href="#vs2010">Visual Studio 2010</a>
|
||||
</li>
|
||||
<li>
|
||||
Install the
|
||||
<a href="#dxsdk">Microsoft DirectX SDK</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
|
@ -971,25 +967,6 @@
|
|||
developer install location
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b><code>--with-dxsdk=</code></b><i>path</i></td>
|
||||
<td>
|
||||
select location of the Windows Direct X SDK install
|
||||
<br>
|
||||
The <a name="dxsdk">Microsoft DirectX 9.0 SDK</a>
|
||||
header files and libraries
|
||||
from the Summer 2004 edition
|
||||
are required for building OpenJDK.
|
||||
This SDK can be downloaded from
|
||||
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FD044A42-9912-42A3-9A9E-D857199F888E&displaylang=en" target="_blank">
|
||||
Microsoft DirectX 9.0 SDK (Summer 2004)</a>.
|
||||
If the link above becomes obsolete, the SDK can be found from
|
||||
<a href="http://download.microsoft.com" target="_blank">the Microsoft Download Site</a>
|
||||
(search with "DirectX 9.0 SDK Update Summer 2004").
|
||||
Installation usually will set the environment variable
|
||||
<code>DXSDK_DIR</code> to it's install location.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b><code>--with-freetype=</code></b><i>path</i></td>
|
||||
<td>
|
||||
|
|
|
@ -203,6 +203,15 @@ AC_DEFUN([BASIC_REMOVE_SYMBOLIC_LINKS],
|
|||
fi
|
||||
])
|
||||
|
||||
# Register a --with argument but mark it as deprecated
|
||||
# $1: The name of the with argument to deprecate, not including --with-
|
||||
AC_DEFUN([BASIC_DEPRECATED_ARG_WITH],
|
||||
[
|
||||
AC_ARG_WITH($1, [AS_HELP_STRING([--with-$1],
|
||||
[Deprecated. Option is kept for backwards compatibility and is ignored])],
|
||||
[AC_MSG_WARN([Option --with-$1 is deprecated and will be ignored.])])
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([BASIC_INIT],
|
||||
[
|
||||
# Save the original command line. This is passed to us by the wrapper configure script.
|
||||
|
|
|
@ -211,7 +211,7 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN],
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2008-01-23'
|
||||
timestamp='2012-02-10'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
@ -42,9 +42,7 @@ timestamp='2008-01-23'
|
|||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
|
@ -52,16 +50,16 @@ timestamp='2008-01-23'
|
|||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Originally written by Per Bothner <per@bothner.com>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
# Originally written by Per Bothner. Please send patches (context
|
||||
# diff format) to <config-patches@gnu.org> and include a ChangeLog
|
||||
# entry.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
#
|
||||
# The plan is that this can be called by configure scripts if you
|
||||
# don't specify an explicit build system type.
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
|
@ -81,8 +79,9 @@ version="\
|
|||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
@ -169,7 +168,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
|||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
|
@ -195,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep __ELF__ >/dev/null
|
||||
| grep -q __ELF__
|
||||
then
|
||||
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
||||
# Return netbsd for either. FIX?
|
||||
|
@ -294,7 +293,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
exit ;;
|
||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
||||
exitcode=$?
|
||||
trap '' 0
|
||||
exit $exitcode ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# Should we change UNAME_MACHINE based on the output of uname instead
|
||||
|
@ -349,14 +351,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7; exit ;;
|
||||
esac ;;
|
||||
s390x:SunOS:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
|
||||
echo i386-pc-auroraux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
eval $set_cc_for_build
|
||||
SUN_ARCH="i386"
|
||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
SUN_ARCH="x86_64"
|
||||
fi
|
||||
fi
|
||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
|
@ -557,7 +578,7 @@ EOF
|
|||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[456])
|
||||
*:AIX:*:[4567])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
|
@ -665,7 +686,7 @@ EOF
|
|||
# => hppa64-hp-hpux11.23
|
||||
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||
grep __LP64__ >/dev/null
|
||||
grep -q __LP64__
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
else
|
||||
|
@ -794,13 +815,12 @@ EOF
|
|||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:FreeBSD:*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
pc98)
|
||||
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
case ${UNAME_PROCESSOR} in
|
||||
amd64)
|
||||
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
esac
|
||||
exit ;;
|
||||
i*:CYGWIN*:*)
|
||||
|
@ -809,6 +829,9 @@ EOF
|
|||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:MSYS*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msys
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
|
@ -816,12 +839,12 @@ EOF
|
|||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
*:Interix*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
authenticamd | genuineintel | EM64T)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
|
@ -831,6 +854,9 @@ EOF
|
|||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
8664:Windows_NT:*)
|
||||
echo x86_64-pc-mks
|
||||
exit ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
|
@ -860,92 +886,13 @@ EOF
|
|||
i*86:Minix:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
aarch64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo cris-axis-linux-gnu
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo crisv32-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo frv-unknown-linux-gnu
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
aarch64_be:Linux:*:*)
|
||||
UNAME_MACHINE=aarch64_be
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
mips:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips
|
||||
#undef mipsel
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mipsel
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips64
|
||||
#undef mips64el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mips64el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips64
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo or32-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
alpha:Linux:*:*)
|
||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||
EV5) UNAME_MACHINE=alphaev5 ;;
|
||||
|
@ -956,10 +903,89 @@ EOF
|
|||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_PCS_VFP
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
|
||||
fi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
hexagon:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
LIBC=gnu
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
mips:Linux:*:* | mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef ${UNAME_MACHINE}
|
||||
#undef ${UNAME_MACHINE}el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=${UNAME_MACHINE}el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=${UNAME_MACHINE}
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
padre:Linux:*:*)
|
||||
echo sparc-unknown-linux-gnu
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
exit ;;
|
||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||
# Look for CPU level
|
||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||
|
@ -968,8 +994,11 @@ EOF
|
|||
*) echo hppa-unknown-linux-gnu ;;
|
||||
esac
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
|
@ -983,78 +1012,18 @@ EOF
|
|||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
tile*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
vax:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||||
exit ;;
|
||||
x86_64:Linux:*:*)
|
||||
echo x86_64-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||
| sed -ne '/supported targets:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported targets: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_targets" in
|
||||
elf32-i386)
|
||||
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit ;;
|
||||
"")
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||
# one that does not give us useful --help.
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
|
||||
exit ;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
#else
|
||||
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=gnuaout
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^LIBC/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${LIBC}" != x && {
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit
|
||||
}
|
||||
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
|
||||
;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||
# earlier versions are messed up and put the nodename in both
|
||||
|
@ -1083,7 +1052,7 @@ EOF
|
|||
i*86:syllable:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-syllable
|
||||
exit ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i*86:*DOS:*:*)
|
||||
|
@ -1127,8 +1096,11 @@ EOF
|
|||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
|
@ -1166,6 +1138,16 @@ EOF
|
|||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
||||
OS_REL='.3'
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
|
@ -1178,7 +1160,7 @@ EOF
|
|||
rs6000:LynxOS:2.*:*)
|
||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
|
||||
echo powerpc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
|
@ -1241,6 +1223,9 @@ EOF
|
|||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||
echo i586-pc-beos
|
||||
exit ;;
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
|
@ -1267,12 +1252,17 @@ EOF
|
|||
exit ;;
|
||||
*:Darwin:*:*)
|
||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||
eval $set_cc_for_build
|
||||
echo "int main(){}" > $dummy.c
|
||||
if test "`$CC_FOR_BUILD -o $dummy $dummy.c; file $dummy | grep -c x86_64`" = 1 ; then
|
||||
UNAME_PROCESSOR=x86_64
|
||||
fi
|
||||
case $UNAME_PROCESSOR in
|
||||
i386)
|
||||
eval $set_cc_for_build
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
UNAME_PROCESSOR="x86_64"
|
||||
fi
|
||||
fi ;;
|
||||
unknown) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
|
@ -1288,6 +1278,9 @@ EOF
|
|||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit ;;
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-?:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
|
@ -1354,6 +1347,12 @@ EOF
|
|||
i*86:rdos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-rdos
|
||||
exit ;;
|
||||
i*86:AROS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-aros
|
||||
exit ;;
|
||||
x86_64:VMkernel:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-esx
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
|
|
5
common/autoconf/configure
vendored
5
common/autoconf/configure
vendored
|
@ -219,9 +219,4 @@ else
|
|||
echo configure exiting with result code $conf_result_code
|
||||
fi
|
||||
|
||||
# Move the log file to the output root, if this was successfully created
|
||||
if test -d "$OUTPUT_ROOT"; then
|
||||
mv -f config.log "$OUTPUT_ROOT" 2> /dev/null
|
||||
fi
|
||||
|
||||
exit $conf_result_code
|
||||
|
|
|
@ -232,9 +232,15 @@ CUSTOM_LATE_HOOK
|
|||
# We're messing a bit with internal autoconf variables to put the config.status
|
||||
# in the output directory instead of the current directory.
|
||||
CONFIG_STATUS="$OUTPUT_ROOT/config.status"
|
||||
|
||||
# Create the actual output files. Now the main work of configure is done.
|
||||
AC_OUTPUT
|
||||
|
||||
# Try to move the config.log file to the output directory.
|
||||
if test -e ./config.log; then
|
||||
$MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null
|
||||
fi
|
||||
|
||||
# Make the compare script executable
|
||||
$CHMOD +x $OUTPUT_ROOT/compare.sh
|
||||
|
||||
|
|
|
@ -709,7 +709,6 @@ STATIC_LIBRARY
|
|||
SHARED_LIBRARY
|
||||
OBJ_SUFFIX
|
||||
COMPILER_NAME
|
||||
TARGET_BITS_FLAG
|
||||
JT_HOME
|
||||
JTREGEXE
|
||||
LIPO
|
||||
|
@ -766,8 +765,6 @@ BUILD_LD
|
|||
BUILD_CXX
|
||||
BUILD_CC
|
||||
MSVCR_DLL
|
||||
DXSDK_INCLUDE_PATH
|
||||
DXSDK_LIB_PATH
|
||||
VS_PATH
|
||||
VS_LIB
|
||||
VS_INCLUDE
|
||||
|
@ -1031,6 +1028,7 @@ with_override_corba
|
|||
with_override_jaxp
|
||||
with_override_jaxws
|
||||
with_override_hotspot
|
||||
with_override_nashorn
|
||||
with_override_jdk
|
||||
with_import_hotspot
|
||||
with_msvcr_dll
|
||||
|
@ -1784,17 +1782,19 @@ Optional Packages:
|
|||
--with-override-jaxp use this jaxp dir for the build
|
||||
--with-override-jaxws use this jaxws dir for the build
|
||||
--with-override-hotspot use this hotspot dir for the build
|
||||
--with-override-nashorn use this nashorn dir for the build
|
||||
--with-override-jdk use this jdk dir for the build
|
||||
--with-import-hotspot import hotspot binaries from this jdk image or
|
||||
hotspot build dist dir instead of building from
|
||||
source
|
||||
--with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows
|
||||
only) [probed]
|
||||
--with-dxsdk the DirectX SDK (Windows only) [probed]
|
||||
--with-dxsdk-lib the DirectX SDK lib directory (Windows only)
|
||||
[probed]
|
||||
--with-dxsdk-include the DirectX SDK include directory (Windows only)
|
||||
[probed]
|
||||
--with-dxsdk Deprecated. Option is kept for backwards
|
||||
compatibility and is ignored
|
||||
--with-dxsdk-lib Deprecated. Option is kept for backwards
|
||||
compatibility and is ignored
|
||||
--with-dxsdk-include Deprecated. Option is kept for backwards
|
||||
compatibility and is ignored
|
||||
--with-jtreg Regression Test Harness [probed]
|
||||
--with-extra-cflags extra flags to be used when compiling jdk c-files
|
||||
--with-extra-cxxflags extra flags to be used when compiling jdk c++-files
|
||||
|
@ -3144,6 +3144,10 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
|
|||
|
||||
|
||||
|
||||
# Register a --with argument but mark it as deprecated
|
||||
# $1: The name of the with argument to deprecate, not including --with-
|
||||
|
||||
|
||||
|
||||
|
||||
# Test that variable $1 denoting a program is not empty. If empty, exit with an error.
|
||||
|
@ -3805,10 +3809,6 @@ fi
|
|||
|
||||
|
||||
|
||||
# Setup the DXSDK paths
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3818,7 +3818,7 @@ fi
|
|||
#CUSTOM_AUTOCONF_INCLUDE
|
||||
|
||||
# Do not change or remove the following line, it is needed for consistency checks:
|
||||
DATE_WHEN_GENERATED=1378914658
|
||||
DATE_WHEN_GENERATED=1379504921
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
|
@ -8352,7 +8352,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -8709,7 +8709,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -9063,7 +9063,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -9422,7 +9422,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -9775,7 +9775,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -11075,7 +11075,7 @@ elif test "x$with_user_release_suffix" != x; then
|
|||
else
|
||||
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
|
||||
# Avoid [:alnum:] since it depends on the locale.
|
||||
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'`
|
||||
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
|
||||
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
fi
|
||||
|
||||
|
@ -16102,6 +16102,10 @@ if test "x$with_add_source_root" != x; then
|
|||
test -f $with_add_source_root/hotspot/make/Makefile; then
|
||||
as_fn_error $? "Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources." "$LINENO" 5
|
||||
fi
|
||||
if test -f $with_add_source_root/nashorn/makefiles/Makefile || \
|
||||
test -f $with_add_source_root/nashorn/make/Makefile; then
|
||||
as_fn_error $? "Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources." "$LINENO" 5
|
||||
fi
|
||||
if test -f $with_add_source_root/jdk/makefiles/Makefile || \
|
||||
test -f $with_add_source_root/jdk/make/Makefile; then
|
||||
as_fn_error $? "Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources." "$LINENO" 5
|
||||
|
@ -16137,6 +16141,10 @@ if test "x$with_override_source_root" != x; then
|
|||
test -f $with_override_source_root/hotspot/make/Makefile; then
|
||||
as_fn_error $? "Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override." "$LINENO" 5
|
||||
fi
|
||||
if test -f $with_override_source_root/nashorn/makefiles/Makefile || \
|
||||
test -f $with_override_source_root/nashorn/make/Makefile; then
|
||||
as_fn_error $? "Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override." "$LINENO" 5
|
||||
fi
|
||||
if test -f $with_override_source_root/jdk/makefiles/Makefile || \
|
||||
test -f $with_override_source_root/jdk/make/Makefile; then
|
||||
as_fn_error $? "Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override." "$LINENO" 5
|
||||
|
@ -16199,6 +16207,13 @@ fi
|
|||
|
||||
|
||||
|
||||
# Check whether --with-override-nashorn was given.
|
||||
if test "${with_override_nashorn+set}" = set; then :
|
||||
withval=$with_override_nashorn;
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --with-override-jdk was given.
|
||||
if test "${with_override_jdk+set}" = set; then :
|
||||
withval=$with_override_jdk;
|
||||
|
@ -16276,7 +16291,7 @@ if test "x$with_override_nashorn" != x; then
|
|||
cd "$with_override_nashorn"
|
||||
NASHORN_TOPDIR="`pwd`"
|
||||
cd "$CURDIR"
|
||||
if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then
|
||||
if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then
|
||||
as_fn_error $? "You have to override nashorn with a full nashorn repo!" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if nashorn should be overridden" >&5
|
||||
|
@ -17086,7 +17101,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -17586,437 +17601,29 @@ $as_echo "$as_me: The path of MSVCR_DLL, which resolves as \"$path\", is invalid
|
|||
|
||||
# Check whether --with-dxsdk was given.
|
||||
if test "${with_dxsdk+set}" = set; then :
|
||||
withval=$with_dxsdk;
|
||||
withval=$with_dxsdk; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&5
|
||||
$as_echo "$as_me: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&2;}
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
# Check whether --with-dxsdk-lib was given.
|
||||
if test "${with_dxsdk_lib+set}" = set; then :
|
||||
withval=$with_dxsdk_lib;
|
||||
withval=$with_dxsdk_lib; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&5
|
||||
$as_echo "$as_me: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&2;}
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
# Check whether --with-dxsdk-include was given.
|
||||
if test "${with_dxsdk_include+set}" = set; then :
|
||||
withval=$with_dxsdk_include;
|
||||
withval=$with_dxsdk_include; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&5
|
||||
$as_echo "$as_me: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&2;}
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK" >&5
|
||||
$as_echo_n "checking for DirectX SDK... " >&6; }
|
||||
|
||||
if test "x$with_dxsdk" != x; then
|
||||
dxsdk_path="$with_dxsdk"
|
||||
elif test "x$DXSDK_DIR" != x; then
|
||||
dxsdk_path="$DXSDK_DIR"
|
||||
elif test -d "C:/DXSDK"; then
|
||||
dxsdk_path="C:/DXSDK"
|
||||
else
|
||||
as_fn_error $? "Could not find the DirectX SDK" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dxsdk_path" >&5
|
||||
$as_echo "$dxsdk_path" >&6; }
|
||||
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
|
||||
|
||||
# Input might be given as Windows format, start by converting to
|
||||
# unix format.
|
||||
path="$dxsdk_path"
|
||||
new_path=`$CYGPATH -u "$path"`
|
||||
|
||||
# Cygwin tries to hide some aspects of the Windows file system, such that binaries are
|
||||
# named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
|
||||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
|
||||
$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
|
||||
as_fn_error $? "Cannot locate the the path of dxsdk_path" "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Call helper function which possibly converts this using DOS-style short mode.
|
||||
# If so, the updated path is stored in $new_path.
|
||||
|
||||
input_path="$new_path"
|
||||
# Check if we need to convert this using DOS-style short mode. If the path
|
||||
# contains just simple characters, use it. Otherwise (spaces, weird characters),
|
||||
# take no chances and rewrite it.
|
||||
# Note: m4 eats our [], so we need to use [ and ] instead.
|
||||
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
|
||||
if test "x$has_forbidden_chars" != x; then
|
||||
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
|
||||
shortmode_path=`$CYGPATH -s -m -a "$input_path"`
|
||||
path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
|
||||
if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
|
||||
# Going to short mode and back again did indeed matter. Since short mode is
|
||||
# case insensitive, let's make it lowercase to improve readability.
|
||||
shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
# Now convert it back to Unix-stile (cygpath)
|
||||
input_path=`$CYGPATH -u "$shortmode_path"`
|
||||
new_path="$input_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
|
||||
if test "x$test_cygdrive_prefix" = x; then
|
||||
# As a simple fix, exclude /usr/bin since it's not a real path.
|
||||
if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
|
||||
# The path is in a Cygwin special directory (e.g. /home). We need this converted to
|
||||
# a path prefixed by /cygdrive for fixpath to work.
|
||||
new_path="$CYGWIN_ROOT_PATH$input_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if test "x$path" != "x$new_path"; then
|
||||
dxsdk_path="$new_path"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5
|
||||
$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
|
||||
fi
|
||||
|
||||
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
|
||||
|
||||
path="$dxsdk_path"
|
||||
has_colon=`$ECHO $path | $GREP ^.:`
|
||||
new_path="$path"
|
||||
if test "x$has_colon" = x; then
|
||||
# Not in mixed or Windows style, start by that.
|
||||
new_path=`cmd //c echo $path`
|
||||
fi
|
||||
|
||||
|
||||
input_path="$new_path"
|
||||
# Check if we need to convert this using DOS-style short mode. If the path
|
||||
# contains just simple characters, use it. Otherwise (spaces, weird characters),
|
||||
# take no chances and rewrite it.
|
||||
# Note: m4 eats our [], so we need to use [ and ] instead.
|
||||
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
|
||||
if test "x$has_forbidden_chars" != x; then
|
||||
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
|
||||
new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
fi
|
||||
|
||||
|
||||
windows_path="$new_path"
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
|
||||
unix_path=`$CYGPATH -u "$windows_path"`
|
||||
new_path="$unix_path"
|
||||
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
|
||||
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
|
||||
new_path="$unix_path"
|
||||
fi
|
||||
|
||||
if test "x$path" != "x$new_path"; then
|
||||
dxsdk_path="$new_path"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5
|
||||
$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;}
|
||||
fi
|
||||
|
||||
# Save the first 10 bytes of this path to the storage, so fixpath can work.
|
||||
all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
|
||||
|
||||
else
|
||||
# We're on a posix platform. Hooray! :)
|
||||
path="$dxsdk_path"
|
||||
has_space=`$ECHO "$path" | $GREP " "`
|
||||
if test "x$has_space" != x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5
|
||||
$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;}
|
||||
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Use eval to expand a potential ~
|
||||
eval path="$path"
|
||||
if test ! -f "$path" && test ! -d "$path"; then
|
||||
as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5
|
||||
fi
|
||||
|
||||
dxsdk_path="`cd "$path"; $THEPWDCMD -L`"
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK lib dir" >&5
|
||||
$as_echo_n "checking for DirectX SDK lib dir... " >&6; }
|
||||
if test "x$with_dxsdk_lib" != x; then
|
||||
DXSDK_LIB_PATH="$with_dxsdk_lib"
|
||||
elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
|
||||
DXSDK_LIB_PATH="$dxsdk_path/Lib/x64"
|
||||
else
|
||||
DXSDK_LIB_PATH="$dxsdk_path/Lib"
|
||||
fi
|
||||
# dsound.lib is linked to in jsoundds
|
||||
if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then
|
||||
as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_LIB_PATH" >&5
|
||||
$as_echo "$DXSDK_LIB_PATH" >&6; }
|
||||
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
|
||||
|
||||
# Input might be given as Windows format, start by converting to
|
||||
# unix format.
|
||||
path="$DXSDK_LIB_PATH"
|
||||
new_path=`$CYGPATH -u "$path"`
|
||||
|
||||
# Cygwin tries to hide some aspects of the Windows file system, such that binaries are
|
||||
# named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
|
||||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
|
||||
$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
|
||||
as_fn_error $? "Cannot locate the the path of DXSDK_LIB_PATH" "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Call helper function which possibly converts this using DOS-style short mode.
|
||||
# If so, the updated path is stored in $new_path.
|
||||
|
||||
input_path="$new_path"
|
||||
# Check if we need to convert this using DOS-style short mode. If the path
|
||||
# contains just simple characters, use it. Otherwise (spaces, weird characters),
|
||||
# take no chances and rewrite it.
|
||||
# Note: m4 eats our [], so we need to use [ and ] instead.
|
||||
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
|
||||
if test "x$has_forbidden_chars" != x; then
|
||||
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
|
||||
shortmode_path=`$CYGPATH -s -m -a "$input_path"`
|
||||
path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
|
||||
if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
|
||||
# Going to short mode and back again did indeed matter. Since short mode is
|
||||
# case insensitive, let's make it lowercase to improve readability.
|
||||
shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
# Now convert it back to Unix-stile (cygpath)
|
||||
input_path=`$CYGPATH -u "$shortmode_path"`
|
||||
new_path="$input_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
|
||||
if test "x$test_cygdrive_prefix" = x; then
|
||||
# As a simple fix, exclude /usr/bin since it's not a real path.
|
||||
if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
|
||||
# The path is in a Cygwin special directory (e.g. /home). We need this converted to
|
||||
# a path prefixed by /cygdrive for fixpath to work.
|
||||
new_path="$CYGWIN_ROOT_PATH$input_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if test "x$path" != "x$new_path"; then
|
||||
DXSDK_LIB_PATH="$new_path"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5
|
||||
$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
|
||||
fi
|
||||
|
||||
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
|
||||
|
||||
path="$DXSDK_LIB_PATH"
|
||||
has_colon=`$ECHO $path | $GREP ^.:`
|
||||
new_path="$path"
|
||||
if test "x$has_colon" = x; then
|
||||
# Not in mixed or Windows style, start by that.
|
||||
new_path=`cmd //c echo $path`
|
||||
fi
|
||||
|
||||
|
||||
input_path="$new_path"
|
||||
# Check if we need to convert this using DOS-style short mode. If the path
|
||||
# contains just simple characters, use it. Otherwise (spaces, weird characters),
|
||||
# take no chances and rewrite it.
|
||||
# Note: m4 eats our [], so we need to use [ and ] instead.
|
||||
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
|
||||
if test "x$has_forbidden_chars" != x; then
|
||||
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
|
||||
new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
fi
|
||||
|
||||
|
||||
windows_path="$new_path"
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
|
||||
unix_path=`$CYGPATH -u "$windows_path"`
|
||||
new_path="$unix_path"
|
||||
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
|
||||
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
|
||||
new_path="$unix_path"
|
||||
fi
|
||||
|
||||
if test "x$path" != "x$new_path"; then
|
||||
DXSDK_LIB_PATH="$new_path"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5
|
||||
$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;}
|
||||
fi
|
||||
|
||||
# Save the first 10 bytes of this path to the storage, so fixpath can work.
|
||||
all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
|
||||
|
||||
else
|
||||
# We're on a posix platform. Hooray! :)
|
||||
path="$DXSDK_LIB_PATH"
|
||||
has_space=`$ECHO "$path" | $GREP " "`
|
||||
if test "x$has_space" != x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5
|
||||
$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;}
|
||||
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Use eval to expand a potential ~
|
||||
eval path="$path"
|
||||
if test ! -f "$path" && test ! -d "$path"; then
|
||||
as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
|
||||
fi
|
||||
|
||||
DXSDK_LIB_PATH="`cd "$path"; $THEPWDCMD -L`"
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK include dir" >&5
|
||||
$as_echo_n "checking for DirectX SDK include dir... " >&6; }
|
||||
if test "x$with_dxsdk_include" != x; then
|
||||
DXSDK_INCLUDE_PATH="$with_dxsdk_include"
|
||||
else
|
||||
DXSDK_INCLUDE_PATH="$dxsdk_path/Include"
|
||||
fi
|
||||
# dsound.h is included in jsoundds
|
||||
if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then
|
||||
as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_INCLUDE_PATH" >&5
|
||||
$as_echo "$DXSDK_INCLUDE_PATH" >&6; }
|
||||
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
|
||||
|
||||
# Input might be given as Windows format, start by converting to
|
||||
# unix format.
|
||||
path="$DXSDK_INCLUDE_PATH"
|
||||
new_path=`$CYGPATH -u "$path"`
|
||||
|
||||
# Cygwin tries to hide some aspects of the Windows file system, such that binaries are
|
||||
# named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
|
||||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
|
||||
$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
|
||||
as_fn_error $? "Cannot locate the the path of DXSDK_INCLUDE_PATH" "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Call helper function which possibly converts this using DOS-style short mode.
|
||||
# If so, the updated path is stored in $new_path.
|
||||
|
||||
input_path="$new_path"
|
||||
# Check if we need to convert this using DOS-style short mode. If the path
|
||||
# contains just simple characters, use it. Otherwise (spaces, weird characters),
|
||||
# take no chances and rewrite it.
|
||||
# Note: m4 eats our [], so we need to use [ and ] instead.
|
||||
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
|
||||
if test "x$has_forbidden_chars" != x; then
|
||||
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
|
||||
shortmode_path=`$CYGPATH -s -m -a "$input_path"`
|
||||
path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
|
||||
if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
|
||||
# Going to short mode and back again did indeed matter. Since short mode is
|
||||
# case insensitive, let's make it lowercase to improve readability.
|
||||
shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
# Now convert it back to Unix-stile (cygpath)
|
||||
input_path=`$CYGPATH -u "$shortmode_path"`
|
||||
new_path="$input_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
|
||||
if test "x$test_cygdrive_prefix" = x; then
|
||||
# As a simple fix, exclude /usr/bin since it's not a real path.
|
||||
if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
|
||||
# The path is in a Cygwin special directory (e.g. /home). We need this converted to
|
||||
# a path prefixed by /cygdrive for fixpath to work.
|
||||
new_path="$CYGWIN_ROOT_PATH$input_path"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if test "x$path" != "x$new_path"; then
|
||||
DXSDK_INCLUDE_PATH="$new_path"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5
|
||||
$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
|
||||
fi
|
||||
|
||||
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
|
||||
|
||||
path="$DXSDK_INCLUDE_PATH"
|
||||
has_colon=`$ECHO $path | $GREP ^.:`
|
||||
new_path="$path"
|
||||
if test "x$has_colon" = x; then
|
||||
# Not in mixed or Windows style, start by that.
|
||||
new_path=`cmd //c echo $path`
|
||||
fi
|
||||
|
||||
|
||||
input_path="$new_path"
|
||||
# Check if we need to convert this using DOS-style short mode. If the path
|
||||
# contains just simple characters, use it. Otherwise (spaces, weird characters),
|
||||
# take no chances and rewrite it.
|
||||
# Note: m4 eats our [], so we need to use [ and ] instead.
|
||||
has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
|
||||
if test "x$has_forbidden_chars" != x; then
|
||||
# Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
|
||||
new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
fi
|
||||
|
||||
|
||||
windows_path="$new_path"
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
|
||||
unix_path=`$CYGPATH -u "$windows_path"`
|
||||
new_path="$unix_path"
|
||||
elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
|
||||
unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
|
||||
new_path="$unix_path"
|
||||
fi
|
||||
|
||||
if test "x$path" != "x$new_path"; then
|
||||
DXSDK_INCLUDE_PATH="$new_path"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5
|
||||
$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;}
|
||||
fi
|
||||
|
||||
# Save the first 10 bytes of this path to the storage, so fixpath can work.
|
||||
all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
|
||||
|
||||
else
|
||||
# We're on a posix platform. Hooray! :)
|
||||
path="$DXSDK_INCLUDE_PATH"
|
||||
has_space=`$ECHO "$path" | $GREP " "`
|
||||
if test "x$has_space" != x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5
|
||||
$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;}
|
||||
as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Use eval to expand a potential ~
|
||||
eval path="$path"
|
||||
if test ! -f "$path" && test ! -d "$path"; then
|
||||
as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5
|
||||
fi
|
||||
|
||||
DXSDK_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
@ -18140,7 +17747,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -18451,7 +18058,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -18757,7 +18364,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -19350,7 +18957,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -19786,7 +19393,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -20922,7 +20529,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -21358,7 +20965,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -22259,7 +21866,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -22640,7 +22247,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -22987,7 +22594,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -23324,7 +22931,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -23645,7 +23252,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -24020,7 +23627,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -24326,7 +23933,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -24737,7 +24344,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -25137,7 +24744,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -25466,7 +25073,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -25778,7 +25385,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -26084,7 +25691,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -26390,7 +25997,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -26696,7 +26303,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -27055,7 +26662,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -27415,7 +27022,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -27788,7 +27395,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -28159,7 +27766,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -28468,7 +28075,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh
|
|||
# the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
|
||||
# "foo.exe" is OK but "foo" is an error.
|
||||
#
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file precense.
|
||||
# This test is therefore slightly more accurate than "test -f" to check for file presence.
|
||||
# It is also a way to make sure we got the proper file name for the real test later on.
|
||||
test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
|
||||
if test "x$test_shortpath" = x; then
|
||||
|
@ -28830,35 +28437,41 @@ done
|
|||
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
|
||||
# Always specify -m flags on Solaris
|
||||
|
||||
# keep track of c/cxx flags that we added outselves...
|
||||
# to prevent emitting warning...
|
||||
TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
|
||||
# When we add flags to the "official" CFLAGS etc, we need to
|
||||
# keep track of these additions in ADDED_CFLAGS etc. These
|
||||
# will later be checked to make sure only controlled additions
|
||||
# have been made to CFLAGS etc.
|
||||
ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
|
||||
CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
|
||||
CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
|
||||
LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
|
||||
|
||||
CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}"
|
||||
CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}"
|
||||
LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}"
|
||||
|
||||
CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
|
||||
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
|
||||
|
||||
elif test "x$COMPILE_TYPE" = xreduced; then
|
||||
if test "x$OPENJDK_TARGET_OS" != xwindows; then
|
||||
# Specify -m if running reduced on other Posix platforms
|
||||
|
||||
# keep track of c/cxx flags that we added outselves...
|
||||
# to prevent emitting warning...
|
||||
TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
|
||||
# When we add flags to the "official" CFLAGS etc, we need to
|
||||
# keep track of these additions in ADDED_CFLAGS etc. These
|
||||
# will later be checked to make sure only controlled additions
|
||||
# have been made to CFLAGS etc.
|
||||
ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
|
||||
CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
|
||||
CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
|
||||
LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
|
||||
|
||||
CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}"
|
||||
CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}"
|
||||
LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}"
|
||||
|
||||
CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
|
||||
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
|
||||
|
||||
fi
|
||||
fi
|
||||
|
@ -33618,6 +33231,7 @@ fi
|
|||
# We're messing a bit with internal autoconf variables to put the config.status
|
||||
# in the output directory instead of the current directory.
|
||||
CONFIG_STATUS="$OUTPUT_ROOT/config.status"
|
||||
|
||||
# Create the actual output files. Now the main work of configure is done.
|
||||
cat >confcache <<\_ACEOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
|
@ -34899,6 +34513,11 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
|
|||
fi
|
||||
|
||||
|
||||
# Try to move the config.log file to the output directory.
|
||||
if test -e ./config.log; then
|
||||
$MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null
|
||||
fi
|
||||
|
||||
# Make the compare script executable
|
||||
$CHMOD +x $OUTPUT_ROOT/compare.sh
|
||||
|
||||
|
|
|
@ -446,7 +446,7 @@ elif test "x$with_user_release_suffix" != x; then
|
|||
else
|
||||
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
|
||||
# Avoid [:alnum:] since it depends on the locale.
|
||||
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'`
|
||||
CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'`
|
||||
USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
fi
|
||||
AC_SUBST(USER_RELEASE_SUFFIX)
|
||||
|
|
|
@ -422,18 +422,21 @@ AC_SUBST(OS_VERSION_MICRO)
|
|||
# Add -mX to various FLAGS variables.
|
||||
AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS],
|
||||
[
|
||||
# keep track of c/cxx flags that we added outselves...
|
||||
# to prevent emitting warning...
|
||||
TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}"
|
||||
AC_SUBST(TARGET_BITS_FLAG)
|
||||
# When we add flags to the "official" CFLAGS etc, we need to
|
||||
# keep track of these additions in ADDED_CFLAGS etc. These
|
||||
# will later be checked to make sure only controlled additions
|
||||
# have been made to CFLAGS etc.
|
||||
ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}"
|
||||
|
||||
CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}"
|
||||
CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}"
|
||||
LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}"
|
||||
CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
|
||||
CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
|
||||
LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
|
||||
|
||||
CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
|
||||
CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
|
||||
CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS],
|
||||
|
|
|
@ -101,6 +101,10 @@ if test "x$with_add_source_root" != x; then
|
|||
test -f $with_add_source_root/hotspot/make/Makefile; then
|
||||
AC_MSG_ERROR([Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources.])
|
||||
fi
|
||||
if test -f $with_add_source_root/nashorn/makefiles/Makefile || \
|
||||
test -f $with_add_source_root/nashorn/make/Makefile; then
|
||||
AC_MSG_ERROR([Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources.])
|
||||
fi
|
||||
if test -f $with_add_source_root/jdk/makefiles/Makefile || \
|
||||
test -f $with_add_source_root/jdk/make/Makefile; then
|
||||
AC_MSG_ERROR([Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources.])
|
||||
|
@ -136,6 +140,10 @@ if test "x$with_override_source_root" != x; then
|
|||
test -f $with_override_source_root/hotspot/make/Makefile; then
|
||||
AC_MSG_ERROR([Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override.])
|
||||
fi
|
||||
if test -f $with_override_source_root/nashorn/makefiles/Makefile || \
|
||||
test -f $with_override_source_root/nashorn/make/Makefile; then
|
||||
AC_MSG_ERROR([Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override.])
|
||||
fi
|
||||
if test -f $with_override_source_root/jdk/makefiles/Makefile || \
|
||||
test -f $with_override_source_root/jdk/make/Makefile; then
|
||||
AC_MSG_ERROR([Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override.])
|
||||
|
@ -177,6 +185,9 @@ AC_ARG_WITH(override-jaxws, [AS_HELP_STRING([--with-override-jaxws],
|
|||
AC_ARG_WITH(override-hotspot, [AS_HELP_STRING([--with-override-hotspot],
|
||||
[use this hotspot dir for the build])])
|
||||
|
||||
AC_ARG_WITH(override-nashorn, [AS_HELP_STRING([--with-override-nashorn],
|
||||
[use this nashorn dir for the build])])
|
||||
|
||||
AC_ARG_WITH(override-jdk, [AS_HELP_STRING([--with-override-jdk],
|
||||
[use this jdk dir for the build])])
|
||||
|
||||
|
@ -241,7 +252,7 @@ if test "x$with_override_nashorn" != x; then
|
|||
cd "$with_override_nashorn"
|
||||
NASHORN_TOPDIR="`pwd`"
|
||||
cd "$CURDIR"
|
||||
if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then
|
||||
if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then
|
||||
AC_MSG_ERROR([You have to override nashorn with a full nashorn repo!])
|
||||
fi
|
||||
AC_MSG_CHECKING([if nashorn should be overridden])
|
||||
|
|
|
@ -291,10 +291,6 @@ X_CFLAGS:=@X_CFLAGS@
|
|||
X_LIBS:=@X_LIBS@
|
||||
OPENWIN_HOME:=@OPENWIN_HOME@
|
||||
|
||||
# DirectX SDK
|
||||
DXSDK_LIB_PATH=@DXSDK_LIB_PATH@
|
||||
DXSDK_INCLUDE_PATH=@DXSDK_INCLUDE_PATH@
|
||||
|
||||
# The lowest required version of macosx to enforce compatiblity for
|
||||
MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
|
||||
|
||||
|
@ -304,7 +300,6 @@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
|
|||
COMPILER_TYPE:=@COMPILER_TYPE@
|
||||
COMPILER_NAME:=@COMPILER_NAME@
|
||||
|
||||
TARGET_BITS_FLAG=@TARGET_BITS_FLAG@
|
||||
COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@
|
||||
|
||||
CC_OUT_OPTION:=@CC_OUT_OPTION@
|
||||
|
|
|
@ -176,7 +176,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_PATHS],
|
|||
[
|
||||
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
|
||||
TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV
|
||||
TOOLCHAIN_SETUP_DXSDK
|
||||
BASIC_DEPRECATED_ARG_WITH([dxsdk])
|
||||
BASIC_DEPRECATED_ARG_WITH([dxsdk-lib])
|
||||
BASIC_DEPRECATED_ARG_WITH([dxsdk-include])
|
||||
fi
|
||||
|
||||
AC_SUBST(MSVCR_DLL)
|
||||
|
|
|
@ -277,61 +277,3 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
|
|||
AC_MSG_RESULT([$MSVCR_DLL])
|
||||
BASIC_FIXUP_PATH(MSVCR_DLL)
|
||||
])
|
||||
|
||||
|
||||
# Setup the DXSDK paths
|
||||
AC_DEFUN([TOOLCHAIN_SETUP_DXSDK],
|
||||
[
|
||||
AC_ARG_WITH(dxsdk, [AS_HELP_STRING([--with-dxsdk],
|
||||
[the DirectX SDK (Windows only) @<:@probed@:>@])])
|
||||
AC_ARG_WITH(dxsdk-lib, [AS_HELP_STRING([--with-dxsdk-lib],
|
||||
[the DirectX SDK lib directory (Windows only) @<:@probed@:>@])])
|
||||
AC_ARG_WITH(dxsdk-include, [AS_HELP_STRING([--with-dxsdk-include],
|
||||
[the DirectX SDK include directory (Windows only) @<:@probed@:>@])])
|
||||
|
||||
AC_MSG_CHECKING([for DirectX SDK])
|
||||
|
||||
if test "x$with_dxsdk" != x; then
|
||||
dxsdk_path="$with_dxsdk"
|
||||
elif test "x$DXSDK_DIR" != x; then
|
||||
dxsdk_path="$DXSDK_DIR"
|
||||
elif test -d "C:/DXSDK"; then
|
||||
dxsdk_path="C:/DXSDK"
|
||||
else
|
||||
AC_MSG_ERROR([Could not find the DirectX SDK])
|
||||
fi
|
||||
AC_MSG_RESULT([$dxsdk_path])
|
||||
BASIC_FIXUP_PATH(dxsdk_path)
|
||||
|
||||
AC_MSG_CHECKING([for DirectX SDK lib dir])
|
||||
if test "x$with_dxsdk_lib" != x; then
|
||||
DXSDK_LIB_PATH="$with_dxsdk_lib"
|
||||
elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then
|
||||
DXSDK_LIB_PATH="$dxsdk_path/Lib/x64"
|
||||
else
|
||||
DXSDK_LIB_PATH="$dxsdk_path/Lib"
|
||||
fi
|
||||
# dsound.lib is linked to in jsoundds
|
||||
if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then
|
||||
AC_MSG_ERROR([Invalid DirectX SDK lib dir])
|
||||
fi
|
||||
AC_MSG_RESULT([$DXSDK_LIB_PATH])
|
||||
BASIC_FIXUP_PATH(DXSDK_LIB_PATH)
|
||||
|
||||
AC_MSG_CHECKING([for DirectX SDK include dir])
|
||||
if test "x$with_dxsdk_include" != x; then
|
||||
DXSDK_INCLUDE_PATH="$with_dxsdk_include"
|
||||
else
|
||||
DXSDK_INCLUDE_PATH="$dxsdk_path/Include"
|
||||
fi
|
||||
# dsound.h is included in jsoundds
|
||||
if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then
|
||||
AC_MSG_ERROR([Invalid DirectX SDK lib dir])
|
||||
fi
|
||||
AC_MSG_RESULT([$DXSDK_INCLUDE_PATH])
|
||||
BASIC_FIXUP_PATH(DXSDK_INCLUDE_PATH)
|
||||
|
||||
AC_SUBST(DXSDK_LIB_PATH)
|
||||
AC_SUBST(DXSDK_INCLUDE_PATH)
|
||||
LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH"
|
||||
])
|
||||
|
|
|
@ -47,7 +47,7 @@ python=""
|
|||
bpython=""
|
||||
|
||||
if [ "#!" = "$has_hash_bang" ] ; then
|
||||
python="`head -n 1 ${whichhg} | cut -b 3-`"
|
||||
python="`head -n 1 ${whichhg} | cut -b 3- | sed -e 's/^[ \t]*//;s/[ \t]*$//'`"
|
||||
bpython="`basename "$python"`"
|
||||
fi
|
||||
|
||||
|
|
|
@ -228,3 +228,4 @@ a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101
|
|||
d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
|
||||
4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105
|
||||
2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106
|
||||
23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.net.SocketException;
|
|||
import java.net.ServerSocket;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import com.sun.corba.se.pept.transport.Acceptor;
|
||||
|
||||
|
@ -44,6 +45,22 @@ public class DefaultSocketFactoryImpl
|
|||
implements ORBSocketFactory
|
||||
{
|
||||
private ORB orb;
|
||||
private static final boolean keepAlive;
|
||||
|
||||
static {
|
||||
keepAlive = java.security.AccessController.doPrivileged(
|
||||
new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run () {
|
||||
String value =
|
||||
System.getProperty("com.sun.CORBA.transport.enableTcpKeepAlive");
|
||||
if (value != null)
|
||||
return new Boolean(!"false".equalsIgnoreCase(value));
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setORB(ORB orb)
|
||||
{
|
||||
|
@ -85,6 +102,9 @@ public class DefaultSocketFactoryImpl
|
|||
// Disable Nagle's algorithm (i.e., always send immediately).
|
||||
socket.setTcpNoDelay(true);
|
||||
|
||||
if (keepAlive)
|
||||
socket.setKeepAlive(true);
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
@ -95,6 +115,8 @@ public class DefaultSocketFactoryImpl
|
|||
{
|
||||
// Disable Nagle's algorithm (i.e., always send immediately).
|
||||
socket.setTcpNoDelay(true);
|
||||
if (keepAlive)
|
||||
socket.setKeepAlive(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -375,3 +375,7 @@ acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105
|
|||
18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48
|
||||
aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106
|
||||
50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49
|
||||
5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107
|
||||
a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50
|
||||
85072013aad46050a362d10ab78e963121c8014c jdk8-b108
|
||||
566db1b0e6efca31f181456e54c8911d0192410d hs25-b51
|
||||
|
|
|
@ -1213,6 +1213,7 @@ public class CommandProcessor {
|
|||
}
|
||||
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
|
||||
if (t.countTokens() == 1) {
|
||||
String name = t.nextToken();
|
||||
out.println("intConstant " + name + " " + db.lookupIntConstant(name));
|
||||
} else if (t.countTokens() == 0) {
|
||||
Iterator i = db.getIntConstants();
|
||||
|
@ -1235,6 +1236,7 @@ public class CommandProcessor {
|
|||
}
|
||||
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
|
||||
if (t.countTokens() == 1) {
|
||||
String name = t.nextToken();
|
||||
out.println("longConstant " + name + " " + db.lookupLongConstant(name));
|
||||
} else if (t.countTokens() == 0) {
|
||||
Iterator i = db.getLongConstants();
|
||||
|
|
|
@ -81,7 +81,7 @@ class BsdAddress implements Address {
|
|||
|
||||
public Address getCompKlassAddressAt(long offset)
|
||||
throws UnalignedAddressException, UnmappedAddressException {
|
||||
return debugger.readCompOopAddress(addr + offset);
|
||||
return debugger.readCompKlassAddress(addr + offset);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -792,7 +792,7 @@ public class VM {
|
|||
|
||||
public boolean isCompressedKlassPointersEnabled() {
|
||||
if (compressedKlassPointersEnabled == null) {
|
||||
Flag flag = getCommandLineFlag("UseCompressedKlassPointers");
|
||||
Flag flag = getCommandLineFlag("UseCompressedClassPointers");
|
||||
compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE:
|
||||
(flag.getBool()? Boolean.TRUE: Boolean.FALSE);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class HeapSummary extends Tool {
|
|||
printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
|
||||
printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
|
||||
printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
|
||||
printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap));
|
||||
printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap));
|
||||
printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
|
||||
printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
|
|||
psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \
|
||||
parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
|
||||
gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
|
||||
mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp
|
||||
mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(INCLUDE_NMT), false)
|
||||
|
|
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
|||
|
||||
HS_MAJOR_VER=25
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=50
|
||||
HS_BUILD_NUMBER=51
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=8
|
||||
|
|
|
@ -105,7 +105,7 @@ bool LIR_Assembler::is_single_instruction(LIR_Op* op) {
|
|||
if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
|
||||
}
|
||||
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
if (src->is_address() && !src->is_stack() && src->type() == T_ADDRESS &&
|
||||
src->as_address_ptr()->disp() == oopDesc::klass_offset_in_bytes()) return false;
|
||||
}
|
||||
|
@ -963,7 +963,7 @@ int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType typ
|
|||
case T_METADATA: __ ld_ptr(base, offset, to_reg->as_register()); break;
|
||||
case T_ADDRESS:
|
||||
#ifdef _LP64
|
||||
if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedKlassPointers) {
|
||||
if (offset == oopDesc::klass_offset_in_bytes() && UseCompressedClassPointers) {
|
||||
__ lduw(base, offset, to_reg->as_register());
|
||||
__ decode_klass_not_null(to_reg->as_register());
|
||||
} else
|
||||
|
@ -2208,7 +2208,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||
// We don't know the array types are compatible
|
||||
if (basic_type != T_OBJECT) {
|
||||
// Simple test for basic type arrays
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
// We don't need decode because we just need to compare
|
||||
__ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
|
||||
__ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
|
||||
|
@ -2342,7 +2342,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||
// but not necessarily exactly of type default_type.
|
||||
Label known_ok, halt;
|
||||
metadata2reg(op->expected_type()->constant_encoding(), tmp);
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
// tmp holds the default type. It currently comes uncompressed after the
|
||||
// load of a constant, so encode it.
|
||||
__ encode_klass_not_null(tmp);
|
||||
|
|
|
@ -186,7 +186,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
|||
set((intx)markOopDesc::prototype(), t1);
|
||||
}
|
||||
st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
// Save klass
|
||||
mov(klass, t1);
|
||||
encode_klass_not_null(t1);
|
||||
|
@ -196,7 +196,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
|||
}
|
||||
if (len->is_valid()) {
|
||||
st(len, obj, arrayOopDesc::length_offset_in_bytes());
|
||||
} else if (UseCompressedKlassPointers) {
|
||||
} else if (UseCompressedClassPointers) {
|
||||
// otherwise length is in the class gap
|
||||
store_klass_gap(G0, obj);
|
||||
}
|
||||
|
|
|
@ -3911,7 +3911,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) {
|
|||
// The number of bytes in this code is used by
|
||||
// MachCallDynamicJavaNode::ret_addr_offset()
|
||||
// if this changes, change that.
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass);
|
||||
decode_klass_not_null(klass);
|
||||
} else {
|
||||
|
@ -3920,7 +3920,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) {
|
|||
}
|
||||
|
||||
void MacroAssembler::store_klass(Register klass, Register dst_oop) {
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
assert(dst_oop != klass, "not enough registers");
|
||||
encode_klass_not_null(klass);
|
||||
st(klass, dst_oop, oopDesc::klass_offset_in_bytes());
|
||||
|
@ -3930,7 +3930,7 @@ void MacroAssembler::store_klass(Register klass, Register dst_oop) {
|
|||
}
|
||||
|
||||
void MacroAssembler::store_klass_gap(Register s, Register d) {
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
assert(s != d, "not enough registers");
|
||||
st(s, d, oopDesc::klass_gap_offset_in_bytes());
|
||||
}
|
||||
|
@ -4089,7 +4089,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
|
|||
}
|
||||
|
||||
void MacroAssembler::encode_klass_not_null(Register r) {
|
||||
assert (UseCompressedKlassPointers, "must be compressed");
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
assert(r != G6_heapbase, "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
|
@ -4105,7 +4105,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
|
|||
if (src == dst) {
|
||||
encode_klass_not_null(src);
|
||||
} else {
|
||||
assert (UseCompressedKlassPointers, "must be compressed");
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
set((intptr_t)Universe::narrow_klass_base(), dst);
|
||||
sub(src, dst, dst);
|
||||
|
@ -4119,7 +4119,7 @@ void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
|
|||
// generated by decode_klass_not_null() and reinit_heapbase(). Hence, if
|
||||
// the instructions they generate change, then this method needs to be updated.
|
||||
int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
||||
assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
|
||||
assert (UseCompressedClassPointers, "only for compressed klass ptrs");
|
||||
// set + add + set
|
||||
int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 +
|
||||
insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base());
|
||||
|
@ -4135,7 +4135,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
|||
void MacroAssembler::decode_klass_not_null(Register r) {
|
||||
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
|
||||
// pd_code_size_limit.
|
||||
assert (UseCompressedKlassPointers, "must be compressed");
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
assert(r != G6_heapbase, "bad register choice");
|
||||
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
|
||||
|
@ -4151,7 +4151,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
|
|||
} else {
|
||||
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
|
||||
// pd_code_size_limit.
|
||||
assert (UseCompressedKlassPointers, "must be compressed");
|
||||
assert (UseCompressedClassPointers, "must be compressed");
|
||||
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
|
||||
if (Universe::narrow_klass_shift() != 0) {
|
||||
assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice");
|
||||
|
@ -4167,7 +4167,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
|
|||
}
|
||||
|
||||
void MacroAssembler::reinit_heapbase() {
|
||||
if (UseCompressedOops || UseCompressedKlassPointers) {
|
||||
if (UseCompressedOops || UseCompressedClassPointers) {
|
||||
if (Universe::heap() != NULL) {
|
||||
set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase);
|
||||
} else {
|
||||
|
|
|
@ -557,7 +557,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
|
|||
int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
|
||||
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
|
||||
int klass_load_size;
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
|
||||
} else {
|
||||
|
@ -1657,7 +1657,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
|
|||
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
|
||||
st->print_cr("\nUEP:");
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
|
||||
st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
|
||||
|
@ -1897,7 +1897,7 @@ bool Matcher::narrow_oop_use_complex_address() {
|
|||
|
||||
bool Matcher::narrow_klass_use_complex_address() {
|
||||
NOT_LP64(ShouldNotCallThis());
|
||||
assert(UseCompressedKlassPointers, "only for compressed klass code");
|
||||
assert(UseCompressedClassPointers, "only for compressed klass code");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2561,7 +2561,7 @@ encode %{
|
|||
int off = __ offset();
|
||||
__ load_klass(O0, G3_scratch);
|
||||
int klass_load_size;
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
assert(Universe::heap() != NULL, "java heap should be initialized");
|
||||
klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
|
||||
} else {
|
||||
|
|
|
@ -2945,7 +2945,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||
|
||||
BLOCK_COMMENT("arraycopy argument klass checks");
|
||||
// get src->klass()
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ delayed()->nop(); // ??? not good
|
||||
__ load_klass(src, G3_src_klass);
|
||||
} else {
|
||||
|
@ -2980,7 +2980,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||
// Load 32-bits signed value. Use br() instruction with it to check icc.
|
||||
__ lduw(G3_src_klass, lh_offset, G5_lh);
|
||||
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ load_klass(dst, G4_dst_klass);
|
||||
}
|
||||
// Handle objArrays completely differently...
|
||||
|
@ -2988,7 +2988,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||
__ set(objArray_lh, O5_temp);
|
||||
__ cmp(G5_lh, O5_temp);
|
||||
__ br(Assembler::equal, false, Assembler::pt, L_objArray);
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ delayed()->nop();
|
||||
} else {
|
||||
__ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
|
||||
|
|
|
@ -218,13 +218,13 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
|
|||
// ld;ld;ld,jmp,nop
|
||||
const int basic = 5*BytesPerInstWord +
|
||||
// shift;add for load_klass (only shift with zero heap based)
|
||||
(UseCompressedKlassPointers ?
|
||||
(UseCompressedClassPointers ?
|
||||
MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
|
||||
return basic + slop;
|
||||
} else {
|
||||
const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
|
||||
// shift;add for load_klass (only shift with zero heap based)
|
||||
(UseCompressedKlassPointers ?
|
||||
(UseCompressedClassPointers ?
|
||||
MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
|
||||
return (basic + slop);
|
||||
}
|
||||
|
|
|
@ -148,7 +148,7 @@
|
|||
|
||||
static int adjust_reg_range(int range) {
|
||||
// Reduce the number of available regs (to free r12) in case of compressed oops
|
||||
if (UseCompressedOops || UseCompressedKlassPointers) return range - 1;
|
||||
if (UseCompressedOops || UseCompressedClassPointers) return range - 1;
|
||||
return range;
|
||||
}
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@ int LIR_Assembler::check_icache() {
|
|||
Register receiver = FrameMap::receiver_opr->as_register();
|
||||
Register ic_klass = IC_Klass;
|
||||
const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
|
||||
const bool do_post_padding = VerifyOops || UseCompressedKlassPointers;
|
||||
const bool do_post_padding = VerifyOops || UseCompressedClassPointers;
|
||||
if (!do_post_padding) {
|
||||
// insert some nops so that the verified entry point is aligned on CodeEntryAlignment
|
||||
while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
|
||||
|
@ -1263,7 +1263,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
|
|||
break;
|
||||
|
||||
case T_ADDRESS:
|
||||
if (UseCompressedKlassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {
|
||||
if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {
|
||||
__ movl(dest->as_register(), from_addr);
|
||||
} else {
|
||||
__ movptr(dest->as_register(), from_addr);
|
||||
|
@ -1371,7 +1371,7 @@ void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_Patch
|
|||
__ verify_oop(dest->as_register());
|
||||
} else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ decode_klass_not_null(dest->as_register());
|
||||
}
|
||||
#endif
|
||||
|
@ -1716,7 +1716,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
|
|||
} else if (obj == klass_RInfo) {
|
||||
klass_RInfo = dst;
|
||||
}
|
||||
if (k->is_loaded() && !UseCompressedKlassPointers) {
|
||||
if (k->is_loaded() && !UseCompressedClassPointers) {
|
||||
select_different_registers(obj, dst, k_RInfo, klass_RInfo);
|
||||
} else {
|
||||
Rtmp1 = op->tmp3()->as_register();
|
||||
|
@ -1724,14 +1724,6 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
|
|||
}
|
||||
|
||||
assert_different_registers(obj, k_RInfo, klass_RInfo);
|
||||
if (!k->is_loaded()) {
|
||||
klass2reg_with_patching(k_RInfo, op->info_for_patch());
|
||||
} else {
|
||||
#ifdef _LP64
|
||||
__ mov_metadata(k_RInfo, k->constant_encoding());
|
||||
#endif // _LP64
|
||||
}
|
||||
assert(obj != k_RInfo, "must be different");
|
||||
|
||||
__ cmpptr(obj, (int32_t)NULL_WORD);
|
||||
if (op->should_profile()) {
|
||||
|
@ -1748,13 +1740,21 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
|
|||
} else {
|
||||
__ jcc(Assembler::equal, *obj_is_null);
|
||||
}
|
||||
|
||||
if (!k->is_loaded()) {
|
||||
klass2reg_with_patching(k_RInfo, op->info_for_patch());
|
||||
} else {
|
||||
#ifdef _LP64
|
||||
__ mov_metadata(k_RInfo, k->constant_encoding());
|
||||
#endif // _LP64
|
||||
}
|
||||
__ verify_oop(obj);
|
||||
|
||||
if (op->fast_check()) {
|
||||
// get object class
|
||||
// not a safepoint as obj null check happens earlier
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ load_klass(Rtmp1, obj);
|
||||
__ cmpptr(k_RInfo, Rtmp1);
|
||||
} else {
|
||||
|
@ -3294,7 +3294,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||
// We don't know the array types are compatible
|
||||
if (basic_type != T_OBJECT) {
|
||||
// Simple test for basic type arrays
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ movl(tmp, src_klass_addr);
|
||||
__ cmpl(tmp, dst_klass_addr);
|
||||
} else {
|
||||
|
@ -3456,21 +3456,21 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
|||
Label known_ok, halt;
|
||||
__ mov_metadata(tmp, default_type->constant_encoding());
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
__ encode_klass_not_null(tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (basic_type != T_OBJECT) {
|
||||
|
||||
if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr);
|
||||
if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
|
||||
else __ cmpptr(tmp, dst_klass_addr);
|
||||
__ jcc(Assembler::notEqual, halt);
|
||||
if (UseCompressedKlassPointers) __ cmpl(tmp, src_klass_addr);
|
||||
if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr);
|
||||
else __ cmpptr(tmp, src_klass_addr);
|
||||
__ jcc(Assembler::equal, known_ok);
|
||||
} else {
|
||||
if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr);
|
||||
if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
|
||||
else __ cmpptr(tmp, dst_klass_addr);
|
||||
__ jcc(Assembler::equal, known_ok);
|
||||
__ cmpptr(src, dst);
|
||||
|
|
|
@ -1239,7 +1239,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
|
|||
}
|
||||
LIR_Opr reg = rlock_result(x);
|
||||
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
|
||||
if (!x->klass()->is_loaded() || UseCompressedKlassPointers) {
|
||||
if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
|
||||
tmp3 = new_register(objectType);
|
||||
}
|
||||
__ checkcast(reg, obj.result(), x->klass(),
|
||||
|
@ -1261,7 +1261,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
|
|||
}
|
||||
obj.load_item();
|
||||
LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
|
||||
if (!x->klass()->is_loaded() || UseCompressedKlassPointers) {
|
||||
if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
|
||||
tmp3 = new_register(objectType);
|
||||
}
|
||||
__ instanceof(reg, obj.result(), x->klass(),
|
||||
|
|
|
@ -157,7 +157,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
|||
movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
|
||||
}
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) { // Take care not to kill klass
|
||||
if (UseCompressedClassPointers) { // Take care not to kill klass
|
||||
movptr(t1, klass);
|
||||
encode_klass_not_null(t1);
|
||||
movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
|
||||
|
@ -171,7 +171,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
|
|||
movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
|
||||
}
|
||||
#ifdef _LP64
|
||||
else if (UseCompressedKlassPointers) {
|
||||
else if (UseCompressedClassPointers) {
|
||||
xorptr(t1, t1);
|
||||
store_klass_gap(obj, t1);
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
|
|||
assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
|
||||
int start_offset = offset();
|
||||
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
load_klass(rscratch1, receiver);
|
||||
cmpptr(rscratch1, iCache);
|
||||
} else {
|
||||
|
@ -345,7 +345,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
|
|||
jump_cc(Assembler::notEqual,
|
||||
RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
|
||||
const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
|
||||
assert(UseCompressedKlassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
|
||||
assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1635,7 +1635,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
|
|||
#ifdef ASSERT
|
||||
// TraceBytecodes does not use r12 but saves it over the call, so don't verify
|
||||
// r12 is the heapbase.
|
||||
LP64_ONLY(if ((UseCompressedOops || UseCompressedKlassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
|
||||
LP64_ONLY(if ((UseCompressedOops || UseCompressedClassPointers) && !TraceBytecodes) verify_heapbase("call_VM_base: heap base corrupted?");)
|
||||
#endif // ASSERT
|
||||
|
||||
assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
|
||||
|
@ -4802,7 +4802,7 @@ void MacroAssembler::restore_cpu_control_state_after_jni() {
|
|||
|
||||
void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
|
||||
decode_klass_not_null(dst);
|
||||
} else
|
||||
|
@ -4817,7 +4817,7 @@ void MacroAssembler::load_prototype_header(Register dst, Register src) {
|
|||
|
||||
void MacroAssembler::store_klass(Register dst, Register src) {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
encode_klass_not_null(src);
|
||||
movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
|
||||
} else
|
||||
|
@ -4892,7 +4892,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
|
|||
|
||||
#ifdef _LP64
|
||||
void MacroAssembler::store_klass_gap(Register dst, Register src) {
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
// Store to klass gap in destination
|
||||
movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
|
||||
}
|
||||
|
@ -5075,7 +5075,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
|
|||
// when (Universe::heap() != NULL). Hence, if the instructions they
|
||||
// generate change, then this method needs to be updated.
|
||||
int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
||||
assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
|
||||
assert (UseCompressedClassPointers, "only for compressed klass ptrs");
|
||||
// mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
|
||||
return (Universe::narrow_klass_shift() == 0 ? 20 : 24);
|
||||
}
|
||||
|
@ -5085,7 +5085,7 @@ int MacroAssembler::instr_size_for_decode_klass_not_null() {
|
|||
void MacroAssembler::decode_klass_not_null(Register r) {
|
||||
// Note: it will change flags
|
||||
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
|
||||
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert(r != r12_heapbase, "Decoding a klass in r12");
|
||||
// Cannot assert, unverified entry point counts instructions (see .ad file)
|
||||
// vtableStubs also counts instructions in pd_code_size_limit.
|
||||
|
@ -5103,7 +5103,7 @@ void MacroAssembler::decode_klass_not_null(Register r) {
|
|||
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
|
||||
// Note: it will change flags
|
||||
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
|
||||
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
if (dst == src) {
|
||||
decode_klass_not_null(dst);
|
||||
} else {
|
||||
|
@ -5141,7 +5141,7 @@ void MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
|
|||
}
|
||||
|
||||
void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
|
||||
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int klass_index = oop_recorder()->find_index(k);
|
||||
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
|
||||
|
@ -5149,7 +5149,7 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
|
|||
}
|
||||
|
||||
void MacroAssembler::set_narrow_klass(Address dst, Klass* k) {
|
||||
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int klass_index = oop_recorder()->find_index(k);
|
||||
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
|
||||
|
@ -5175,7 +5175,7 @@ void MacroAssembler::cmp_narrow_oop(Address dst, jobject obj) {
|
|||
}
|
||||
|
||||
void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) {
|
||||
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int klass_index = oop_recorder()->find_index(k);
|
||||
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
|
||||
|
@ -5183,7 +5183,7 @@ void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) {
|
|||
}
|
||||
|
||||
void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
|
||||
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
|
||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
int klass_index = oop_recorder()->find_index(k);
|
||||
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
|
||||
|
@ -5191,7 +5191,7 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
|
|||
}
|
||||
|
||||
void MacroAssembler::reinit_heapbase() {
|
||||
if (UseCompressedOops || UseCompressedKlassPointers) {
|
||||
if (UseCompressedOops || UseCompressedClassPointers) {
|
||||
if (Universe::heap() != NULL) {
|
||||
if (Universe::narrow_oop_base() == NULL) {
|
||||
MacroAssembler::xorptr(r12_heapbase, r12_heapbase);
|
||||
|
|
|
@ -34,9 +34,9 @@
|
|||
// Run with +PrintInterpreter to get the VM to print out the size.
|
||||
// Max size with JVMTI
|
||||
#ifdef AMD64
|
||||
const static int InterpreterCodeSize = 200 * 1024;
|
||||
const static int InterpreterCodeSize = 208 * 1024;
|
||||
#else
|
||||
const static int InterpreterCodeSize = 168 * 1024;
|
||||
const static int InterpreterCodeSize = 176 * 1024;
|
||||
#endif // AMD64
|
||||
|
||||
#endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP
|
||||
|
|
|
@ -211,11 +211,11 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
|
|||
if (is_vtable_stub) {
|
||||
// Vtable stub size
|
||||
return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) +
|
||||
(UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
|
||||
(UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
|
||||
} else {
|
||||
// Itable stub size
|
||||
return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
|
||||
(UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
|
||||
(UseCompressedClassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
|
||||
}
|
||||
// In order to tune these parameters, run the JVM with VM options
|
||||
// +PrintMiscellaneous and +WizardMode to see information about
|
||||
|
|
|
@ -1391,7 +1391,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const
|
|||
#ifndef PRODUCT
|
||||
void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||
{
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
|
||||
st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
|
||||
st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
|
||||
|
@ -1408,7 +1408,7 @@ void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
|||
{
|
||||
MacroAssembler masm(&cbuf);
|
||||
uint insts_size = cbuf.insts_size();
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
masm.load_klass(rscratch1, j_rarg0);
|
||||
masm.cmpptr(rax, rscratch1);
|
||||
} else {
|
||||
|
@ -1557,7 +1557,7 @@ bool Matcher::narrow_oop_use_complex_address() {
|
|||
}
|
||||
|
||||
bool Matcher::narrow_klass_use_complex_address() {
|
||||
assert(UseCompressedKlassPointers, "only for compressed klass code");
|
||||
assert(UseCompressedClassPointers, "only for compressed klass code");
|
||||
return (LogKlassAlignmentInBytes <= 3);
|
||||
}
|
||||
|
||||
|
|
|
@ -3589,8 +3589,6 @@ jint os::init_2(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
|
||||
// initialize suspend/resume support - must do this before signal_sets_init()
|
||||
if (SR_initialize() != 0) {
|
||||
perror("SR_initialize failed");
|
||||
|
|
|
@ -4805,8 +4805,6 @@ jint os::init_2(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
|
||||
// initialize suspend/resume support - must do this before signal_sets_init()
|
||||
if (SR_initialize() != 0) {
|
||||
perror("SR_initialize failed");
|
||||
|
|
|
@ -5178,9 +5178,7 @@ jint os::init_2(void) {
|
|||
if(Verbose && PrintMiscellaneous)
|
||||
tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
|
||||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
}
|
||||
|
||||
// Check minimum allowable stack size for thread creation and to initialize
|
||||
// the java system classes, including StackOverflowError - depends on page
|
||||
|
|
|
@ -3189,9 +3189,12 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, boo
|
|||
return p_buf;
|
||||
|
||||
} else {
|
||||
if (TracePageSizes && Verbose) {
|
||||
tty->print_cr("Reserving large pages in a single large chunk.");
|
||||
}
|
||||
// normal policy just allocate it all at once
|
||||
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
|
||||
char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot);
|
||||
char * res = (char *)VirtualAlloc(addr, bytes, flag, prot);
|
||||
if (res != NULL) {
|
||||
address pc = CALLER_PC;
|
||||
MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc);
|
||||
|
@ -3917,8 +3920,6 @@ jint os::init_2(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
os::large_page_init();
|
||||
|
||||
// Setup Windows Exceptions
|
||||
|
||||
// for debugging float code generation bugs
|
||||
|
@ -5429,7 +5430,7 @@ char* os::build_agent_function_name(const char *sym_name, const char *lib_name,
|
|||
if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {
|
||||
lib_name = ++start;
|
||||
} else {
|
||||
// Need to check for C:
|
||||
// Need to check for drive prefix
|
||||
if ((start = strchr(lib_name, ':')) != NULL) {
|
||||
lib_name = ++start;
|
||||
}
|
||||
|
@ -5714,7 +5715,66 @@ BOOL os::Advapi32Dll::AdvapiAvailable() {
|
|||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
// test the code path in reserve_memory_special() that tries to allocate memory in a single
|
||||
// contiguous memory block at a particular address.
|
||||
// The test first tries to find a good approximate address to allocate at by using the same
|
||||
// method to allocate some memory at any address. The test then tries to allocate memory in
|
||||
// the vicinity (not directly after it to avoid possible by-chance use of that location)
|
||||
// This is of course only some dodgy assumption, there is no guarantee that the vicinity of
|
||||
// the previously allocated memory is available for allocation. The only actual failure
|
||||
// that is reported is when the test tries to allocate at a particular location but gets a
|
||||
// different valid one. A NULL return value at this point is not considered an error but may
|
||||
// be legitimate.
|
||||
// If -XX:+VerboseInternalVMTests is enabled, print some explanatory messages.
|
||||
void TestReserveMemorySpecial_test() {
|
||||
// No tests available for this platform
|
||||
if (!UseLargePages) {
|
||||
if (VerboseInternalVMTests) {
|
||||
gclog_or_tty->print("Skipping test because large pages are disabled");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// save current value of globals
|
||||
bool old_use_large_pages_individual_allocation = UseLargePagesIndividualAllocation;
|
||||
bool old_use_numa_interleaving = UseNUMAInterleaving;
|
||||
|
||||
// set globals to make sure we hit the correct code path
|
||||
UseLargePagesIndividualAllocation = UseNUMAInterleaving = false;
|
||||
|
||||
// do an allocation at an address selected by the OS to get a good one.
|
||||
const size_t large_allocation_size = os::large_page_size() * 4;
|
||||
char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
|
||||
if (result == NULL) {
|
||||
if (VerboseInternalVMTests) {
|
||||
gclog_or_tty->print("Failed to allocate control block with size "SIZE_FORMAT". Skipping remainder of test.",
|
||||
large_allocation_size);
|
||||
}
|
||||
} else {
|
||||
os::release_memory_special(result, large_allocation_size);
|
||||
|
||||
// allocate another page within the recently allocated memory area which seems to be a good location. At least
|
||||
// we managed to get it once.
|
||||
const size_t expected_allocation_size = os::large_page_size();
|
||||
char* expected_location = result + os::large_page_size();
|
||||
char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
|
||||
if (actual_location == NULL) {
|
||||
if (VerboseInternalVMTests) {
|
||||
gclog_or_tty->print("Failed to allocate any memory at "PTR_FORMAT" size "SIZE_FORMAT". Skipping remainder of test.",
|
||||
expected_location, large_allocation_size);
|
||||
}
|
||||
} else {
|
||||
// release memory
|
||||
os::release_memory_special(actual_location, expected_allocation_size);
|
||||
// only now check, after releasing any memory to avoid any leaks.
|
||||
assert(actual_location == expected_location,
|
||||
err_msg("Failed to allocate memory at requested location "PTR_FORMAT" of size "SIZE_FORMAT", is "PTR_FORMAT" instead",
|
||||
expected_location, expected_allocation_size, actual_location));
|
||||
}
|
||||
}
|
||||
|
||||
// restore globals
|
||||
UseLargePagesIndividualAllocation = old_use_large_pages_individual_allocation;
|
||||
UseNUMAInterleaving = old_use_numa_interleaving;
|
||||
}
|
||||
#endif
|
||||
#endif // PRODUCT
|
||||
|
||||
|
|
|
@ -35,7 +35,9 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
|
|||
|
||||
// Used on 64 bit platforms for UseCompressedOops base address
|
||||
#ifdef _LP64
|
||||
define_pd_global(uintx, HeapBaseMinAddress, CONST64(4)*G);
|
||||
// use 6G as default base address because by default the OS maps the application
|
||||
// to 4G on Solaris-Sparc. This leaves at least 2G for the native heap.
|
||||
define_pd_global(uintx, HeapBaseMinAddress, CONST64(6)*G);
|
||||
#else
|
||||
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
|
||||
#endif
|
||||
|
|
|
@ -4,9 +4,9 @@ It's main purpose is to recreate output similar to
|
|||
requires a 1.5 JDK to build and simply typing make should build it.
|
||||
|
||||
It produces a jar file, logc.jar, that can be run on the
|
||||
hotspot.log from LogCompilation output like this:
|
||||
HotSpot log (by default, hotspot_pid{pid}.log) from LogCompilation output like this:
|
||||
|
||||
java -jar logc.jar hotspot.log
|
||||
java -jar logc.jar hotspot_pid1234.log
|
||||
|
||||
This will produce something like the normal PrintCompilation output.
|
||||
Adding the -i option with also report inlining like PrintInlining.
|
||||
|
|
|
@ -709,10 +709,10 @@ static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
|
|||
Bytecodes::Code code = field_access.code();
|
||||
|
||||
// We must load class, initialize class and resolvethe field
|
||||
FieldAccessInfo result; // initialize class if needed
|
||||
fieldDescriptor result; // initialize class if needed
|
||||
constantPoolHandle constants(THREAD, caller->constants());
|
||||
LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL);
|
||||
return result.klass()();
|
||||
LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK_NULL);
|
||||
return result.field_holder();
|
||||
}
|
||||
|
||||
|
||||
|
@ -826,11 +826,11 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
|
|||
if (stub_id == Runtime1::access_field_patching_id) {
|
||||
|
||||
Bytecode_field field_access(caller_method, bci);
|
||||
FieldAccessInfo result; // initialize class if needed
|
||||
fieldDescriptor result; // initialize class if needed
|
||||
Bytecodes::Code code = field_access.code();
|
||||
constantPoolHandle constants(THREAD, caller_method->constants());
|
||||
LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK);
|
||||
patch_field_offset = result.field_offset();
|
||||
LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK);
|
||||
patch_field_offset = result.offset();
|
||||
|
||||
// If we're patching a field which is volatile then at compile it
|
||||
// must not have been know to be volatile, so the generated code
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
|
@ -75,7 +75,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
|
|||
|
||||
assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool");
|
||||
|
||||
_cp_index = index;
|
||||
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
|
||||
|
||||
// Get the field's name, signature, and type.
|
||||
|
@ -116,7 +115,7 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
|
|||
// The declared holder of this field may not have been loaded.
|
||||
// Bail out with partial field information.
|
||||
if (!holder_is_accessible) {
|
||||
// _cp_index and _type have already been set.
|
||||
// _type has already been set.
|
||||
// The default values for _flags and _constant_value will suffice.
|
||||
// We need values for _holder, _offset, and _is_constant,
|
||||
_holder = declared_holder;
|
||||
|
@ -146,8 +145,6 @@ ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NUL
|
|||
ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
|
||||
ASSERT_IN_VM;
|
||||
|
||||
_cp_index = -1;
|
||||
|
||||
// Get the field's name, signature, and type.
|
||||
ciEnv* env = CURRENT_ENV;
|
||||
_name = env->get_symbol(fd->name());
|
||||
|
@ -351,12 +348,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass,
|
|||
}
|
||||
}
|
||||
|
||||
FieldAccessInfo result;
|
||||
constantPoolHandle c_pool(THREAD,
|
||||
accessing_klass->get_instanceKlass()->constants());
|
||||
LinkResolver::resolve_field(result, c_pool, _cp_index,
|
||||
Bytecodes::java_code(bc),
|
||||
true, false, KILL_COMPILE_ON_FATAL_(false));
|
||||
fieldDescriptor result;
|
||||
LinkResolver::resolve_field(result, _holder->get_instanceKlass(),
|
||||
_name->get_symbol(), _signature->get_symbol(),
|
||||
accessing_klass->get_Klass(), bc, true, false,
|
||||
KILL_COMPILE_ON_FATAL_(false));
|
||||
|
||||
// update the hit-cache, unless there is a problem with memory scoping:
|
||||
if (accessing_klass->is_shared() || !is_shared()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
|
@ -53,9 +53,6 @@ private:
|
|||
ciInstanceKlass* _known_to_link_with_get;
|
||||
ciConstant _constant_value;
|
||||
|
||||
// Used for will_link
|
||||
int _cp_index;
|
||||
|
||||
ciType* compute_type();
|
||||
ciType* compute_type_impl();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
|
@ -522,8 +522,7 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
|
|||
|
||||
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
|
||||
if (fs.access_flags().is_static()) continue;
|
||||
fieldDescriptor fd;
|
||||
fd.initialize(k, fs.index());
|
||||
fieldDescriptor& fd = fs.field_descriptor();
|
||||
ciField* field = new (arena) ciField(&fd);
|
||||
fields->append(field);
|
||||
}
|
||||
|
|
|
@ -286,7 +286,10 @@ int ciMethod::itable_index() {
|
|||
check_is_loaded();
|
||||
assert(holder()->is_linked(), "must be linked");
|
||||
VM_ENTRY_MARK;
|
||||
return klassItable::compute_itable_index(get_Method());
|
||||
Method* m = get_Method();
|
||||
if (!m->has_itable_index())
|
||||
return Method::nonvirtual_vtable_index;
|
||||
return m->itable_index();
|
||||
}
|
||||
#endif // SHARK
|
||||
|
||||
|
@ -1137,6 +1140,10 @@ bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {
|
|||
// ------------------------------------------------------------------
|
||||
// ciMethod::check_call
|
||||
bool ciMethod::check_call(int refinfo_index, bool is_static) const {
|
||||
// This method is used only in C2 from InlineTree::ok_to_inline,
|
||||
// and is only used under -Xcomp or -XX:CompileTheWorld.
|
||||
// It appears to fail when applied to an invokeinterface call site.
|
||||
// FIXME: Remove this method and resolve_method_statically; refactor to use the other LinkResolver entry points.
|
||||
VM_ENTRY_MARK;
|
||||
{
|
||||
EXCEPTION_MARK;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
|
@ -44,6 +44,7 @@ class ciSymbol : public ciBaseObject {
|
|||
friend class ciInstanceKlass;
|
||||
friend class ciSignature;
|
||||
friend class ciMethod;
|
||||
friend class ciField;
|
||||
friend class ciObjArrayKlass;
|
||||
|
||||
private:
|
||||
|
|
|
@ -3995,9 +3995,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
|||
this_klass->set_has_final_method();
|
||||
}
|
||||
this_klass->copy_method_ordering(method_ordering, CHECK_NULL);
|
||||
// The InstanceKlass::_methods_jmethod_ids cache and the
|
||||
// InstanceKlass::_methods_cached_itable_indices cache are
|
||||
// both managed on the assumption that the initial cache
|
||||
// The InstanceKlass::_methods_jmethod_ids cache
|
||||
// is managed on the assumption that the initial cache
|
||||
// size is equal to the number of methods in the class. If
|
||||
// that changes, then InstanceKlass::idnum_can_increment()
|
||||
// has to be changed accordingly.
|
||||
|
|
|
@ -1319,6 +1319,25 @@ static void clear_pending_exception_if_not_oom(TRAPS) {
|
|||
// The CHECK at the caller will propagate the exception out
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the given method should be compiled when doing compile-the-world.
|
||||
*
|
||||
* TODO: This should be a private method in a CompileTheWorld class.
|
||||
*/
|
||||
static bool can_be_compiled(methodHandle m, int comp_level) {
|
||||
assert(CompileTheWorld, "must be");
|
||||
|
||||
// It's not valid to compile a native wrapper for MethodHandle methods
|
||||
// that take a MemberName appendix since the bytecode signature is not
|
||||
// correct.
|
||||
vmIntrinsics::ID iid = m->intrinsic_id();
|
||||
if (MethodHandles::is_signature_polymorphic(iid) && MethodHandles::has_member_arg(iid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CompilationPolicy::can_be_compiled(m, comp_level);
|
||||
}
|
||||
|
||||
void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
|
||||
int len = (int)strlen(name);
|
||||
if (len > 6 && strcmp(".class", name + len - 6) == 0) {
|
||||
|
@ -1362,8 +1381,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
|
|||
int comp_level = CompilationPolicy::policy()->initial_compile_level();
|
||||
for (int n = 0; n < k->methods()->length(); n++) {
|
||||
methodHandle m (THREAD, k->methods()->at(n));
|
||||
if (CompilationPolicy::can_be_compiled(m, comp_level)) {
|
||||
|
||||
if (can_be_compiled(m, comp_level)) {
|
||||
if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) {
|
||||
// Give sweeper a chance to keep up with CTW
|
||||
VM_ForceSafepoint op;
|
||||
|
@ -1375,7 +1393,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
|
|||
methodHandle(), 0, "CTW", THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
clear_pending_exception_if_not_oom(CHECK);
|
||||
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string());
|
||||
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
|
||||
} else {
|
||||
_compile_the_world_method_counter++;
|
||||
}
|
||||
|
@ -1391,11 +1409,13 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
|
|||
methodHandle(), 0, "CTW", THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
clear_pending_exception_if_not_oom(CHECK);
|
||||
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name()->as_C_string());
|
||||
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
|
||||
} else {
|
||||
_compile_the_world_method_counter++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
nmethod* nm = m->code();
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -161,31 +161,36 @@ address CompiledIC::stub_address() const {
|
|||
|
||||
|
||||
void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {
|
||||
methodHandle method = call_info->selected_method();
|
||||
bool is_invoke_interface = (bytecode == Bytecodes::_invokeinterface && !call_info->has_vtable_index());
|
||||
assert(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "");
|
||||
assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
|
||||
assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");
|
||||
|
||||
address entry;
|
||||
if (is_invoke_interface) {
|
||||
int index = klassItable::compute_itable_index(call_info->resolved_method()());
|
||||
entry = VtableStubs::create_stub(false, index, method());
|
||||
if (call_info->call_kind() == CallInfo::itable_call) {
|
||||
assert(bytecode == Bytecodes::_invokeinterface, "");
|
||||
int itable_index = call_info->itable_index();
|
||||
entry = VtableStubs::find_itable_stub(itable_index);
|
||||
#ifdef ASSERT
|
||||
assert(entry != NULL, "entry not computed");
|
||||
int index = call_info->resolved_method()->itable_index();
|
||||
assert(index == itable_index, "CallInfo pre-computes this");
|
||||
#endif //ASSERT
|
||||
InstanceKlass* k = call_info->resolved_method()->method_holder();
|
||||
assert(k->is_interface(), "sanity check");
|
||||
assert(k->verify_itable_index(itable_index), "sanity check");
|
||||
InlineCacheBuffer::create_transition_stub(this, k, entry);
|
||||
} else {
|
||||
// Can be different than method->vtable_index(), due to package-private etc.
|
||||
assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
|
||||
// Can be different than selected_method->vtable_index(), due to package-private etc.
|
||||
int vtable_index = call_info->vtable_index();
|
||||
entry = VtableStubs::create_stub(true, vtable_index, method());
|
||||
InlineCacheBuffer::create_transition_stub(this, method(), entry);
|
||||
assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
|
||||
entry = VtableStubs::find_vtable_stub(vtable_index);
|
||||
InlineCacheBuffer::create_transition_stub(this, NULL, entry);
|
||||
}
|
||||
|
||||
if (TraceICs) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT,
|
||||
instruction_address(), method->print_value_string(), entry);
|
||||
instruction_address(), call_info->selected_method()->print_value_string(), entry);
|
||||
}
|
||||
|
||||
// We can't check this anymore. With lazy deopt we could have already
|
||||
|
|
|
@ -111,7 +111,7 @@ void VtableStubs::initialize() {
|
|||
}
|
||||
|
||||
|
||||
address VtableStubs::create_stub(bool is_vtable_stub, int vtable_index, Method* method) {
|
||||
address VtableStubs::find_stub(bool is_vtable_stub, int vtable_index) {
|
||||
assert(vtable_index >= 0, "must be positive");
|
||||
|
||||
VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL;
|
||||
|
|
|
@ -121,9 +121,11 @@ class VtableStubs : AllStatic {
|
|||
static VtableStub* lookup (bool is_vtable_stub, int vtable_index);
|
||||
static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s);
|
||||
static inline uint hash (bool is_vtable_stub, int vtable_index);
|
||||
static address find_stub (bool is_vtable_stub, int vtable_index);
|
||||
|
||||
public:
|
||||
static address create_stub(bool is_vtable_stub, int vtable_index, Method* method); // return the entry point of a stub for this call
|
||||
static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); }
|
||||
static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); }
|
||||
static bool is_entry_point(address pc); // is pc a vtable stub entry point?
|
||||
static bool contains(address pc); // is pc within any stub?
|
||||
static VtableStub* stub_containing(address pc); // stub containing pc or NULL
|
||||
|
|
|
@ -230,7 +230,7 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
|
|||
// depends on this property.
|
||||
debug_only(
|
||||
FreeChunk* junk = NULL;
|
||||
assert(UseCompressedKlassPointers ||
|
||||
assert(UseCompressedClassPointers ||
|
||||
junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
|
||||
"Offset of FreeChunk::_prev within FreeChunk must match"
|
||||
" that of OopDesc::_klass within OopDesc");
|
||||
|
@ -1407,7 +1407,7 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
|
|||
assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size");
|
||||
OrderAccess::storestore();
|
||||
|
||||
if (UseCompressedKlassPointers) {
|
||||
if (UseCompressedClassPointers) {
|
||||
// Copy gap missed by (aligned) header size calculation below
|
||||
obj->set_klass_gap(old->klass_gap());
|
||||
}
|
||||
|
|
|
@ -481,9 +481,8 @@ uint ConcurrentMark::scale_parallel_threads(uint n_par_threads) {
|
|||
|
||||
ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) :
|
||||
_g1h(g1h),
|
||||
_markBitMap1(MinObjAlignment - 1),
|
||||
_markBitMap2(MinObjAlignment - 1),
|
||||
|
||||
_markBitMap1(log2_intptr(MinObjAlignment)),
|
||||
_markBitMap2(log2_intptr(MinObjAlignment)),
|
||||
_parallel_marking_threads(0),
|
||||
_max_parallel_marking_threads(0),
|
||||
_sleep_factor(0.0),
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
|
||||
if (has_count_table()) {
|
||||
check_card_num(from_card_num,
|
||||
assert(from_card_num >= 0 && from_card_num < _committed_max_card_num,
|
||||
err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
|
||||
assert(from_card_num < to_card_num,
|
||||
err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
|
||||
|
|
|
@ -72,24 +72,20 @@ class G1CardCounts: public CHeapObj<mtGC> {
|
|||
return has_reserved_count_table() && _committed_max_card_num > 0;
|
||||
}
|
||||
|
||||
void check_card_num(size_t card_num, const char* msg) {
|
||||
assert(card_num >= 0 && card_num < _committed_max_card_num, msg);
|
||||
}
|
||||
|
||||
size_t ptr_2_card_num(const jbyte* card_ptr) {
|
||||
assert(card_ptr >= _ct_bot,
|
||||
err_msg("Inavalied card pointer: "
|
||||
err_msg("Invalid card pointer: "
|
||||
"card_ptr: " PTR_FORMAT ", "
|
||||
"_ct_bot: " PTR_FORMAT,
|
||||
card_ptr, _ct_bot));
|
||||
size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte));
|
||||
check_card_num(card_num,
|
||||
assert(card_num >= 0 && card_num < _committed_max_card_num,
|
||||
err_msg("card pointer out of range: " PTR_FORMAT, card_ptr));
|
||||
return card_num;
|
||||
}
|
||||
|
||||
jbyte* card_num_2_ptr(size_t card_num) {
|
||||
check_card_num(card_num,
|
||||
assert(card_num >= 0 && card_num < _committed_max_card_num,
|
||||
err_msg("card num out of range: "SIZE_FORMAT, card_num));
|
||||
return (jbyte*) (_ct_bot + card_num);
|
||||
}
|
||||
|
|
|
@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() {
|
|||
return JNI_OK;
|
||||
}
|
||||
|
||||
size_t G1CollectedHeap::conservative_max_heap_alignment() {
|
||||
return HeapRegion::max_region_size();
|
||||
}
|
||||
|
||||
void G1CollectedHeap::ref_processing_init() {
|
||||
// Reference processing in G1 currently works as follows:
|
||||
//
|
||||
|
|
|
@ -1092,6 +1092,9 @@ public:
|
|||
// specified by the policy object.
|
||||
jint initialize();
|
||||
|
||||
// Return the (conservative) maximum heap alignment for any G1 heap
|
||||
static size_t conservative_max_heap_alignment();
|
||||
|
||||
// Initialize weak reference processing.
|
||||
virtual void ref_processing_init();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
|
@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
|
|||
// many regions in the heap (based on the min heap size).
|
||||
#define TARGET_REGION_NUMBER 2048
|
||||
|
||||
size_t HeapRegion::max_region_size() {
|
||||
return (size_t)MAX_REGION_SIZE;
|
||||
}
|
||||
|
||||
void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
|
||||
uintx region_size = G1HeapRegionSize;
|
||||
if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
|
@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
|||
~((1 << (size_t) LogOfHRGrainBytes) - 1);
|
||||
}
|
||||
|
||||
static size_t max_region_size();
|
||||
|
||||
// It sets up the heap region size (GrainBytes / GrainWords), as
|
||||
// well as other related fields that are based on the heap region
|
||||
// size (LogOfHRGrainBytes / LogOfHRGrainWords /
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
class PtrQueueSet;
|
||||
class PtrQueue VALUE_OBJ_CLASS_SPEC {
|
||||
friend class VMStructs;
|
||||
|
||||
protected:
|
||||
// The ptr queue set to which this queue belongs.
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define VM_STRUCTS_G1(nonstatic_field, static_field) \
|
||||
\
|
||||
static_field(HeapRegion, GrainBytes, size_t) \
|
||||
static_field(HeapRegion, LogOfHRGrainBytes, int) \
|
||||
\
|
||||
nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \
|
||||
nonstatic_field(HeapRegionSeq, _length, uint) \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
|
@ -68,9 +68,6 @@ class GenerationSizer : public TwoGenerationCollectorPolicy {
|
|||
size_t min_old_gen_size() { return _min_gen1_size; }
|
||||
size_t old_gen_size() { return _initial_gen1_size; }
|
||||
size_t max_old_gen_size() { return _max_gen1_size; }
|
||||
|
||||
size_t metaspace_size() { return MetaspaceSize; }
|
||||
size_t max_metaspace_size() { return MaxMetaspaceSize; }
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP
|
||||
|
|
|
@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap {
|
|||
set_alignment(_old_gen_alignment, intra_heap_alignment());
|
||||
}
|
||||
|
||||
// Return the (conservative) maximum heap alignment
|
||||
static size_t conservative_max_heap_alignment() {
|
||||
return intra_heap_alignment();
|
||||
}
|
||||
|
||||
// For use by VM operations
|
||||
enum CollectionType {
|
||||
Scavenge,
|
||||
|
@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap {
|
|||
|
||||
// The alignment used for eden and survivors within the young gen
|
||||
// and for boundary between young gen and old gen.
|
||||
size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; }
|
||||
static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; }
|
||||
|
||||
size_t capacity() const;
|
||||
size_t used() const;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
|
@ -26,11 +26,9 @@
|
|||
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP
|
||||
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/shared/gcUtil.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/shared/gcUtil.hpp"
|
||||
|
||||
class AllocationStats VALUE_OBJ_CLASS_SPEC {
|
||||
// A duration threshold (in ms) used to filter
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
|
@ -26,11 +26,9 @@
|
|||
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP
|
||||
|
||||
#include "utilities/macros.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/shared/generationCounters.hpp"
|
||||
#include "memory/generation.hpp"
|
||||
#include "runtime/perfData.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
// A HSpaceCounter is a holder class for performance counters
|
||||
// that track a collections (logical spaces) in a heap;
|
||||
|
|
|
@ -87,15 +87,15 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
|
|||
const MetaspaceSizes meta_space(
|
||||
MetaspaceAux::allocated_capacity_bytes(),
|
||||
MetaspaceAux::allocated_used_bytes(),
|
||||
MetaspaceAux::reserved_in_bytes());
|
||||
MetaspaceAux::reserved_bytes());
|
||||
const MetaspaceSizes data_space(
|
||||
MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType),
|
||||
MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType),
|
||||
MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType));
|
||||
MetaspaceAux::reserved_bytes(Metaspace::NonClassType));
|
||||
const MetaspaceSizes class_space(
|
||||
MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType),
|
||||
MetaspaceAux::allocated_used_bytes(Metaspace::ClassType),
|
||||
MetaspaceAux::reserved_in_bytes(Metaspace::ClassType));
|
||||
MetaspaceAux::reserved_bytes(Metaspace::ClassType));
|
||||
|
||||
return MetaspaceSummary(meta_space, data_space, class_space);
|
||||
}
|
||||
|
|
|
@ -496,15 +496,15 @@ IRT_END
|
|||
|
||||
IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode))
|
||||
// resolve field
|
||||
FieldAccessInfo info;
|
||||
fieldDescriptor info;
|
||||
constantPoolHandle pool(thread, method(thread)->constants());
|
||||
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic);
|
||||
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
|
||||
|
||||
{
|
||||
JvmtiHideSingleStepping jhss(thread);
|
||||
LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode),
|
||||
bytecode, false, CHECK);
|
||||
LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
|
||||
bytecode, CHECK);
|
||||
} // end JvmtiHideSingleStepping
|
||||
|
||||
// check if link resolution caused cpCache to be updated
|
||||
|
@ -524,7 +524,7 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
|
|||
// class is intitialized. This is required so that access to the static
|
||||
// field will call the initialization function every time until the class
|
||||
// is completely initialized ala. in 2.17.5 in JVM Specification.
|
||||
InstanceKlass *klass = InstanceKlass::cast(info.klass()());
|
||||
InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
|
||||
bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
|
||||
!klass->is_initialized());
|
||||
Bytecodes::Code get_code = (Bytecodes::Code)0;
|
||||
|
@ -539,9 +539,9 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecode
|
|||
cache_entry(thread)->set_field(
|
||||
get_code,
|
||||
put_code,
|
||||
info.klass(),
|
||||
info.field_index(),
|
||||
info.field_offset(),
|
||||
info.field_holder(),
|
||||
info.index(),
|
||||
info.offset(),
|
||||
state,
|
||||
info.access_flags().is_final(),
|
||||
info.access_flags().is_volatile(),
|
||||
|
@ -686,29 +686,55 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
|
|||
if (already_resolved(thread)) return;
|
||||
|
||||
if (bytecode == Bytecodes::_invokeinterface) {
|
||||
|
||||
if (TraceItables && Verbose) {
|
||||
ResourceMark rm(thread);
|
||||
tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string());
|
||||
}
|
||||
}
|
||||
#ifdef ASSERT
|
||||
if (bytecode == Bytecodes::_invokeinterface) {
|
||||
if (info.resolved_method()->method_holder() ==
|
||||
SystemDictionary::Object_klass()) {
|
||||
// NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec
|
||||
// (see also cpCacheOop.cpp for details)
|
||||
// (see also CallInfo::set_interface for details)
|
||||
assert(info.call_kind() == CallInfo::vtable_call ||
|
||||
info.call_kind() == CallInfo::direct_call, "");
|
||||
methodHandle rm = info.resolved_method();
|
||||
assert(rm->is_final() || info.has_vtable_index(),
|
||||
"should have been set already");
|
||||
cache_entry(thread)->set_method(bytecode, rm, info.vtable_index());
|
||||
} else if (!info.resolved_method()->has_itable_index()) {
|
||||
// Resolved something like CharSequence.toString. Use vtable not itable.
|
||||
assert(info.call_kind() != CallInfo::itable_call, "");
|
||||
} else {
|
||||
// Setup itable entry
|
||||
int index = klassItable::compute_itable_index(info.resolved_method()());
|
||||
cache_entry(thread)->set_interface_call(info.resolved_method(), index);
|
||||
assert(info.call_kind() == CallInfo::itable_call, "");
|
||||
int index = info.resolved_method()->itable_index();
|
||||
assert(info.itable_index() == index, "");
|
||||
}
|
||||
} else {
|
||||
cache_entry(thread)->set_method(
|
||||
assert(info.call_kind() == CallInfo::direct_call ||
|
||||
info.call_kind() == CallInfo::vtable_call, "");
|
||||
}
|
||||
#endif
|
||||
switch (info.call_kind()) {
|
||||
case CallInfo::direct_call:
|
||||
cache_entry(thread)->set_direct_call(
|
||||
bytecode,
|
||||
info.resolved_method());
|
||||
break;
|
||||
case CallInfo::vtable_call:
|
||||
cache_entry(thread)->set_vtable_call(
|
||||
bytecode,
|
||||
info.resolved_method(),
|
||||
info.vtable_index());
|
||||
break;
|
||||
case CallInfo::itable_call:
|
||||
cache_entry(thread)->set_itable_call(
|
||||
bytecode,
|
||||
info.resolved_method(),
|
||||
info.itable_index());
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
IRT_END
|
||||
|
|
|
@ -46,19 +46,6 @@
|
|||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/vmThread.hpp"
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Implementation of FieldAccessInfo
|
||||
|
||||
void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
|
||||
BasicType field_type, AccessFlags access_flags) {
|
||||
_klass = klass;
|
||||
_name = name;
|
||||
_field_index = field_index;
|
||||
_field_offset = field_offset;
|
||||
_field_type = field_type;
|
||||
_access_flags = access_flags;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Implementation of CallInfo
|
||||
|
@ -66,26 +53,25 @@ BasicType field_type, AccessFlags access_flags) {
|
|||
|
||||
void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
|
||||
int vtable_index = Method::nonvirtual_vtable_index;
|
||||
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
|
||||
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
|
||||
}
|
||||
|
||||
|
||||
void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) {
|
||||
void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) {
|
||||
// This is only called for interface methods. If the resolved_method
|
||||
// comes from java/lang/Object, it can be the subject of a virtual call, so
|
||||
// we should pick the vtable index from the resolved method.
|
||||
// Other than that case, there is no valid vtable index to specify.
|
||||
int vtable_index = Method::invalid_vtable_index;
|
||||
if (resolved_method->method_holder() == SystemDictionary::Object_klass()) {
|
||||
assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check");
|
||||
vtable_index = resolved_method->vtable_index();
|
||||
}
|
||||
set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
|
||||
// In that case, the caller must call set_virtual instead of set_interface.
|
||||
assert(resolved_method->method_holder()->is_interface(), "");
|
||||
assert(itable_index == resolved_method()->itable_index(), "");
|
||||
set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK);
|
||||
}
|
||||
|
||||
void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
|
||||
assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index");
|
||||
set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
|
||||
assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), "");
|
||||
CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call);
|
||||
set_common(resolved_klass, selected_klass, resolved_method, selected_method, kind, vtable_index, CHECK);
|
||||
assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
|
||||
}
|
||||
|
||||
|
@ -98,20 +84,29 @@ void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix
|
|||
resolved_method->is_compiled_lambda_form(),
|
||||
"linkMethod must return one of these");
|
||||
int vtable_index = Method::nonvirtual_vtable_index;
|
||||
assert(resolved_method->vtable_index() == vtable_index, "");
|
||||
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
|
||||
assert(!resolved_method->has_vtable_index(), "");
|
||||
set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
|
||||
_resolved_appendix = resolved_appendix;
|
||||
_resolved_method_type = resolved_method_type;
|
||||
}
|
||||
|
||||
void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
|
||||
void CallInfo::set_common(KlassHandle resolved_klass,
|
||||
KlassHandle selected_klass,
|
||||
methodHandle resolved_method,
|
||||
methodHandle selected_method,
|
||||
CallKind kind,
|
||||
int index,
|
||||
TRAPS) {
|
||||
assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
|
||||
_resolved_klass = resolved_klass;
|
||||
_selected_klass = selected_klass;
|
||||
_resolved_method = resolved_method;
|
||||
_selected_method = selected_method;
|
||||
_vtable_index = vtable_index;
|
||||
_call_kind = kind;
|
||||
_call_index = index;
|
||||
_resolved_appendix = Handle();
|
||||
DEBUG_ONLY(verify()); // verify before making side effects
|
||||
|
||||
if (CompilationPolicy::must_be_compiled(selected_method)) {
|
||||
// This path is unusual, mostly used by the '-Xcomp' stress test mode.
|
||||
|
||||
|
@ -138,6 +133,65 @@ void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass
|
|||
}
|
||||
}
|
||||
|
||||
// utility query for unreflecting a method
|
||||
CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) {
|
||||
Klass* resolved_method_holder = resolved_method->method_holder();
|
||||
if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st
|
||||
resolved_klass = resolved_method_holder;
|
||||
}
|
||||
_resolved_klass = resolved_klass;
|
||||
_selected_klass = resolved_klass;
|
||||
_resolved_method = resolved_method;
|
||||
_selected_method = resolved_method;
|
||||
// classify:
|
||||
CallKind kind = CallInfo::unknown_kind;
|
||||
int index = resolved_method->vtable_index();
|
||||
if (resolved_method->can_be_statically_bound()) {
|
||||
kind = CallInfo::direct_call;
|
||||
} else if (!resolved_method_holder->is_interface()) {
|
||||
// Could be an Object method inherited into an interface, but still a vtable call.
|
||||
kind = CallInfo::vtable_call;
|
||||
} else if (!resolved_klass->is_interface()) {
|
||||
// A miranda method. Compute the vtable index.
|
||||
ResourceMark rm;
|
||||
klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
|
||||
index = vt->index_of_miranda(resolved_method->name(),
|
||||
resolved_method->signature());
|
||||
kind = CallInfo::vtable_call;
|
||||
} else {
|
||||
// A regular interface call.
|
||||
kind = CallInfo::itable_call;
|
||||
index = resolved_method->itable_index();
|
||||
}
|
||||
assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index));
|
||||
_call_kind = kind;
|
||||
_call_index = index;
|
||||
_resolved_appendix = Handle();
|
||||
DEBUG_ONLY(verify());
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void CallInfo::verify() {
|
||||
switch (call_kind()) { // the meaning and allowed value of index depends on kind
|
||||
case CallInfo::direct_call:
|
||||
if (_call_index == Method::nonvirtual_vtable_index) break;
|
||||
// else fall through to check vtable index:
|
||||
case CallInfo::vtable_call:
|
||||
assert(resolved_klass()->verify_vtable_index(_call_index), "");
|
||||
break;
|
||||
case CallInfo::itable_call:
|
||||
assert(resolved_method()->method_holder()->verify_itable_index(_call_index), "");
|
||||
break;
|
||||
case CallInfo::unknown_kind:
|
||||
assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
|
||||
break;
|
||||
default:
|
||||
fatal(err_msg_res("Unexpected call kind %d", call_kind()));
|
||||
}
|
||||
}
|
||||
#endif //ASSERT
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Klass resolution
|
||||
|
@ -163,13 +217,6 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i
|
|||
result = KlassHandle(THREAD, result_oop);
|
||||
}
|
||||
|
||||
void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
|
||||
Klass* result_oop =
|
||||
ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK);
|
||||
result = KlassHandle(THREAD, result_oop);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Method resolution
|
||||
//
|
||||
|
@ -360,7 +407,12 @@ void LinkResolver::check_method_accessability(KlassHandle ref_klass,
|
|||
|
||||
void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
|
||||
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
|
||||
|
||||
// This method is used only
|
||||
// (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
|
||||
// and
|
||||
// (2) in Bytecode_invoke::static_target
|
||||
// It appears to fail when applied to an invokeinterface call site.
|
||||
// FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
|
||||
// resolve klass
|
||||
if (code == Bytecodes::_invokedynamic) {
|
||||
resolved_klass = SystemDictionary::MethodHandle_klass();
|
||||
|
@ -580,45 +632,49 @@ void LinkResolver::check_field_accessability(KlassHandle ref_klass,
|
|||
}
|
||||
}
|
||||
|
||||
void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
|
||||
resolve_field(result, pool, index, byte, check_only, true, CHECK);
|
||||
void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
|
||||
// Load these early in case the resolve of the containing klass fails
|
||||
Symbol* field = pool->name_ref_at(index);
|
||||
Symbol* sig = pool->signature_ref_at(index);
|
||||
|
||||
// resolve specified klass
|
||||
KlassHandle resolved_klass;
|
||||
resolve_klass(resolved_klass, pool, index, CHECK);
|
||||
|
||||
KlassHandle current_klass(THREAD, pool->pool_holder());
|
||||
resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK);
|
||||
}
|
||||
|
||||
void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) {
|
||||
void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig,
|
||||
KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class,
|
||||
TRAPS) {
|
||||
assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
|
||||
byte == Bytecodes::_getfield || byte == Bytecodes::_putfield, "bad bytecode");
|
||||
byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
|
||||
(byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
|
||||
|
||||
bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
|
||||
bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic);
|
||||
|
||||
// resolve specified klass
|
||||
KlassHandle resolved_klass;
|
||||
if (update_pool) {
|
||||
resolve_klass(resolved_klass, pool, index, CHECK);
|
||||
} else {
|
||||
resolve_klass_no_update(resolved_klass, pool, index, CHECK);
|
||||
}
|
||||
// Load these early in case the resolve of the containing klass fails
|
||||
Symbol* field = pool->name_ref_at(index);
|
||||
Symbol* sig = pool->signature_ref_at(index);
|
||||
// Check if there's a resolved klass containing the field
|
||||
if( resolved_klass.is_null() ) {
|
||||
if (resolved_klass.is_null()) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
|
||||
}
|
||||
|
||||
// Resolve instance field
|
||||
fieldDescriptor fd; // find_field initializes fd if found
|
||||
KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
|
||||
// check if field exists; i.e., if a klass containing the field def has been selected
|
||||
if (sel_klass.is_null()){
|
||||
if (sel_klass.is_null()) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
|
||||
}
|
||||
|
||||
if (!check_access)
|
||||
// Access checking may be turned off when calling from within the VM.
|
||||
return;
|
||||
|
||||
// check access
|
||||
KlassHandle ref_klass(THREAD, pool->pool_holder());
|
||||
check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
|
||||
check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
|
||||
|
||||
// check for errors
|
||||
if (is_static != fd.is_static()) {
|
||||
|
@ -629,7 +685,7 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||
}
|
||||
|
||||
// Final fields can only be accessed from its own class.
|
||||
if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
|
||||
if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
|
||||
THROW(vmSymbols::java_lang_IllegalAccessError());
|
||||
}
|
||||
|
||||
|
@ -639,19 +695,18 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||
//
|
||||
// note 2: we don't want to force initialization if we are just checking
|
||||
// if the field access is legal; e.g., during compilation
|
||||
if (is_static && !check_only) {
|
||||
if (is_static && initialize_class) {
|
||||
sel_klass->initialize(CHECK);
|
||||
}
|
||||
|
||||
{
|
||||
if (sel_klass() != current_klass()) {
|
||||
HandleMark hm(THREAD);
|
||||
Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader());
|
||||
Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
|
||||
Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader());
|
||||
Symbol* signature_ref = pool->signature_ref_at(index);
|
||||
{
|
||||
ResourceMark rm(THREAD);
|
||||
Symbol* failed_type_symbol =
|
||||
SystemDictionary::check_signature_loaders(signature_ref,
|
||||
SystemDictionary::check_signature_loaders(sig,
|
||||
ref_loader, sel_loader,
|
||||
false,
|
||||
CHECK);
|
||||
|
@ -677,9 +732,6 @@ void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle poo
|
|||
|
||||
// return information. note that the klass is set to the actual klass containing the
|
||||
// field, otherwise access of static fields in superclasses will not work.
|
||||
KlassHandle holder (THREAD, fd.field_holder());
|
||||
Symbol* name = fd.name();
|
||||
result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
|
||||
}
|
||||
|
||||
|
||||
|
@ -906,10 +958,6 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
|||
THROW(vmSymbols::java_lang_NullPointerException());
|
||||
}
|
||||
|
||||
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
|
||||
// has not been rewritten, and the vtable initialized.
|
||||
assert(resolved_method->method_holder()->is_linked(), "must be linked");
|
||||
|
||||
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
|
||||
// has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
|
||||
// a missing receiver might result in a bogus lookup.
|
||||
|
@ -920,6 +968,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
|||
vtable_index = vtable_index_of_miranda_method(resolved_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature(), CHECK);
|
||||
|
||||
assert(vtable_index >= 0 , "we should have valid vtable index at this point");
|
||||
|
||||
InstanceKlass* inst = InstanceKlass::cast(recv_klass());
|
||||
|
@ -927,6 +976,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
|||
} else {
|
||||
// at this point we are sure that resolved_method is virtual and not
|
||||
// a miranda method; therefore, it must have a valid vtable index.
|
||||
assert(!resolved_method->has_itable_index(), "");
|
||||
vtable_index = resolved_method->vtable_index();
|
||||
// We could get a negative vtable_index for final methods,
|
||||
// because as an optimization they are they are never put in the vtable,
|
||||
|
@ -1006,6 +1056,12 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||
lookup_instance_method_in_klasses(sel_method, recv_klass,
|
||||
resolved_method->name(),
|
||||
resolved_method->signature(), CHECK);
|
||||
if (sel_method.is_null() && !check_null_and_abstract) {
|
||||
// In theory this is a harmless placeholder value, but
|
||||
// in practice leaving in null affects the nsk default method tests.
|
||||
// This needs further study.
|
||||
sel_method = resolved_method;
|
||||
}
|
||||
// check if method exists
|
||||
if (sel_method.is_null()) {
|
||||
ResourceMark rm(THREAD);
|
||||
|
@ -1046,7 +1102,14 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
|||
sel_method->signature()));
|
||||
}
|
||||
// setup result
|
||||
result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
|
||||
if (!resolved_method->has_itable_index()) {
|
||||
int vtable_index = resolved_method->vtable_index();
|
||||
assert(vtable_index == sel_method->vtable_index(), "sanity check");
|
||||
result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
|
||||
return;
|
||||
}
|
||||
int itable_index = resolved_method()->itable_index();
|
||||
result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1293,6 +1356,7 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
|
|||
}
|
||||
|
||||
if (TraceMethodHandles) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("resolve_invokedynamic #%d %s %s",
|
||||
ConstantPool::decode_invokedynamic_index(index),
|
||||
method_name->as_C_string(), method_signature->as_C_string());
|
||||
|
@ -1342,9 +1406,16 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
|||
//------------------------------------------------------------------------------------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
|
||||
void FieldAccessInfo::print() {
|
||||
void CallInfo::print() {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset());
|
||||
const char* kindstr = "unknown";
|
||||
switch (_call_kind) {
|
||||
case direct_call: kindstr = "direct"; break;
|
||||
case vtable_call: kindstr = "vtable"; break;
|
||||
case itable_call: kindstr = "itable"; break;
|
||||
}
|
||||
tty->print_cr("Call %s@%d %s", kindstr, _call_index,
|
||||
_resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -30,63 +30,54 @@
|
|||
|
||||
// All the necessary definitions for run-time link resolution.
|
||||
|
||||
// LinkInfo & its subclasses provide all the information gathered
|
||||
// for a particular link after resolving it. A link is any reference
|
||||
// CallInfo provides all the information gathered for a particular
|
||||
// linked call site after resolving it. A link is any reference
|
||||
// made from within the bytecodes of a method to an object outside of
|
||||
// that method. If the info is invalid, the link has not been resolved
|
||||
// successfully.
|
||||
|
||||
class LinkInfo VALUE_OBJ_CLASS_SPEC {
|
||||
};
|
||||
|
||||
|
||||
// Link information for getfield/putfield & getstatic/putstatic bytecodes.
|
||||
|
||||
class FieldAccessInfo: public LinkInfo {
|
||||
protected:
|
||||
KlassHandle _klass;
|
||||
Symbol* _name;
|
||||
AccessFlags _access_flags;
|
||||
int _field_index; // original index in the klass
|
||||
int _field_offset;
|
||||
BasicType _field_type;
|
||||
|
||||
class CallInfo VALUE_OBJ_CLASS_SPEC {
|
||||
public:
|
||||
void set(KlassHandle klass, Symbol* name, int field_index, int field_offset,
|
||||
BasicType field_type, AccessFlags access_flags);
|
||||
KlassHandle klass() const { return _klass; }
|
||||
Symbol* name() const { return _name; }
|
||||
int field_index() const { return _field_index; }
|
||||
int field_offset() const { return _field_offset; }
|
||||
BasicType field_type() const { return _field_type; }
|
||||
AccessFlags access_flags() const { return _access_flags; }
|
||||
|
||||
// debugging
|
||||
void print() PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
|
||||
// Link information for all calls.
|
||||
|
||||
class CallInfo: public LinkInfo {
|
||||
// Ways that a method call might be selected (or not) based on receiver type.
|
||||
// Note that an invokevirtual instruction might be linked with no_dispatch,
|
||||
// and an invokeinterface instruction might be linked with any of the three options
|
||||
enum CallKind {
|
||||
direct_call, // jump into resolved_method (must be concrete)
|
||||
vtable_call, // select recv.klass.method_at_vtable(index)
|
||||
itable_call, // select recv.klass.method_at_itable(resolved_method.holder, index)
|
||||
unknown_kind = -1
|
||||
};
|
||||
private:
|
||||
KlassHandle _resolved_klass; // static receiver klass
|
||||
KlassHandle _resolved_klass; // static receiver klass, resolved from a symbolic reference
|
||||
KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass)
|
||||
methodHandle _resolved_method; // static target method
|
||||
methodHandle _selected_method; // dynamic (actual) target method
|
||||
int _vtable_index; // vtable index of selected method
|
||||
CallKind _call_kind; // kind of call (static(=bytecode static/special +
|
||||
// others inferred), vtable, itable)
|
||||
int _call_index; // vtable or itable index of selected class method (if any)
|
||||
Handle _resolved_appendix; // extra argument in constant pool (if CPCE::has_appendix)
|
||||
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
|
||||
|
||||
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS);
|
||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method , TRAPS);
|
||||
void set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index , TRAPS);
|
||||
void set_virtual( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
|
||||
void set_handle( methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
|
||||
void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index , TRAPS);
|
||||
void set_common( KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, CallKind kind, int index, TRAPS);
|
||||
|
||||
friend class LinkResolver;
|
||||
|
||||
public:
|
||||
CallInfo() {
|
||||
#ifndef PRODUCT
|
||||
_call_kind = CallInfo::unknown_kind;
|
||||
_call_index = Method::garbage_vtable_index;
|
||||
#endif //PRODUCT
|
||||
}
|
||||
|
||||
// utility to extract an effective CallInfo from a method and an optional receiver limit
|
||||
// does not queue the method for compilation
|
||||
CallInfo(Method* resolved_method, Klass* resolved_klass = NULL);
|
||||
|
||||
KlassHandle resolved_klass() const { return _resolved_klass; }
|
||||
KlassHandle selected_klass() const { return _selected_klass; }
|
||||
methodHandle resolved_method() const { return _resolved_method; }
|
||||
|
@ -95,21 +86,43 @@ class CallInfo: public LinkInfo {
|
|||
Handle resolved_method_type() const { return _resolved_method_type; }
|
||||
|
||||
BasicType result_type() const { return selected_method()->result_type(); }
|
||||
bool has_vtable_index() const { return _vtable_index >= 0; }
|
||||
bool is_statically_bound() const { return _vtable_index == Method::nonvirtual_vtable_index; }
|
||||
CallKind call_kind() const { return _call_kind; }
|
||||
int call_index() const { return _call_index; }
|
||||
int vtable_index() const {
|
||||
// Even for interface calls the vtable index could be non-negative.
|
||||
// See CallInfo::set_interface.
|
||||
assert(has_vtable_index() || is_statically_bound(), "");
|
||||
return _vtable_index;
|
||||
assert(call_kind() == vtable_call || call_kind() == direct_call, "");
|
||||
// The returned value is < 0 if the call is statically bound.
|
||||
// But, the returned value may be >= 0 even if the kind is direct_call.
|
||||
// It is up to the caller to decide which way to go.
|
||||
return _call_index;
|
||||
}
|
||||
int itable_index() const {
|
||||
assert(call_kind() == itable_call, "");
|
||||
// The returned value is always >= 0, a valid itable index.
|
||||
return _call_index;
|
||||
}
|
||||
|
||||
// debugging
|
||||
#ifdef ASSERT
|
||||
bool has_vtable_index() const { return _call_index >= 0 && _call_kind != CallInfo::itable_call; }
|
||||
bool is_statically_bound() const { return _call_index == Method::nonvirtual_vtable_index; }
|
||||
#endif //ASSERT
|
||||
void verify() PRODUCT_RETURN;
|
||||
void print() PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
// Link information for getfield/putfield & getstatic/putstatic bytecodes
|
||||
// is represented using a fieldDescriptor.
|
||||
|
||||
// The LinkResolver is used to resolve constant-pool references at run-time.
|
||||
// It does all necessary link-time checks & throws exceptions if necessary.
|
||||
|
||||
class LinkResolver: AllStatic {
|
||||
friend class klassVtable;
|
||||
friend class klassItable;
|
||||
|
||||
private:
|
||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
|
@ -120,7 +133,6 @@ class LinkResolver: AllStatic {
|
|||
static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
|
||||
|
||||
static void resolve_klass (KlassHandle& result, constantPoolHandle pool, int index, TRAPS);
|
||||
static void resolve_klass_no_update (KlassHandle& result, constantPoolHandle pool, int index, TRAPS); // no update of constantPool entry
|
||||
|
||||
static void resolve_pool (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
|
||||
|
||||
|
@ -148,9 +160,16 @@ class LinkResolver: AllStatic {
|
|||
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
|
||||
|
||||
// runtime/static resolving for fields
|
||||
static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS);
|
||||
// takes an extra bool argument "update_pool" to decide whether to update the constantPool during klass resolution.
|
||||
static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS);
|
||||
static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
|
||||
static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
|
||||
KlassHandle current_klass, Bytecodes::Code access_kind, bool check_access, bool initialize_class, TRAPS);
|
||||
|
||||
// source of access_kind codes:
|
||||
static Bytecodes::Code field_access_kind(bool is_static, bool is_put) {
|
||||
return (is_static
|
||||
? (is_put ? Bytecodes::_putstatic : Bytecodes::_getstatic)
|
||||
: (is_put ? Bytecodes::_putfield : Bytecodes::_getfield ));
|
||||
}
|
||||
|
||||
// runtime resolving:
|
||||
// resolved_klass = specified class (i.e., static receiver class)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
|
@ -33,10 +33,10 @@
|
|||
#include "runtime/globals.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
|
||||
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
|
|
|
@ -47,6 +47,11 @@
|
|||
|
||||
// CollectorPolicy methods.
|
||||
|
||||
// Align down. If the aligning result in 0, return 'alignment'.
|
||||
static size_t restricted_align_down(size_t size, size_t alignment) {
|
||||
return MAX2(alignment, align_size_down_(size, alignment));
|
||||
}
|
||||
|
||||
void CollectorPolicy::initialize_flags() {
|
||||
assert(max_alignment() >= min_alignment(),
|
||||
err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT,
|
||||
|
@ -59,18 +64,24 @@ void CollectorPolicy::initialize_flags() {
|
|||
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
|
||||
}
|
||||
|
||||
if (MetaspaceSize > MaxMetaspaceSize) {
|
||||
MaxMetaspaceSize = MetaspaceSize;
|
||||
}
|
||||
MetaspaceSize = MAX2(min_alignment(), align_size_down_(MetaspaceSize, min_alignment()));
|
||||
// Don't increase Metaspace size limit above specified.
|
||||
MaxMetaspaceSize = align_size_down(MaxMetaspaceSize, max_alignment());
|
||||
if (MetaspaceSize > MaxMetaspaceSize) {
|
||||
MetaspaceSize = MaxMetaspaceSize;
|
||||
if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) {
|
||||
FLAG_SET_ERGO(uintx, MaxMetaspaceSize,
|
||||
restricted_align_down(MaxMetaspaceSize, max_alignment()));
|
||||
}
|
||||
|
||||
MinMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MinMetaspaceExpansion, min_alignment()));
|
||||
MaxMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MaxMetaspaceExpansion, min_alignment()));
|
||||
if (MetaspaceSize > MaxMetaspaceSize) {
|
||||
FLAG_SET_ERGO(uintx, MetaspaceSize, MaxMetaspaceSize);
|
||||
}
|
||||
|
||||
if (!is_size_aligned(MetaspaceSize, min_alignment())) {
|
||||
FLAG_SET_ERGO(uintx, MetaspaceSize,
|
||||
restricted_align_down(MetaspaceSize, min_alignment()));
|
||||
}
|
||||
|
||||
assert(MetaspaceSize <= MaxMetaspaceSize, "Must be");
|
||||
|
||||
MinMetaspaceExpansion = restricted_align_down(MinMetaspaceExpansion, min_alignment());
|
||||
MaxMetaspaceExpansion = restricted_align_down(MaxMetaspaceExpansion, min_alignment());
|
||||
|
||||
MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());
|
||||
|
||||
|
@ -145,6 +156,30 @@ void CollectorPolicy::cleared_all_soft_refs() {
|
|||
_all_soft_refs_clear = true;
|
||||
}
|
||||
|
||||
size_t CollectorPolicy::compute_max_alignment() {
|
||||
// The card marking array and the offset arrays for old generations are
|
||||
// committed in os pages as well. Make sure they are entirely full (to
|
||||
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
||||
// byte entry and the os page size is 4096, the maximum heap size should
|
||||
// be 512*4096 = 2MB aligned.
|
||||
|
||||
// There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable
|
||||
// is supported.
|
||||
// Requirements of any new remembered set implementations must be added here.
|
||||
size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
|
||||
|
||||
// Parallel GC does its own alignment of the generations to avoid requiring a
|
||||
// large page (256M on some platforms) for the permanent generation. The
|
||||
// other collectors should also be updated to do their own alignment and then
|
||||
// this use of lcm() should be removed.
|
||||
if (UseLargePages && !UseParallelGC) {
|
||||
// in presence of large pages we have to make sure that our
|
||||
// alignment is large page aware
|
||||
alignment = lcm(os::large_page_size(), alignment);
|
||||
}
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
// GenCollectorPolicy methods.
|
||||
|
||||
|
@ -175,29 +210,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
|
|||
GCTimeRatio);
|
||||
}
|
||||
|
||||
size_t GenCollectorPolicy::compute_max_alignment() {
|
||||
// The card marking array and the offset arrays for old generations are
|
||||
// committed in os pages as well. Make sure they are entirely full (to
|
||||
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
||||
// byte entry and the os page size is 4096, the maximum heap size should
|
||||
// be 512*4096 = 2MB aligned.
|
||||
size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name());
|
||||
|
||||
// Parallel GC does its own alignment of the generations to avoid requiring a
|
||||
// large page (256M on some platforms) for the permanent generation. The
|
||||
// other collectors should also be updated to do their own alignment and then
|
||||
// this use of lcm() should be removed.
|
||||
if (UseLargePages && !UseParallelGC) {
|
||||
// in presence of large pages we have to make sure that our
|
||||
// alignment is large page aware
|
||||
alignment = lcm(os::large_page_size(), alignment);
|
||||
}
|
||||
|
||||
assert(alignment >= min_alignment(), "Must be");
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
void GenCollectorPolicy::initialize_flags() {
|
||||
// All sizes must be multiples of the generation granularity.
|
||||
set_min_alignment((uintx) Generation::GenGrain);
|
||||
|
|
|
@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
|||
{}
|
||||
|
||||
public:
|
||||
// Return maximum heap alignment that may be imposed by the policy
|
||||
static size_t compute_max_alignment();
|
||||
|
||||
void set_min_alignment(size_t align) { _min_alignment = align; }
|
||||
size_t min_alignment() { return _min_alignment; }
|
||||
void set_max_alignment(size_t align) { _max_alignment = align; }
|
||||
|
@ -234,9 +237,6 @@ class GenCollectorPolicy : public CollectorPolicy {
|
|||
// Try to allocate space by expanding the heap.
|
||||
virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
|
||||
|
||||
// compute max heap alignment
|
||||
size_t compute_max_alignment();
|
||||
|
||||
// Scale the base_size by NewRation according to
|
||||
// result = base_size / (NewRatio + 1)
|
||||
// and align by min_alignment()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
|
@ -148,6 +148,11 @@ public:
|
|||
return gen_policy()->size_policy();
|
||||
}
|
||||
|
||||
// Return the (conservative) maximum heap alignment
|
||||
static size_t conservative_max_heap_alignment() {
|
||||
return Generation::GenGrain;
|
||||
}
|
||||
|
||||
size_t capacity() const;
|
||||
size_t used() const;
|
||||
|
||||
|
|
|
@ -50,13 +50,6 @@
|
|||
// Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
|
||||
size_t Metablock::_min_block_byte_size = sizeof(Metablock);
|
||||
|
||||
#ifdef ASSERT
|
||||
size_t Metablock::_overhead =
|
||||
Chunk::aligned_overhead_size(sizeof(Metablock)) / BytesPerWord;
|
||||
#else
|
||||
size_t Metablock::_overhead = 0;
|
||||
#endif
|
||||
|
||||
// New blocks returned by the Metaspace are zero initialized.
|
||||
// We should fix the constructors to not assume this instead.
|
||||
Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {
|
||||
|
|
|
@ -48,7 +48,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC {
|
|||
} _header;
|
||||
} _block;
|
||||
static size_t _min_block_byte_size;
|
||||
static size_t _overhead;
|
||||
|
||||
typedef union block_t Block;
|
||||
typedef struct header_t Header;
|
||||
|
@ -73,7 +72,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC {
|
|||
void set_prev(Metablock* v) { _block._header._prev = v; }
|
||||
|
||||
static size_t min_block_byte_size() { return _min_block_byte_size; }
|
||||
static size_t overhead() { return _overhead; }
|
||||
|
||||
bool is_free() { return header()->_word_size != 0; }
|
||||
void clear_next() { set_next(NULL); }
|
||||
|
|
|
@ -51,7 +51,7 @@ const bool metaspace_slow_verify = false;
|
|||
// Parameters for stress mode testing
|
||||
const uint metadata_deallocate_a_lot_block = 10;
|
||||
const uint metadata_deallocate_a_lock_chunk = 3;
|
||||
size_t const allocation_from_dictionary_limit = 64 * K;
|
||||
size_t const allocation_from_dictionary_limit = 4 * K;
|
||||
|
||||
MetaWord* last_allocated = 0;
|
||||
|
||||
|
@ -177,8 +177,8 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
|
|||
void return_chunks(ChunkIndex index, Metachunk* chunks);
|
||||
|
||||
// Total of the space in the free chunks list
|
||||
size_t free_chunks_total();
|
||||
size_t free_chunks_total_in_bytes();
|
||||
size_t free_chunks_total_words();
|
||||
size_t free_chunks_total_bytes();
|
||||
|
||||
// Number of chunks in the free chunks list
|
||||
size_t free_chunks_count();
|
||||
|
@ -228,6 +228,10 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC {
|
|||
BlockTreeDictionary* _dictionary;
|
||||
static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size);
|
||||
|
||||
// Only allocate and split from freelist if the size of the allocation
|
||||
// is at least 1/4th the size of the available block.
|
||||
const static int WasteMultiplier = 4;
|
||||
|
||||
// Accessors
|
||||
BlockTreeDictionary* dictionary() const { return _dictionary; }
|
||||
|
||||
|
@ -287,6 +291,10 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
|
|||
MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
|
||||
MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
|
||||
|
||||
size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; }
|
||||
size_t expanded_words() const { return _virtual_space.committed_size() / BytesPerWord; }
|
||||
size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; }
|
||||
|
||||
// address of next available space in _virtual_space;
|
||||
// Accessors
|
||||
VirtualSpaceNode* next() { return _next; }
|
||||
|
@ -323,12 +331,10 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
|
|||
|
||||
// Allocate a chunk from the virtual space and return it.
|
||||
Metachunk* get_chunk_vs(size_t chunk_word_size);
|
||||
Metachunk* get_chunk_vs_with_expand(size_t chunk_word_size);
|
||||
|
||||
// Expands/shrinks the committed space in a virtual space. Delegates
|
||||
// to Virtualspace
|
||||
bool expand_by(size_t words, bool pre_touch = false);
|
||||
bool shrink_by(size_t words);
|
||||
|
||||
// In preparation for deleting this node, remove all the chunks
|
||||
// in the node from any freelist.
|
||||
|
@ -336,8 +342,6 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
|
|||
|
||||
#ifdef ASSERT
|
||||
// Debug support
|
||||
static void verify_virtual_space_total();
|
||||
static void verify_virtual_space_count();
|
||||
void mangle();
|
||||
#endif
|
||||
|
||||
|
@ -423,10 +427,13 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
|
|||
// Can this virtual list allocate >1 spaces? Also, used to determine
|
||||
// whether to allocate unlimited small chunks in this virtual space
|
||||
bool _is_class;
|
||||
bool can_grow() const { return !is_class() || !UseCompressedKlassPointers; }
|
||||
bool can_grow() const { return !is_class() || !UseCompressedClassPointers; }
|
||||
|
||||
// Sum of space in all virtual spaces and number of virtual spaces
|
||||
size_t _virtual_space_total;
|
||||
// Sum of reserved and committed memory in the virtual spaces
|
||||
size_t _reserved_words;
|
||||
size_t _committed_words;
|
||||
|
||||
// Number of virtual spaces
|
||||
size_t _virtual_space_count;
|
||||
|
||||
~VirtualSpaceList();
|
||||
|
@ -440,7 +447,7 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
|
|||
_current_virtual_space = v;
|
||||
}
|
||||
|
||||
void link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size);
|
||||
void link_vs(VirtualSpaceNode* new_entry);
|
||||
|
||||
// Get another virtual space and add it to the list. This
|
||||
// is typically prompted by a failed attempt to allocate a chunk
|
||||
|
@ -457,6 +464,8 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
|
|||
size_t grow_chunks_by_words,
|
||||
size_t medium_chunk_bunch);
|
||||
|
||||
bool expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch = false);
|
||||
|
||||
// Get the first chunk for a Metaspace. Used for
|
||||
// special cases such as the boot class loader, reflection
|
||||
// class loader and anonymous class loader.
|
||||
|
@ -472,10 +481,15 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
|
|||
// Allocate the first virtualspace.
|
||||
void initialize(size_t word_size);
|
||||
|
||||
size_t virtual_space_total() { return _virtual_space_total; }
|
||||
size_t reserved_words() { return _reserved_words; }
|
||||
size_t reserved_bytes() { return reserved_words() * BytesPerWord; }
|
||||
size_t committed_words() { return _committed_words; }
|
||||
size_t committed_bytes() { return committed_words() * BytesPerWord; }
|
||||
|
||||
void inc_virtual_space_total(size_t v);
|
||||
void dec_virtual_space_total(size_t v);
|
||||
void inc_reserved_words(size_t v);
|
||||
void dec_reserved_words(size_t v);
|
||||
void inc_committed_words(size_t v);
|
||||
void dec_committed_words(size_t v);
|
||||
void inc_virtual_space_count();
|
||||
void dec_virtual_space_count();
|
||||
|
||||
|
@ -623,6 +637,7 @@ class SpaceManager : public CHeapObj<mtClass> {
|
|||
|
||||
// Add chunk to the list of chunks in use
|
||||
void add_chunk(Metachunk* v, bool make_current);
|
||||
void retire_current_chunk();
|
||||
|
||||
Mutex* lock() const { return _lock; }
|
||||
|
||||
|
@ -722,9 +737,7 @@ class SpaceManager : public CHeapObj<mtClass> {
|
|||
// MinChunkSize is a placeholder for the real minimum size JJJ
|
||||
size_t byte_size = word_size * BytesPerWord;
|
||||
|
||||
size_t byte_size_with_overhead = byte_size + Metablock::overhead();
|
||||
|
||||
size_t raw_bytes_size = MAX2(byte_size_with_overhead,
|
||||
size_t raw_bytes_size = MAX2(byte_size,
|
||||
Metablock::min_block_byte_size());
|
||||
raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
|
||||
size_t raw_word_size = raw_bytes_size / BytesPerWord;
|
||||
|
@ -807,12 +820,25 @@ MetaWord* BlockFreelist::get_block(size_t word_size) {
|
|||
}
|
||||
|
||||
Metablock* free_block =
|
||||
dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::exactly);
|
||||
dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::atLeast);
|
||||
if (free_block == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (MetaWord*) free_block;
|
||||
const size_t block_size = free_block->size();
|
||||
if (block_size > WasteMultiplier * word_size) {
|
||||
return_block((MetaWord*)free_block, block_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaWord* new_block = (MetaWord*)free_block;
|
||||
assert(block_size >= word_size, "Incorrect size of block from freelist");
|
||||
const size_t unused = block_size - word_size;
|
||||
if (unused >= TreeChunk<Metablock, FreeList>::min_size()) {
|
||||
return_block(new_block + word_size, unused);
|
||||
}
|
||||
|
||||
return new_block;
|
||||
}
|
||||
|
||||
void BlockFreelist::print_on(outputStream* st) const {
|
||||
|
@ -855,9 +881,9 @@ Metachunk* VirtualSpaceNode::take_from_committed(size_t chunk_word_size) {
|
|||
|
||||
if (!is_available(chunk_word_size)) {
|
||||
if (TraceMetadataChunkAllocation) {
|
||||
tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size);
|
||||
gclog_or_tty->print("VirtualSpaceNode::take_from_committed() not available %d words ", chunk_word_size);
|
||||
// Dump some information about the virtual space that is nearly full
|
||||
print_on(tty);
|
||||
print_on(gclog_or_tty);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -878,20 +904,11 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) {
|
|||
if (TraceMetavirtualspaceAllocation && !result) {
|
||||
gclog_or_tty->print_cr("VirtualSpaceNode::expand_by() failed "
|
||||
"for byte size " SIZE_FORMAT, bytes);
|
||||
virtual_space()->print();
|
||||
virtual_space()->print_on(gclog_or_tty);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Shrink the virtual space (commit more of the reserved space)
|
||||
bool VirtualSpaceNode::shrink_by(size_t words) {
|
||||
size_t bytes = words * BytesPerWord;
|
||||
virtual_space()->shrink_by(bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add another chunk to the chunk list.
|
||||
|
||||
Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
Metachunk* result = take_from_committed(chunk_word_size);
|
||||
|
@ -901,23 +918,6 @@ Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
|
|||
return result;
|
||||
}
|
||||
|
||||
Metachunk* VirtualSpaceNode::get_chunk_vs_with_expand(size_t chunk_word_size) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
|
||||
Metachunk* new_chunk = get_chunk_vs(chunk_word_size);
|
||||
|
||||
if (new_chunk == NULL) {
|
||||
// Only a small part of the virtualspace is committed when first
|
||||
// allocated so committing more here can be expected.
|
||||
size_t page_size_words = os::vm_page_size() / BytesPerWord;
|
||||
size_t aligned_expand_vs_by_words = align_size_up(chunk_word_size,
|
||||
page_size_words);
|
||||
expand_by(aligned_expand_vs_by_words, false);
|
||||
new_chunk = get_chunk_vs(chunk_word_size);
|
||||
}
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
bool VirtualSpaceNode::initialize() {
|
||||
|
||||
if (!_rs.is_reserved()) {
|
||||
|
@ -977,13 +977,22 @@ VirtualSpaceList::~VirtualSpaceList() {
|
|||
}
|
||||
}
|
||||
|
||||
void VirtualSpaceList::inc_virtual_space_total(size_t v) {
|
||||
void VirtualSpaceList::inc_reserved_words(size_t v) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
_virtual_space_total = _virtual_space_total + v;
|
||||
_reserved_words = _reserved_words + v;
|
||||
}
|
||||
void VirtualSpaceList::dec_virtual_space_total(size_t v) {
|
||||
void VirtualSpaceList::dec_reserved_words(size_t v) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
_virtual_space_total = _virtual_space_total - v;
|
||||
_reserved_words = _reserved_words - v;
|
||||
}
|
||||
|
||||
void VirtualSpaceList::inc_committed_words(size_t v) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
_committed_words = _committed_words + v;
|
||||
}
|
||||
void VirtualSpaceList::dec_committed_words(size_t v) {
|
||||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
_committed_words = _committed_words - v;
|
||||
}
|
||||
|
||||
void VirtualSpaceList::inc_virtual_space_count() {
|
||||
|
@ -1034,7 +1043,8 @@ void VirtualSpaceList::purge() {
|
|||
}
|
||||
|
||||
vsl->purge(chunk_manager());
|
||||
dec_virtual_space_total(vsl->reserved()->word_size());
|
||||
dec_reserved_words(vsl->reserved_words());
|
||||
dec_committed_words(vsl->committed_words());
|
||||
dec_virtual_space_count();
|
||||
purged_vsl = vsl;
|
||||
delete vsl;
|
||||
|
@ -1062,12 +1072,12 @@ size_t VirtualSpaceList::used_words_sum() {
|
|||
// Sum used region [bottom, top) in each virtualspace
|
||||
allocated_by_vs += vsl->used_words_in_vs();
|
||||
}
|
||||
assert(allocated_by_vs >= chunk_manager()->free_chunks_total(),
|
||||
assert(allocated_by_vs >= chunk_manager()->free_chunks_total_words(),
|
||||
err_msg("Total in free chunks " SIZE_FORMAT
|
||||
" greater than total from virtual_spaces " SIZE_FORMAT,
|
||||
allocated_by_vs, chunk_manager()->free_chunks_total()));
|
||||
allocated_by_vs, chunk_manager()->free_chunks_total_words()));
|
||||
size_t used =
|
||||
allocated_by_vs - chunk_manager()->free_chunks_total();
|
||||
allocated_by_vs - chunk_manager()->free_chunks_total_words();
|
||||
return used;
|
||||
}
|
||||
|
||||
|
@ -1088,7 +1098,8 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
|
|||
_is_class(false),
|
||||
_virtual_space_list(NULL),
|
||||
_current_virtual_space(NULL),
|
||||
_virtual_space_total(0),
|
||||
_reserved_words(0),
|
||||
_committed_words(0),
|
||||
_virtual_space_count(0) {
|
||||
MutexLockerEx cl(SpaceManager::expand_lock(),
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
|
@ -1105,7 +1116,8 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
|
|||
_is_class(true),
|
||||
_virtual_space_list(NULL),
|
||||
_current_virtual_space(NULL),
|
||||
_virtual_space_total(0),
|
||||
_reserved_words(0),
|
||||
_committed_words(0),
|
||||
_virtual_space_count(0) {
|
||||
MutexLockerEx cl(SpaceManager::expand_lock(),
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
|
@ -1115,7 +1127,7 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
|
|||
_chunk_manager.free_chunks(SmallIndex)->set_size(ClassSmallChunk);
|
||||
_chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
|
||||
assert(succeeded, " VirtualSpaceList initialization should not fail");
|
||||
link_vs(class_entry, rs.size()/BytesPerWord);
|
||||
link_vs(class_entry);
|
||||
}
|
||||
|
||||
size_t VirtualSpaceList::free_bytes() {
|
||||
|
@ -1138,31 +1150,47 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
|
|||
delete new_entry;
|
||||
return false;
|
||||
} else {
|
||||
assert(new_entry->reserved_words() == vs_word_size, "Must be");
|
||||
// ensure lock-free iteration sees fully initialized node
|
||||
OrderAccess::storestore();
|
||||
link_vs(new_entry, vs_word_size);
|
||||
link_vs(new_entry);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry, size_t vs_word_size) {
|
||||
void VirtualSpaceList::link_vs(VirtualSpaceNode* new_entry) {
|
||||
if (virtual_space_list() == NULL) {
|
||||
set_virtual_space_list(new_entry);
|
||||
} else {
|
||||
current_virtual_space()->set_next(new_entry);
|
||||
}
|
||||
set_current_virtual_space(new_entry);
|
||||
inc_virtual_space_total(vs_word_size);
|
||||
inc_reserved_words(new_entry->reserved_words());
|
||||
inc_committed_words(new_entry->committed_words());
|
||||
inc_virtual_space_count();
|
||||
#ifdef ASSERT
|
||||
new_entry->mangle();
|
||||
#endif
|
||||
if (TraceMetavirtualspaceAllocation && Verbose) {
|
||||
VirtualSpaceNode* vsl = current_virtual_space();
|
||||
vsl->print_on(tty);
|
||||
vsl->print_on(gclog_or_tty);
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtualSpaceList::expand_by(VirtualSpaceNode* node, size_t word_size, bool pre_touch) {
|
||||
size_t before = node->committed_words();
|
||||
|
||||
bool result = node->expand_by(word_size, pre_touch);
|
||||
|
||||
size_t after = node->committed_words();
|
||||
|
||||
// after and before can be the same if the memory was pre-committed.
|
||||
assert(after >= before, "Must be");
|
||||
inc_committed_words(after - before);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
|
||||
size_t grow_chunks_by_words,
|
||||
size_t medium_chunk_bunch) {
|
||||
|
@ -1186,7 +1214,7 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
|
|||
size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words,
|
||||
page_size_words);
|
||||
bool vs_expanded =
|
||||
current_virtual_space()->expand_by(aligned_expand_vs_by_words, false);
|
||||
expand_by(current_virtual_space(), aligned_expand_vs_by_words);
|
||||
if (!vs_expanded) {
|
||||
// Should the capacity of the metaspaces be expanded for
|
||||
// this allocation? If it's the virtual space for classes and is
|
||||
|
@ -1197,7 +1225,14 @@ Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
|
|||
MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words);
|
||||
if (grow_vs(grow_vs_words)) {
|
||||
// Got it. It's on the list now. Get a chunk from it.
|
||||
next = current_virtual_space()->get_chunk_vs_with_expand(grow_chunks_by_words);
|
||||
assert(current_virtual_space()->expanded_words() == 0,
|
||||
"New virtuals space nodes should not have expanded");
|
||||
|
||||
size_t grow_chunks_by_words_aligned = align_size_up(grow_chunks_by_words,
|
||||
page_size_words);
|
||||
// We probably want to expand by aligned_expand_vs_by_words here.
|
||||
expand_by(current_virtual_space(), grow_chunks_by_words_aligned);
|
||||
next = current_virtual_space()->get_chunk_vs(grow_chunks_by_words);
|
||||
}
|
||||
} else {
|
||||
// Allocation will fail and induce a GC
|
||||
|
@ -1307,7 +1342,7 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
|
|||
// reserved space, because this is a larger space prereserved for compressed
|
||||
// class pointers.
|
||||
if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) {
|
||||
size_t real_allocated = Metaspace::space_list()->virtual_space_total() +
|
||||
size_t real_allocated = Metaspace::space_list()->reserved_words() +
|
||||
MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
|
||||
if (real_allocated >= MaxMetaspaceSize) {
|
||||
return false;
|
||||
|
@ -1508,7 +1543,7 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm,
|
|||
sm->sum_count_in_chunks_in_use());
|
||||
dummy_chunk->print_on(gclog_or_tty);
|
||||
gclog_or_tty->print_cr(" Free chunks total %d count %d",
|
||||
vsl->chunk_manager()->free_chunks_total(),
|
||||
vsl->chunk_manager()->free_chunks_total_words(),
|
||||
vsl->chunk_manager()->free_chunks_count());
|
||||
}
|
||||
}
|
||||
|
@ -1565,12 +1600,12 @@ bool Metadebug::test_metadata_failure() {
|
|||
|
||||
// ChunkManager methods
|
||||
|
||||
size_t ChunkManager::free_chunks_total() {
|
||||
size_t ChunkManager::free_chunks_total_words() {
|
||||
return _free_chunks_total;
|
||||
}
|
||||
|
||||
size_t ChunkManager::free_chunks_total_in_bytes() {
|
||||
return free_chunks_total() * BytesPerWord;
|
||||
size_t ChunkManager::free_chunks_total_bytes() {
|
||||
return free_chunks_total_words() * BytesPerWord;
|
||||
}
|
||||
|
||||
size_t ChunkManager::free_chunks_count() {
|
||||
|
@ -1698,7 +1733,7 @@ void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) {
|
|||
assert_lock_strong(SpaceManager::expand_lock());
|
||||
slow_locked_verify();
|
||||
if (TraceMetadataChunkAllocation) {
|
||||
tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk "
|
||||
gclog_or_tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk "
|
||||
PTR_FORMAT " size " SIZE_FORMAT,
|
||||
chunk, chunk->word_size());
|
||||
}
|
||||
|
@ -1729,7 +1764,7 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
|
|||
dec_free_chunks_total(chunk->capacity_word_size());
|
||||
|
||||
if (TraceMetadataChunkAllocation && Verbose) {
|
||||
tty->print_cr("ChunkManager::free_chunks_get: free_list "
|
||||
gclog_or_tty->print_cr("ChunkManager::free_chunks_get: free_list "
|
||||
PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
|
||||
free_list, chunk, chunk->word_size());
|
||||
}
|
||||
|
@ -1741,8 +1776,8 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
|
|||
if (chunk != NULL) {
|
||||
if (TraceMetadataHumongousAllocation) {
|
||||
size_t waste = chunk->word_size() - word_size;
|
||||
tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT
|
||||
" for requested size " SIZE_FORMAT
|
||||
gclog_or_tty->print_cr("Free list allocate humongous chunk size "
|
||||
SIZE_FORMAT " for requested size " SIZE_FORMAT
|
||||
" waste " SIZE_FORMAT,
|
||||
chunk->word_size(), word_size, waste);
|
||||
}
|
||||
|
@ -1786,10 +1821,10 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
|
|||
} else {
|
||||
list_count = humongous_dictionary()->total_count();
|
||||
}
|
||||
tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
|
||||
gclog_or_tty->print("ChunkManager::chunk_freelist_allocate: " PTR_FORMAT " chunk "
|
||||
PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ",
|
||||
this, chunk, chunk->word_size(), list_count);
|
||||
locked_print_free_chunks(tty);
|
||||
locked_print_free_chunks(gclog_or_tty);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
|
@ -2278,6 +2313,7 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
|
|||
ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
|
||||
|
||||
if (index != HumongousIndex) {
|
||||
retire_current_chunk();
|
||||
set_current_chunk(new_chunk);
|
||||
new_chunk->set_next(chunks_in_use(index));
|
||||
set_chunks_in_use(index, new_chunk);
|
||||
|
@ -2308,7 +2344,17 @@ void SpaceManager::add_chunk(Metachunk* new_chunk, bool make_current) {
|
|||
sum_count_in_chunks_in_use());
|
||||
new_chunk->print_on(gclog_or_tty);
|
||||
if (vs_list() != NULL) {
|
||||
vs_list()->chunk_manager()->locked_print_free_chunks(tty);
|
||||
vs_list()->chunk_manager()->locked_print_free_chunks(gclog_or_tty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpaceManager::retire_current_chunk() {
|
||||
if (current_chunk() != NULL) {
|
||||
size_t remaining_words = current_chunk()->free_word_size();
|
||||
if (remaining_words >= TreeChunk<Metablock, FreeList>::min_size()) {
|
||||
block_freelists()->return_block(current_chunk()->allocate(remaining_words), remaining_words);
|
||||
inc_used_metrics(remaining_words);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2320,10 +2366,10 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size,
|
|||
grow_chunks_by_words,
|
||||
medium_chunk_bunch());
|
||||
|
||||
if (TraceMetadataHumongousAllocation &&
|
||||
if (TraceMetadataHumongousAllocation && next != NULL &&
|
||||
SpaceManager::is_humongous(next->word_size())) {
|
||||
gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT,
|
||||
next->word_size());
|
||||
gclog_or_tty->print_cr(" new humongous chunk word size "
|
||||
PTR_FORMAT, next->word_size());
|
||||
}
|
||||
|
||||
return next;
|
||||
|
@ -2441,9 +2487,6 @@ void SpaceManager::dump(outputStream* const out) const {
|
|||
curr = curr->next()) {
|
||||
out->print("%d) ", i++);
|
||||
curr->print_on(out);
|
||||
if (TraceMetadataChunkAllocation && Verbose) {
|
||||
block_freelists()->print_on(out);
|
||||
}
|
||||
curr_total += curr->word_size();
|
||||
used += curr->used_word_size();
|
||||
capacity += curr->capacity_word_size();
|
||||
|
@ -2451,6 +2494,10 @@ void SpaceManager::dump(outputStream* const out) const {
|
|||
}
|
||||
}
|
||||
|
||||
if (TraceMetadataChunkAllocation && Verbose) {
|
||||
block_freelists()->print_on(out);
|
||||
}
|
||||
|
||||
size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size();
|
||||
// Free space isn't wasted.
|
||||
waste -= free;
|
||||
|
@ -2538,13 +2585,13 @@ size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) {
|
|||
return used * BytesPerWord;
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) {
|
||||
size_t MetaspaceAux::free_bytes_slow(Metaspace::MetadataType mdtype) {
|
||||
size_t free = 0;
|
||||
ClassLoaderDataGraphMetaspaceIterator iter;
|
||||
while (iter.repeat()) {
|
||||
Metaspace* msp = iter.get_next();
|
||||
if (msp != NULL) {
|
||||
free += msp->free_words(mdtype);
|
||||
free += msp->free_words_slow(mdtype);
|
||||
}
|
||||
}
|
||||
return free * BytesPerWord;
|
||||
|
@ -2567,34 +2614,56 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
|
|||
return capacity * BytesPerWord;
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) {
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
return list == NULL ? 0 : list->virtual_space_total();
|
||||
size_t MetaspaceAux::capacity_bytes_slow() {
|
||||
#ifdef PRODUCT
|
||||
// Use allocated_capacity_bytes() in PRODUCT instead of this function.
|
||||
guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT");
|
||||
#endif
|
||||
size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType);
|
||||
size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType);
|
||||
assert(allocated_capacity_bytes() == class_capacity + non_class_capacity,
|
||||
err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT
|
||||
" class_capacity + non_class_capacity " SIZE_FORMAT
|
||||
" class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT,
|
||||
allocated_capacity_bytes(), class_capacity + non_class_capacity,
|
||||
class_capacity, non_class_capacity));
|
||||
|
||||
return class_capacity + non_class_capacity;
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); }
|
||||
size_t MetaspaceAux::reserved_bytes(Metaspace::MetadataType mdtype) {
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
return list == NULL ? 0 : list->reserved_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) {
|
||||
size_t MetaspaceAux::committed_bytes(Metaspace::MetadataType mdtype) {
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
return list == NULL ? 0 : list->committed_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::min_chunk_size_words() { return Metaspace::first_chunk_word_size(); }
|
||||
|
||||
size_t MetaspaceAux::free_chunks_total_words(Metaspace::MetadataType mdtype) {
|
||||
VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
|
||||
if (list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
ChunkManager* chunk = list->chunk_manager();
|
||||
chunk->slow_verify();
|
||||
return chunk->free_chunks_total();
|
||||
return chunk->free_chunks_total_words();
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::free_chunks_total_in_bytes(Metaspace::MetadataType mdtype) {
|
||||
return free_chunks_total(mdtype) * BytesPerWord;
|
||||
size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) {
|
||||
return free_chunks_total_words(mdtype) * BytesPerWord;
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::free_chunks_total() {
|
||||
return free_chunks_total(Metaspace::ClassType) +
|
||||
free_chunks_total(Metaspace::NonClassType);
|
||||
size_t MetaspaceAux::free_chunks_total_words() {
|
||||
return free_chunks_total_words(Metaspace::ClassType) +
|
||||
free_chunks_total_words(Metaspace::NonClassType);
|
||||
}
|
||||
|
||||
size_t MetaspaceAux::free_chunks_total_in_bytes() {
|
||||
return free_chunks_total() * BytesPerWord;
|
||||
size_t MetaspaceAux::free_chunks_total_bytes() {
|
||||
return free_chunks_total_words() * BytesPerWord;
|
||||
}
|
||||
|
||||
void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
|
||||
|
@ -2605,14 +2674,14 @@ void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
|
|||
"(" SIZE_FORMAT ")",
|
||||
prev_metadata_used,
|
||||
allocated_used_bytes(),
|
||||
reserved_in_bytes());
|
||||
reserved_bytes());
|
||||
} else {
|
||||
gclog_or_tty->print(" " SIZE_FORMAT "K"
|
||||
"->" SIZE_FORMAT "K"
|
||||
"(" SIZE_FORMAT "K)",
|
||||
prev_metadata_used / K,
|
||||
allocated_used_bytes() / K,
|
||||
reserved_in_bytes()/ K);
|
||||
prev_metadata_used/K,
|
||||
allocated_used_bytes()/K,
|
||||
reserved_bytes()/K);
|
||||
}
|
||||
|
||||
gclog_or_tty->print("]");
|
||||
|
@ -2625,14 +2694,14 @@ void MetaspaceAux::print_on(outputStream* out) {
|
|||
out->print_cr(" Metaspace total "
|
||||
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
|
||||
" reserved " SIZE_FORMAT "K",
|
||||
allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_in_bytes()/K);
|
||||
allocated_capacity_bytes()/K, allocated_used_bytes()/K, reserved_bytes()/K);
|
||||
|
||||
out->print_cr(" data space "
|
||||
SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
|
||||
" reserved " SIZE_FORMAT "K",
|
||||
allocated_capacity_bytes(nct)/K,
|
||||
allocated_used_bytes(nct)/K,
|
||||
reserved_in_bytes(nct)/K);
|
||||
reserved_bytes(nct)/K);
|
||||
if (Metaspace::using_class_space()) {
|
||||
Metaspace::MetadataType ct = Metaspace::ClassType;
|
||||
out->print_cr(" class space "
|
||||
|
@ -2640,17 +2709,17 @@ void MetaspaceAux::print_on(outputStream* out) {
|
|||
" reserved " SIZE_FORMAT "K",
|
||||
allocated_capacity_bytes(ct)/K,
|
||||
allocated_used_bytes(ct)/K,
|
||||
reserved_in_bytes(ct)/K);
|
||||
reserved_bytes(ct)/K);
|
||||
}
|
||||
}
|
||||
|
||||
// Print information for class space and data space separately.
|
||||
// This is almost the same as above.
|
||||
void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
|
||||
size_t free_chunks_capacity_bytes = free_chunks_total_in_bytes(mdtype);
|
||||
size_t free_chunks_capacity_bytes = free_chunks_total_bytes(mdtype);
|
||||
size_t capacity_bytes = capacity_bytes_slow(mdtype);
|
||||
size_t used_bytes = used_bytes_slow(mdtype);
|
||||
size_t free_bytes = free_in_bytes(mdtype);
|
||||
size_t free_bytes = free_bytes_slow(mdtype);
|
||||
size_t used_and_free = used_bytes + free_bytes +
|
||||
free_chunks_capacity_bytes;
|
||||
out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT
|
||||
|
@ -2836,7 +2905,7 @@ void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address
|
|||
// to work with compressed klass pointers.
|
||||
bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
|
||||
assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS");
|
||||
assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
|
||||
assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
|
||||
address lower_base = MIN2((address)metaspace_base, cds_base);
|
||||
address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
|
||||
(address)(metaspace_base + class_metaspace_size()));
|
||||
|
@ -2846,7 +2915,7 @@ bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cd
|
|||
// Try to allocate the metaspace at the requested addr.
|
||||
void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
|
||||
assert(using_class_space(), "called improperly");
|
||||
assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
|
||||
assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
|
||||
assert(class_metaspace_size() < KlassEncodingMetaspaceMax,
|
||||
"Metaspace size is too big");
|
||||
|
||||
|
@ -2869,9 +2938,9 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a
|
|||
|
||||
// If no successful allocation then try to allocate the space anywhere. If
|
||||
// that fails then OOM doom. At this point we cannot try allocating the
|
||||
// metaspace as if UseCompressedKlassPointers is off because too much
|
||||
// initialization has happened that depends on UseCompressedKlassPointers.
|
||||
// So, UseCompressedKlassPointers cannot be turned off at this point.
|
||||
// metaspace as if UseCompressedClassPointers is off because too much
|
||||
// initialization has happened that depends on UseCompressedClassPointers.
|
||||
// So, UseCompressedClassPointers cannot be turned off at this point.
|
||||
if (!metaspace_rs.is_reserved()) {
|
||||
metaspace_rs = ReservedSpace(class_metaspace_size(),
|
||||
os::vm_allocation_granularity(), false);
|
||||
|
@ -2904,12 +2973,12 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a
|
|||
}
|
||||
}
|
||||
|
||||
// For UseCompressedKlassPointers the class space is reserved above the top of
|
||||
// For UseCompressedClassPointers the class space is reserved above the top of
|
||||
// the Java heap. The argument passed in is at the base of the compressed space.
|
||||
void Metaspace::initialize_class_space(ReservedSpace rs) {
|
||||
// The reserved space size may be bigger because of alignment, esp with UseLargePages
|
||||
assert(rs.size() >= ClassMetaspaceSize,
|
||||
err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
|
||||
assert(rs.size() >= CompressedClassSpaceSize,
|
||||
err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
|
||||
assert(using_class_space(), "Must be using class space");
|
||||
_class_space_list = new VirtualSpaceList(rs);
|
||||
}
|
||||
|
@ -2921,7 +2990,7 @@ void Metaspace::global_initialize() {
|
|||
int max_alignment = os::vm_page_size();
|
||||
size_t cds_total = 0;
|
||||
|
||||
set_class_metaspace_size(align_size_up(ClassMetaspaceSize,
|
||||
set_class_metaspace_size(align_size_up(CompressedClassSpaceSize,
|
||||
os::vm_allocation_granularity()));
|
||||
|
||||
MetaspaceShared::set_max_alignment(max_alignment);
|
||||
|
@ -2941,8 +3010,8 @@ void Metaspace::global_initialize() {
|
|||
#ifdef _LP64
|
||||
// Set the compressed klass pointer base so that decoding of these pointers works
|
||||
// properly when creating the shared archive.
|
||||
assert(UseCompressedOops && UseCompressedKlassPointers,
|
||||
"UseCompressedOops and UseCompressedKlassPointers must be set");
|
||||
assert(UseCompressedOops && UseCompressedClassPointers,
|
||||
"UseCompressedOops and UseCompressedClassPointers must be set");
|
||||
Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
|
||||
if (TraceMetavirtualspaceAllocation && Verbose) {
|
||||
gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
|
||||
|
@ -2979,7 +3048,7 @@ void Metaspace::global_initialize() {
|
|||
}
|
||||
|
||||
#ifdef _LP64
|
||||
// If UseCompressedKlassPointers is set then allocate the metaspace area
|
||||
// If UseCompressedClassPointers is set then allocate the metaspace area
|
||||
// above the heap and above the CDS area (if it exists).
|
||||
if (using_class_space()) {
|
||||
if (UseSharedSpaces) {
|
||||
|
@ -2997,7 +3066,7 @@ void Metaspace::global_initialize() {
|
|||
// on the medium chunk list. The next chunk will be small and progress
|
||||
// from there. This size calculated by -version.
|
||||
_first_class_chunk_word_size = MIN2((size_t)MediumChunk*6,
|
||||
(ClassMetaspaceSize/BytesPerWord)*2);
|
||||
(CompressedClassSpaceSize/BytesPerWord)*2);
|
||||
_first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
|
||||
// Arbitrarily set the initial virtual space to a multiple
|
||||
// of the boot class loader size.
|
||||
|
@ -3064,7 +3133,7 @@ size_t Metaspace::align_word_size_up(size_t word_size) {
|
|||
|
||||
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
|
||||
// DumpSharedSpaces doesn't use class metadata area (yet)
|
||||
// Also, don't use class_vsm() unless UseCompressedKlassPointers is true.
|
||||
// Also, don't use class_vsm() unless UseCompressedClassPointers is true.
|
||||
if (mdtype == ClassType && using_class_space()) {
|
||||
return class_vsm()->allocate(word_size);
|
||||
} else {
|
||||
|
@ -3103,7 +3172,7 @@ size_t Metaspace::used_words_slow(MetadataType mdtype) const {
|
|||
}
|
||||
}
|
||||
|
||||
size_t Metaspace::free_words(MetadataType mdtype) const {
|
||||
size_t Metaspace::free_words_slow(MetadataType mdtype) const {
|
||||
if (mdtype == ClassType) {
|
||||
return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;
|
||||
} else {
|
||||
|
@ -3213,7 +3282,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
|
|||
MetaspaceAux::dump(gclog_or_tty);
|
||||
}
|
||||
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support
|
||||
const char* space_string = (mdtype == ClassType) ? "Class Metadata space" :
|
||||
const char* space_string = (mdtype == ClassType) ? "Compressed class space" :
|
||||
"Metadata space";
|
||||
report_java_out_of_memory(space_string);
|
||||
|
||||
|
@ -3311,3 +3380,59 @@ void Metaspace::dump(outputStream* const out) const {
|
|||
class_vsm()->dump(out);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////// Unit tests ///////////////
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
class MetaspaceAuxTest : AllStatic {
|
||||
public:
|
||||
static void test_reserved() {
|
||||
size_t reserved = MetaspaceAux::reserved_bytes();
|
||||
|
||||
assert(reserved > 0, "assert");
|
||||
|
||||
size_t committed = MetaspaceAux::committed_bytes();
|
||||
assert(committed <= reserved, "assert");
|
||||
|
||||
size_t reserved_metadata = MetaspaceAux::reserved_bytes(Metaspace::NonClassType);
|
||||
assert(reserved_metadata > 0, "assert");
|
||||
assert(reserved_metadata <= reserved, "assert");
|
||||
|
||||
if (UseCompressedClassPointers) {
|
||||
size_t reserved_class = MetaspaceAux::reserved_bytes(Metaspace::ClassType);
|
||||
assert(reserved_class > 0, "assert");
|
||||
assert(reserved_class < reserved, "assert");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_committed() {
|
||||
size_t committed = MetaspaceAux::committed_bytes();
|
||||
|
||||
assert(committed > 0, "assert");
|
||||
|
||||
size_t reserved = MetaspaceAux::reserved_bytes();
|
||||
assert(committed <= reserved, "assert");
|
||||
|
||||
size_t committed_metadata = MetaspaceAux::committed_bytes(Metaspace::NonClassType);
|
||||
assert(committed_metadata > 0, "assert");
|
||||
assert(committed_metadata <= committed, "assert");
|
||||
|
||||
if (UseCompressedClassPointers) {
|
||||
size_t committed_class = MetaspaceAux::committed_bytes(Metaspace::ClassType);
|
||||
assert(committed_class > 0, "assert");
|
||||
assert(committed_class < committed, "assert");
|
||||
}
|
||||
}
|
||||
|
||||
static void test() {
|
||||
test_reserved();
|
||||
test_committed();
|
||||
}
|
||||
};
|
||||
|
||||
void MetaspaceAux_test() {
|
||||
MetaspaceAuxTest::test();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -182,9 +182,8 @@ class Metaspace : public CHeapObj<mtClass> {
|
|||
|
||||
char* bottom() const;
|
||||
size_t used_words_slow(MetadataType mdtype) const;
|
||||
size_t free_words(MetadataType mdtype) const;
|
||||
size_t free_words_slow(MetadataType mdtype) const;
|
||||
size_t capacity_words_slow(MetadataType mdtype) const;
|
||||
size_t waste_words(MetadataType mdtype) const;
|
||||
|
||||
size_t used_bytes_slow(MetadataType mdtype) const;
|
||||
size_t capacity_bytes_slow(MetadataType mdtype) const;
|
||||
|
@ -213,27 +212,22 @@ class Metaspace : public CHeapObj<mtClass> {
|
|||
|
||||
void iterate(AllocRecordClosure *closure);
|
||||
|
||||
// Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False.
|
||||
// Return TRUE only if UseCompressedClassPointers is True and DumpSharedSpaces is False.
|
||||
static bool using_class_space() {
|
||||
return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces);
|
||||
return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class MetaspaceAux : AllStatic {
|
||||
static size_t free_chunks_total(Metaspace::MetadataType mdtype);
|
||||
|
||||
public:
|
||||
// Statistics for class space and data space in metaspace.
|
||||
static size_t free_chunks_total_words(Metaspace::MetadataType mdtype);
|
||||
|
||||
// These methods iterate over the classloader data graph
|
||||
// for the given Metaspace type. These are slow.
|
||||
static size_t used_bytes_slow(Metaspace::MetadataType mdtype);
|
||||
static size_t free_in_bytes(Metaspace::MetadataType mdtype);
|
||||
static size_t free_bytes_slow(Metaspace::MetadataType mdtype);
|
||||
static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype);
|
||||
|
||||
// Iterates over the virtual space list.
|
||||
static size_t reserved_in_bytes(Metaspace::MetadataType mdtype);
|
||||
static size_t capacity_bytes_slow();
|
||||
|
||||
// Running sum of space in all Metachunks that has been
|
||||
// allocated to a Metaspace. This is used instead of
|
||||
|
@ -263,17 +257,16 @@ class MetaspaceAux : AllStatic {
|
|||
}
|
||||
|
||||
// Used by MetaspaceCounters
|
||||
static size_t free_chunks_total();
|
||||
static size_t free_chunks_total_in_bytes();
|
||||
static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
|
||||
static size_t free_chunks_total_words();
|
||||
static size_t free_chunks_total_bytes();
|
||||
static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype);
|
||||
|
||||
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
|
||||
return _allocated_capacity_words[mdtype];
|
||||
}
|
||||
static size_t allocated_capacity_words() {
|
||||
return _allocated_capacity_words[Metaspace::NonClassType] +
|
||||
(Metaspace::using_class_space() ?
|
||||
_allocated_capacity_words[Metaspace::ClassType] : 0);
|
||||
return allocated_capacity_words(Metaspace::NonClassType) +
|
||||
allocated_capacity_words(Metaspace::ClassType);
|
||||
}
|
||||
static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
|
||||
return allocated_capacity_words(mdtype) * BytesPerWord;
|
||||
|
@ -286,9 +279,8 @@ class MetaspaceAux : AllStatic {
|
|||
return _allocated_used_words[mdtype];
|
||||
}
|
||||
static size_t allocated_used_words() {
|
||||
return _allocated_used_words[Metaspace::NonClassType] +
|
||||
(Metaspace::using_class_space() ?
|
||||
_allocated_used_words[Metaspace::ClassType] : 0);
|
||||
return allocated_used_words(Metaspace::NonClassType) +
|
||||
allocated_used_words(Metaspace::ClassType);
|
||||
}
|
||||
static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
|
||||
return allocated_used_words(mdtype) * BytesPerWord;
|
||||
|
@ -300,31 +292,22 @@ class MetaspaceAux : AllStatic {
|
|||
static size_t free_bytes();
|
||||
static size_t free_bytes(Metaspace::MetadataType mdtype);
|
||||
|
||||
// Total capacity in all Metaspaces
|
||||
static size_t capacity_bytes_slow() {
|
||||
#ifdef PRODUCT
|
||||
// Use allocated_capacity_bytes() in PRODUCT instead of this function.
|
||||
guarantee(false, "Should not call capacity_bytes_slow() in the PRODUCT");
|
||||
#endif
|
||||
size_t class_capacity = capacity_bytes_slow(Metaspace::ClassType);
|
||||
size_t non_class_capacity = capacity_bytes_slow(Metaspace::NonClassType);
|
||||
assert(allocated_capacity_bytes() == class_capacity + non_class_capacity,
|
||||
err_msg("bad accounting: allocated_capacity_bytes() " SIZE_FORMAT
|
||||
" class_capacity + non_class_capacity " SIZE_FORMAT
|
||||
" class_capacity " SIZE_FORMAT " non_class_capacity " SIZE_FORMAT,
|
||||
allocated_capacity_bytes(), class_capacity + non_class_capacity,
|
||||
class_capacity, non_class_capacity));
|
||||
|
||||
return class_capacity + non_class_capacity;
|
||||
static size_t reserved_bytes(Metaspace::MetadataType mdtype);
|
||||
static size_t reserved_bytes() {
|
||||
return reserved_bytes(Metaspace::ClassType) +
|
||||
reserved_bytes(Metaspace::NonClassType);
|
||||
}
|
||||
|
||||
// Total space reserved in all Metaspaces
|
||||
static size_t reserved_in_bytes() {
|
||||
return reserved_in_bytes(Metaspace::ClassType) +
|
||||
reserved_in_bytes(Metaspace::NonClassType);
|
||||
static size_t committed_bytes(Metaspace::MetadataType mdtype);
|
||||
static size_t committed_bytes() {
|
||||
return committed_bytes(Metaspace::ClassType) +
|
||||
committed_bytes(Metaspace::NonClassType);
|
||||
}
|
||||
|
||||
static size_t min_chunk_size();
|
||||
static size_t min_chunk_size_words();
|
||||
static size_t min_chunk_size_bytes() {
|
||||
return min_chunk_size_words() * BytesPerWord;
|
||||
}
|
||||
|
||||
// Print change in used metadata.
|
||||
static void print_metaspace_change(size_t prev_metadata_used);
|
||||
|
|
|
@ -65,26 +65,25 @@ class MetaspacePerfCounters: public CHeapObj<mtInternal> {
|
|||
|
||||
MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t MetaspaceCounters::calculate_capacity() {
|
||||
// The total capacity is the sum of
|
||||
// 1) capacity of Metachunks in use by all Metaspaces
|
||||
// 2) unused space at the end of each Metachunk
|
||||
// 3) space in the freelist
|
||||
size_t total_capacity = MetaspaceAux::allocated_capacity_bytes()
|
||||
+ MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_in_bytes();
|
||||
return total_capacity;
|
||||
size_t MetaspaceCounters::used() {
|
||||
return MetaspaceAux::allocated_used_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceCounters::capacity() {
|
||||
return MetaspaceAux::committed_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceCounters::max_capacity() {
|
||||
return MetaspaceAux::reserved_bytes();
|
||||
}
|
||||
|
||||
void MetaspaceCounters::initialize_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_perf_counters == NULL, "Should only be initialized once");
|
||||
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size();
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
|
||||
size_t min_capacity = 0;
|
||||
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity,
|
||||
capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,31 +91,29 @@ void MetaspaceCounters::update_performance_counters() {
|
|||
if (UsePerfData) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
_perf_counters->update(capacity, max_capacity, used);
|
||||
_perf_counters->update(capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t CompressedClassSpaceCounters::calculate_capacity() {
|
||||
return MetaspaceAux::allocated_capacity_bytes(_class_type) +
|
||||
MetaspaceAux::free_bytes(_class_type) +
|
||||
MetaspaceAux::free_chunks_total_in_bytes(_class_type);
|
||||
size_t CompressedClassSpaceCounters::used() {
|
||||
return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedClassSpaceCounters::capacity() {
|
||||
return MetaspaceAux::committed_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedClassSpaceCounters::max_capacity() {
|
||||
return MetaspaceAux::reserved_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
void CompressedClassSpaceCounters::update_performance_counters() {
|
||||
if (UsePerfData && UseCompressedKlassPointers) {
|
||||
if (UsePerfData && UseCompressedClassPointers) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
|
||||
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
|
||||
|
||||
_perf_counters->update(capacity, max_capacity, used);
|
||||
_perf_counters->update(capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,13 +122,10 @@ void CompressedClassSpaceCounters::initialize_performance_counters() {
|
|||
assert(_perf_counters == NULL, "Should only be initialized once");
|
||||
const char* ns = "compressedclassspace";
|
||||
|
||||
if (UseCompressedKlassPointers) {
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size();
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
|
||||
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
|
||||
|
||||
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
|
||||
if (UseCompressedClassPointers) {
|
||||
size_t min_capacity = 0;
|
||||
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(),
|
||||
max_capacity(), used());
|
||||
} else {
|
||||
_perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
|
||||
}
|
||||
|
|
|
@ -25,13 +25,15 @@
|
|||
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class MetaspacePerfCounters;
|
||||
|
||||
class MetaspaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t calculate_capacity();
|
||||
static size_t used();
|
||||
static size_t capacity();
|
||||
static size_t max_capacity();
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
|
@ -40,8 +42,9 @@ class MetaspaceCounters: public AllStatic {
|
|||
|
||||
class CompressedClassSpaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t calculate_capacity();
|
||||
static const Metaspace::MetadataType _class_type = Metaspace::ClassType;
|
||||
static size_t used();
|
||||
static size_t capacity();
|
||||
static size_t max_capacity();
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
|
|
|
@ -602,7 +602,7 @@ oop Universe::gen_out_of_memory_error(oop default_err) {
|
|||
}
|
||||
}
|
||||
|
||||
static intptr_t non_oop_bits = 0;
|
||||
intptr_t Universe::_non_oop_bits = 0;
|
||||
|
||||
void* Universe::non_oop_word() {
|
||||
// Neither the high bits nor the low bits of this value is allowed
|
||||
|
@ -616,11 +616,11 @@ void* Universe::non_oop_word() {
|
|||
// Using the OS-supplied non-memory-address word (usually 0 or -1)
|
||||
// will take care of the high bits, however many there are.
|
||||
|
||||
if (non_oop_bits == 0) {
|
||||
non_oop_bits = (intptr_t)os::non_memory_address_word() | 1;
|
||||
if (_non_oop_bits == 0) {
|
||||
_non_oop_bits = (intptr_t)os::non_memory_address_word() | 1;
|
||||
}
|
||||
|
||||
return (void*)non_oop_bits;
|
||||
return (void*)_non_oop_bits;
|
||||
}
|
||||
|
||||
jint universe_init() {
|
||||
|
@ -872,13 +872,16 @@ jint Universe::initialize_heap() {
|
|||
|
||||
// Reserve the Java heap, which is now the same for all GCs.
|
||||
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
|
||||
assert(alignment <= Arguments::conservative_max_heap_alignment(),
|
||||
err_msg("actual alignment "SIZE_FORMAT" must be within maximum heap alignment "SIZE_FORMAT,
|
||||
alignment, Arguments::conservative_max_heap_alignment()));
|
||||
size_t total_reserved = align_size_up(heap_size, alignment);
|
||||
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
|
||||
"heap size is too big for compressed oops");
|
||||
|
||||
bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size());
|
||||
assert(!UseLargePages
|
||||
|| UseParallelOldGC
|
||||
|| UseParallelGC
|
||||
|| use_large_pages, "Wrong alignment to use large pages");
|
||||
|
||||
char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop);
|
||||
|
@ -1028,7 +1031,7 @@ bool universe_post_init() {
|
|||
|
||||
msg = java_lang_String::create_from_str("Metadata space", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg());
|
||||
msg = java_lang_String::create_from_str("Class Metadata space", CHECK_false);
|
||||
msg = java_lang_String::create_from_str("Compressed class space", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false);
|
||||
|
|
|
@ -179,9 +179,11 @@ class Universe: AllStatic {
|
|||
// The particular choice of collected heap.
|
||||
static CollectedHeap* _collectedHeap;
|
||||
|
||||
static intptr_t _non_oop_bits;
|
||||
|
||||
// For UseCompressedOops.
|
||||
static struct NarrowPtrStruct _narrow_oop;
|
||||
// For UseCompressedKlassPointers.
|
||||
// For UseCompressedClassPointers.
|
||||
static struct NarrowPtrStruct _narrow_klass;
|
||||
static address _narrow_ptrs_base;
|
||||
|
||||
|
@ -229,7 +231,7 @@ class Universe: AllStatic {
|
|||
_narrow_oop._base = base;
|
||||
}
|
||||
static void set_narrow_klass_base(address base) {
|
||||
assert(UseCompressedKlassPointers, "no compressed klass ptrs?");
|
||||
assert(UseCompressedClassPointers, "no compressed klass ptrs?");
|
||||
_narrow_klass._base = base;
|
||||
}
|
||||
static void set_narrow_oop_use_implicit_null_checks(bool use) {
|
||||
|
@ -353,7 +355,7 @@ class Universe: AllStatic {
|
|||
static int narrow_oop_shift() { return _narrow_oop._shift; }
|
||||
static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; }
|
||||
|
||||
// For UseCompressedKlassPointers
|
||||
// For UseCompressedClassPointers
|
||||
static address narrow_klass_base() { return _narrow_klass._base; }
|
||||
static bool is_narrow_klass_base(void* addr) { return (narrow_klass_base() == (address)addr); }
|
||||
static int narrow_klass_shift() { return _narrow_klass._shift; }
|
||||
|
|
|
@ -65,7 +65,7 @@ class arrayOopDesc : public oopDesc {
|
|||
// declared nonstatic fields in arrayOopDesc if not compressed, otherwise
|
||||
// it occupies the second half of the _klass field in oopDesc.
|
||||
static int length_offset_in_bytes() {
|
||||
return UseCompressedKlassPointers ? klass_gap_offset_in_bytes() :
|
||||
return UseCompressedClassPointers ? klass_gap_offset_in_bytes() :
|
||||
sizeof(arrayOopDesc);
|
||||
}
|
||||
|
||||
|
|
|
@ -389,32 +389,6 @@ Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_oop, int whi
|
|||
}
|
||||
|
||||
|
||||
// This is an interface for the compiler that allows accessing non-resolved entries
|
||||
// in the constant pool - but still performs the validations tests. Must be used
|
||||
// in a pre-parse of the compiler - to determine what it can do and not do.
|
||||
// Note: We cannot update the ConstantPool from the vm_thread.
|
||||
Klass* ConstantPool::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) {
|
||||
int which = this_oop->klass_ref_index_at(index);
|
||||
CPSlot entry = this_oop->slot_at(which);
|
||||
if (entry.is_resolved()) {
|
||||
assert(entry.get_klass()->is_klass(), "must be");
|
||||
return entry.get_klass();
|
||||
} else {
|
||||
assert(entry.is_unresolved(), "must be either symbol or klass");
|
||||
Symbol* name = entry.get_symbol();
|
||||
oop loader = this_oop->pool_holder()->class_loader();
|
||||
oop protection_domain = this_oop->pool_holder()->protection_domain();
|
||||
Handle h_loader(THREAD, loader);
|
||||
Handle h_prot (THREAD, protection_domain);
|
||||
KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD));
|
||||
|
||||
// Do access check for klasses
|
||||
if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL);
|
||||
return k();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool,
|
||||
int which) {
|
||||
if (cpool->cache() == NULL) return NULL; // nothing to load yet
|
||||
|
|
|
@ -729,8 +729,6 @@ class ConstantPool : public Metadata {
|
|||
static oop method_type_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||
static Klass* klass_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||
static Klass* klass_ref_at_if_loaded (constantPoolHandle this_oop, int which);
|
||||
// Same as above - but does LinkResolving.
|
||||
static Klass* klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS);
|
||||
|
||||
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
|
||||
// future by other Java code. These take constant pool indices rather than
|
||||
|
|
|
@ -140,9 +140,10 @@ void ConstantPoolCacheEntry::set_parameter_size(int value) {
|
|||
err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
|
||||
}
|
||||
|
||||
void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
|
||||
void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code,
|
||||
methodHandle method,
|
||||
int vtable_index) {
|
||||
bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean
|
||||
assert(method->interpreter_entry() != NULL, "should have been set at this point");
|
||||
assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache");
|
||||
|
||||
|
@ -160,7 +161,8 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
|
|||
// ...and fall through as if we were handling invokevirtual:
|
||||
case Bytecodes::_invokevirtual:
|
||||
{
|
||||
if (method->can_be_statically_bound()) {
|
||||
if (!is_vtable_call) {
|
||||
assert(method->can_be_statically_bound(), "");
|
||||
// set_f2_as_vfinal_method checks if is_vfinal flag is true.
|
||||
set_method_flags(as_TosState(method->result_type()),
|
||||
( 1 << is_vfinal_shift) |
|
||||
|
@ -169,6 +171,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
|
|||
method()->size_of_parameters());
|
||||
set_f2_as_vfinal_method(method());
|
||||
} else {
|
||||
assert(!method->can_be_statically_bound(), "");
|
||||
assert(vtable_index >= 0, "valid index");
|
||||
assert(!method->is_final_method(), "sanity");
|
||||
set_method_flags(as_TosState(method->result_type()),
|
||||
|
@ -182,6 +185,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
|
|||
|
||||
case Bytecodes::_invokespecial:
|
||||
case Bytecodes::_invokestatic:
|
||||
assert(!is_vtable_call, "");
|
||||
// Note: Read and preserve the value of the is_vfinal flag on any
|
||||
// invokevirtual bytecode shared with this constant pool cache entry.
|
||||
// It is cheap and safe to consult is_vfinal() at all times.
|
||||
|
@ -232,8 +236,22 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
|
|||
NOT_PRODUCT(verify(tty));
|
||||
}
|
||||
|
||||
void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) {
|
||||
int index = Method::nonvirtual_vtable_index;
|
||||
// index < 0; FIXME: inline and customize set_direct_or_vtable_call
|
||||
set_direct_or_vtable_call(invoke_code, method, index);
|
||||
}
|
||||
|
||||
void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) {
|
||||
void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
|
||||
// either the method is a miranda or its holder should accept the given index
|
||||
assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), "");
|
||||
// index >= 0; FIXME: inline and customize set_direct_or_vtable_call
|
||||
set_direct_or_vtable_call(invoke_code, method, index);
|
||||
}
|
||||
|
||||
void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
|
||||
assert(method->method_holder()->verify_itable_index(index), "");
|
||||
assert(invoke_code == Bytecodes::_invokeinterface, "");
|
||||
InstanceKlass* interf = method->method_holder();
|
||||
assert(interf->is_interface(), "must be an interface");
|
||||
assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
|
||||
|
|
|
@ -219,15 +219,29 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
|
|||
Klass* root_klass // needed by the GC to dirty the klass
|
||||
);
|
||||
|
||||
void set_method( // sets entry to resolved method entry
|
||||
private:
|
||||
void set_direct_or_vtable_call(
|
||||
Bytecodes::Code invoke_code, // the bytecode used for invoking the method
|
||||
methodHandle method, // the method/prototype if any (NULL, otherwise)
|
||||
int vtable_index // the vtable index if any, else negative
|
||||
);
|
||||
|
||||
void set_interface_call(
|
||||
methodHandle method, // Resolved method
|
||||
int index // Method index into interface
|
||||
public:
|
||||
void set_direct_call( // sets entry to exact concrete method entry
|
||||
Bytecodes::Code invoke_code, // the bytecode used for invoking the method
|
||||
methodHandle method // the method to call
|
||||
);
|
||||
|
||||
void set_vtable_call( // sets entry to vtable index
|
||||
Bytecodes::Code invoke_code, // the bytecode used for invoking the method
|
||||
methodHandle method, // resolved method which declares the vtable index
|
||||
int vtable_index // the vtable index
|
||||
);
|
||||
|
||||
void set_itable_call(
|
||||
Bytecodes::Code invoke_code, // the bytecode used; must be invokeinterface
|
||||
methodHandle method, // the resolved interface method
|
||||
int itable_index // index into itable for the method
|
||||
);
|
||||
|
||||
void set_method_handle(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/fieldInfo.hpp"
|
||||
#include "runtime/fieldDescriptor.hpp"
|
||||
|
||||
// The is the base class for iteration over the fields array
|
||||
// describing the declared fields in the class. Several subclasses
|
||||
|
@ -43,8 +44,10 @@ class FieldStreamBase : public StackObj {
|
|||
int _index;
|
||||
int _limit;
|
||||
int _generic_signature_slot;
|
||||
fieldDescriptor _fd_buf;
|
||||
|
||||
FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); }
|
||||
InstanceKlass* field_holder() const { return _constants->pool_holder(); }
|
||||
|
||||
int init_generic_signature_start_slot() {
|
||||
int length = _fields->length();
|
||||
|
@ -102,6 +105,7 @@ class FieldStreamBase : public StackObj {
|
|||
_index = 0;
|
||||
_limit = klass->java_fields_count();
|
||||
init_generic_signature_start_slot();
|
||||
assert(klass == field_holder(), "");
|
||||
}
|
||||
FieldStreamBase(instanceKlassHandle klass) {
|
||||
_fields = klass->fields();
|
||||
|
@ -109,6 +113,7 @@ class FieldStreamBase : public StackObj {
|
|||
_index = 0;
|
||||
_limit = klass->java_fields_count();
|
||||
init_generic_signature_start_slot();
|
||||
assert(klass == field_holder(), "");
|
||||
}
|
||||
|
||||
// accessors
|
||||
|
@ -180,6 +185,12 @@ class FieldStreamBase : public StackObj {
|
|||
return field()->contended_group();
|
||||
}
|
||||
|
||||
// bridge to a heavier API:
|
||||
fieldDescriptor& field_descriptor() const {
|
||||
fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
|
||||
field.reinitialize(field_holder(), _index);
|
||||
return field;
|
||||
}
|
||||
};
|
||||
|
||||
// Iterate over only the internal fields
|
||||
|
|
|
@ -286,7 +286,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
|
|||
init_previous_versions();
|
||||
set_generic_signature_index(0);
|
||||
release_set_methods_jmethod_ids(NULL);
|
||||
release_set_methods_cached_itable_indices(NULL);
|
||||
set_annotations(NULL);
|
||||
set_jvmti_cached_class_field_map(NULL);
|
||||
set_initial_method_idnum(0);
|
||||
|
@ -1149,7 +1148,7 @@ bool InstanceKlass::find_local_field(Symbol* name, Symbol* sig, fieldDescriptor*
|
|||
Symbol* f_name = fs.name();
|
||||
Symbol* f_sig = fs.signature();
|
||||
if (f_name == name && f_sig == sig) {
|
||||
fd->initialize(const_cast<InstanceKlass*>(this), fs.index());
|
||||
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1218,7 +1217,7 @@ Klass* InstanceKlass::find_field(Symbol* name, Symbol* sig, bool is_static, fiel
|
|||
bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
|
||||
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
|
||||
if (fs.offset() == offset) {
|
||||
fd->initialize(const_cast<InstanceKlass*>(this), fs.index());
|
||||
fd->reinitialize(const_cast<InstanceKlass*>(this), fs.index());
|
||||
if (fd->is_static() == is_static) return true;
|
||||
}
|
||||
}
|
||||
|
@ -1251,8 +1250,7 @@ void InstanceKlass::methods_do(void f(Method* method)) {
|
|||
void InstanceKlass::do_local_static_fields(FieldClosure* cl) {
|
||||
for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
|
||||
if (fs.access_flags().is_static()) {
|
||||
fieldDescriptor fd;
|
||||
fd.initialize(this, fs.index());
|
||||
fieldDescriptor& fd = fs.field_descriptor();
|
||||
cl->do_field(&fd);
|
||||
}
|
||||
}
|
||||
|
@ -1268,8 +1266,7 @@ void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAP
|
|||
void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) {
|
||||
for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) {
|
||||
if (fs.access_flags().is_static()) {
|
||||
fieldDescriptor fd;
|
||||
fd.initialize(this_oop(), fs.index());
|
||||
fieldDescriptor& fd = fs.field_descriptor();
|
||||
f(&fd, CHECK);
|
||||
}
|
||||
}
|
||||
|
@ -1291,7 +1288,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
|
|||
int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
|
||||
int j = 0;
|
||||
for (int i = 0; i < length; i += 1) {
|
||||
fd.initialize(this, i);
|
||||
fd.reinitialize(this, i);
|
||||
if (!fd.is_static()) {
|
||||
fields_sorted[j + 0] = fd.offset();
|
||||
fields_sorted[j + 1] = i;
|
||||
|
@ -1303,7 +1300,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
|
|||
// _sort_Fn is defined in growableArray.hpp.
|
||||
qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
fd.initialize(this, fields_sorted[i + 1]);
|
||||
fd.reinitialize(this, fields_sorted[i + 1]);
|
||||
assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
|
||||
cl->do_field(&fd);
|
||||
}
|
||||
|
@ -1686,87 +1683,6 @@ jmethodID InstanceKlass::jmethod_id_or_null(Method* method) {
|
|||
}
|
||||
|
||||
|
||||
// Cache an itable index
|
||||
void InstanceKlass::set_cached_itable_index(size_t idnum, int index) {
|
||||
int* indices = methods_cached_itable_indices_acquire();
|
||||
int* to_dealloc_indices = NULL;
|
||||
|
||||
// We use a double-check locking idiom here because this cache is
|
||||
// performance sensitive. In the normal system, this cache only
|
||||
// transitions from NULL to non-NULL which is safe because we use
|
||||
// release_set_methods_cached_itable_indices() to advertise the
|
||||
// new cache. A partially constructed cache should never be seen
|
||||
// by a racing thread. Cache reads and writes proceed without a
|
||||
// lock, but creation of the cache itself requires no leaks so a
|
||||
// lock is generally acquired in that case.
|
||||
//
|
||||
// If the RedefineClasses() API has been used, then this cache can
|
||||
// grow and we'll have transitions from non-NULL to bigger non-NULL.
|
||||
// Cache creation requires no leaks and we require safety between all
|
||||
// cache accesses and freeing of the old cache so a lock is generally
|
||||
// acquired when the RedefineClasses() API has been used.
|
||||
|
||||
if (indices == NULL || idnum_can_increment()) {
|
||||
// we need a cache or the cache can grow
|
||||
MutexLocker ml(JNICachedItableIndex_lock);
|
||||
// reacquire the cache to see if another thread already did the work
|
||||
indices = methods_cached_itable_indices_acquire();
|
||||
size_t length = 0;
|
||||
// cache size is stored in element[0], other elements offset by one
|
||||
if (indices == NULL || (length = (size_t)indices[0]) <= idnum) {
|
||||
size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count());
|
||||
int* new_indices = NEW_C_HEAP_ARRAY(int, size+1, mtClass);
|
||||
new_indices[0] = (int)size;
|
||||
// copy any existing entries
|
||||
size_t i;
|
||||
for (i = 0; i < length; i++) {
|
||||
new_indices[i+1] = indices[i+1];
|
||||
}
|
||||
// Set all the rest to -1
|
||||
for (i = length; i < size; i++) {
|
||||
new_indices[i+1] = -1;
|
||||
}
|
||||
if (indices != NULL) {
|
||||
// We have an old cache to delete so save it for after we
|
||||
// drop the lock.
|
||||
to_dealloc_indices = indices;
|
||||
}
|
||||
release_set_methods_cached_itable_indices(indices = new_indices);
|
||||
}
|
||||
|
||||
if (idnum_can_increment()) {
|
||||
// this cache can grow so we have to write to it safely
|
||||
indices[idnum+1] = index;
|
||||
}
|
||||
} else {
|
||||
CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
|
||||
}
|
||||
|
||||
if (!idnum_can_increment()) {
|
||||
// The cache cannot grow and this JNI itable index value does not
|
||||
// have to be unique like a jmethodID. If there is a race to set it,
|
||||
// it doesn't matter.
|
||||
indices[idnum+1] = index;
|
||||
}
|
||||
|
||||
if (to_dealloc_indices != NULL) {
|
||||
// we allocated a new cache so free the old one
|
||||
FreeHeap(to_dealloc_indices);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Retrieve a cached itable index
|
||||
int InstanceKlass::cached_itable_index(size_t idnum) {
|
||||
int* indices = methods_cached_itable_indices_acquire();
|
||||
if (indices != NULL && ((size_t)indices[0]) > idnum) {
|
||||
// indices exist and are long enough, retrieve possible cached
|
||||
return indices[idnum+1];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Walk the list of dependent nmethods searching for nmethods which
|
||||
// are dependent on the changes that were passed in and mark them for
|
||||
|
@ -2326,12 +2242,6 @@ void InstanceKlass::release_C_heap_structures() {
|
|||
}
|
||||
}
|
||||
|
||||
int* indices = methods_cached_itable_indices_acquire();
|
||||
if (indices != (int*)NULL) {
|
||||
release_set_methods_cached_itable_indices(NULL);
|
||||
FreeHeap(indices);
|
||||
}
|
||||
|
||||
// release dependencies
|
||||
nmethodBucket* b = _dependencies;
|
||||
_dependencies = NULL;
|
||||
|
@ -2782,6 +2692,18 @@ static const char* state_names[] = {
|
|||
"allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error"
|
||||
};
|
||||
|
||||
static void print_vtable(intptr_t* start, int len, outputStream* st) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
intptr_t e = start[i];
|
||||
st->print("%d : " INTPTR_FORMAT, i, e);
|
||||
if (e != 0 && ((Metadata*)e)->is_metaspace_object()) {
|
||||
st->print(" ");
|
||||
((Metadata*)e)->print_value_on(st);
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceKlass::print_on(outputStream* st) const {
|
||||
assert(is_klass(), "must be klass");
|
||||
Klass::print_on(st);
|
||||
|
@ -2816,7 +2738,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
|||
|
||||
st->print(BULLET"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr();
|
||||
st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr();
|
||||
if (Verbose) {
|
||||
if (Verbose || WizardMode) {
|
||||
Array<Method*>* method_array = methods();
|
||||
for(int i = 0; i < method_array->length(); i++) {
|
||||
st->print("%d : ", i); method_array->at(i)->print_value(); st->cr();
|
||||
|
@ -2867,7 +2789,9 @@ void InstanceKlass::print_on(outputStream* st) const {
|
|||
st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"vtable length %d (start addr: " INTPTR_FORMAT ")", vtable_length(), start_of_vtable()); st->cr();
|
||||
if (vtable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_vtable(), vtable_length(), st);
|
||||
st->print(BULLET"itable length %d (start addr: " INTPTR_FORMAT ")", itable_length(), start_of_itable()); st->cr();
|
||||
if (itable_length() > 0 && (Verbose || WizardMode)) print_vtable(start_of_itable(), itable_length(), st);
|
||||
st->print_cr(BULLET"---- static fields (%d words):", static_field_size());
|
||||
FieldPrinter print_static_field(st);
|
||||
((InstanceKlass*)this)->do_local_static_fields(&print_static_field);
|
||||
|
@ -2889,6 +2813,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
|||
|
||||
void InstanceKlass::print_value_on(outputStream* st) const {
|
||||
assert(is_klass(), "must be klass");
|
||||
if (Verbose || WizardMode) access_flags().print_on(st);
|
||||
name()->print_value_on(st);
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,6 @@ class InstanceKlass: public Klass {
|
|||
MemberNameTable* _member_names; // Member names
|
||||
JNIid* _jni_ids; // First JNI identifier for static fields in this class
|
||||
jmethodID* _methods_jmethod_ids; // jmethodIDs corresponding to method_idnum, or NULL if none
|
||||
int* _methods_cached_itable_indices; // itable_index cache for JNI invoke corresponding to methods idnum, or NULL
|
||||
nmethodBucket* _dependencies; // list of dependent nmethods
|
||||
nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class
|
||||
BreakpointInfo* _breakpoints; // bpt lists, managed by Method*
|
||||
|
@ -690,10 +689,6 @@ class InstanceKlass: public Klass {
|
|||
size_t *length_p, jmethodID* id_p);
|
||||
jmethodID jmethod_id_or_null(Method* method);
|
||||
|
||||
// cached itable index support
|
||||
void set_cached_itable_index(size_t idnum, int index);
|
||||
int cached_itable_index(size_t idnum);
|
||||
|
||||
// annotations support
|
||||
Annotations* annotations() const { return _annotations; }
|
||||
void set_annotations(Annotations* anno) { _annotations = anno; }
|
||||
|
@ -994,11 +989,6 @@ private:
|
|||
void release_set_methods_jmethod_ids(jmethodID* jmeths)
|
||||
{ OrderAccess::release_store_ptr(&_methods_jmethod_ids, jmeths); }
|
||||
|
||||
int* methods_cached_itable_indices_acquire() const
|
||||
{ return (int*)OrderAccess::load_ptr_acquire(&_methods_cached_itable_indices); }
|
||||
void release_set_methods_cached_itable_indices(int* indices)
|
||||
{ OrderAccess::release_store_ptr(&_methods_cached_itable_indices, indices); }
|
||||
|
||||
// Lock during initialization
|
||||
public:
|
||||
// Lock for (1) initialization; (2) access to the ConstantPool of this class.
|
||||
|
|
|
@ -37,9 +37,9 @@ class instanceOopDesc : public oopDesc {
|
|||
|
||||
// If compressed, the offset of the fields of the instance may not be aligned.
|
||||
static int base_offset_in_bytes() {
|
||||
// offset computation code breaks if UseCompressedKlassPointers
|
||||
// offset computation code breaks if UseCompressedClassPointers
|
||||
// only is true
|
||||
return (UseCompressedOops && UseCompressedKlassPointers) ?
|
||||
return (UseCompressedOops && UseCompressedClassPointers) ?
|
||||
klass_gap_offset_in_bytes() :
|
||||
sizeof(instanceOopDesc);
|
||||
}
|
||||
|
|
|
@ -674,13 +674,23 @@ void Klass::oop_verify_on(oop obj, outputStream* st) {
|
|||
|
||||
#ifndef PRODUCT
|
||||
|
||||
void Klass::verify_vtable_index(int i) {
|
||||
bool Klass::verify_vtable_index(int i) {
|
||||
if (oop_is_instance()) {
|
||||
assert(i>=0 && i<((InstanceKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds");
|
||||
int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size();
|
||||
assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
|
||||
} else {
|
||||
assert(oop_is_array(), "Must be");
|
||||
assert(i>=0 && i<((ArrayKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds");
|
||||
int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size();
|
||||
assert(i >= 0 && i < limit, err_msg("index %d out of bounds %d", i, limit));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Klass::verify_itable_index(int i) {
|
||||
assert(oop_is_instance(), "");
|
||||
int method_count = klassItable::method_count_for_interface(this);
|
||||
assert(i >= 0 && i < method_count, "index out of bounds");
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -699,7 +699,8 @@ class Klass : public Metadata {
|
|||
void verify(bool check_dictionary = true) { verify_on(tty, check_dictionary); }
|
||||
|
||||
#ifndef PRODUCT
|
||||
void verify_vtable_index(int index);
|
||||
bool verify_vtable_index(int index);
|
||||
bool verify_itable_index(int index);
|
||||
#endif
|
||||
|
||||
virtual void oop_verify_on(oop obj, outputStream* st);
|
||||
|
|
|
@ -47,11 +47,12 @@ inline InstanceKlass* klassVtable::ik() const {
|
|||
|
||||
|
||||
// this function computes the vtable size (including the size needed for miranda
|
||||
// methods) and the number of miranda methods in this class
|
||||
// methods) and the number of miranda methods in this class.
|
||||
// Note on Miranda methods: Let's say there is a class C that implements
|
||||
// interface I. Let's say there is a method m in I that neither C nor any
|
||||
// of its super classes implement (i.e there is no method of any access, with
|
||||
// the same name and signature as m), then m is a Miranda method which is
|
||||
// interface I, and none of C's superclasses implements I.
|
||||
// Let's say there is an abstract method m in I that neither C
|
||||
// nor any of its super classes implement (i.e there is no method of any access,
|
||||
// with the same name and signature as m), then m is a Miranda method which is
|
||||
// entered as a public abstract method in C's vtable. From then on it should
|
||||
// treated as any other public method in C for method over-ride purposes.
|
||||
void klassVtable::compute_vtable_size_and_num_mirandas(
|
||||
|
@ -111,10 +112,13 @@ void klassVtable::compute_vtable_size_and_num_mirandas(
|
|||
}
|
||||
|
||||
int klassVtable::index_of(Method* m, int len) const {
|
||||
assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods");
|
||||
assert(m->has_vtable_index(), "do not ask this of non-vtable methods");
|
||||
return m->vtable_index();
|
||||
}
|
||||
|
||||
// Copy super class's vtable to the first part (prefix) of this class's vtable,
|
||||
// and return the number of entries copied. Expects that 'super' is the Java
|
||||
// super class (arrays can have "array" super classes that must be skipped).
|
||||
int klassVtable::initialize_from_super(KlassHandle super) {
|
||||
if (super.is_null()) {
|
||||
return 0;
|
||||
|
@ -139,14 +143,14 @@ int klassVtable::initialize_from_super(KlassHandle super) {
|
|||
}
|
||||
}
|
||||
|
||||
// Revised lookup semantics introduced 1.3 (Kestral beta)
|
||||
//
|
||||
// Revised lookup semantics introduced 1.3 (Kestrel beta)
|
||||
void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
|
||||
|
||||
// Note: Arrays can have intermediate array supers. Use java_super to skip them.
|
||||
KlassHandle super (THREAD, klass()->java_super());
|
||||
int nofNewEntries = 0;
|
||||
|
||||
|
||||
if (PrintVtables && !klass()->oop_is_array()) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
|
||||
|
@ -174,8 +178,10 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
|
|||
int len = methods->length();
|
||||
int initialized = super_vtable_len;
|
||||
|
||||
// update_inherited_vtable can stop for gc - ensure using handles
|
||||
// Check each of this class's methods against super;
|
||||
// if override, replace in copy of super vtable, otherwise append to end
|
||||
for (int i = 0; i < len; i++) {
|
||||
// update_inherited_vtable can stop for gc - ensure using handles
|
||||
HandleMark hm(THREAD);
|
||||
assert(methods->at(i)->is_method(), "must be a Method*");
|
||||
methodHandle mh(THREAD, methods->at(i));
|
||||
|
@ -189,11 +195,11 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
|
|||
}
|
||||
}
|
||||
|
||||
// add miranda methods; it will also update the value of initialized
|
||||
fill_in_mirandas(&initialized);
|
||||
// add miranda methods to end of vtable.
|
||||
initialized = fill_in_mirandas(initialized);
|
||||
|
||||
// In class hierarchies where the accessibility is not increasing (i.e., going from private ->
|
||||
// package_private -> publicprotected), the vtable might actually be smaller than our initial
|
||||
// package_private -> public/protected), the vtable might actually be smaller than our initial
|
||||
// calculation.
|
||||
assert(initialized <= _length, "vtable initialization failed");
|
||||
for(;initialized < _length; initialized++) {
|
||||
|
@ -248,14 +254,8 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
|
|||
return superk;
|
||||
}
|
||||
|
||||
// Methods that are "effectively" final don't need vtable entries.
|
||||
bool method_is_effectively_final(
|
||||
AccessFlags klass_flags, methodHandle target) {
|
||||
return target->is_final() || klass_flags.is_final() && !target->is_overpass();
|
||||
}
|
||||
|
||||
// Update child's copy of super vtable for overrides
|
||||
// OR return true if a new vtable entry is required
|
||||
// OR return true if a new vtable entry is required.
|
||||
// Only called for InstanceKlass's, i.e. not for arrays
|
||||
// If that changed, could not use _klass as handle for klass
|
||||
bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len,
|
||||
|
@ -263,6 +263,7 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
|
|||
ResourceMark rm;
|
||||
bool allocate_new = true;
|
||||
assert(klass->oop_is_instance(), "must be InstanceKlass");
|
||||
assert(klass == target_method()->method_holder(), "caller resp.");
|
||||
|
||||
// Initialize the method's vtable index to "nonvirtual".
|
||||
// If we allocate a vtable entry, we will update it to a non-negative number.
|
||||
|
@ -273,11 +274,17 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
|
|||
return false;
|
||||
}
|
||||
|
||||
if (method_is_effectively_final(klass->access_flags(), target_method)) {
|
||||
if (target_method->is_final_method(klass->access_flags())) {
|
||||
// a final method never needs a new entry; final methods can be statically
|
||||
// resolved and they have to be present in the vtable only if they override
|
||||
// a super's method, in which case they re-use its entry
|
||||
allocate_new = false;
|
||||
} else if (klass->is_interface()) {
|
||||
allocate_new = false; // see note below in needs_new_vtable_entry
|
||||
// An interface never allocates new vtable slots, only inherits old ones.
|
||||
// This method will either be assigned its own itable index later,
|
||||
// or be assigned an inherited vtable index in the loop below.
|
||||
target_method()->set_vtable_index(Method::pending_itable_index);
|
||||
}
|
||||
|
||||
// we need a new entry if there is no superclass
|
||||
|
@ -411,8 +418,14 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
|
|||
Symbol* classname,
|
||||
AccessFlags class_flags,
|
||||
TRAPS) {
|
||||
if (class_flags.is_interface()) {
|
||||
// Interfaces do not use vtables, so there is no point to assigning
|
||||
// a vtable index to any of their methods. If we refrain from doing this,
|
||||
// we can use Method::_vtable_index to hold the itable index
|
||||
return false;
|
||||
}
|
||||
|
||||
if (method_is_effectively_final(class_flags, target_method) ||
|
||||
if (target_method->is_final_method(class_flags) ||
|
||||
// a final method never needs a new entry; final methods can be statically
|
||||
// resolved and they have to be present in the vtable only if they override
|
||||
// a super's method, in which case they re-use its entry
|
||||
|
@ -500,7 +513,8 @@ int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) {
|
|||
return Method::invalid_vtable_index;
|
||||
}
|
||||
|
||||
// check if an entry is miranda
|
||||
// check if an entry at an index is miranda
|
||||
// requires that method m at entry be declared ("held") by an interface.
|
||||
bool klassVtable::is_miranda_entry_at(int i) {
|
||||
Method* m = method_at(i);
|
||||
Klass* method_holder = m->method_holder();
|
||||
|
@ -516,7 +530,9 @@ bool klassVtable::is_miranda_entry_at(int i) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// check if a method is a miranda method, given a class's methods table and it's super
|
||||
// check if a method is a miranda method, given a class's methods table and its super
|
||||
// "miranda" means not static, not defined by this class, and not defined
|
||||
// in super unless it is private and therefore inaccessible to this class.
|
||||
// the caller must make sure that the method belongs to an interface implemented by the class
|
||||
bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
|
||||
if (m->is_static()) {
|
||||
|
@ -541,6 +557,14 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* su
|
|||
return false;
|
||||
}
|
||||
|
||||
// Scans current_interface_methods for miranda methods that do not
|
||||
// already appear in new_mirandas and are also not defined-and-non-private
|
||||
// in super (superclass). These mirandas are added to all_mirandas if it is
|
||||
// not null; in addition, those that are not duplicates of miranda methods
|
||||
// inherited by super from its interfaces are added to new_mirandas.
|
||||
// Thus, new_mirandas will be the set of mirandas that this class introduces,
|
||||
// all_mirandas will be the set of all mirandas applicable to this class
|
||||
// including all defined in superclasses.
|
||||
void klassVtable::add_new_mirandas_to_lists(
|
||||
GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas,
|
||||
Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
|
||||
|
@ -599,17 +623,22 @@ void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas,
|
|||
}
|
||||
}
|
||||
|
||||
// fill in mirandas
|
||||
void klassVtable::fill_in_mirandas(int* initialized) {
|
||||
// Discover miranda methods ("miranda" = "interface abstract, no binding"),
|
||||
// and append them into the vtable starting at index initialized,
|
||||
// return the new value of initialized.
|
||||
int klassVtable::fill_in_mirandas(int initialized) {
|
||||
GrowableArray<Method*> mirandas(20);
|
||||
get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
|
||||
ik()->local_interfaces());
|
||||
for (int i = 0; i < mirandas.length(); i++) {
|
||||
put_method_at(mirandas.at(i), *initialized);
|
||||
++(*initialized);
|
||||
put_method_at(mirandas.at(i), initialized);
|
||||
++initialized;
|
||||
}
|
||||
return initialized;
|
||||
}
|
||||
|
||||
// Copy this class's vtable to the vtable beginning at start.
|
||||
// Used to copy superclass vtable to prefix of subclass's vtable.
|
||||
void klassVtable::copy_vtable_to(vtableEntry* start) {
|
||||
Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size());
|
||||
}
|
||||
|
@ -723,6 +752,12 @@ static int initialize_count = 0;
|
|||
|
||||
// Initialization
|
||||
void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
|
||||
if (_klass->is_interface()) {
|
||||
// This needs to go after vtable indexes are assigned but
|
||||
// before implementors need to know the number of itable indexes.
|
||||
assign_itable_indexes_for_interface(_klass());
|
||||
}
|
||||
|
||||
// Cannot be setup doing bootstrapping, interfaces don't have
|
||||
// itables, and klass with only ones entry have empty itables
|
||||
if (Universe::is_bootstrapping() ||
|
||||
|
@ -754,45 +789,89 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
|
|||
}
|
||||
|
||||
|
||||
inline bool interface_method_needs_itable_index(Method* m) {
|
||||
if (m->is_static()) return false; // e.g., Stream.empty
|
||||
if (m->is_initializer()) return false; // <init> or <clinit>
|
||||
// If an interface redeclares a method from java.lang.Object,
|
||||
// it should already have a vtable index, don't touch it.
|
||||
// e.g., CharSequence.toString (from initialize_vtable)
|
||||
// if (m->has_vtable_index()) return false; // NO!
|
||||
return true;
|
||||
}
|
||||
|
||||
int klassItable::assign_itable_indexes_for_interface(Klass* klass) {
|
||||
// an interface does not have an itable, but its methods need to be numbered
|
||||
if (TraceItables) tty->print_cr("%3d: Initializing itable for interface %s", ++initialize_count,
|
||||
klass->name()->as_C_string());
|
||||
Array<Method*>* methods = InstanceKlass::cast(klass)->methods();
|
||||
int nof_methods = methods->length();
|
||||
int ime_num = 0;
|
||||
for (int i = 0; i < nof_methods; i++) {
|
||||
Method* m = methods->at(i);
|
||||
if (interface_method_needs_itable_index(m)) {
|
||||
assert(!m->is_final_method(), "no final interface methods");
|
||||
// If m is already assigned a vtable index, do not disturb it.
|
||||
if (!m->has_vtable_index()) {
|
||||
assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable");
|
||||
m->set_itable_index(ime_num);
|
||||
// Progress to next itable entry
|
||||
ime_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(ime_num == method_count_for_interface(klass), "proper sizing");
|
||||
return ime_num;
|
||||
}
|
||||
|
||||
int klassItable::method_count_for_interface(Klass* interf) {
|
||||
assert(interf->oop_is_instance(), "must be");
|
||||
assert(interf->is_interface(), "must be");
|
||||
Array<Method*>* methods = InstanceKlass::cast(interf)->methods();
|
||||
int nof_methods = methods->length();
|
||||
while (nof_methods > 0) {
|
||||
Method* m = methods->at(nof_methods-1);
|
||||
if (m->has_itable_index()) {
|
||||
int length = m->itable_index() + 1;
|
||||
#ifdef ASSERT
|
||||
while (nof_methods = 0) {
|
||||
m = methods->at(--nof_methods);
|
||||
assert(!m->has_itable_index() || m->itable_index() < length, "");
|
||||
}
|
||||
#endif //ASSERT
|
||||
return length; // return the rightmost itable index, plus one
|
||||
}
|
||||
nof_methods -= 1;
|
||||
}
|
||||
// no methods have itable indexes
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) {
|
||||
Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods();
|
||||
int nof_methods = methods->length();
|
||||
HandleMark hm;
|
||||
KlassHandle klass = _klass;
|
||||
assert(nof_methods > 0, "at least one method must exist for interface to be in vtable");
|
||||
Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader());
|
||||
int ime_num = 0;
|
||||
|
||||
// Skip first Method* if it is a class initializer
|
||||
int i = methods->at(0)->is_static_initializer() ? 1 : 0;
|
||||
|
||||
// m, method_name, method_signature, klass reset each loop so they
|
||||
// don't need preserving across check_signature_loaders call
|
||||
// methods needs a handle in case of gc from check_signature_loaders
|
||||
for(; i < nof_methods; i++) {
|
||||
int ime_count = method_count_for_interface(interf_h());
|
||||
for (int i = 0; i < nof_methods; i++) {
|
||||
Method* m = methods->at(i);
|
||||
Symbol* method_name = m->name();
|
||||
Symbol* method_signature = m->signature();
|
||||
|
||||
// This is same code as in Linkresolver::lookup_instance_method_in_klasses
|
||||
Method* target = klass->uncached_lookup_method(method_name, method_signature);
|
||||
while (target != NULL && target->is_static()) {
|
||||
// continue with recursive lookup through the superclass
|
||||
Klass* super = target->method_holder()->super();
|
||||
target = (super == NULL) ? (Method*)NULL : super->uncached_lookup_method(method_name, method_signature);
|
||||
methodHandle target;
|
||||
if (m->has_itable_index()) {
|
||||
LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK);
|
||||
}
|
||||
if (target == NULL || !target->is_public() || target->is_abstract()) {
|
||||
// Entry do not resolve. Leave it empty
|
||||
} else {
|
||||
// Entry did resolve, check loader constraints before initializing
|
||||
// if checkconstraints requested
|
||||
methodHandle target_h (THREAD, target); // preserve across gc
|
||||
if (checkconstraints) {
|
||||
Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
|
||||
if (method_holder_loader() != interface_loader()) {
|
||||
ResourceMark rm(THREAD);
|
||||
Symbol* failed_type_symbol =
|
||||
SystemDictionary::check_signature_loaders(method_signature,
|
||||
SystemDictionary::check_signature_loaders(m->signature(),
|
||||
method_holder_loader,
|
||||
interface_loader,
|
||||
true, CHECK);
|
||||
|
@ -803,9 +882,9 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
|||
"and the class loader (instance of %s) for interface "
|
||||
"%s have different Class objects for the type %s "
|
||||
"used in the signature";
|
||||
char* sig = target_h()->name_and_sig_as_C_string();
|
||||
char* sig = target()->name_and_sig_as_C_string();
|
||||
const char* loader1 = SystemDictionary::loader_name(method_holder_loader());
|
||||
char* current = klass->name()->as_C_string();
|
||||
char* current = _klass->name()->as_C_string();
|
||||
const char* loader2 = SystemDictionary::loader_name(interface_loader());
|
||||
char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string();
|
||||
char* failed_type_name = failed_type_symbol->as_C_string();
|
||||
|
@ -821,10 +900,10 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
|||
}
|
||||
|
||||
// ime may have moved during GC so recalculate address
|
||||
itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target_h());
|
||||
int ime_num = m->itable_index();
|
||||
assert(ime_num < ime_count, "oob");
|
||||
itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target());
|
||||
}
|
||||
// Progress to next entry
|
||||
ime_num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -913,20 +992,22 @@ class InterfaceVisiterClosure : public StackObj {
|
|||
virtual void doit(Klass* intf, int method_count) = 0;
|
||||
};
|
||||
|
||||
// Visit all interfaces with at-least one method (excluding <clinit>)
|
||||
// Visit all interfaces with at least one itable method
|
||||
void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosure *blk) {
|
||||
// Handle array argument
|
||||
for(int i = 0; i < transitive_intf->length(); i++) {
|
||||
Klass* intf = transitive_intf->at(i);
|
||||
assert(intf->is_interface(), "sanity check");
|
||||
|
||||
// Find no. of methods excluding a <clinit>
|
||||
int method_count = InstanceKlass::cast(intf)->methods()->length();
|
||||
if (method_count > 0) {
|
||||
Method* m = InstanceKlass::cast(intf)->methods()->at(0);
|
||||
assert(m != NULL && m->is_method(), "sanity check");
|
||||
if (m->name() == vmSymbols::object_initializer_name()) {
|
||||
method_count--;
|
||||
// Find no. of itable methods
|
||||
int method_count = 0;
|
||||
// method_count = klassItable::method_count_for_interface(intf);
|
||||
Array<Method*>* methods = InstanceKlass::cast(intf)->methods();
|
||||
if (methods->length() > 0) {
|
||||
for (int i = methods->length(); --i >= 0; ) {
|
||||
if (interface_method_needs_itable_index(methods->at(i))) {
|
||||
method_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1024,40 +1105,26 @@ void klassItable::setup_itable_offset_table(instanceKlassHandle klass) {
|
|||
}
|
||||
|
||||
|
||||
// m must be a method in an interface
|
||||
int klassItable::compute_itable_index(Method* m) {
|
||||
InstanceKlass* intf = m->method_holder();
|
||||
assert(intf->is_interface(), "sanity check");
|
||||
Array<Method*>* methods = intf->methods();
|
||||
int index = 0;
|
||||
while(methods->at(index) != m) {
|
||||
index++;
|
||||
assert(index < methods->length(), "should find index for resolve_invoke");
|
||||
}
|
||||
// Adjust for <clinit>, which is left out of table if first method
|
||||
if (methods->length() > 0 && methods->at(0)->is_static_initializer()) {
|
||||
index--;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
// inverse to compute_itable_index
|
||||
// inverse to itable_index
|
||||
Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) {
|
||||
assert(InstanceKlass::cast(intf)->is_interface(), "sanity check");
|
||||
assert(intf->verify_itable_index(itable_index), "");
|
||||
Array<Method*>* methods = InstanceKlass::cast(intf)->methods();
|
||||
|
||||
int index = itable_index;
|
||||
// Adjust for <clinit>, which is left out of table if first method
|
||||
if (methods->length() > 0 && methods->at(0)->is_static_initializer()) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if (itable_index < 0 || index >= methods->length())
|
||||
if (itable_index < 0 || itable_index >= method_count_for_interface(intf))
|
||||
return NULL; // help caller defend against bad indexes
|
||||
|
||||
int index = itable_index;
|
||||
Method* m = methods->at(index);
|
||||
assert(compute_itable_index(m) == itable_index, "correct inverse");
|
||||
int index2 = -1;
|
||||
while (!m->has_itable_index() ||
|
||||
(index2 = m->itable_index()) != itable_index) {
|
||||
assert(index2 < itable_index, "monotonic");
|
||||
if (++index == methods->length())
|
||||
return NULL;
|
||||
m = methods->at(index);
|
||||
}
|
||||
assert(m->itable_index() == itable_index, "correct inverse");
|
||||
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ class klassVtable : public ResourceObj {
|
|||
|
||||
// support for miranda methods
|
||||
bool is_miranda_entry_at(int i);
|
||||
void fill_in_mirandas(int* initialized);
|
||||
int fill_in_mirandas(int initialized);
|
||||
static bool is_miranda(Method* m, Array<Method*>* class_methods, Klass* super);
|
||||
static void add_new_mirandas_to_lists(
|
||||
GrowableArray<Method*>* new_mirandas,
|
||||
|
@ -150,6 +150,8 @@ class klassVtable : public ResourceObj {
|
|||
// from_compiled_code_entry_point -> nmethod entry point
|
||||
// from_interpreter_entry_point -> i2cadapter
|
||||
class vtableEntry VALUE_OBJ_CLASS_SPEC {
|
||||
friend class VMStructs;
|
||||
|
||||
public:
|
||||
// size in words
|
||||
static int size() {
|
||||
|
@ -288,12 +290,12 @@ class klassItable : public ResourceObj {
|
|||
#endif // INCLUDE_JVMTI
|
||||
|
||||
// Setup of itable
|
||||
static int assign_itable_indexes_for_interface(Klass* klass);
|
||||
static int method_count_for_interface(Klass* klass);
|
||||
static int compute_itable_size(Array<Klass*>* transitive_interfaces);
|
||||
static void setup_itable_offset_table(instanceKlassHandle klass);
|
||||
|
||||
// Resolving of method to index
|
||||
static int compute_itable_index(Method* m);
|
||||
// ...and back again:
|
||||
static Method* method_for_itable_index(Klass* klass, int itable_index);
|
||||
|
||||
// Debugging/Statistics
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue