This commit is contained in:
Daniel D. Daugherty 2013-09-20 18:19:07 -07:00
commit 80b2573b1c
875 changed files with 31883 additions and 13163 deletions

View file

@ -228,3 +228,4 @@ bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102
b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104 b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104
589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105 589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105
514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106 514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106
892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107

View file

@ -228,3 +228,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104 96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105 5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105
8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106
0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107

View file

@ -404,7 +404,6 @@ COMPILER_PATH.desc = Compiler install directory
CACERTS_FILE.desc = Location of certificates file CACERTS_FILE.desc = Location of certificates file
DEVTOOLS_PATH.desc = Directory containing zip and gnumake DEVTOOLS_PATH.desc = Directory containing zip and gnumake
CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files 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) # Make variables to print out (description and value)
VARIABLE_PRINTVAL_LIST += \ VARIABLE_PRINTVAL_LIST += \
@ -429,17 +428,6 @@ VARIABLE_CHECKDIR_LIST += \
VARIABLE_CHECKFIL_LIST += \ VARIABLE_CHECKFIL_LIST += \
CACERTS_FILE 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 # For pattern rules below, so all are treated the same
DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval) DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval)
DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir) DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir)

View file

@ -444,10 +444,6 @@
Install Install
<a href="#vs2010">Visual Studio 2010</a> <a href="#vs2010">Visual Studio 2010</a>
</li> </li>
<li>
Install the
<a href="#dxsdk">Microsoft DirectX SDK</a>
</li>
</ul> </ul>
</td> </td>
<td> <td>
@ -971,25 +967,6 @@
developer install location developer install location
</td> </td>
</tr> </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&amp;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> <tr>
<td><b><code>--with-freetype=</code></b><i>path</i></td> <td><b><code>--with-freetype=</code></b><i>path</i></td>
<td> <td>

View file

@ -203,6 +203,15 @@ AC_DEFUN([BASIC_REMOVE_SYMBOLIC_LINKS],
fi 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], AC_DEFUN_ONCE([BASIC_INIT],
[ [
# Save the original command line. This is passed to us by the wrapper configure script. # Save the original command line. This is passed to us by the wrapper configure script.

View file

@ -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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then if test "x$test_shortpath" = x; then

View file

@ -26,10 +26,10 @@
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# Free Software Foundation, Inc. # 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 # 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 # 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. # General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, see <http://www.gnu.org/licenses/>.
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# #
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # 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. # the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner <per@bothner.com>. # Originally written by Per Bothner. Please send patches (context
# Please send patches to <config-patches@gnu.org>. Submit a context # diff format) to <config-patches@gnu.org> and include a ChangeLog
# diff and a properly formatted ChangeLog entry. # entry.
# #
# This script attempts to guess a canonical system name similar to # This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and # config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1. # exits with 0. Otherwise, it exits with 1.
# #
# The plan is that this can be called by configure scripts if you # You can get the latest version of this script from:
# don't specify an explicit build system type. # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
me=`echo "$0" | sed -e 's,.*/,,'` me=`echo "$0" | sed -e 's,.*/,,'`
@ -81,8 +79,9 @@ version="\
GNU config.guess ($timestamp) GNU config.guess ($timestamp)
Originally written by Per Bothner. Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. 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 This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." 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 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*) *:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or # 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 # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old # switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward # 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) arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null | grep -q __ELF__
then then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX? # Return netbsd for either. FIX?
@ -205,7 +204,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi fi
;; ;;
*) *)
os=netbsd os=netbsd
;; ;;
esac esac
# The OS release # The OS release
@ -248,7 +247,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;; ;;
*5.*) *5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;; ;;
esac esac
# According to Compaq, /usr/sbin/psrinfo has been available on # According to Compaq, /usr/sbin/psrinfo has been available on
@ -294,7 +293,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel. # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r. # 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` 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*:*) Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem? # 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 # Should we change UNAME_MACHINE based on the output of uname instead
@ -320,7 +322,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe echo s390-ibm-zvmoe
exit ;; exit ;;
*:OS400:*:*) *:OS400:*:*)
echo powerpc-ibm-os400 echo powerpc-ibm-os400
exit ;; exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE} echo arm-acorn-riscix${UNAME_RELEASE}
@ -349,14 +351,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;; sparc) echo sparc-icl-nx7; exit ;;
esac ;; esac ;;
s390x:SunOS:*:*)
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4H:SunOS:5.*:*) sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;; exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;; exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) 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 ;; exit ;;
sun4*:SunOS:6*:*) sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize # According to config.sub, this is the proper way to canonicalize
@ -400,23 +421,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should # MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem. # be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE} echo m68k-atari-mint${UNAME_RELEASE}
exit ;; exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE} echo m68k-atari-mint${UNAME_RELEASE}
exit ;; exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE} echo m68k-atari-mint${UNAME_RELEASE}
exit ;; exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE} echo m68k-milan-mint${UNAME_RELEASE}
exit ;; exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE} echo m68k-hades-mint${UNAME_RELEASE}
exit ;; exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE} echo m68k-unknown-mint${UNAME_RELEASE}
exit ;; exit ;;
m68k:machten:*:*) m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE} echo m68k-apple-machten${UNAME_RELEASE}
exit ;; exit ;;
@ -486,8 +507,8 @@ EOF
echo m88k-motorola-sysv3 echo m88k-motorola-sysv3
exit ;; exit ;;
AViiON:dgux:*:*) AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures # DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p` UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@ -500,7 +521,7 @@ EOF
else else
echo i586-dg-dgux${UNAME_RELEASE} echo i586-dg-dgux${UNAME_RELEASE}
fi fi
exit ;; exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3) M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3 echo m88k-dolphin-sysv3
exit ;; exit ;;
@ -557,7 +578,7 @@ EOF
echo rs6000-ibm-aix3.2 echo rs6000-ibm-aix3.2
fi fi
exit ;; exit ;;
*:AIX:*:[456]) *:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` 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 if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000 IBM_ARCH=rs6000
@ -600,52 +621,52 @@ EOF
9000/[678][0-9][0-9]) 9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0 532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;; 32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;; 64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;; esac ;;
esac esac
fi fi
if [ "${HP_ARCH}" = "" ]; then if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE #define _HPUX_SOURCE
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
int main () int main ()
{ {
#if defined(_SC_KERNEL_BITS) #if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS); long bits = sysconf(_SC_KERNEL_BITS);
#endif #endif
long cpu = sysconf (_SC_CPU_VERSION); long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu) switch (cpu)
{ {
case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0: case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS) #if defined(_SC_KERNEL_BITS)
switch (bits) switch (bits)
{ {
case 64: puts ("hppa2.0w"); break; case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break; case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break; default: puts ("hppa2.0"); break;
} break; } break;
#else /* !defined(_SC_KERNEL_BITS) */ #else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break; puts ("hppa2.0"); break;
#endif #endif
default: puts ("hppa1.0"); break; default: puts ("hppa1.0"); break;
} }
exit (0); exit (0);
} }
EOF EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa test -z "$HP_ARCH" && HP_ARCH=hppa
@ -665,7 +686,7 @@ EOF
# => hppa64-hp-hpux11.23 # => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep __LP64__ >/dev/null grep -q __LP64__
then then
HP_ARCH="hppa2.0w" HP_ARCH="hppa2.0w"
else else
@ -736,22 +757,22 @@ EOF
exit ;; exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd echo c1-convex-bsd
exit ;; exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc if getsysinfo -f scalar_acc
then echo c32-convex-bsd then echo c32-convex-bsd
else echo c2-convex-bsd else echo c2-convex-bsd
fi fi
exit ;; exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd echo c34-convex-bsd
exit ;; exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd echo c38-convex-bsd
exit ;; exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd echo c4-convex-bsd
exit ;; exit ;;
CRAY*Y-MP:*:*:*) CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;; exit ;;
@ -775,14 +796,14 @@ EOF
exit ;; exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;; exit ;;
5000:UNIX_System_V:4.*:*) 5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;; exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@ -794,13 +815,12 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;; exit ;;
*:FreeBSD:*:*) *:FreeBSD:*:*)
case ${UNAME_MACHINE} in UNAME_PROCESSOR=`/usr/bin/uname -p`
pc98) case ${UNAME_PROCESSOR} in
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
amd64) amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; 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 esac
exit ;; exit ;;
i*:CYGWIN*:*) i*:CYGWIN*:*)
@ -809,19 +829,22 @@ EOF
*:MINGW*:*) *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32 echo ${UNAME_MACHINE}-pc-mingw32
exit ;; exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*) i*:windows32*:*)
# uname -m includes "-pc" on this system. # uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32 echo ${UNAME_MACHINE}-mingw32
exit ;; exit ;;
i*:PW*:*) i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32 echo ${UNAME_MACHINE}-pc-pw32
exit ;; exit ;;
*:Interix*:[3456]*) *:Interix*:*)
case ${UNAME_MACHINE} in case ${UNAME_MACHINE} in
x86) x86)
echo i586-pc-interix${UNAME_RELEASE} echo i586-pc-interix${UNAME_RELEASE}
exit ;; exit ;;
EM64T | authenticamd) authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE} echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;; exit ;;
IA64) IA64)
@ -831,6 +854,9 @@ EOF
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks echo i${UNAME_MACHINE}-pc-mks
exit ;; exit ;;
8664:Windows_NT:*)
echo x86_64-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*) i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem? # 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 # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@ -860,92 +886,13 @@ EOF
i*86:Minix:*:*) i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix echo ${UNAME_MACHINE}-pc-minix
exit ;; exit ;;
arm*:Linux:*:*) aarch64: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:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; exit ;;
cris:Linux:*:*) aarch64_be:Linux:*:*)
echo cris-axis-linux-gnu UNAME_MACHINE=aarch64_be
exit ;;
crisv32:Linux:*:*)
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; 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:*:*) alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;; EV5) UNAME_MACHINE=alphaev5 ;;
@ -955,11 +902,90 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;; EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;; EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;; EV68*) UNAME_MACHINE=alphaev68 ;;
esac 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 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;; 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:*:*) parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level # Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@ -968,14 +994,17 @@ EOF
*) echo hppa-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;;
esac esac
exit ;; exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*) ppc64:Linux:*:*)
echo hppa64-unknown-linux-gnu echo powerpc64-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;; exit ;;
s390:Linux:*:* | s390x:Linux:*:*) s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux echo ${UNAME_MACHINE}-ibm-linux
exit ;; exit ;;
sh64*:Linux:*:*) sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; exit ;;
sh*:Linux:*:*) sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
@ -983,78 +1012,18 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*) sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*) vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;; exit ;;
x86_64:Linux:*:*) x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; exit ;;
xtensa*:Linux:*:*) xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; 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*:*) i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both # earlier versions are messed up and put the nodename in both
@ -1062,11 +1031,11 @@ EOF
echo i386-sequent-sysv4 echo i386-sequent-sysv4
exit ;; exit ;;
i*86:UNIX_SV:4.2MP:2.*) i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version # Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2... # number series starting with 2...
# I am not positive that other SVR4 systems won't match this, # I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms. # I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it. # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;; exit ;;
i*86:OS/2:*:*) i*86:OS/2:*:*)
@ -1083,7 +1052,7 @@ EOF
i*86:syllable:*:*) i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable echo ${UNAME_MACHINE}-pc-syllable
exit ;; 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} echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;; exit ;;
i*86:*DOS:*:*) i*86:*DOS:*:*)
@ -1098,7 +1067,7 @@ EOF
fi fi
exit ;; exit ;;
i*86:*:5:[678]*) i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6. # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;; *486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;; *Pentium) UNAME_MACHINE=i586 ;;
@ -1126,10 +1095,13 @@ EOF
exit ;; exit ;;
pc:*:*:*) pc:*:*:*)
# Left here for compatibility: # Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about # uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386. # the processor, so we play safe by assuming i586.
echo i386-pc-msdosdjgpp # Note: whatever this is, it MUST be the same as what config.sub
exit ;; # 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*:*) Intel:Mach:3*:*)
echo i386-pc-mach3 echo i386-pc-mach3
exit ;; exit ;;
@ -1164,8 +1136,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;; && { 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*:*) m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE} echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;; exit ;;
@ -1178,7 +1160,7 @@ EOF
rs6000:LynxOS:2.*:*) rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE} echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;; 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} echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;; exit ;;
SM[BE]S:UNIX_SV:*:*) SM[BE]S:UNIX_SV:*:*)
@ -1198,10 +1180,10 @@ EOF
echo ns32k-sni-sysv echo ns32k-sni-sysv
fi fi
exit ;; exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV> # says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4 echo i586-unisys-sysv4
exit ;; exit ;;
*:UNIX_System_V:4*:FTX*) *:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>. # From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm # How about differentiating between stratus architectures? -djm
@ -1227,11 +1209,11 @@ EOF
exit ;; exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE} echo mips-nec-sysv${UNAME_RELEASE}
else else
echo mips-unknown-sysv${UNAME_RELEASE} echo mips-unknown-sysv${UNAME_RELEASE}
fi fi
exit ;; exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos echo powerpc-be-beos
exit ;; exit ;;
@ -1241,6 +1223,9 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible. BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos echo i586-pc-beos
exit ;; exit ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
SX-4:SUPER-UX:*:*) SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE} echo sx4-nec-superux${UNAME_RELEASE}
exit ;; exit ;;
@ -1267,12 +1252,17 @@ EOF
exit ;; exit ;;
*:Darwin:*:*) *:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown 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 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 ;; unknown) UNAME_PROCESSOR=powerpc ;;
esac esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@ -1288,6 +1278,9 @@ EOF
*:QNX:*:4*) *:QNX:*:4*)
echo i386-pc-qnx echo i386-pc-qnx
exit ;; exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-?:NONSTOP_KERNEL:*:*) NSE-?:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE} echo nse-tandem-nsk${UNAME_RELEASE}
exit ;; exit ;;
@ -1333,13 +1326,13 @@ EOF
echo pdp10-unknown-its echo pdp10-unknown-its
exit ;; exit ;;
SEI:*:*:SEIUX) SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE} echo mips-sei-seiux${UNAME_RELEASE}
exit ;; exit ;;
*:DragonFly:*:*) *:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;; exit ;;
*:*VMS:*:*) *:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null` UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;; A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;;
@ -1354,6 +1347,12 @@ EOF
i*86:rdos:*:*) i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos echo ${UNAME_MACHINE}-pc-rdos
exit ;; exit ;;
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac esac
#echo '(No uname command or uname output not recognized.)' 1>&2 #echo '(No uname command or uname output not recognized.)' 1>&2
@ -1376,11 +1375,11 @@ main ()
#include <sys/param.h> #include <sys/param.h>
printf ("m68k-sony-newsos%s\n", printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4 #ifdef NEWSOS4
"4" "4"
#else #else
"" ""
#endif #endif
); exit (0); ); exit (0);
#endif #endif
#endif #endif

View file

@ -219,9 +219,4 @@ else
echo configure exiting with result code $conf_result_code echo configure exiting with result code $conf_result_code
fi 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 exit $conf_result_code

View file

@ -232,9 +232,15 @@ CUSTOM_LATE_HOOK
# We're messing a bit with internal autoconf variables to put the config.status # We're messing a bit with internal autoconf variables to put the config.status
# in the output directory instead of the current directory. # in the output directory instead of the current directory.
CONFIG_STATUS="$OUTPUT_ROOT/config.status" CONFIG_STATUS="$OUTPUT_ROOT/config.status"
# Create the actual output files. Now the main work of configure is done. # Create the actual output files. Now the main work of configure is done.
AC_OUTPUT 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 # Make the compare script executable
$CHMOD +x $OUTPUT_ROOT/compare.sh $CHMOD +x $OUTPUT_ROOT/compare.sh

View file

@ -709,7 +709,6 @@ STATIC_LIBRARY
SHARED_LIBRARY SHARED_LIBRARY
OBJ_SUFFIX OBJ_SUFFIX
COMPILER_NAME COMPILER_NAME
TARGET_BITS_FLAG
JT_HOME JT_HOME
JTREGEXE JTREGEXE
LIPO LIPO
@ -766,8 +765,6 @@ BUILD_LD
BUILD_CXX BUILD_CXX
BUILD_CC BUILD_CC
MSVCR_DLL MSVCR_DLL
DXSDK_INCLUDE_PATH
DXSDK_LIB_PATH
VS_PATH VS_PATH
VS_LIB VS_LIB
VS_INCLUDE VS_INCLUDE
@ -1031,6 +1028,7 @@ with_override_corba
with_override_jaxp with_override_jaxp
with_override_jaxws with_override_jaxws
with_override_hotspot with_override_hotspot
with_override_nashorn
with_override_jdk with_override_jdk
with_import_hotspot with_import_hotspot
with_msvcr_dll with_msvcr_dll
@ -1784,17 +1782,19 @@ Optional Packages:
--with-override-jaxp use this jaxp dir for the build --with-override-jaxp use this jaxp dir for the build
--with-override-jaxws use this jaxws 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-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-override-jdk use this jdk dir for the build
--with-import-hotspot import hotspot binaries from this jdk image or --with-import-hotspot import hotspot binaries from this jdk image or
hotspot build dist dir instead of building from hotspot build dist dir instead of building from
source source
--with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows --with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows
only) [probed] only) [probed]
--with-dxsdk the DirectX SDK (Windows only) [probed] --with-dxsdk Deprecated. Option is kept for backwards
--with-dxsdk-lib the DirectX SDK lib directory (Windows only) compatibility and is ignored
[probed] --with-dxsdk-lib Deprecated. Option is kept for backwards
--with-dxsdk-include the DirectX SDK include directory (Windows only) compatibility and is ignored
[probed] --with-dxsdk-include Deprecated. Option is kept for backwards
compatibility and is ignored
--with-jtreg Regression Test Harness [probed] --with-jtreg Regression Test Harness [probed]
--with-extra-cflags extra flags to be used when compiling jdk c-files --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 --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. # 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 #CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks: # 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then if test "x$test_shortpath" = x; then
@ -11075,7 +11075,7 @@ elif test "x$with_user_release_suffix" != x; then
else else
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
# Avoid [:alnum:] since it depends on the locale. # 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'` USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi fi
@ -16102,6 +16102,10 @@ if test "x$with_add_source_root" != x; then
test -f $with_add_source_root/hotspot/make/Makefile; 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 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 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 || \ if test -f $with_add_source_root/jdk/makefiles/Makefile || \
test -f $with_add_source_root/jdk/make/Makefile; then 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 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 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 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 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 || \ if test -f $with_override_source_root/jdk/makefiles/Makefile || \
test -f $with_override_source_root/jdk/make/Makefile; then 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 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. # Check whether --with-override-jdk was given.
if test "${with_override_jdk+set}" = set; then : if test "${with_override_jdk+set}" = set; then :
withval=$with_override_jdk; withval=$with_override_jdk;
@ -16276,7 +16291,7 @@ if test "x$with_override_nashorn" != x; then
cd "$with_override_nashorn" cd "$with_override_nashorn"
NASHORN_TOPDIR="`pwd`" NASHORN_TOPDIR="`pwd`"
cd "$CURDIR" 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 as_fn_error $? "You have to override nashorn with a full nashorn repo!" "$LINENO" 5
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if nashorn should be overridden" >&5 { $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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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. # Check whether --with-dxsdk was given.
if test "${with_dxsdk+set}" = set; then : 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 fi
# Check whether --with-dxsdk-lib was given. # Check whether --with-dxsdk-lib was given.
if test "${with_dxsdk_lib+set}" = set; then : 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 fi
# Check whether --with-dxsdk-include was given. # Check whether --with-dxsdk-include was given.
if test "${with_dxsdk_include+set}" = set; then : 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 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 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then 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 # 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. # "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. # 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` test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
if test "x$test_shortpath" = x; then if test "x$test_shortpath" = x; then
@ -28830,35 +28437,41 @@ done
if test "x$OPENJDK_TARGET_OS" = xsolaris; then if test "x$OPENJDK_TARGET_OS" = xsolaris; then
# Always specify -m flags on Solaris # Always specify -m flags on Solaris
# keep track of c/cxx flags that we added outselves... # When we add flags to the "official" CFLAGS etc, we need to
# to prevent emitting warning... # keep track of these additions in ADDED_CFLAGS etc. These
TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" # 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}" CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
elif test "x$COMPILE_TYPE" = xreduced; then elif test "x$COMPILE_TYPE" = xreduced; then
if test "x$OPENJDK_TARGET_OS" != xwindows; then if test "x$OPENJDK_TARGET_OS" != xwindows; then
# Specify -m if running reduced on other Posix platforms # Specify -m if running reduced on other Posix platforms
# keep track of c/cxx flags that we added outselves... # When we add flags to the "official" CFLAGS etc, we need to
# to prevent emitting warning... # keep track of these additions in ADDED_CFLAGS etc. These
TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" # 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}" CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}"
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}"
LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}"
fi fi
fi fi
@ -33618,6 +33231,7 @@ fi
# We're messing a bit with internal autoconf variables to put the config.status # We're messing a bit with internal autoconf variables to put the config.status
# in the output directory instead of the current directory. # in the output directory instead of the current directory.
CONFIG_STATUS="$OUTPUT_ROOT/config.status" CONFIG_STATUS="$OUTPUT_ROOT/config.status"
# Create the actual output files. Now the main work of configure is done. # Create the actual output files. Now the main work of configure is done.
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure # 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 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 # Make the compare script executable
$CHMOD +x $OUTPUT_ROOT/compare.sh $CHMOD +x $OUTPUT_ROOT/compare.sh

View file

@ -446,7 +446,7 @@ elif test "x$with_user_release_suffix" != x; then
else else
BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` BUILD_DATE=`date '+%Y_%m_%d_%H_%M'`
# Avoid [:alnum:] since it depends on the locale. # 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'` USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
fi fi
AC_SUBST(USER_RELEASE_SUFFIX) AC_SUBST(USER_RELEASE_SUFFIX)

View file

@ -422,18 +422,21 @@ AC_SUBST(OS_VERSION_MICRO)
# Add -mX to various FLAGS variables. # Add -mX to various FLAGS variables.
AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS], AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS],
[ [
# keep track of c/cxx flags that we added outselves... # When we add flags to the "official" CFLAGS etc, we need to
# to prevent emitting warning... # keep track of these additions in ADDED_CFLAGS etc. These
TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" # will later be checked to make sure only controlled additions
AC_SUBST(TARGET_BITS_FLAG) # 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}" CFLAGS="${CFLAGS}${ADDED_CFLAGS}"
CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}"
LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}"
CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}"
CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}"
LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}"
]) ])
AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS], AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS],

View file

@ -101,6 +101,10 @@ if test "x$with_add_source_root" != x; then
test -f $with_add_source_root/hotspot/make/Makefile; 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.]) AC_MSG_ERROR([Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources.])
fi 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 || \ if test -f $with_add_source_root/jdk/makefiles/Makefile || \
test -f $with_add_source_root/jdk/make/Makefile; then 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.]) 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 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.]) 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 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 || \ if test -f $with_override_source_root/jdk/makefiles/Makefile || \
test -f $with_override_source_root/jdk/make/Makefile; then 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.]) 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], AC_ARG_WITH(override-hotspot, [AS_HELP_STRING([--with-override-hotspot],
[use this hotspot dir for the build])]) [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], AC_ARG_WITH(override-jdk, [AS_HELP_STRING([--with-override-jdk],
[use this jdk dir for the build])]) [use this jdk dir for the build])])
@ -241,7 +252,7 @@ if test "x$with_override_nashorn" != x; then
cd "$with_override_nashorn" cd "$with_override_nashorn"
NASHORN_TOPDIR="`pwd`" NASHORN_TOPDIR="`pwd`"
cd "$CURDIR" 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!]) AC_MSG_ERROR([You have to override nashorn with a full nashorn repo!])
fi fi
AC_MSG_CHECKING([if nashorn should be overridden]) AC_MSG_CHECKING([if nashorn should be overridden])

View file

@ -291,10 +291,6 @@ X_CFLAGS:=@X_CFLAGS@
X_LIBS:=@X_LIBS@ X_LIBS:=@X_LIBS@
OPENWIN_HOME:=@OPENWIN_HOME@ 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 # The lowest required version of macosx to enforce compatiblity for
MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
@ -304,7 +300,6 @@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
COMPILER_TYPE:=@COMPILER_TYPE@ COMPILER_TYPE:=@COMPILER_TYPE@
COMPILER_NAME:=@COMPILER_NAME@ COMPILER_NAME:=@COMPILER_NAME@
TARGET_BITS_FLAG=@TARGET_BITS_FLAG@
COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@ COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@
CC_OUT_OPTION:=@CC_OUT_OPTION@ CC_OUT_OPTION:=@CC_OUT_OPTION@

View file

@ -176,7 +176,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_PATHS],
[ [
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV 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 fi
AC_SUBST(MSVCR_DLL) AC_SUBST(MSVCR_DLL)

View file

@ -277,61 +277,3 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
AC_MSG_RESULT([$MSVCR_DLL]) AC_MSG_RESULT([$MSVCR_DLL])
BASIC_FIXUP_PATH(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"
])

View file

@ -47,7 +47,7 @@ python=""
bpython="" bpython=""
if [ "#!" = "$has_hash_bang" ] ; then 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"`" bpython="`basename "$python"`"
fi fi

View file

@ -228,3 +228,4 @@ a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101
d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105 4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105
2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106
23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107

View file

@ -32,6 +32,7 @@ import java.net.SocketException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel; import java.nio.channels.ServerSocketChannel;
import java.security.PrivilegedAction;
import com.sun.corba.se.pept.transport.Acceptor; import com.sun.corba.se.pept.transport.Acceptor;
@ -44,6 +45,22 @@ public class DefaultSocketFactoryImpl
implements ORBSocketFactory implements ORBSocketFactory
{ {
private ORB orb; 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) public void setORB(ORB orb)
{ {
@ -85,6 +102,9 @@ public class DefaultSocketFactoryImpl
// Disable Nagle's algorithm (i.e., always send immediately). // Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true); socket.setTcpNoDelay(true);
if (keepAlive)
socket.setKeepAlive(true);
return socket; return socket;
} }
@ -95,6 +115,8 @@ public class DefaultSocketFactoryImpl
{ {
// Disable Nagle's algorithm (i.e., always send immediately). // Disable Nagle's algorithm (i.e., always send immediately).
socket.setTcpNoDelay(true); socket.setTcpNoDelay(true);
if (keepAlive)
socket.setKeepAlive(true);
} }
} }

View file

@ -375,3 +375,7 @@ acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105
18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48 18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48
aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106
50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49
5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107
a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50
85072013aad46050a362d10ab78e963121c8014c jdk8-b108
566db1b0e6efca31f181456e54c8911d0192410d hs25-b51

View file

@ -1213,6 +1213,7 @@ public class CommandProcessor {
} }
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase(); HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
if (t.countTokens() == 1) { if (t.countTokens() == 1) {
String name = t.nextToken();
out.println("intConstant " + name + " " + db.lookupIntConstant(name)); out.println("intConstant " + name + " " + db.lookupIntConstant(name));
} else if (t.countTokens() == 0) { } else if (t.countTokens() == 0) {
Iterator i = db.getIntConstants(); Iterator i = db.getIntConstants();
@ -1235,6 +1236,7 @@ public class CommandProcessor {
} }
HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase(); HotSpotTypeDataBase db = (HotSpotTypeDataBase)agent.getTypeDataBase();
if (t.countTokens() == 1) { if (t.countTokens() == 1) {
String name = t.nextToken();
out.println("longConstant " + name + " " + db.lookupLongConstant(name)); out.println("longConstant " + name + " " + db.lookupLongConstant(name));
} else if (t.countTokens() == 0) { } else if (t.countTokens() == 0) {
Iterator i = db.getLongConstants(); Iterator i = db.getLongConstants();

View file

@ -81,7 +81,7 @@ class BsdAddress implements Address {
public Address getCompKlassAddressAt(long offset) public Address getCompKlassAddressAt(long offset)
throws UnalignedAddressException, UnmappedAddressException { throws UnalignedAddressException, UnmappedAddressException {
return debugger.readCompOopAddress(addr + offset); return debugger.readCompKlassAddress(addr + offset);
} }
// //

View file

@ -792,7 +792,7 @@ public class VM {
public boolean isCompressedKlassPointersEnabled() { public boolean isCompressedKlassPointersEnabled() {
if (compressedKlassPointersEnabled == null) { if (compressedKlassPointersEnabled == null) {
Flag flag = getCommandLineFlag("UseCompressedKlassPointers"); Flag flag = getCommandLineFlag("UseCompressedClassPointers");
compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE: compressedKlassPointersEnabled = (flag == null) ? Boolean.FALSE:
(flag.getBool()? Boolean.TRUE: Boolean.FALSE); (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
} }

View file

@ -66,18 +66,18 @@ public class HeapSummary extends Tool {
printGCAlgorithm(flagMap); printGCAlgorithm(flagMap);
System.out.println(); System.out.println();
System.out.println("Heap Configuration:"); System.out.println("Heap Configuration:");
printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap)); printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap)); printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap)); printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
printValMB("NewSize = ", getFlagValue("NewSize", flagMap)); printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap)); printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
printValMB("OldSize = ", getFlagValue("OldSize", flagMap)); printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
printValue("NewRatio = ", getFlagValue("NewRatio", flagMap)); printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap)); printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap)); printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap)); printValMB("CompressedClassSpaceSize = ", getFlagValue("CompressedClassSpaceSize", flagMap));
printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap)); printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes()); printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
System.out.println(); System.out.println();
System.out.println("Heap Usage:"); System.out.println("Heap Usage:");

View file

@ -99,7 +99,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \ psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \
parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \ parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \ gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp
endif endif
ifeq ($(INCLUDE_NMT), false) ifeq ($(INCLUDE_NMT), false)

View file

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25 HS_MAJOR_VER=25
HS_MINOR_VER=0 HS_MINOR_VER=0
HS_BUILD_NUMBER=50 HS_BUILD_NUMBER=51
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8

View file

@ -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 (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 && if (src->is_address() && !src->is_stack() && src->type() == T_ADDRESS &&
src->as_address_ptr()->disp() == oopDesc::klass_offset_in_bytes()) return false; 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_METADATA: __ ld_ptr(base, offset, to_reg->as_register()); break;
case T_ADDRESS: case T_ADDRESS:
#ifdef _LP64 #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()); __ lduw(base, offset, to_reg->as_register());
__ decode_klass_not_null(to_reg->as_register()); __ decode_klass_not_null(to_reg->as_register());
} else } else
@ -2208,7 +2208,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// We don't know the array types are compatible // We don't know the array types are compatible
if (basic_type != T_OBJECT) { if (basic_type != T_OBJECT) {
// Simple test for basic type arrays // Simple test for basic type arrays
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
// We don't need decode because we just need to compare // We don't need decode because we just need to compare
__ lduw(src, oopDesc::klass_offset_in_bytes(), tmp); __ lduw(src, oopDesc::klass_offset_in_bytes(), tmp);
__ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2); __ 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. // but not necessarily exactly of type default_type.
Label known_ok, halt; Label known_ok, halt;
metadata2reg(op->expected_type()->constant_encoding(), tmp); metadata2reg(op->expected_type()->constant_encoding(), tmp);
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
// tmp holds the default type. It currently comes uncompressed after the // tmp holds the default type. It currently comes uncompressed after the
// load of a constant, so encode it. // load of a constant, so encode it.
__ encode_klass_not_null(tmp); __ encode_klass_not_null(tmp);

View file

@ -186,7 +186,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
set((intx)markOopDesc::prototype(), t1); set((intx)markOopDesc::prototype(), t1);
} }
st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
// Save klass // Save klass
mov(klass, t1); mov(klass, t1);
encode_klass_not_null(t1); encode_klass_not_null(t1);
@ -196,7 +196,7 @@ void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register
} }
if (len->is_valid()) { if (len->is_valid()) {
st(len, obj, arrayOopDesc::length_offset_in_bytes()); st(len, obj, arrayOopDesc::length_offset_in_bytes());
} else if (UseCompressedKlassPointers) { } else if (UseCompressedClassPointers) {
// otherwise length is in the class gap // otherwise length is in the class gap
store_klass_gap(G0, obj); store_klass_gap(G0, obj);
} }

View file

@ -3911,7 +3911,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) {
// The number of bytes in this code is used by // The number of bytes in this code is used by
// MachCallDynamicJavaNode::ret_addr_offset() // MachCallDynamicJavaNode::ret_addr_offset()
// if this changes, change that. // if this changes, change that.
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass); lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass);
decode_klass_not_null(klass); decode_klass_not_null(klass);
} else { } else {
@ -3920,7 +3920,7 @@ void MacroAssembler::load_klass(Register src_oop, Register klass) {
} }
void MacroAssembler::store_klass(Register klass, Register dst_oop) { void MacroAssembler::store_klass(Register klass, Register dst_oop) {
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
assert(dst_oop != klass, "not enough registers"); assert(dst_oop != klass, "not enough registers");
encode_klass_not_null(klass); encode_klass_not_null(klass);
st(klass, dst_oop, oopDesc::klass_offset_in_bytes()); 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) { void MacroAssembler::store_klass_gap(Register s, Register d) {
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
assert(s != d, "not enough registers"); assert(s != d, "not enough registers");
st(s, d, oopDesc::klass_gap_offset_in_bytes()); 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) { 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(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
assert(r != G6_heapbase, "bad register choice"); assert(r != G6_heapbase, "bad register choice");
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase); 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) { if (src == dst) {
encode_klass_not_null(src); encode_klass_not_null(src);
} else { } else {
assert (UseCompressedKlassPointers, "must be compressed"); assert (UseCompressedClassPointers, "must be compressed");
assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized"); assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
set((intptr_t)Universe::narrow_klass_base(), dst); set((intptr_t)Universe::narrow_klass_base(), dst);
sub(src, dst, 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 // generated by decode_klass_not_null() and reinit_heapbase(). Hence, if
// the instructions they generate change, then this method needs to be updated. // the instructions they generate change, then this method needs to be updated.
int MacroAssembler::instr_size_for_decode_klass_not_null() { 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 // set + add + set
int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 + int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 +
insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base()); 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) { void MacroAssembler::decode_klass_not_null(Register r) {
// Do not add assert code to this unless you change vtableStubs_sparc.cpp // Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit. // 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(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
assert(r != G6_heapbase, "bad register choice"); assert(r != G6_heapbase, "bad register choice");
set((intptr_t)Universe::narrow_klass_base(), G6_heapbase); set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
@ -4151,7 +4151,7 @@ void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
} else { } else {
// Do not add assert code to this unless you change vtableStubs_sparc.cpp // Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit. // 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(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
if (Universe::narrow_klass_shift() != 0) { if (Universe::narrow_klass_shift() != 0) {
assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice"); 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() { void MacroAssembler::reinit_heapbase() {
if (UseCompressedOops || UseCompressedKlassPointers) { if (UseCompressedOops || UseCompressedClassPointers) {
if (Universe::heap() != NULL) { if (Universe::heap() != NULL) {
set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase); set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase);
} else { } else {

View file

@ -557,7 +557,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size(); int entry_offset = InstanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes(); int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
int klass_load_size; int klass_load_size;
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized"); assert(Universe::heap() != NULL, "java heap should be initialized");
klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord; klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else { } else {
@ -1657,7 +1657,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
st->print_cr("\nUEP:"); st->print_cr("\nUEP:");
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized"); 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("\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"); 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() { bool Matcher::narrow_klass_use_complex_address() {
NOT_LP64(ShouldNotCallThis()); NOT_LP64(ShouldNotCallThis());
assert(UseCompressedKlassPointers, "only for compressed klass code"); assert(UseCompressedClassPointers, "only for compressed klass code");
return false; return false;
} }
@ -2561,7 +2561,7 @@ encode %{
int off = __ offset(); int off = __ offset();
__ load_klass(O0, G3_scratch); __ load_klass(O0, G3_scratch);
int klass_load_size; int klass_load_size;
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized"); assert(Universe::heap() != NULL, "java heap should be initialized");
klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord; klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else { } else {

View file

@ -2945,7 +2945,7 @@ class StubGenerator: public StubCodeGenerator {
BLOCK_COMMENT("arraycopy argument klass checks"); BLOCK_COMMENT("arraycopy argument klass checks");
// get src->klass() // get src->klass()
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ delayed()->nop(); // ??? not good __ delayed()->nop(); // ??? not good
__ load_klass(src, G3_src_klass); __ load_klass(src, G3_src_klass);
} else { } else {
@ -2980,7 +2980,7 @@ class StubGenerator: public StubCodeGenerator {
// Load 32-bits signed value. Use br() instruction with it to check icc. // Load 32-bits signed value. Use br() instruction with it to check icc.
__ lduw(G3_src_klass, lh_offset, G5_lh); __ lduw(G3_src_klass, lh_offset, G5_lh);
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ load_klass(dst, G4_dst_klass); __ load_klass(dst, G4_dst_klass);
} }
// Handle objArrays completely differently... // Handle objArrays completely differently...
@ -2988,7 +2988,7 @@ class StubGenerator: public StubCodeGenerator {
__ set(objArray_lh, O5_temp); __ set(objArray_lh, O5_temp);
__ cmp(G5_lh, O5_temp); __ cmp(G5_lh, O5_temp);
__ br(Assembler::equal, false, Assembler::pt, L_objArray); __ br(Assembler::equal, false, Assembler::pt, L_objArray);
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ delayed()->nop(); __ delayed()->nop();
} else { } else {
__ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass); __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);

View file

@ -218,13 +218,13 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
// ld;ld;ld,jmp,nop // ld;ld;ld,jmp,nop
const int basic = 5*BytesPerInstWord + const int basic = 5*BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based) // shift;add for load_klass (only shift with zero heap based)
(UseCompressedKlassPointers ? (UseCompressedClassPointers ?
MacroAssembler::instr_size_for_decode_klass_not_null() : 0); MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return basic + slop; return basic + slop;
} else { } else {
const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord + const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based) // shift;add for load_klass (only shift with zero heap based)
(UseCompressedKlassPointers ? (UseCompressedClassPointers ?
MacroAssembler::instr_size_for_decode_klass_not_null() : 0); MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return (basic + slop); return (basic + slop);
} }

View file

@ -148,7 +148,7 @@
static int adjust_reg_range(int range) { static int adjust_reg_range(int range) {
// Reduce the number of available regs (to free r12) in case of compressed oops // 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; return range;
} }

View file

@ -341,7 +341,7 @@ int LIR_Assembler::check_icache() {
Register receiver = FrameMap::receiver_opr->as_register(); Register receiver = FrameMap::receiver_opr->as_register();
Register ic_klass = IC_Klass; Register ic_klass = IC_Klass;
const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); 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) { if (!do_post_padding) {
// insert some nops so that the verified entry point is aligned on CodeEntryAlignment // insert some nops so that the verified entry point is aligned on CodeEntryAlignment
while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { 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; break;
case T_ADDRESS: 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); __ movl(dest->as_register(), from_addr);
} else { } else {
__ movptr(dest->as_register(), from_addr); __ 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()); __ verify_oop(dest->as_register());
} else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ decode_klass_not_null(dest->as_register()); __ decode_klass_not_null(dest->as_register());
} }
#endif #endif
@ -1716,7 +1716,7 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
} else if (obj == klass_RInfo) { } else if (obj == klass_RInfo) {
klass_RInfo = dst; klass_RInfo = dst;
} }
if (k->is_loaded() && !UseCompressedKlassPointers) { if (k->is_loaded() && !UseCompressedClassPointers) {
select_different_registers(obj, dst, k_RInfo, klass_RInfo); select_different_registers(obj, dst, k_RInfo, klass_RInfo);
} else { } else {
Rtmp1 = op->tmp3()->as_register(); 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); 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); __ cmpptr(obj, (int32_t)NULL_WORD);
if (op->should_profile()) { if (op->should_profile()) {
@ -1748,13 +1740,21 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
} else { } else {
__ jcc(Assembler::equal, *obj_is_null); __ 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); __ verify_oop(obj);
if (op->fast_check()) { if (op->fast_check()) {
// get object class // get object class
// not a safepoint as obj null check happens earlier // not a safepoint as obj null check happens earlier
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ load_klass(Rtmp1, obj); __ load_klass(Rtmp1, obj);
__ cmpptr(k_RInfo, Rtmp1); __ cmpptr(k_RInfo, Rtmp1);
} else { } else {
@ -3294,7 +3294,7 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
// We don't know the array types are compatible // We don't know the array types are compatible
if (basic_type != T_OBJECT) { if (basic_type != T_OBJECT) {
// Simple test for basic type arrays // Simple test for basic type arrays
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ movl(tmp, src_klass_addr); __ movl(tmp, src_klass_addr);
__ cmpl(tmp, dst_klass_addr); __ cmpl(tmp, dst_klass_addr);
} else { } else {
@ -3456,21 +3456,21 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
Label known_ok, halt; Label known_ok, halt;
__ mov_metadata(tmp, default_type->constant_encoding()); __ mov_metadata(tmp, default_type->constant_encoding());
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
__ encode_klass_not_null(tmp); __ encode_klass_not_null(tmp);
} }
#endif #endif
if (basic_type != T_OBJECT) { 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); else __ cmpptr(tmp, dst_klass_addr);
__ jcc(Assembler::notEqual, halt); __ jcc(Assembler::notEqual, halt);
if (UseCompressedKlassPointers) __ cmpl(tmp, src_klass_addr); if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr);
else __ cmpptr(tmp, src_klass_addr); else __ cmpptr(tmp, src_klass_addr);
__ jcc(Assembler::equal, known_ok); __ jcc(Assembler::equal, known_ok);
} else { } else {
if (UseCompressedKlassPointers) __ cmpl(tmp, dst_klass_addr); if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);
else __ cmpptr(tmp, dst_klass_addr); else __ cmpptr(tmp, dst_klass_addr);
__ jcc(Assembler::equal, known_ok); __ jcc(Assembler::equal, known_ok);
__ cmpptr(src, dst); __ cmpptr(src, dst);

View file

@ -1239,7 +1239,7 @@ void LIRGenerator::do_CheckCast(CheckCast* x) {
} }
LIR_Opr reg = rlock_result(x); LIR_Opr reg = rlock_result(x);
LIR_Opr tmp3 = LIR_OprFact::illegalOpr; LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
if (!x->klass()->is_loaded() || UseCompressedKlassPointers) { if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
tmp3 = new_register(objectType); tmp3 = new_register(objectType);
} }
__ checkcast(reg, obj.result(), x->klass(), __ checkcast(reg, obj.result(), x->klass(),
@ -1261,7 +1261,7 @@ void LIRGenerator::do_InstanceOf(InstanceOf* x) {
} }
obj.load_item(); obj.load_item();
LIR_Opr tmp3 = LIR_OprFact::illegalOpr; LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
if (!x->klass()->is_loaded() || UseCompressedKlassPointers) { if (!x->klass()->is_loaded() || UseCompressedClassPointers) {
tmp3 = new_register(objectType); tmp3 = new_register(objectType);
} }
__ instanceof(reg, obj.result(), x->klass(), __ instanceof(reg, obj.result(), x->klass(),

View file

@ -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()); movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
} }
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { // Take care not to kill klass if (UseCompressedClassPointers) { // Take care not to kill klass
movptr(t1, klass); movptr(t1, klass);
encode_klass_not_null(t1); encode_klass_not_null(t1);
movl(Address(obj, oopDesc::klass_offset_in_bytes()), 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); movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
} }
#ifdef _LP64 #ifdef _LP64
else if (UseCompressedKlassPointers) { else if (UseCompressedClassPointers) {
xorptr(t1, t1); xorptr(t1, t1);
store_klass_gap(obj, 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"); assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
int start_offset = offset(); int start_offset = offset();
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
load_klass(rscratch1, receiver); load_klass(rscratch1, receiver);
cmpptr(rscratch1, iCache); cmpptr(rscratch1, iCache);
} else { } else {
@ -345,7 +345,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
jump_cc(Assembler::notEqual, jump_cc(Assembler::notEqual,
RuntimeAddress(SharedRuntime::get_ic_miss_stub())); RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); 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");
} }

View file

@ -1635,7 +1635,7 @@ void MacroAssembler::call_VM_base(Register oop_result,
#ifdef ASSERT #ifdef ASSERT
// TraceBytecodes does not use r12 but saves it over the call, so don't verify // TraceBytecodes does not use r12 but saves it over the call, so don't verify
// r12 is the heapbase. // 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 #endif // ASSERT
assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); 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) { void MacroAssembler::load_klass(Register dst, Register src) {
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
movl(dst, Address(src, oopDesc::klass_offset_in_bytes())); movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
decode_klass_not_null(dst); decode_klass_not_null(dst);
} else } else
@ -4817,7 +4817,7 @@ void MacroAssembler::load_prototype_header(Register dst, Register src) {
void MacroAssembler::store_klass(Register dst, Register src) { void MacroAssembler::store_klass(Register dst, Register src) {
#ifdef _LP64 #ifdef _LP64
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
encode_klass_not_null(src); encode_klass_not_null(src);
movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
} else } else
@ -4892,7 +4892,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
#ifdef _LP64 #ifdef _LP64
void MacroAssembler::store_klass_gap(Register dst, Register src) { void MacroAssembler::store_klass_gap(Register dst, Register src) {
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
// Store to klass gap in destination // Store to klass gap in destination
movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src); 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 // when (Universe::heap() != NULL). Hence, if the instructions they
// generate change, then this method needs to be updated. // generate change, then this method needs to be updated.
int MacroAssembler::instr_size_for_decode_klass_not_null() { 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()). // mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
return (Universe::narrow_klass_shift() == 0 ? 20 : 24); 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) { void MacroAssembler::decode_klass_not_null(Register r) {
// Note: it will change flags // Note: it will change flags
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); 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"); assert(r != r12_heapbase, "Decoding a klass in r12");
// Cannot assert, unverified entry point counts instructions (see .ad file) // Cannot assert, unverified entry point counts instructions (see .ad file)
// vtableStubs also counts instructions in pd_code_size_limit. // 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) { void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
// Note: it will change flags // Note: it will change flags
assert(Universe::narrow_klass_base() != NULL, "Base should be initialized"); 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) { if (dst == src) {
decode_klass_not_null(dst); decode_klass_not_null(dst);
} else { } else {
@ -5141,7 +5141,7 @@ void MacroAssembler::set_narrow_oop(Address dst, jobject obj) {
} }
void MacroAssembler::set_narrow_klass(Register dst, Klass* k) { 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"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k); int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index); 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) { 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"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k); int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index); 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) { 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"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k); int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index); 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) { 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"); assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k); int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index); RelocationHolder rspec = metadata_Relocation::spec(klass_index);
@ -5191,7 +5191,7 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
} }
void MacroAssembler::reinit_heapbase() { void MacroAssembler::reinit_heapbase() {
if (UseCompressedOops || UseCompressedKlassPointers) { if (UseCompressedOops || UseCompressedClassPointers) {
if (Universe::heap() != NULL) { if (Universe::heap() != NULL) {
if (Universe::narrow_oop_base() == NULL) { if (Universe::narrow_oop_base() == NULL) {
MacroAssembler::xorptr(r12_heapbase, r12_heapbase); MacroAssembler::xorptr(r12_heapbase, r12_heapbase);

View file

@ -34,9 +34,9 @@
// Run with +PrintInterpreter to get the VM to print out the size. // Run with +PrintInterpreter to get the VM to print out the size.
// Max size with JVMTI // Max size with JVMTI
#ifdef AMD64 #ifdef AMD64
const static int InterpreterCodeSize = 200 * 1024; const static int InterpreterCodeSize = 208 * 1024;
#else #else
const static int InterpreterCodeSize = 168 * 1024; const static int InterpreterCodeSize = 176 * 1024;
#endif // AMD64 #endif // AMD64
#endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP #endif // CPU_X86_VM_TEMPLATEINTERPRETER_X86_HPP

View file

@ -211,11 +211,11 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
if (is_vtable_stub) { if (is_vtable_stub) {
// Vtable stub size // Vtable stub size
return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) + 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 { } else {
// Itable stub size // Itable stub size
return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) + 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 // In order to tune these parameters, run the JVM with VM options
// +PrintMiscellaneous and +WizardMode to see information about // +PrintMiscellaneous and +WizardMode to see information about

View file

@ -1391,7 +1391,7 @@ uint BoxLockNode::size(PhaseRegAlloc *ra_) const
#ifndef PRODUCT #ifndef PRODUCT
void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 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("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 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); MacroAssembler masm(&cbuf);
uint insts_size = cbuf.insts_size(); uint insts_size = cbuf.insts_size();
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
masm.load_klass(rscratch1, j_rarg0); masm.load_klass(rscratch1, j_rarg0);
masm.cmpptr(rax, rscratch1); masm.cmpptr(rax, rscratch1);
} else { } else {
@ -1557,7 +1557,7 @@ bool Matcher::narrow_oop_use_complex_address() {
} }
bool Matcher::narrow_klass_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); return (LogKlassAlignmentInBytes <= 3);
} }

View file

@ -3589,8 +3589,6 @@ jint os::init_2(void)
#endif #endif
} }
os::large_page_init();
// initialize suspend/resume support - must do this before signal_sets_init() // initialize suspend/resume support - must do this before signal_sets_init()
if (SR_initialize() != 0) { if (SR_initialize() != 0) {
perror("SR_initialize failed"); perror("SR_initialize failed");

View file

@ -4805,8 +4805,6 @@ jint os::init_2(void)
#endif #endif
} }
os::large_page_init();
// initialize suspend/resume support - must do this before signal_sets_init() // initialize suspend/resume support - must do this before signal_sets_init()
if (SR_initialize() != 0) { if (SR_initialize() != 0) {
perror("SR_initialize failed"); perror("SR_initialize failed");

View file

@ -5178,9 +5178,7 @@ jint os::init_2(void) {
if(Verbose && PrintMiscellaneous) if(Verbose && PrintMiscellaneous)
tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
#endif #endif
} }
os::large_page_init();
// Check minimum allowable stack size for thread creation and to initialize // Check minimum allowable stack size for thread creation and to initialize
// the java system classes, including StackOverflowError - depends on page // the java system classes, including StackOverflowError - depends on page

View file

@ -3189,9 +3189,12 @@ char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, boo
return p_buf; return p_buf;
} else { } else {
if (TracePageSizes && Verbose) {
tty->print_cr("Reserving large pages in a single large chunk.");
}
// normal policy just allocate it all at once // normal policy just allocate it all at once
DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; 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) { if (res != NULL) {
address pc = CALLER_PC; address pc = CALLER_PC;
MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc); MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc);
@ -3917,8 +3920,6 @@ jint os::init_2(void) {
#endif #endif
} }
os::large_page_init();
// Setup Windows Exceptions // Setup Windows Exceptions
// for debugging float code generation bugs // 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) { if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {
lib_name = ++start; lib_name = ++start;
} else { } else {
// Need to check for C: // Need to check for drive prefix
if ((start = strchr(lib_name, ':')) != NULL) { if ((start = strchr(lib_name, ':')) != NULL) {
lib_name = ++start; lib_name = ++start;
} }
@ -5714,7 +5715,66 @@ BOOL os::Advapi32Dll::AdvapiAvailable() {
#endif #endif
#ifndef PRODUCT #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() { 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

View file

@ -35,7 +35,9 @@ define_pd_global(intx, CompilerThreadStackSize, 0);
// Used on 64 bit platforms for UseCompressedOops base address // Used on 64 bit platforms for UseCompressedOops base address
#ifdef _LP64 #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 #else
define_pd_global(uintx, HeapBaseMinAddress, 2*G); define_pd_global(uintx, HeapBaseMinAddress, 2*G);
#endif #endif

View file

@ -4,14 +4,14 @@ It's main purpose is to recreate output similar to
requires a 1.5 JDK to build and simply typing make should build it. 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 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. This will produce something like the normal PrintCompilation output.
Adding the -i option with also report inlining like PrintInlining. Adding the -i option with also report inlining like PrintInlining.
More information about the LogCompilation output can be found at More information about the LogCompilation output can be found at
https://wikis.oracle.com/display/HotSpotInternals/LogCompilation+overview https://wikis.oracle.com/display/HotSpotInternals/LogCompilation+overview
https://wikis.oracle.com/display/HotSpotInternals/PrintCompilation https://wikis.oracle.com/display/HotSpotInternals/PrintCompilation

View file

@ -709,10 +709,10 @@ static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
Bytecodes::Code code = field_access.code(); Bytecodes::Code code = field_access.code();
// We must load class, initialize class and resolvethe field // 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()); constantPoolHandle constants(THREAD, caller->constants());
LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL); LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK_NULL);
return result.klass()(); 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) { if (stub_id == Runtime1::access_field_patching_id) {
Bytecode_field field_access(caller_method, bci); 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(); Bytecodes::Code code = field_access.code();
constantPoolHandle constants(THREAD, caller_method->constants()); constantPoolHandle constants(THREAD, caller_method->constants());
LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK); LinkResolver::resolve_field_access(result, constants, field_access.index(), Bytecodes::java_code(code), CHECK);
patch_field_offset = result.field_offset(); patch_field_offset = result.offset();
// If we're patching a field which is volatile then at compile it // 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 // must not have been know to be volatile, so the generated code

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -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"); assert(klass->get_instanceKlass()->is_linked(), "must be linked before using its constan-pool");
_cp_index = index;
constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants()); constantPoolHandle cpool(thread, klass->get_instanceKlass()->constants());
// Get the field's name, signature, and type. // 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. // The declared holder of this field may not have been loaded.
// Bail out with partial field information. // Bail out with partial field information.
if (!holder_is_accessible) { 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. // The default values for _flags and _constant_value will suffice.
// We need values for _holder, _offset, and _is_constant, // We need values for _holder, _offset, and _is_constant,
_holder = declared_holder; _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) { ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
ASSERT_IN_VM; ASSERT_IN_VM;
_cp_index = -1;
// Get the field's name, signature, and type. // Get the field's name, signature, and type.
ciEnv* env = CURRENT_ENV; ciEnv* env = CURRENT_ENV;
_name = env->get_symbol(fd->name()); _name = env->get_symbol(fd->name());
@ -351,12 +348,11 @@ bool ciField::will_link(ciInstanceKlass* accessing_klass,
} }
} }
FieldAccessInfo result; fieldDescriptor result;
constantPoolHandle c_pool(THREAD, LinkResolver::resolve_field(result, _holder->get_instanceKlass(),
accessing_klass->get_instanceKlass()->constants()); _name->get_symbol(), _signature->get_symbol(),
LinkResolver::resolve_field(result, c_pool, _cp_index, accessing_klass->get_Klass(), bc, true, false,
Bytecodes::java_code(bc), KILL_COMPILE_ON_FATAL_(false));
true, false, KILL_COMPILE_ON_FATAL_(false));
// update the hit-cache, unless there is a problem with memory scoping: // update the hit-cache, unless there is a problem with memory scoping:
if (accessing_klass->is_shared() || !is_shared()) { if (accessing_klass->is_shared() || !is_shared()) {

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -53,9 +53,6 @@ private:
ciInstanceKlass* _known_to_link_with_get; ciInstanceKlass* _known_to_link_with_get;
ciConstant _constant_value; ciConstant _constant_value;
// Used for will_link
int _cp_index;
ciType* compute_type(); ciType* compute_type();
ciType* compute_type_impl(); ciType* compute_type_impl();

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -522,8 +522,7 @@ ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>*
for (JavaFieldStream fs(k); !fs.done(); fs.next()) { for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) continue; if (fs.access_flags().is_static()) continue;
fieldDescriptor fd; fieldDescriptor& fd = fs.field_descriptor();
fd.initialize(k, fs.index());
ciField* field = new (arena) ciField(&fd); ciField* field = new (arena) ciField(&fd);
fields->append(field); fields->append(field);
} }

View file

@ -286,7 +286,10 @@ int ciMethod::itable_index() {
check_is_loaded(); check_is_loaded();
assert(holder()->is_linked(), "must be linked"); assert(holder()->is_linked(), "must be linked");
VM_ENTRY_MARK; 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 #endif // SHARK
@ -1137,6 +1140,10 @@ bool ciMethod::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciMethod::check_call // ciMethod::check_call
bool ciMethod::check_call(int refinfo_index, bool is_static) const { 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; VM_ENTRY_MARK;
{ {
EXCEPTION_MARK; EXCEPTION_MARK;

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,6 +44,7 @@ class ciSymbol : public ciBaseObject {
friend class ciInstanceKlass; friend class ciInstanceKlass;
friend class ciSignature; friend class ciSignature;
friend class ciMethod; friend class ciMethod;
friend class ciField;
friend class ciObjArrayKlass; friend class ciObjArrayKlass;
private: private:

View file

@ -3995,9 +3995,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass->set_has_final_method(); this_klass->set_has_final_method();
} }
this_klass->copy_method_ordering(method_ordering, CHECK_NULL); this_klass->copy_method_ordering(method_ordering, CHECK_NULL);
// The InstanceKlass::_methods_jmethod_ids cache and the // The InstanceKlass::_methods_jmethod_ids cache
// InstanceKlass::_methods_cached_itable_indices cache are // is managed on the assumption that the initial cache
// both managed on the assumption that the initial cache
// size is equal to the number of methods in the class. If // size is equal to the number of methods in the class. If
// that changes, then InstanceKlass::idnum_can_increment() // that changes, then InstanceKlass::idnum_can_increment()
// has to be changed accordingly. // has to be changed accordingly.

View file

@ -1319,6 +1319,25 @@ static void clear_pending_exception_if_not_oom(TRAPS) {
// The CHECK at the caller will propagate the exception out // 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) { void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
int len = (int)strlen(name); int len = (int)strlen(name);
if (len > 6 && strcmp(".class", name + len - 6) == 0) { 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(); int comp_level = CompilationPolicy::policy()->initial_compile_level();
for (int n = 0; n < k->methods()->length(); n++) { for (int n = 0; n < k->methods()->length(); n++) {
methodHandle m (THREAD, k->methods()->at(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) { if (++_codecache_sweep_counter == CompileTheWorldSafepointInterval) {
// Give sweeper a chance to keep up with CTW // Give sweeper a chance to keep up with CTW
VM_ForceSafepoint op; VM_ForceSafepoint op;
@ -1375,7 +1393,7 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
methodHandle(), 0, "CTW", THREAD); methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK); 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 { } else {
_compile_the_world_method_counter++; _compile_the_world_method_counter++;
} }
@ -1391,11 +1409,13 @@ void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
methodHandle(), 0, "CTW", THREAD); methodHandle(), 0, "CTW", THREAD);
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK); 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 { } else {
_compile_the_world_method_counter++; _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(); nmethod* nm = m->code();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -161,31 +161,36 @@ address CompiledIC::stub_address() const {
void CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) { 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(CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "");
assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic"); assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?"); assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");
address entry; address entry;
if (is_invoke_interface) { if (call_info->call_kind() == CallInfo::itable_call) {
int index = klassItable::compute_itable_index(call_info->resolved_method()()); assert(bytecode == Bytecodes::_invokeinterface, "");
entry = VtableStubs::create_stub(false, index, method()); int itable_index = call_info->itable_index();
entry = VtableStubs::find_itable_stub(itable_index);
#ifdef ASSERT
assert(entry != NULL, "entry not computed"); 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(); 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); InlineCacheBuffer::create_transition_stub(this, k, entry);
} else { } 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(); int vtable_index = call_info->vtable_index();
entry = VtableStubs::create_stub(true, vtable_index, method()); assert(call_info->resolved_klass()->verify_vtable_index(vtable_index), "sanity check");
InlineCacheBuffer::create_transition_stub(this, method(), entry); entry = VtableStubs::find_vtable_stub(vtable_index);
InlineCacheBuffer::create_transition_stub(this, NULL, entry);
} }
if (TraceICs) { if (TraceICs) {
ResourceMark rm; ResourceMark rm;
tty->print_cr ("IC@" INTPTR_FORMAT ": to megamorphic %s entry: " INTPTR_FORMAT, 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 // We can't check this anymore. With lazy deopt we could have already

View file

@ -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"); assert(vtable_index >= 0, "must be positive");
VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL; VtableStub* s = ShareVtableStubs ? lookup(is_vtable_stub, vtable_index) : NULL;

View file

@ -121,9 +121,11 @@ class VtableStubs : AllStatic {
static VtableStub* lookup (bool is_vtable_stub, int vtable_index); static VtableStub* lookup (bool is_vtable_stub, int vtable_index);
static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s); static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s);
static inline uint hash (bool is_vtable_stub, int vtable_index); static inline uint hash (bool is_vtable_stub, int vtable_index);
static address find_stub (bool is_vtable_stub, int vtable_index);
public: 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 is_entry_point(address pc); // is pc a vtable stub entry point?
static bool contains(address pc); // is pc within any stub? static bool contains(address pc); // is pc within any stub?
static VtableStub* stub_containing(address pc); // stub containing pc or NULL static VtableStub* stub_containing(address pc); // stub containing pc or NULL

View file

@ -230,7 +230,7 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
// depends on this property. // depends on this property.
debug_only( debug_only(
FreeChunk* junk = NULL; FreeChunk* junk = NULL;
assert(UseCompressedKlassPointers || assert(UseCompressedClassPointers ||
junk->prev_addr() == (void*)(oop(junk)->klass_addr()), junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
"Offset of FreeChunk::_prev within FreeChunk must match" "Offset of FreeChunk::_prev within FreeChunk must match"
" that of OopDesc::_klass within OopDesc"); " 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"); assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size");
OrderAccess::storestore(); OrderAccess::storestore();
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
// Copy gap missed by (aligned) header size calculation below // Copy gap missed by (aligned) header size calculation below
obj->set_klass_gap(old->klass_gap()); obj->set_klass_gap(old->klass_gap());
} }

View file

@ -481,9 +481,8 @@ uint ConcurrentMark::scale_parallel_threads(uint n_par_threads) {
ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) : ConcurrentMark::ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs) :
_g1h(g1h), _g1h(g1h),
_markBitMap1(MinObjAlignment - 1), _markBitMap1(log2_intptr(MinObjAlignment)),
_markBitMap2(MinObjAlignment - 1), _markBitMap2(log2_intptr(MinObjAlignment)),
_parallel_marking_threads(0), _parallel_marking_threads(0),
_max_parallel_marking_threads(0), _max_parallel_marking_threads(0),
_sleep_factor(0.0), _sleep_factor(0.0),

View file

@ -33,8 +33,8 @@
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) { void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
if (has_count_table()) { 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)); err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
assert(from_card_num < to_card_num, assert(from_card_num < to_card_num,
err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT, err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
from_card_num, to_card_num)); from_card_num, to_card_num));

View file

@ -72,25 +72,21 @@ class G1CardCounts: public CHeapObj<mtGC> {
return has_reserved_count_table() && _committed_max_card_num > 0; 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) { size_t ptr_2_card_num(const jbyte* card_ptr) {
assert(card_ptr >= _ct_bot, assert(card_ptr >= _ct_bot,
err_msg("Inavalied card pointer: " err_msg("Invalid card pointer: "
"card_ptr: " PTR_FORMAT ", " "card_ptr: " PTR_FORMAT ", "
"_ct_bot: " PTR_FORMAT, "_ct_bot: " PTR_FORMAT,
card_ptr, _ct_bot)); card_ptr, _ct_bot));
size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte)); 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)); err_msg("card pointer out of range: " PTR_FORMAT, card_ptr));
return card_num; return card_num;
} }
jbyte* card_num_2_ptr(size_t 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)); err_msg("card num out of range: "SIZE_FORMAT, card_num));
return (jbyte*) (_ct_bot + card_num); return (jbyte*) (_ct_bot + card_num);
} }

View file

@ -2191,6 +2191,10 @@ jint G1CollectedHeap::initialize() {
return JNI_OK; return JNI_OK;
} }
size_t G1CollectedHeap::conservative_max_heap_alignment() {
return HeapRegion::max_region_size();
}
void G1CollectedHeap::ref_processing_init() { void G1CollectedHeap::ref_processing_init() {
// Reference processing in G1 currently works as follows: // Reference processing in G1 currently works as follows:
// //

View file

@ -1092,6 +1092,9 @@ public:
// specified by the policy object. // specified by the policy object.
jint initialize(); jint initialize();
// Return the (conservative) maximum heap alignment for any G1 heap
static size_t conservative_max_heap_alignment();
// Initialize weak reference processing. // Initialize weak reference processing.
virtual void ref_processing_init(); virtual void ref_processing_init();

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -149,6 +149,10 @@ void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr,
// many regions in the heap (based on the min heap size). // many regions in the heap (based on the min heap size).
#define TARGET_REGION_NUMBER 2048 #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) { void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_heap_size) {
uintx region_size = G1HeapRegionSize; uintx region_size = G1HeapRegionSize;
if (FLAG_IS_DEFAULT(G1HeapRegionSize)) { if (FLAG_IS_DEFAULT(G1HeapRegionSize)) {

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -355,6 +355,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
~((1 << (size_t) LogOfHRGrainBytes) - 1); ~((1 << (size_t) LogOfHRGrainBytes) - 1);
} }
static size_t max_region_size();
// It sets up the heap region size (GrainBytes / GrainWords), as // It sets up the heap region size (GrainBytes / GrainWords), as
// well as other related fields that are based on the heap region // well as other related fields that are based on the heap region
// size (LogOfHRGrainBytes / LogOfHRGrainWords / // size (LogOfHRGrainBytes / LogOfHRGrainWords /

View file

@ -38,6 +38,7 @@
class PtrQueueSet; class PtrQueueSet;
class PtrQueue VALUE_OBJ_CLASS_SPEC { class PtrQueue VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
protected: protected:
// The ptr queue set to which this queue belongs. // The ptr queue set to which this queue belongs.

View file

@ -31,7 +31,8 @@
#define VM_STRUCTS_G1(nonstatic_field, static_field) \ #define VM_STRUCTS_G1(nonstatic_field, static_field) \
\ \
static_field(HeapRegion, GrainBytes, size_t) \ static_field(HeapRegion, GrainBytes, size_t) \
static_field(HeapRegion, LogOfHRGrainBytes, int) \
\ \
nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \ nonstatic_field(HeapRegionSeq, _regions, HeapRegion**) \
nonstatic_field(HeapRegionSeq, _length, uint) \ nonstatic_field(HeapRegionSeq, _length, uint) \

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -68,9 +68,6 @@ class GenerationSizer : public TwoGenerationCollectorPolicy {
size_t min_old_gen_size() { return _min_gen1_size; } size_t min_old_gen_size() { return _min_gen1_size; }
size_t old_gen_size() { return _initial_gen1_size; } size_t old_gen_size() { return _initial_gen1_size; }
size_t max_old_gen_size() { return _max_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 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP

View file

@ -86,6 +86,11 @@ class ParallelScavengeHeap : public CollectedHeap {
set_alignment(_old_gen_alignment, intra_heap_alignment()); 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 // For use by VM operations
enum CollectionType { enum CollectionType {
Scavenge, Scavenge,
@ -122,7 +127,7 @@ class ParallelScavengeHeap : public CollectedHeap {
// The alignment used for eden and survivors within the young gen // The alignment used for eden and survivors within the young gen
// and for boundary between young gen and old 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 capacity() const;
size_t used() const; size_t used() const;

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,11 +26,9 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_ALLOCATIONSTATS_HPP
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/gcUtil.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
#endif // INCLUDE_ALL_GCS #include "gc_implementation/shared/gcUtil.hpp"
class AllocationStats VALUE_OBJ_CLASS_SPEC { class AllocationStats VALUE_OBJ_CLASS_SPEC {
// A duration threshold (in ms) used to filter // A duration threshold (in ms) used to filter

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,11 +26,9 @@
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/shared/generationCounters.hpp" #include "gc_implementation/shared/generationCounters.hpp"
#include "memory/generation.hpp" #include "memory/generation.hpp"
#include "runtime/perfData.hpp" #include "runtime/perfData.hpp"
#endif // INCLUDE_ALL_GCS
// A HSpaceCounter is a holder class for performance counters // A HSpaceCounter is a holder class for performance counters
// that track a collections (logical spaces) in a heap; // that track a collections (logical spaces) in a heap;

View file

@ -87,15 +87,15 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
const MetaspaceSizes meta_space( const MetaspaceSizes meta_space(
MetaspaceAux::allocated_capacity_bytes(), MetaspaceAux::allocated_capacity_bytes(),
MetaspaceAux::allocated_used_bytes(), MetaspaceAux::allocated_used_bytes(),
MetaspaceAux::reserved_in_bytes()); MetaspaceAux::reserved_bytes());
const MetaspaceSizes data_space( const MetaspaceSizes data_space(
MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType), MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType),
MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType), MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType),
MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType)); MetaspaceAux::reserved_bytes(Metaspace::NonClassType));
const MetaspaceSizes class_space( const MetaspaceSizes class_space(
MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType), MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType),
MetaspaceAux::allocated_used_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); return MetaspaceSummary(meta_space, data_space, class_space);
} }

View file

@ -496,15 +496,15 @@ IRT_END
IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode)) IRT_ENTRY(void, InterpreterRuntime::resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode))
// resolve field // resolve field
FieldAccessInfo info; fieldDescriptor info;
constantPoolHandle pool(thread, method(thread)->constants()); constantPoolHandle pool(thread, method(thread)->constants());
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic); bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_putstatic);
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic); bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
{ {
JvmtiHideSingleStepping jhss(thread); JvmtiHideSingleStepping jhss(thread);
LinkResolver::resolve_field(info, pool, get_index_u2_cpcache(thread, bytecode), LinkResolver::resolve_field_access(info, pool, get_index_u2_cpcache(thread, bytecode),
bytecode, false, CHECK); bytecode, CHECK);
} // end JvmtiHideSingleStepping } // end JvmtiHideSingleStepping
// check if link resolution caused cpCache to be updated // 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 // class is intitialized. This is required so that access to the static
// field will call the initialization function every time until the class // field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification. // 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) && bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) &&
!klass->is_initialized()); !klass->is_initialized());
Bytecodes::Code get_code = (Bytecodes::Code)0; 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( cache_entry(thread)->set_field(
get_code, get_code,
put_code, put_code,
info.klass(), info.field_holder(),
info.field_index(), info.index(),
info.field_offset(), info.offset(),
state, state,
info.access_flags().is_final(), info.access_flags().is_final(),
info.access_flags().is_volatile(), info.access_flags().is_volatile(),
@ -686,29 +686,55 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes
if (already_resolved(thread)) return; if (already_resolved(thread)) return;
if (bytecode == Bytecodes::_invokeinterface) { if (bytecode == Bytecodes::_invokeinterface) {
if (TraceItables && Verbose) { if (TraceItables && Verbose) {
ResourceMark rm(thread); 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()); 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() == if (info.resolved_method()->method_holder() ==
SystemDictionary::Object_klass()) { SystemDictionary::Object_klass()) {
// NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec // 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(); methodHandle rm = info.resolved_method();
assert(rm->is_final() || info.has_vtable_index(), assert(rm->is_final() || info.has_vtable_index(),
"should have been set already"); "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 { } else {
// Setup itable entry // Setup itable entry
int index = klassItable::compute_itable_index(info.resolved_method()()); assert(info.call_kind() == CallInfo::itable_call, "");
cache_entry(thread)->set_interface_call(info.resolved_method(), index); int index = info.resolved_method()->itable_index();
assert(info.itable_index() == index, "");
} }
} else { } 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, bytecode,
info.resolved_method(), info.resolved_method(),
info.vtable_index()); 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 IRT_END

View file

@ -46,19 +46,6 @@
#include "runtime/thread.inline.hpp" #include "runtime/thread.inline.hpp"
#include "runtime/vmThread.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 // Implementation of CallInfo
@ -66,26 +53,25 @@ BasicType field_type, AccessFlags access_flags) {
void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
int vtable_index = Method::nonvirtual_vtable_index; 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 // 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 // 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. // we should pick the vtable index from the resolved method.
// Other than that case, there is no valid vtable index to specify. // In that case, the caller must call set_virtual instead of set_interface.
int vtable_index = Method::invalid_vtable_index; assert(resolved_method->method_holder()->is_interface(), "");
if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { assert(itable_index == resolved_method()->itable_index(), "");
assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK);
vtable_index = resolved_method->vtable_index();
}
set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
} }
void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { 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"); 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"); 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(), resolved_method->is_compiled_lambda_form(),
"linkMethod must return one of these"); "linkMethod must return one of these");
int vtable_index = Method::nonvirtual_vtable_index; int vtable_index = Method::nonvirtual_vtable_index;
assert(resolved_method->vtable_index() == vtable_index, ""); assert(!resolved_method->has_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);
_resolved_appendix = resolved_appendix; _resolved_appendix = resolved_appendix;
_resolved_method_type = resolved_method_type; _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"); assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
_resolved_klass = resolved_klass; _resolved_klass = resolved_klass;
_selected_klass = selected_klass; _selected_klass = selected_klass;
_resolved_method = resolved_method; _resolved_method = resolved_method;
_selected_method = selected_method; _selected_method = selected_method;
_vtable_index = vtable_index; _call_kind = kind;
_call_index = index;
_resolved_appendix = Handle(); _resolved_appendix = Handle();
DEBUG_ONLY(verify()); // verify before making side effects
if (CompilationPolicy::must_be_compiled(selected_method)) { if (CompilationPolicy::must_be_compiled(selected_method)) {
// This path is unusual, mostly used by the '-Xcomp' stress test mode. // 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 // Klass resolution
@ -163,13 +217,6 @@ void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, i
result = KlassHandle(THREAD, result_oop); 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 // 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, void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) { 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 // resolve klass
if (code == Bytecodes::_invokedynamic) { if (code == Bytecodes::_invokedynamic) {
resolved_klass = SystemDictionary::MethodHandle_klass(); 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) { void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
resolve_field(result, pool, index, byte, check_only, true, 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);
// 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 || 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_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
bool is_put = (byte == Bytecodes::_putfield || 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 // Check if there's a resolved klass containing the field
if( resolved_klass.is_null() ) { if (resolved_klass.is_null()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
} }
// Resolve instance field // Resolve instance field
fieldDescriptor fd; // find_field initializes fd if found
KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); 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 // 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); ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); 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 // check access
KlassHandle ref_klass(THREAD, pool->pool_holder()); check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
// check for errors // check for errors
if (is_static != fd.is_static()) { 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. // 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()); 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 // 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 the field access is legal; e.g., during compilation
if (is_static && !check_only) { if (is_static && initialize_class) {
sel_klass->initialize(CHECK); sel_klass->initialize(CHECK);
} }
{ if (sel_klass() != current_klass()) {
HandleMark hm(THREAD); 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()); Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader());
Symbol* signature_ref = pool->signature_ref_at(index);
{ {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Symbol* failed_type_symbol = Symbol* failed_type_symbol =
SystemDictionary::check_signature_loaders(signature_ref, SystemDictionary::check_signature_loaders(sig,
ref_loader, sel_loader, ref_loader, sel_loader,
false, false,
CHECK); 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 // 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. // 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()); 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 // 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 // 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. // 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, vtable_index = vtable_index_of_miranda_method(resolved_klass,
resolved_method->name(), resolved_method->name(),
resolved_method->signature(), CHECK); resolved_method->signature(), CHECK);
assert(vtable_index >= 0 , "we should have valid vtable index at this point"); assert(vtable_index >= 0 , "we should have valid vtable index at this point");
InstanceKlass* inst = InstanceKlass::cast(recv_klass()); InstanceKlass* inst = InstanceKlass::cast(recv_klass());
@ -927,6 +976,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
} else { } else {
// at this point we are sure that resolved_method is virtual and not // at this point we are sure that resolved_method is virtual and not
// a miranda method; therefore, it must have a valid vtable index. // a miranda method; therefore, it must have a valid vtable index.
assert(!resolved_method->has_itable_index(), "");
vtable_index = resolved_method->vtable_index(); vtable_index = resolved_method->vtable_index();
// We could get a negative vtable_index for final methods, // We could get a negative vtable_index for final methods,
// because as an optimization they are they are never put in the vtable, // 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, lookup_instance_method_in_klasses(sel_method, recv_klass,
resolved_method->name(), resolved_method->name(),
resolved_method->signature(), CHECK); 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 // check if method exists
if (sel_method.is_null()) { if (sel_method.is_null()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
@ -1046,7 +1102,14 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
sel_method->signature())); sel_method->signature()));
} }
// setup result // 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,7 +1356,8 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
} }
if (TraceMethodHandles) { if (TraceMethodHandles) {
tty->print_cr("resolve_invokedynamic #%d %s %s", ResourceMark rm(THREAD);
tty->print_cr("resolve_invokedynamic #%d %s %s",
ConstantPool::decode_invokedynamic_index(index), ConstantPool::decode_invokedynamic_index(index),
method_name->as_C_string(), method_signature->as_C_string()); method_name->as_C_string(), method_signature->as_C_string());
tty->print(" BSM info: "); bootstrap_specifier->print(); tty->print(" BSM info: "); bootstrap_specifier->print();
@ -1342,9 +1406,16 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
//------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------
#ifndef PRODUCT #ifndef PRODUCT
void FieldAccessInfo::print() { void CallInfo::print() {
ResourceMark rm; 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 #endif

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,63 +30,54 @@
// All the necessary definitions for run-time link resolution. // All the necessary definitions for run-time link resolution.
// LinkInfo & its subclasses provide all the information gathered // CallInfo provides all the information gathered for a particular
// for a particular link after resolving it. A link is any reference // linked call site after resolving it. A link is any reference
// made from within the bytecodes of a method to an object outside of // 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 // that method. If the info is invalid, the link has not been resolved
// successfully. // successfully.
class LinkInfo VALUE_OBJ_CLASS_SPEC { class CallInfo 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;
public: public:
void set(KlassHandle klass, Symbol* name, int field_index, int field_offset, // Ways that a method call might be selected (or not) based on receiver type.
BasicType field_type, AccessFlags access_flags); // Note that an invokevirtual instruction might be linked with no_dispatch,
KlassHandle klass() const { return _klass; } // and an invokeinterface instruction might be linked with any of the three options
Symbol* name() const { return _name; } enum CallKind {
int field_index() const { return _field_index; } direct_call, // jump into resolved_method (must be concrete)
int field_offset() const { return _field_offset; } vtable_call, // select recv.klass.method_at_vtable(index)
BasicType field_type() const { return _field_type; } itable_call, // select recv.klass.method_at_itable(resolved_method.holder, index)
AccessFlags access_flags() const { return _access_flags; } unknown_kind = -1
};
// debugging
void print() PRODUCT_RETURN;
};
// Link information for all calls.
class CallInfo: public LinkInfo {
private: 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) KlassHandle _selected_klass; // dynamic receiver class (same as static, or subklass)
methodHandle _resolved_method; // static target method methodHandle _resolved_method; // static target method
methodHandle _selected_method; // dynamic (actual) 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_appendix; // extra argument in constant pool (if CPCE::has_appendix)
Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites) Handle _resolved_method_type; // MethodType (for invokedynamic and invokehandle call sites)
void set_static( KlassHandle resolved_klass, methodHandle resolved_method , TRAPS); 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_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_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; friend class LinkResolver;
public: 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 resolved_klass() const { return _resolved_klass; }
KlassHandle selected_klass() const { return _selected_klass; } KlassHandle selected_klass() const { return _selected_klass; }
methodHandle resolved_method() const { return _resolved_method; } methodHandle resolved_method() const { return _resolved_method; }
@ -95,21 +86,43 @@ class CallInfo: public LinkInfo {
Handle resolved_method_type() const { return _resolved_method_type; } Handle resolved_method_type() const { return _resolved_method_type; }
BasicType result_type() const { return selected_method()->result_type(); } BasicType result_type() const { return selected_method()->result_type(); }
bool has_vtable_index() const { return _vtable_index >= 0; } CallKind call_kind() const { return _call_kind; }
bool is_statically_bound() const { return _vtable_index == Method::nonvirtual_vtable_index; } int call_index() const { return _call_index; }
int vtable_index() const { int vtable_index() const {
// Even for interface calls the vtable index could be non-negative. // Even for interface calls the vtable index could be non-negative.
// See CallInfo::set_interface. // See CallInfo::set_interface.
assert(has_vtable_index() || is_statically_bound(), ""); 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. // The LinkResolver is used to resolve constant-pool references at run-time.
// It does all necessary link-time checks & throws exceptions if necessary. // It does all necessary link-time checks & throws exceptions if necessary.
class LinkResolver: AllStatic { class LinkResolver: AllStatic {
friend class klassVtable;
friend class klassItable;
private: private:
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS); 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); 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 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 (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); 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); Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
// runtime/static resolving for fields // runtime/static resolving for fields
static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS); static void resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
// takes an extra bool argument "update_pool" to decide whether to update the constantPool during klass resolution. static void resolve_field(fieldDescriptor& result, KlassHandle resolved_klass, Symbol* field_name, Symbol* field_signature,
static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS); 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: // runtime resolving:
// resolved_klass = specified class (i.e., static receiver class) // resolved_klass = specified class (i.e., static receiver class)

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,10 +33,10 @@
#include "runtime/globals.hpp" #include "runtime/globals.hpp"
#include "utilities/ostream.hpp" #include "utilities/ostream.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
#include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp" #include "gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp"
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp" #include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS

View file

@ -47,6 +47,11 @@
// CollectorPolicy methods. // 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() { void CollectorPolicy::initialize_flags() {
assert(max_alignment() >= min_alignment(), assert(max_alignment() >= min_alignment(),
err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT, 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"); vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
} }
if (MetaspaceSize > MaxMetaspaceSize) { if (!is_size_aligned(MaxMetaspaceSize, max_alignment())) {
MaxMetaspaceSize = MetaspaceSize; FLAG_SET_ERGO(uintx, MaxMetaspaceSize,
} restricted_align_down(MaxMetaspaceSize, max_alignment()));
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;
} }
MinMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MinMetaspaceExpansion, min_alignment())); if (MetaspaceSize > MaxMetaspaceSize) {
MaxMetaspaceExpansion = MAX2(min_alignment(), align_size_down_(MaxMetaspaceExpansion, min_alignment())); 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()); MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, min_alignment());
@ -145,6 +156,30 @@ void CollectorPolicy::cleared_all_soft_refs() {
_all_soft_refs_clear = true; _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. // GenCollectorPolicy methods.
@ -175,29 +210,6 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
GCTimeRatio); 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() { void GenCollectorPolicy::initialize_flags() {
// All sizes must be multiples of the generation granularity. // All sizes must be multiples of the generation granularity.
set_min_alignment((uintx) Generation::GenGrain); set_min_alignment((uintx) Generation::GenGrain);

View file

@ -98,6 +98,9 @@ class CollectorPolicy : public CHeapObj<mtGC> {
{} {}
public: 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; } void set_min_alignment(size_t align) { _min_alignment = align; }
size_t min_alignment() { return _min_alignment; } size_t min_alignment() { return _min_alignment; }
void set_max_alignment(size_t align) { _max_alignment = align; } 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. // Try to allocate space by expanding the heap.
virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab); 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 // Scale the base_size by NewRation according to
// result = base_size / (NewRatio + 1) // result = base_size / (NewRatio + 1)
// and align by min_alignment() // and align by min_alignment()

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -148,6 +148,11 @@ public:
return gen_policy()->size_policy(); 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 capacity() const;
size_t used() const; size_t used() const;

View file

@ -50,13 +50,6 @@
// Chunks, change Chunks so that they can be allocated out of a VirtualSpace. // Chunks, change Chunks so that they can be allocated out of a VirtualSpace.
size_t Metablock::_min_block_byte_size = sizeof(Metablock); 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. // New blocks returned by the Metaspace are zero initialized.
// We should fix the constructors to not assume this instead. // We should fix the constructors to not assume this instead.
Metablock* Metablock::initialize(MetaWord* p, size_t word_size) { Metablock* Metablock::initialize(MetaWord* p, size_t word_size) {

View file

@ -48,7 +48,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC {
} _header; } _header;
} _block; } _block;
static size_t _min_block_byte_size; static size_t _min_block_byte_size;
static size_t _overhead;
typedef union block_t Block; typedef union block_t Block;
typedef struct header_t Header; typedef struct header_t Header;
@ -73,7 +72,6 @@ class Metablock VALUE_OBJ_CLASS_SPEC {
void set_prev(Metablock* v) { _block._header._prev = v; } void set_prev(Metablock* v) { _block._header._prev = v; }
static size_t min_block_byte_size() { return _min_block_byte_size; } 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; } bool is_free() { return header()->_word_size != 0; }
void clear_next() { set_next(NULL); } void clear_next() { set_next(NULL); }

View file

@ -51,7 +51,7 @@ const bool metaspace_slow_verify = false;
// Parameters for stress mode testing // Parameters for stress mode testing
const uint metadata_deallocate_a_lot_block = 10; const uint metadata_deallocate_a_lot_block = 10;
const uint metadata_deallocate_a_lock_chunk = 3; 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; MetaWord* last_allocated = 0;
@ -177,8 +177,8 @@ class ChunkManager VALUE_OBJ_CLASS_SPEC {
void return_chunks(ChunkIndex index, Metachunk* chunks); void return_chunks(ChunkIndex index, Metachunk* chunks);
// Total of the space in the free chunks list // Total of the space in the free chunks list
size_t free_chunks_total(); size_t free_chunks_total_words();
size_t free_chunks_total_in_bytes(); size_t free_chunks_total_bytes();
// Number of chunks in the free chunks list // Number of chunks in the free chunks list
size_t free_chunks_count(); size_t free_chunks_count();
@ -228,6 +228,10 @@ class BlockFreelist VALUE_OBJ_CLASS_SPEC {
BlockTreeDictionary* _dictionary; BlockTreeDictionary* _dictionary;
static Metablock* initialize_free_chunk(MetaWord* p, size_t word_size); 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 // Accessors
BlockTreeDictionary* dictionary() const { return _dictionary; } BlockTreeDictionary* dictionary() const { return _dictionary; }
@ -287,6 +291,10 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } 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; // address of next available space in _virtual_space;
// Accessors // Accessors
VirtualSpaceNode* next() { return _next; } VirtualSpaceNode* next() { return _next; }
@ -323,12 +331,10 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
// Allocate a chunk from the virtual space and return it. // Allocate a chunk from the virtual space and return it.
Metachunk* get_chunk_vs(size_t chunk_word_size); 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 // Expands/shrinks the committed space in a virtual space. Delegates
// to Virtualspace // to Virtualspace
bool expand_by(size_t words, bool pre_touch = false); 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 preparation for deleting this node, remove all the chunks
// in the node from any freelist. // in the node from any freelist.
@ -336,8 +342,6 @@ class VirtualSpaceNode : public CHeapObj<mtClass> {
#ifdef ASSERT #ifdef ASSERT
// Debug support // Debug support
static void verify_virtual_space_total();
static void verify_virtual_space_count();
void mangle(); void mangle();
#endif #endif
@ -423,10 +427,13 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
// Can this virtual list allocate >1 spaces? Also, used to determine // Can this virtual list allocate >1 spaces? Also, used to determine
// whether to allocate unlimited small chunks in this virtual space // whether to allocate unlimited small chunks in this virtual space
bool _is_class; 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 // Sum of reserved and committed memory in the virtual spaces
size_t _virtual_space_total; size_t _reserved_words;
size_t _committed_words;
// Number of virtual spaces
size_t _virtual_space_count; size_t _virtual_space_count;
~VirtualSpaceList(); ~VirtualSpaceList();
@ -440,7 +447,7 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
_current_virtual_space = v; _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 // Get another virtual space and add it to the list. This
// is typically prompted by a failed attempt to allocate a chunk // 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 grow_chunks_by_words,
size_t medium_chunk_bunch); 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 // Get the first chunk for a Metaspace. Used for
// special cases such as the boot class loader, reflection // special cases such as the boot class loader, reflection
// class loader and anonymous class loader. // class loader and anonymous class loader.
@ -472,10 +481,15 @@ class VirtualSpaceList : public CHeapObj<mtClass> {
// Allocate the first virtualspace. // Allocate the first virtualspace.
void initialize(size_t word_size); 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 inc_reserved_words(size_t v);
void dec_virtual_space_total(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 inc_virtual_space_count();
void dec_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 // Add chunk to the list of chunks in use
void add_chunk(Metachunk* v, bool make_current); void add_chunk(Metachunk* v, bool make_current);
void retire_current_chunk();
Mutex* lock() const { return _lock; } Mutex* lock() const { return _lock; }
@ -722,9 +737,7 @@ class SpaceManager : public CHeapObj<mtClass> {
// MinChunkSize is a placeholder for the real minimum size JJJ // MinChunkSize is a placeholder for the real minimum size JJJ
size_t byte_size = word_size * BytesPerWord; 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,
size_t raw_bytes_size = MAX2(byte_size_with_overhead,
Metablock::min_block_byte_size()); Metablock::min_block_byte_size());
raw_bytes_size = ARENA_ALIGN(raw_bytes_size); raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
size_t raw_word_size = raw_bytes_size / BytesPerWord; size_t raw_word_size = raw_bytes_size / BytesPerWord;
@ -807,12 +820,25 @@ MetaWord* BlockFreelist::get_block(size_t word_size) {
} }
Metablock* free_block = Metablock* free_block =
dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::exactly); dictionary()->get_chunk(word_size, FreeBlockDictionary<Metablock>::atLeast);
if (free_block == NULL) { if (free_block == NULL) {
return 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 { 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 (!is_available(chunk_word_size)) {
if (TraceMetadataChunkAllocation) { 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 // Dump some information about the virtual space that is nearly full
print_on(tty); print_on(gclog_or_tty);
} }
return NULL; return NULL;
} }
@ -878,20 +904,11 @@ bool VirtualSpaceNode::expand_by(size_t words, bool pre_touch) {
if (TraceMetavirtualspaceAllocation && !result) { if (TraceMetavirtualspaceAllocation && !result) {
gclog_or_tty->print_cr("VirtualSpaceNode::expand_by() failed " gclog_or_tty->print_cr("VirtualSpaceNode::expand_by() failed "
"for byte size " SIZE_FORMAT, bytes); "for byte size " SIZE_FORMAT, bytes);
virtual_space()->print(); virtual_space()->print_on(gclog_or_tty);
} }
return result; 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) { Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
assert_lock_strong(SpaceManager::expand_lock()); assert_lock_strong(SpaceManager::expand_lock());
Metachunk* result = take_from_committed(chunk_word_size); Metachunk* result = take_from_committed(chunk_word_size);
@ -901,23 +918,6 @@ Metachunk* VirtualSpaceNode::get_chunk_vs(size_t chunk_word_size) {
return result; 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() { bool VirtualSpaceNode::initialize() {
if (!_rs.is_reserved()) { 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()); 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()); 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() { void VirtualSpaceList::inc_virtual_space_count() {
@ -1034,7 +1043,8 @@ void VirtualSpaceList::purge() {
} }
vsl->purge(chunk_manager()); 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(); dec_virtual_space_count();
purged_vsl = vsl; purged_vsl = vsl;
delete vsl; delete vsl;
@ -1062,12 +1072,12 @@ size_t VirtualSpaceList::used_words_sum() {
// Sum used region [bottom, top) in each virtualspace // Sum used region [bottom, top) in each virtualspace
allocated_by_vs += vsl->used_words_in_vs(); 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 err_msg("Total in free chunks " SIZE_FORMAT
" greater than total from virtual_spaces " 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 = size_t used =
allocated_by_vs - chunk_manager()->free_chunks_total(); allocated_by_vs - chunk_manager()->free_chunks_total_words();
return used; return used;
} }
@ -1088,7 +1098,8 @@ VirtualSpaceList::VirtualSpaceList(size_t word_size ) :
_is_class(false), _is_class(false),
_virtual_space_list(NULL), _virtual_space_list(NULL),
_current_virtual_space(NULL), _current_virtual_space(NULL),
_virtual_space_total(0), _reserved_words(0),
_committed_words(0),
_virtual_space_count(0) { _virtual_space_count(0) {
MutexLockerEx cl(SpaceManager::expand_lock(), MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
@ -1105,7 +1116,8 @@ VirtualSpaceList::VirtualSpaceList(ReservedSpace rs) :
_is_class(true), _is_class(true),
_virtual_space_list(NULL), _virtual_space_list(NULL),
_current_virtual_space(NULL), _current_virtual_space(NULL),
_virtual_space_total(0), _reserved_words(0),
_committed_words(0),
_virtual_space_count(0) { _virtual_space_count(0) {
MutexLockerEx cl(SpaceManager::expand_lock(), MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag); 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(SmallIndex)->set_size(ClassSmallChunk);
_chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk); _chunk_manager.free_chunks(MediumIndex)->set_size(ClassMediumChunk);
assert(succeeded, " VirtualSpaceList initialization should not fail"); assert(succeeded, " VirtualSpaceList initialization should not fail");
link_vs(class_entry, rs.size()/BytesPerWord); link_vs(class_entry);
} }
size_t VirtualSpaceList::free_bytes() { size_t VirtualSpaceList::free_bytes() {
@ -1138,31 +1150,47 @@ bool VirtualSpaceList::grow_vs(size_t vs_word_size) {
delete new_entry; delete new_entry;
return false; return false;
} else { } else {
assert(new_entry->reserved_words() == vs_word_size, "Must be");
// ensure lock-free iteration sees fully initialized node // ensure lock-free iteration sees fully initialized node
OrderAccess::storestore(); OrderAccess::storestore();
link_vs(new_entry, vs_word_size); link_vs(new_entry);
return true; 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) { if (virtual_space_list() == NULL) {
set_virtual_space_list(new_entry); set_virtual_space_list(new_entry);
} else { } else {
current_virtual_space()->set_next(new_entry); current_virtual_space()->set_next(new_entry);
} }
set_current_virtual_space(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(); inc_virtual_space_count();
#ifdef ASSERT #ifdef ASSERT
new_entry->mangle(); new_entry->mangle();
#endif #endif
if (TraceMetavirtualspaceAllocation && Verbose) { if (TraceMetavirtualspaceAllocation && Verbose) {
VirtualSpaceNode* vsl = current_virtual_space(); 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, Metachunk* VirtualSpaceList::get_new_chunk(size_t word_size,
size_t grow_chunks_by_words, size_t grow_chunks_by_words,
size_t medium_chunk_bunch) { 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, size_t aligned_expand_vs_by_words = align_size_up(expand_vs_by_words,
page_size_words); page_size_words);
bool vs_expanded = 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) { if (!vs_expanded) {
// Should the capacity of the metaspaces be expanded for // Should the capacity of the metaspaces be expanded for
// this allocation? If it's the virtual space for classes and is // 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); MAX2((size_t)VirtualSpaceSize, aligned_expand_vs_by_words);
if (grow_vs(grow_vs_words)) { if (grow_vs(grow_vs_words)) {
// Got it. It's on the list now. Get a chunk from it. // 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 { } else {
// Allocation will fail and induce a GC // 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 // reserved space, because this is a larger space prereserved for compressed
// class pointers. // class pointers.
if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { 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); MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
if (real_allocated >= MaxMetaspaceSize) { if (real_allocated >= MaxMetaspaceSize) {
return false; return false;
@ -1508,7 +1543,7 @@ void Metadebug::deallocate_chunk_a_lot(SpaceManager* sm,
sm->sum_count_in_chunks_in_use()); sm->sum_count_in_chunks_in_use());
dummy_chunk->print_on(gclog_or_tty); dummy_chunk->print_on(gclog_or_tty);
gclog_or_tty->print_cr(" Free chunks total %d count %d", 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()); vsl->chunk_manager()->free_chunks_count());
} }
} }
@ -1565,12 +1600,12 @@ bool Metadebug::test_metadata_failure() {
// ChunkManager methods // ChunkManager methods
size_t ChunkManager::free_chunks_total() { size_t ChunkManager::free_chunks_total_words() {
return _free_chunks_total; return _free_chunks_total;
} }
size_t ChunkManager::free_chunks_total_in_bytes() { size_t ChunkManager::free_chunks_total_bytes() {
return free_chunks_total() * BytesPerWord; return free_chunks_total_words() * BytesPerWord;
} }
size_t ChunkManager::free_chunks_count() { size_t ChunkManager::free_chunks_count() {
@ -1698,9 +1733,9 @@ void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) {
assert_lock_strong(SpaceManager::expand_lock()); assert_lock_strong(SpaceManager::expand_lock());
slow_locked_verify(); slow_locked_verify();
if (TraceMetadataChunkAllocation) { 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, PTR_FORMAT " size " SIZE_FORMAT,
chunk, chunk->word_size()); chunk, chunk->word_size());
} }
free_chunks_put(chunk); free_chunks_put(chunk);
} }
@ -1729,9 +1764,9 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
dec_free_chunks_total(chunk->capacity_word_size()); dec_free_chunks_total(chunk->capacity_word_size());
if (TraceMetadataChunkAllocation && Verbose) { 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, PTR_FORMAT " head " PTR_FORMAT " size " SIZE_FORMAT,
free_list, chunk, chunk->word_size()); free_list, chunk, chunk->word_size());
} }
} else { } else {
chunk = humongous_dictionary()->get_chunk( chunk = humongous_dictionary()->get_chunk(
@ -1741,10 +1776,10 @@ Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
if (chunk != NULL) { if (chunk != NULL) {
if (TraceMetadataHumongousAllocation) { if (TraceMetadataHumongousAllocation) {
size_t waste = chunk->word_size() - word_size; size_t waste = chunk->word_size() - word_size;
tty->print_cr("Free list allocate humongous chunk size " SIZE_FORMAT gclog_or_tty->print_cr("Free list allocate humongous chunk size "
" for requested size " SIZE_FORMAT SIZE_FORMAT " for requested size " SIZE_FORMAT
" waste " SIZE_FORMAT, " waste " SIZE_FORMAT,
chunk->word_size(), word_size, waste); chunk->word_size(), word_size, waste);
} }
// Chunk is being removed from the chunks free list. // Chunk is being removed from the chunks free list.
dec_free_chunks_total(chunk->capacity_word_size()); dec_free_chunks_total(chunk->capacity_word_size());
@ -1786,10 +1821,10 @@ Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
} else { } else {
list_count = humongous_dictionary()->total_count(); 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 " ", PTR_FORMAT " size " SIZE_FORMAT " count " SIZE_FORMAT " ",
this, chunk, chunk->word_size(), list_count); this, chunk, chunk->word_size(), list_count);
locked_print_free_chunks(tty); locked_print_free_chunks(gclog_or_tty);
} }
return chunk; 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()); ChunkIndex index = ChunkManager::list_index(new_chunk->word_size());
if (index != HumongousIndex) { if (index != HumongousIndex) {
retire_current_chunk();
set_current_chunk(new_chunk); set_current_chunk(new_chunk);
new_chunk->set_next(chunks_in_use(index)); new_chunk->set_next(chunks_in_use(index));
set_chunks_in_use(index, new_chunk); 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()); sum_count_in_chunks_in_use());
new_chunk->print_on(gclog_or_tty); new_chunk->print_on(gclog_or_tty);
if (vs_list() != NULL) { 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, grow_chunks_by_words,
medium_chunk_bunch()); medium_chunk_bunch());
if (TraceMetadataHumongousAllocation && if (TraceMetadataHumongousAllocation && next != NULL &&
SpaceManager::is_humongous(next->word_size())) { SpaceManager::is_humongous(next->word_size())) {
gclog_or_tty->print_cr(" new humongous chunk word size " PTR_FORMAT, gclog_or_tty->print_cr(" new humongous chunk word size "
next->word_size()); PTR_FORMAT, next->word_size());
} }
return next; return next;
@ -2441,9 +2487,6 @@ void SpaceManager::dump(outputStream* const out) const {
curr = curr->next()) { curr = curr->next()) {
out->print("%d) ", i++); out->print("%d) ", i++);
curr->print_on(out); curr->print_on(out);
if (TraceMetadataChunkAllocation && Verbose) {
block_freelists()->print_on(out);
}
curr_total += curr->word_size(); curr_total += curr->word_size();
used += curr->used_word_size(); used += curr->used_word_size();
capacity += curr->capacity_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(); size_t free = current_chunk() == NULL ? 0 : current_chunk()->free_word_size();
// Free space isn't wasted. // Free space isn't wasted.
waste -= free; waste -= free;
@ -2538,13 +2585,13 @@ size_t MetaspaceAux::used_bytes_slow(Metaspace::MetadataType mdtype) {
return used * BytesPerWord; 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; size_t free = 0;
ClassLoaderDataGraphMetaspaceIterator iter; ClassLoaderDataGraphMetaspaceIterator iter;
while (iter.repeat()) { while (iter.repeat()) {
Metaspace* msp = iter.get_next(); Metaspace* msp = iter.get_next();
if (msp != NULL) { if (msp != NULL) {
free += msp->free_words(mdtype); free += msp->free_words_slow(mdtype);
} }
} }
return free * BytesPerWord; return free * BytesPerWord;
@ -2567,34 +2614,56 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
return capacity * BytesPerWord; return capacity * BytesPerWord;
} }
size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) { size_t MetaspaceAux::capacity_bytes_slow() {
VirtualSpaceList* list = Metaspace::get_space_list(mdtype); #ifdef PRODUCT
return list == NULL ? 0 : list->virtual_space_total(); // 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); VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
if (list == NULL) { if (list == NULL) {
return 0; return 0;
} }
ChunkManager* chunk = list->chunk_manager(); ChunkManager* chunk = list->chunk_manager();
chunk->slow_verify(); 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) { size_t MetaspaceAux::free_chunks_total_bytes(Metaspace::MetadataType mdtype) {
return free_chunks_total(mdtype) * BytesPerWord; return free_chunks_total_words(mdtype) * BytesPerWord;
} }
size_t MetaspaceAux::free_chunks_total() { size_t MetaspaceAux::free_chunks_total_words() {
return free_chunks_total(Metaspace::ClassType) + return free_chunks_total_words(Metaspace::ClassType) +
free_chunks_total(Metaspace::NonClassType); free_chunks_total_words(Metaspace::NonClassType);
} }
size_t MetaspaceAux::free_chunks_total_in_bytes() { size_t MetaspaceAux::free_chunks_total_bytes() {
return free_chunks_total() * BytesPerWord; return free_chunks_total_words() * BytesPerWord;
} }
void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) { 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 ")", "(" SIZE_FORMAT ")",
prev_metadata_used, prev_metadata_used,
allocated_used_bytes(), allocated_used_bytes(),
reserved_in_bytes()); reserved_bytes());
} else { } else {
gclog_or_tty->print(" " SIZE_FORMAT "K" gclog_or_tty->print(" " SIZE_FORMAT "K"
"->" SIZE_FORMAT "K" "->" SIZE_FORMAT "K"
"(" SIZE_FORMAT "K)", "(" SIZE_FORMAT "K)",
prev_metadata_used / K, prev_metadata_used/K,
allocated_used_bytes() / K, allocated_used_bytes()/K,
reserved_in_bytes()/ K); reserved_bytes()/K);
} }
gclog_or_tty->print("]"); gclog_or_tty->print("]");
@ -2625,14 +2694,14 @@ void MetaspaceAux::print_on(outputStream* out) {
out->print_cr(" Metaspace total " out->print_cr(" Metaspace total "
SIZE_FORMAT "K, used " SIZE_FORMAT "K," SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
" reserved " 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 " out->print_cr(" data space "
SIZE_FORMAT "K, used " SIZE_FORMAT "K," SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
" reserved " SIZE_FORMAT "K", " reserved " SIZE_FORMAT "K",
allocated_capacity_bytes(nct)/K, allocated_capacity_bytes(nct)/K,
allocated_used_bytes(nct)/K, allocated_used_bytes(nct)/K,
reserved_in_bytes(nct)/K); reserved_bytes(nct)/K);
if (Metaspace::using_class_space()) { if (Metaspace::using_class_space()) {
Metaspace::MetadataType ct = Metaspace::ClassType; Metaspace::MetadataType ct = Metaspace::ClassType;
out->print_cr(" class space " out->print_cr(" class space "
@ -2640,17 +2709,17 @@ void MetaspaceAux::print_on(outputStream* out) {
" reserved " SIZE_FORMAT "K", " reserved " SIZE_FORMAT "K",
allocated_capacity_bytes(ct)/K, allocated_capacity_bytes(ct)/K,
allocated_used_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. // Print information for class space and data space separately.
// This is almost the same as above. // This is almost the same as above.
void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { 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 capacity_bytes = capacity_bytes_slow(mdtype);
size_t used_bytes = used_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 + size_t used_and_free = used_bytes + free_bytes +
free_chunks_capacity_bytes; free_chunks_capacity_bytes;
out->print_cr(" Chunk accounting: used in chunks " SIZE_FORMAT 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. // to work with compressed klass pointers.
bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) { bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS"); 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 lower_base = MIN2((address)metaspace_base, cds_base);
address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()), address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
(address)(metaspace_base + class_metaspace_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. // Try to allocate the metaspace at the requested addr.
void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) { void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
assert(using_class_space(), "called improperly"); assert(using_class_space(), "called improperly");
assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs"); assert(UseCompressedClassPointers, "Only use with CompressedKlassPtrs");
assert(class_metaspace_size() < KlassEncodingMetaspaceMax, assert(class_metaspace_size() < KlassEncodingMetaspaceMax,
"Metaspace size is too big"); "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 // 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 // that fails then OOM doom. At this point we cannot try allocating the
// metaspace as if UseCompressedKlassPointers is off because too much // metaspace as if UseCompressedClassPointers is off because too much
// initialization has happened that depends on UseCompressedKlassPointers. // initialization has happened that depends on UseCompressedClassPointers.
// So, UseCompressedKlassPointers cannot be turned off at this point. // So, UseCompressedClassPointers cannot be turned off at this point.
if (!metaspace_rs.is_reserved()) { if (!metaspace_rs.is_reserved()) {
metaspace_rs = ReservedSpace(class_metaspace_size(), metaspace_rs = ReservedSpace(class_metaspace_size(),
os::vm_allocation_granularity(), false); 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. // the Java heap. The argument passed in is at the base of the compressed space.
void Metaspace::initialize_class_space(ReservedSpace rs) { void Metaspace::initialize_class_space(ReservedSpace rs) {
// The reserved space size may be bigger because of alignment, esp with UseLargePages // The reserved space size may be bigger because of alignment, esp with UseLargePages
assert(rs.size() >= ClassMetaspaceSize, assert(rs.size() >= CompressedClassSpaceSize,
err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize)); err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), CompressedClassSpaceSize));
assert(using_class_space(), "Must be using class space"); assert(using_class_space(), "Must be using class space");
_class_space_list = new VirtualSpaceList(rs); _class_space_list = new VirtualSpaceList(rs);
} }
@ -2921,7 +2990,7 @@ void Metaspace::global_initialize() {
int max_alignment = os::vm_page_size(); int max_alignment = os::vm_page_size();
size_t cds_total = 0; 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())); os::vm_allocation_granularity()));
MetaspaceShared::set_max_alignment(max_alignment); MetaspaceShared::set_max_alignment(max_alignment);
@ -2941,8 +3010,8 @@ void Metaspace::global_initialize() {
#ifdef _LP64 #ifdef _LP64
// Set the compressed klass pointer base so that decoding of these pointers works // Set the compressed klass pointer base so that decoding of these pointers works
// properly when creating the shared archive. // properly when creating the shared archive.
assert(UseCompressedOops && UseCompressedKlassPointers, assert(UseCompressedOops && UseCompressedClassPointers,
"UseCompressedOops and UseCompressedKlassPointers must be set"); "UseCompressedOops and UseCompressedClassPointers must be set");
Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom()); Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
if (TraceMetavirtualspaceAllocation && Verbose) { if (TraceMetavirtualspaceAllocation && Verbose) {
gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT, gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
@ -2979,7 +3048,7 @@ void Metaspace::global_initialize() {
} }
#ifdef _LP64 #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). // above the heap and above the CDS area (if it exists).
if (using_class_space()) { if (using_class_space()) {
if (UseSharedSpaces) { if (UseSharedSpaces) {
@ -2997,7 +3066,7 @@ void Metaspace::global_initialize() {
// on the medium chunk list. The next chunk will be small and progress // on the medium chunk list. The next chunk will be small and progress
// from there. This size calculated by -version. // from there. This size calculated by -version.
_first_class_chunk_word_size = MIN2((size_t)MediumChunk*6, _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); _first_class_chunk_word_size = align_word_size_up(_first_class_chunk_word_size);
// Arbitrarily set the initial virtual space to a multiple // Arbitrarily set the initial virtual space to a multiple
// of the boot class loader size. // 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) { MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
// DumpSharedSpaces doesn't use class metadata area (yet) // 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()) { if (mdtype == ClassType && using_class_space()) {
return class_vsm()->allocate(word_size); return class_vsm()->allocate(word_size);
} else { } 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) { if (mdtype == ClassType) {
return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0; return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;
} else { } else {
@ -3213,7 +3282,7 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
MetaspaceAux::dump(gclog_or_tty); MetaspaceAux::dump(gclog_or_tty);
} }
// -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support // -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"; "Metadata space";
report_java_out_of_memory(space_string); report_java_out_of_memory(space_string);
@ -3311,3 +3380,59 @@ void Metaspace::dump(outputStream* const out) const {
class_vsm()->dump(out); 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

View file

@ -182,9 +182,8 @@ class Metaspace : public CHeapObj<mtClass> {
char* bottom() const; char* bottom() const;
size_t used_words_slow(MetadataType mdtype) 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 capacity_words_slow(MetadataType mdtype) const;
size_t waste_words(MetadataType mdtype) const;
size_t used_bytes_slow(MetadataType mdtype) const; size_t used_bytes_slow(MetadataType mdtype) const;
size_t capacity_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); 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() { static bool using_class_space() {
return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces); return NOT_LP64(false) LP64_ONLY(UseCompressedClassPointers && !DumpSharedSpaces);
} }
}; };
class MetaspaceAux : AllStatic { class MetaspaceAux : AllStatic {
static size_t free_chunks_total(Metaspace::MetadataType mdtype); static size_t free_chunks_total_words(Metaspace::MetadataType mdtype);
public:
// Statistics for class space and data space in metaspace.
// These methods iterate over the classloader data graph // These methods iterate over the classloader data graph
// for the given Metaspace type. These are slow. // for the given Metaspace type. These are slow.
static size_t used_bytes_slow(Metaspace::MetadataType mdtype); 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); static size_t capacity_bytes_slow(Metaspace::MetadataType mdtype);
static size_t capacity_bytes_slow();
// Iterates over the virtual space list.
static size_t reserved_in_bytes(Metaspace::MetadataType mdtype);
// Running sum of space in all Metachunks that has been // Running sum of space in all Metachunks that has been
// allocated to a Metaspace. This is used instead of // allocated to a Metaspace. This is used instead of
@ -263,17 +257,16 @@ class MetaspaceAux : AllStatic {
} }
// Used by MetaspaceCounters // Used by MetaspaceCounters
static size_t free_chunks_total(); static size_t free_chunks_total_words();
static size_t free_chunks_total_in_bytes(); static size_t free_chunks_total_bytes();
static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype); static size_t free_chunks_total_bytes(Metaspace::MetadataType mdtype);
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) { static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
return _allocated_capacity_words[mdtype]; return _allocated_capacity_words[mdtype];
} }
static size_t allocated_capacity_words() { static size_t allocated_capacity_words() {
return _allocated_capacity_words[Metaspace::NonClassType] + return allocated_capacity_words(Metaspace::NonClassType) +
(Metaspace::using_class_space() ? allocated_capacity_words(Metaspace::ClassType);
_allocated_capacity_words[Metaspace::ClassType] : 0);
} }
static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) { static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
return allocated_capacity_words(mdtype) * BytesPerWord; return allocated_capacity_words(mdtype) * BytesPerWord;
@ -286,9 +279,8 @@ class MetaspaceAux : AllStatic {
return _allocated_used_words[mdtype]; return _allocated_used_words[mdtype];
} }
static size_t allocated_used_words() { static size_t allocated_used_words() {
return _allocated_used_words[Metaspace::NonClassType] + return allocated_used_words(Metaspace::NonClassType) +
(Metaspace::using_class_space() ? allocated_used_words(Metaspace::ClassType);
_allocated_used_words[Metaspace::ClassType] : 0);
} }
static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) { static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
return allocated_used_words(mdtype) * BytesPerWord; return allocated_used_words(mdtype) * BytesPerWord;
@ -300,31 +292,22 @@ class MetaspaceAux : AllStatic {
static size_t free_bytes(); static size_t free_bytes();
static size_t free_bytes(Metaspace::MetadataType mdtype); static size_t free_bytes(Metaspace::MetadataType mdtype);
// Total capacity in all Metaspaces static size_t reserved_bytes(Metaspace::MetadataType mdtype);
static size_t capacity_bytes_slow() { static size_t reserved_bytes() {
#ifdef PRODUCT return reserved_bytes(Metaspace::ClassType) +
// Use allocated_capacity_bytes() in PRODUCT instead of this function. reserved_bytes(Metaspace::NonClassType);
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;
} }
// Total space reserved in all Metaspaces static size_t committed_bytes(Metaspace::MetadataType mdtype);
static size_t reserved_in_bytes() { static size_t committed_bytes() {
return reserved_in_bytes(Metaspace::ClassType) + return committed_bytes(Metaspace::ClassType) +
reserved_in_bytes(Metaspace::NonClassType); 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. // Print change in used metadata.
static void print_metaspace_change(size_t prev_metadata_used); static void print_metaspace_change(size_t prev_metadata_used);

View file

@ -65,26 +65,25 @@ class MetaspacePerfCounters: public CHeapObj<mtInternal> {
MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL; MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
size_t MetaspaceCounters::calculate_capacity() { size_t MetaspaceCounters::used() {
// The total capacity is the sum of return MetaspaceAux::allocated_used_bytes();
// 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 MetaspaceCounters::capacity() {
size_t total_capacity = MetaspaceAux::allocated_capacity_bytes() return MetaspaceAux::committed_bytes();
+ MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_in_bytes(); }
return total_capacity;
size_t MetaspaceCounters::max_capacity() {
return MetaspaceAux::reserved_bytes();
} }
void MetaspaceCounters::initialize_performance_counters() { void MetaspaceCounters::initialize_performance_counters() {
if (UsePerfData) { if (UsePerfData) {
assert(_perf_counters == NULL, "Should only be initialized once"); assert(_perf_counters == NULL, "Should only be initialized once");
size_t min_capacity = MetaspaceAux::min_chunk_size(); size_t min_capacity = 0;
size_t capacity = calculate_capacity(); _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity,
size_t max_capacity = MetaspaceAux::reserved_in_bytes(); capacity(), max_capacity(), used());
size_t used = MetaspaceAux::allocated_used_bytes();
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
} }
} }
@ -92,31 +91,29 @@ void MetaspaceCounters::update_performance_counters() {
if (UsePerfData) { if (UsePerfData) {
assert(_perf_counters != NULL, "Should be initialized"); assert(_perf_counters != NULL, "Should be initialized");
size_t capacity = calculate_capacity(); _perf_counters->update(capacity(), max_capacity(), used());
size_t max_capacity = MetaspaceAux::reserved_in_bytes();
size_t used = MetaspaceAux::allocated_used_bytes();
_perf_counters->update(capacity, max_capacity, used);
} }
} }
MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL; MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
size_t CompressedClassSpaceCounters::calculate_capacity() { size_t CompressedClassSpaceCounters::used() {
return MetaspaceAux::allocated_capacity_bytes(_class_type) + return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType);
MetaspaceAux::free_bytes(_class_type) + }
MetaspaceAux::free_chunks_total_in_bytes(_class_type);
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() { void CompressedClassSpaceCounters::update_performance_counters() {
if (UsePerfData && UseCompressedKlassPointers) { if (UsePerfData && UseCompressedClassPointers) {
assert(_perf_counters != NULL, "Should be initialized"); assert(_perf_counters != NULL, "Should be initialized");
size_t capacity = calculate_capacity(); _perf_counters->update(capacity(), max_capacity(), used());
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);
} }
} }
@ -125,13 +122,10 @@ void CompressedClassSpaceCounters::initialize_performance_counters() {
assert(_perf_counters == NULL, "Should only be initialized once"); assert(_perf_counters == NULL, "Should only be initialized once");
const char* ns = "compressedclassspace"; const char* ns = "compressedclassspace";
if (UseCompressedKlassPointers) { if (UseCompressedClassPointers) {
size_t min_capacity = MetaspaceAux::min_chunk_size(); size_t min_capacity = 0;
size_t capacity = calculate_capacity(); _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(),
size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type); max_capacity(), used());
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
} else { } else {
_perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0); _perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
} }

View file

@ -25,13 +25,15 @@
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP #ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP #define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
#include "memory/metaspace.hpp" #include "memory/allocation.hpp"
class MetaspacePerfCounters; class MetaspacePerfCounters;
class MetaspaceCounters: public AllStatic { class MetaspaceCounters: public AllStatic {
static MetaspacePerfCounters* _perf_counters; static MetaspacePerfCounters* _perf_counters;
static size_t calculate_capacity(); static size_t used();
static size_t capacity();
static size_t max_capacity();
public: public:
static void initialize_performance_counters(); static void initialize_performance_counters();
@ -40,8 +42,9 @@ class MetaspaceCounters: public AllStatic {
class CompressedClassSpaceCounters: public AllStatic { class CompressedClassSpaceCounters: public AllStatic {
static MetaspacePerfCounters* _perf_counters; static MetaspacePerfCounters* _perf_counters;
static size_t calculate_capacity(); static size_t used();
static const Metaspace::MetadataType _class_type = Metaspace::ClassType; static size_t capacity();
static size_t max_capacity();
public: public:
static void initialize_performance_counters(); static void initialize_performance_counters();

View file

@ -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() { void* Universe::non_oop_word() {
// Neither the high bits nor the low bits of this value is allowed // 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) // Using the OS-supplied non-memory-address word (usually 0 or -1)
// will take care of the high bits, however many there are. // will take care of the high bits, however many there are.
if (non_oop_bits == 0) { if (_non_oop_bits == 0) {
non_oop_bits = (intptr_t)os::non_memory_address_word() | 1; _non_oop_bits = (intptr_t)os::non_memory_address_word() | 1;
} }
return (void*)non_oop_bits; return (void*)_non_oop_bits;
} }
jint universe_init() { jint universe_init() {
@ -872,13 +872,16 @@ jint Universe::initialize_heap() {
// Reserve the Java heap, which is now the same for all GCs. // Reserve the Java heap, which is now the same for all GCs.
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) { 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); size_t total_reserved = align_size_up(heap_size, alignment);
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())), assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
"heap size is too big for compressed oops"); "heap size is too big for compressed oops");
bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size()); bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size());
assert(!UseLargePages assert(!UseLargePages
|| UseParallelOldGC || UseParallelGC
|| use_large_pages, "Wrong alignment to use large pages"); || use_large_pages, "Wrong alignment to use large pages");
char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop); 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); msg = java_lang_String::create_from_str("Metadata space", CHECK_false);
java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg()); 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()); 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); msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false);

View file

@ -179,9 +179,11 @@ class Universe: AllStatic {
// The particular choice of collected heap. // The particular choice of collected heap.
static CollectedHeap* _collectedHeap; static CollectedHeap* _collectedHeap;
static intptr_t _non_oop_bits;
// For UseCompressedOops. // For UseCompressedOops.
static struct NarrowPtrStruct _narrow_oop; static struct NarrowPtrStruct _narrow_oop;
// For UseCompressedKlassPointers. // For UseCompressedClassPointers.
static struct NarrowPtrStruct _narrow_klass; static struct NarrowPtrStruct _narrow_klass;
static address _narrow_ptrs_base; static address _narrow_ptrs_base;
@ -229,7 +231,7 @@ class Universe: AllStatic {
_narrow_oop._base = base; _narrow_oop._base = base;
} }
static void set_narrow_klass_base(address 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; _narrow_klass._base = base;
} }
static void set_narrow_oop_use_implicit_null_checks(bool use) { 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 int narrow_oop_shift() { return _narrow_oop._shift; }
static bool narrow_oop_use_implicit_null_checks() { return _narrow_oop._use_implicit_null_checks; } 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 address narrow_klass_base() { return _narrow_klass._base; }
static bool is_narrow_klass_base(void* addr) { return (narrow_klass_base() == (address)addr); } static bool is_narrow_klass_base(void* addr) { return (narrow_klass_base() == (address)addr); }
static int narrow_klass_shift() { return _narrow_klass._shift; } static int narrow_klass_shift() { return _narrow_klass._shift; }

View file

@ -65,7 +65,7 @@ class arrayOopDesc : public oopDesc {
// declared nonstatic fields in arrayOopDesc if not compressed, otherwise // declared nonstatic fields in arrayOopDesc if not compressed, otherwise
// it occupies the second half of the _klass field in oopDesc. // it occupies the second half of the _klass field in oopDesc.
static int length_offset_in_bytes() { static int length_offset_in_bytes() {
return UseCompressedKlassPointers ? klass_gap_offset_in_bytes() : return UseCompressedClassPointers ? klass_gap_offset_in_bytes() :
sizeof(arrayOopDesc); sizeof(arrayOopDesc);
} }

View file

@ -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, Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool,
int which) { int which) {
if (cpool->cache() == NULL) return NULL; // nothing to load yet if (cpool->cache() == NULL) return NULL; // nothing to load yet

View file

@ -729,8 +729,6 @@ class ConstantPool : public Metadata {
static oop method_type_at_if_loaded (constantPoolHandle this_oop, int which); 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_at_if_loaded (constantPoolHandle this_oop, int which);
static Klass* klass_ref_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 // 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 // future by other Java code. These take constant pool indices rather than

View file

@ -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)); 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, methodHandle method,
int vtable_index) { 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->interpreter_entry() != NULL, "should have been set at this point");
assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); 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: // ...and fall through as if we were handling invokevirtual:
case Bytecodes::_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_f2_as_vfinal_method checks if is_vfinal flag is true.
set_method_flags(as_TosState(method->result_type()), set_method_flags(as_TosState(method->result_type()),
( 1 << is_vfinal_shift) | ( 1 << is_vfinal_shift) |
@ -169,6 +171,7 @@ void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
method()->size_of_parameters()); method()->size_of_parameters());
set_f2_as_vfinal_method(method()); set_f2_as_vfinal_method(method());
} else { } else {
assert(!method->can_be_statically_bound(), "");
assert(vtable_index >= 0, "valid index"); assert(vtable_index >= 0, "valid index");
assert(!method->is_final_method(), "sanity"); assert(!method->is_final_method(), "sanity");
set_method_flags(as_TosState(method->result_type()), 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::_invokespecial:
case Bytecodes::_invokestatic: case Bytecodes::_invokestatic:
assert(!is_vtable_call, "");
// Note: Read and preserve the value of the is_vfinal flag on any // Note: Read and preserve the value of the is_vfinal flag on any
// invokevirtual bytecode shared with this constant pool cache entry. // invokevirtual bytecode shared with this constant pool cache entry.
// It is cheap and safe to consult is_vfinal() at all times. // 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)); 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(); InstanceKlass* interf = method->method_holder();
assert(interf->is_interface(), "must be an interface"); assert(interf->is_interface(), "must be an interface");
assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");

View file

@ -219,15 +219,29 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
Klass* root_klass // needed by the GC to dirty the klass 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 Bytecodes::Code invoke_code, // the bytecode used for invoking the method
methodHandle method, // the method/prototype if any (NULL, otherwise) methodHandle method, // the method/prototype if any (NULL, otherwise)
int vtable_index // the vtable index if any, else negative int vtable_index // the vtable index if any, else negative
); );
void set_interface_call( public:
methodHandle method, // Resolved method void set_direct_call( // sets entry to exact concrete method entry
int index // Method index into interface 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( void set_method_handle(

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@
#include "oops/instanceKlass.hpp" #include "oops/instanceKlass.hpp"
#include "oops/fieldInfo.hpp" #include "oops/fieldInfo.hpp"
#include "runtime/fieldDescriptor.hpp"
// The is the base class for iteration over the fields array // The is the base class for iteration over the fields array
// describing the declared fields in the class. Several subclasses // describing the declared fields in the class. Several subclasses
@ -43,8 +44,10 @@ class FieldStreamBase : public StackObj {
int _index; int _index;
int _limit; int _limit;
int _generic_signature_slot; int _generic_signature_slot;
fieldDescriptor _fd_buf;
FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); } 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 init_generic_signature_start_slot() {
int length = _fields->length(); int length = _fields->length();
@ -102,6 +105,7 @@ class FieldStreamBase : public StackObj {
_index = 0; _index = 0;
_limit = klass->java_fields_count(); _limit = klass->java_fields_count();
init_generic_signature_start_slot(); init_generic_signature_start_slot();
assert(klass == field_holder(), "");
} }
FieldStreamBase(instanceKlassHandle klass) { FieldStreamBase(instanceKlassHandle klass) {
_fields = klass->fields(); _fields = klass->fields();
@ -109,6 +113,7 @@ class FieldStreamBase : public StackObj {
_index = 0; _index = 0;
_limit = klass->java_fields_count(); _limit = klass->java_fields_count();
init_generic_signature_start_slot(); init_generic_signature_start_slot();
assert(klass == field_holder(), "");
} }
// accessors // accessors
@ -180,6 +185,12 @@ class FieldStreamBase : public StackObj {
return field()->contended_group(); 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 // Iterate over only the internal fields

View file

@ -286,7 +286,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
init_previous_versions(); init_previous_versions();
set_generic_signature_index(0); set_generic_signature_index(0);
release_set_methods_jmethod_ids(NULL); release_set_methods_jmethod_ids(NULL);
release_set_methods_cached_itable_indices(NULL);
set_annotations(NULL); set_annotations(NULL);
set_jvmti_cached_class_field_map(NULL); set_jvmti_cached_class_field_map(NULL);
set_initial_method_idnum(0); 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_name = fs.name();
Symbol* f_sig = fs.signature(); Symbol* f_sig = fs.signature();
if (f_name == name && f_sig == sig) { 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; 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 { bool InstanceKlass::find_local_field_from_offset(int offset, bool is_static, fieldDescriptor* fd) const {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) { for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
if (fs.offset() == offset) { 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; 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) { void InstanceKlass::do_local_static_fields(FieldClosure* cl) {
for (JavaFieldStream fs(this); !fs.done(); fs.next()) { for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) { if (fs.access_flags().is_static()) {
fieldDescriptor fd; fieldDescriptor& fd = fs.field_descriptor();
fd.initialize(this, fs.index());
cl->do_field(&fd); 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) { 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()) { for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) { if (fs.access_flags().is_static()) {
fieldDescriptor fd; fieldDescriptor& fd = fs.field_descriptor();
fd.initialize(this_oop(), fs.index());
f(&fd, CHECK); 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* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
int j = 0; int j = 0;
for (int i = 0; i < length; i += 1) { for (int i = 0; i < length; i += 1) {
fd.initialize(this, i); fd.reinitialize(this, i);
if (!fd.is_static()) { if (!fd.is_static()) {
fields_sorted[j + 0] = fd.offset(); fields_sorted[j + 0] = fd.offset();
fields_sorted[j + 1] = i; fields_sorted[j + 1] = i;
@ -1303,7 +1300,7 @@ void InstanceKlass::do_nonstatic_fields(FieldClosure* cl) {
// _sort_Fn is defined in growableArray.hpp. // _sort_Fn is defined in growableArray.hpp.
qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset); qsort(fields_sorted, length/2, 2*sizeof(int), (_sort_Fn)compare_fields_by_offset);
for (int i = 0; i < length; i += 2) { 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"); assert(!fd.is_static() && fd.offset() == fields_sorted[i], "only nonstatic fields");
cl->do_field(&fd); 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 // Walk the list of dependent nmethods searching for nmethods which
// are dependent on the changes that were passed in and mark them for // 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 // release dependencies
nmethodBucket* b = _dependencies; nmethodBucket* b = _dependencies;
_dependencies = NULL; _dependencies = NULL;
@ -2782,6 +2692,18 @@ static const char* state_names[] = {
"allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" "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 { void InstanceKlass::print_on(outputStream* st) const {
assert(is_klass(), "must be klass"); assert(is_klass(), "must be klass");
Klass::print_on(st); 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"arrays: "); array_klasses()->print_value_on_maybe_null(st); st->cr();
st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr(); st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr();
if (Verbose) { if (Verbose || WizardMode) {
Array<Method*>* method_array = methods(); Array<Method*>* method_array = methods();
for(int i = 0; i < method_array->length(); i++) { for(int i = 0; i < method_array->length(); i++) {
st->print("%d : ", i); method_array->at(i)->print_value(); st->cr(); 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"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"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(); 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(); 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()); st->print_cr(BULLET"---- static fields (%d words):", static_field_size());
FieldPrinter print_static_field(st); FieldPrinter print_static_field(st);
((InstanceKlass*)this)->do_local_static_fields(&print_static_field); ((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 { void InstanceKlass::print_value_on(outputStream* st) const {
assert(is_klass(), "must be klass"); assert(is_klass(), "must be klass");
if (Verbose || WizardMode) access_flags().print_on(st);
name()->print_value_on(st); name()->print_value_on(st);
} }

View file

@ -245,7 +245,6 @@ class InstanceKlass: public Klass {
MemberNameTable* _member_names; // Member names MemberNameTable* _member_names; // Member names
JNIid* _jni_ids; // First JNI identifier for static fields in this class 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 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 nmethodBucket* _dependencies; // list of dependent nmethods
nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class nmethod* _osr_nmethods_head; // Head of list of on-stack replacement nmethods for this class
BreakpointInfo* _breakpoints; // bpt lists, managed by Method* BreakpointInfo* _breakpoints; // bpt lists, managed by Method*
@ -690,10 +689,6 @@ class InstanceKlass: public Klass {
size_t *length_p, jmethodID* id_p); size_t *length_p, jmethodID* id_p);
jmethodID jmethod_id_or_null(Method* method); 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 support
Annotations* annotations() const { return _annotations; } Annotations* annotations() const { return _annotations; }
void set_annotations(Annotations* anno) { _annotations = anno; } void set_annotations(Annotations* anno) { _annotations = anno; }
@ -994,11 +989,6 @@ private:
void release_set_methods_jmethod_ids(jmethodID* jmeths) void release_set_methods_jmethod_ids(jmethodID* jmeths)
{ OrderAccess::release_store_ptr(&_methods_jmethod_ids, 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 // Lock during initialization
public: public:
// Lock for (1) initialization; (2) access to the ConstantPool of this class. // Lock for (1) initialization; (2) access to the ConstantPool of this class.

View file

@ -37,9 +37,9 @@ class instanceOopDesc : public oopDesc {
// If compressed, the offset of the fields of the instance may not be aligned. // If compressed, the offset of the fields of the instance may not be aligned.
static int base_offset_in_bytes() { static int base_offset_in_bytes() {
// offset computation code breaks if UseCompressedKlassPointers // offset computation code breaks if UseCompressedClassPointers
// only is true // only is true
return (UseCompressedOops && UseCompressedKlassPointers) ? return (UseCompressedOops && UseCompressedClassPointers) ?
klass_gap_offset_in_bytes() : klass_gap_offset_in_bytes() :
sizeof(instanceOopDesc); sizeof(instanceOopDesc);
} }

View file

@ -674,13 +674,23 @@ void Klass::oop_verify_on(oop obj, outputStream* st) {
#ifndef PRODUCT #ifndef PRODUCT
void Klass::verify_vtable_index(int i) { bool Klass::verify_vtable_index(int i) {
if (oop_is_instance()) { 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 { } else {
assert(oop_is_array(), "Must be"); 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 #endif

View file

@ -699,7 +699,8 @@ class Klass : public Metadata {
void verify(bool check_dictionary = true) { verify_on(tty, check_dictionary); } void verify(bool check_dictionary = true) { verify_on(tty, check_dictionary); }
#ifndef PRODUCT #ifndef PRODUCT
void verify_vtable_index(int index); bool verify_vtable_index(int index);
bool verify_itable_index(int index);
#endif #endif
virtual void oop_verify_on(oop obj, outputStream* st); virtual void oop_verify_on(oop obj, outputStream* st);

View file

@ -47,11 +47,12 @@ inline InstanceKlass* klassVtable::ik() const {
// this function computes the vtable size (including the size needed for miranda // 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 // 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 // interface I, and none of C's superclasses implements I.
// of its super classes implement (i.e there is no method of any access, with // Let's say there is an abstract method m in I that neither C
// the same name and signature as m), then m is a Miranda method which is // 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 // 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. // treated as any other public method in C for method over-ride purposes.
void klassVtable::compute_vtable_size_and_num_mirandas( 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 { 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(); 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) { int klassVtable::initialize_from_super(KlassHandle super) {
if (super.is_null()) { if (super.is_null()) {
return 0; 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) { void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
// Note: Arrays can have intermediate array supers. Use java_super to skip them. // Note: Arrays can have intermediate array supers. Use java_super to skip them.
KlassHandle super (THREAD, klass()->java_super()); KlassHandle super (THREAD, klass()->java_super());
int nofNewEntries = 0; int nofNewEntries = 0;
if (PrintVtables && !klass()->oop_is_array()) { if (PrintVtables && !klass()->oop_is_array()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); 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 len = methods->length();
int initialized = super_vtable_len; 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++) { for (int i = 0; i < len; i++) {
// update_inherited_vtable can stop for gc - ensure using handles
HandleMark hm(THREAD); HandleMark hm(THREAD);
assert(methods->at(i)->is_method(), "must be a Method*"); assert(methods->at(i)->is_method(), "must be a Method*");
methodHandle mh(THREAD, methods->at(i)); 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 // add miranda methods to end of vtable.
fill_in_mirandas(&initialized); initialized = fill_in_mirandas(initialized);
// In class hierarchies where the accessibility is not increasing (i.e., going from private -> // 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. // calculation.
assert(initialized <= _length, "vtable initialization failed"); assert(initialized <= _length, "vtable initialization failed");
for(;initialized < _length; initialized++) { for(;initialized < _length; initialized++) {
@ -248,14 +254,8 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
return superk; 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 // 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 // Only called for InstanceKlass's, i.e. not for arrays
// If that changed, could not use _klass as handle for klass // 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, 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; ResourceMark rm;
bool allocate_new = true; bool allocate_new = true;
assert(klass->oop_is_instance(), "must be InstanceKlass"); assert(klass->oop_is_instance(), "must be InstanceKlass");
assert(klass == target_method()->method_holder(), "caller resp.");
// Initialize the method's vtable index to "nonvirtual". // Initialize the method's vtable index to "nonvirtual".
// If we allocate a vtable entry, we will update it to a non-negative number. // 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; 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 // 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 // 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 // a super's method, in which case they re-use its entry
allocate_new = false; 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 // 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, Symbol* classname,
AccessFlags class_flags, AccessFlags class_flags,
TRAPS) { 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 // 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 // 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 // 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; 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) { bool klassVtable::is_miranda_entry_at(int i) {
Method* m = method_at(i); Method* m = method_at(i);
Klass* method_holder = m->method_holder(); Klass* method_holder = m->method_holder();
@ -516,7 +530,9 @@ bool klassVtable::is_miranda_entry_at(int i) {
return false; 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 // 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) { bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
if (m->is_static()) { if (m->is_static()) {
@ -541,6 +557,14 @@ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* su
return false; 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( void klassVtable::add_new_mirandas_to_lists(
GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas, GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas,
Array<Method*>* current_interface_methods, Array<Method*>* class_methods, Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
@ -599,17 +623,22 @@ void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas,
} }
} }
// fill in mirandas // Discover miranda methods ("miranda" = "interface abstract, no binding"),
void klassVtable::fill_in_mirandas(int* initialized) { // 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); GrowableArray<Method*> mirandas(20);
get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
ik()->local_interfaces()); ik()->local_interfaces());
for (int i = 0; i < mirandas.length(); i++) { for (int i = 0; i < mirandas.length(); i++) {
put_method_at(mirandas.at(i), *initialized); put_method_at(mirandas.at(i), initialized);
++(*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) { void klassVtable::copy_vtable_to(vtableEntry* start) {
Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size());
} }
@ -723,6 +752,12 @@ static int initialize_count = 0;
// Initialization // Initialization
void klassItable::initialize_itable(bool checkconstraints, TRAPS) { 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 // Cannot be setup doing bootstrapping, interfaces don't have
// itables, and klass with only ones entry have empty itables // itables, and klass with only ones entry have empty itables
if (Universe::is_bootstrapping() || 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) { void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) {
Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods(); Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods();
int nof_methods = methods->length(); int nof_methods = methods->length();
HandleMark hm; HandleMark hm;
KlassHandle klass = _klass;
assert(nof_methods > 0, "at least one method must exist for interface to be in vtable"); 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()); Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader());
int ime_num = 0;
// Skip first Method* if it is a class initializer int ime_count = method_count_for_interface(interf_h());
int i = methods->at(0)->is_static_initializer() ? 1 : 0; for (int i = 0; i < nof_methods; i++) {
// 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++) {
Method* m = methods->at(i); Method* m = methods->at(i);
Symbol* method_name = m->name(); methodHandle target;
Symbol* method_signature = m->signature(); if (m->has_itable_index()) {
LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK);
// 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);
} }
if (target == NULL || !target->is_public() || target->is_abstract()) { if (target == NULL || !target->is_public() || target->is_abstract()) {
// Entry do not resolve. Leave it empty // Entry do not resolve. Leave it empty
} else { } else {
// Entry did resolve, check loader constraints before initializing // Entry did resolve, check loader constraints before initializing
// if checkconstraints requested // if checkconstraints requested
methodHandle target_h (THREAD, target); // preserve across gc
if (checkconstraints) { if (checkconstraints) {
Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
if (method_holder_loader() != interface_loader()) { if (method_holder_loader() != interface_loader()) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
Symbol* failed_type_symbol = Symbol* failed_type_symbol =
SystemDictionary::check_signature_loaders(method_signature, SystemDictionary::check_signature_loaders(m->signature(),
method_holder_loader, method_holder_loader,
interface_loader, interface_loader,
true, CHECK); 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 " "and the class loader (instance of %s) for interface "
"%s have different Class objects for the type %s " "%s have different Class objects for the type %s "
"used in the signature"; "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()); 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()); const char* loader2 = SystemDictionary::loader_name(interface_loader());
char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string(); char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string();
char* failed_type_name = failed_type_symbol->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 // 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; 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) { void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosure *blk) {
// Handle array argument // Handle array argument
for(int i = 0; i < transitive_intf->length(); i++) { for(int i = 0; i < transitive_intf->length(); i++) {
Klass* intf = transitive_intf->at(i); Klass* intf = transitive_intf->at(i);
assert(intf->is_interface(), "sanity check"); assert(intf->is_interface(), "sanity check");
// Find no. of methods excluding a <clinit> // Find no. of itable methods
int method_count = InstanceKlass::cast(intf)->methods()->length(); int method_count = 0;
if (method_count > 0) { // method_count = klassItable::method_count_for_interface(intf);
Method* m = InstanceKlass::cast(intf)->methods()->at(0); Array<Method*>* methods = InstanceKlass::cast(intf)->methods();
assert(m != NULL && m->is_method(), "sanity check"); if (methods->length() > 0) {
if (m->name() == vmSymbols::object_initializer_name()) { for (int i = methods->length(); --i >= 0; ) {
method_count--; 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 // inverse to itable_index
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
Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) { Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) {
assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); assert(InstanceKlass::cast(intf)->is_interface(), "sanity check");
assert(intf->verify_itable_index(itable_index), "");
Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); Array<Method*>* methods = InstanceKlass::cast(intf)->methods();
int index = itable_index; if (itable_index < 0 || itable_index >= method_count_for_interface(intf))
// 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())
return NULL; // help caller defend against bad indexes return NULL; // help caller defend against bad indexes
int index = itable_index;
Method* m = methods->at(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; return m;
} }

View file

@ -124,7 +124,7 @@ class klassVtable : public ResourceObj {
// support for miranda methods // support for miranda methods
bool is_miranda_entry_at(int i); 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 bool is_miranda(Method* m, Array<Method*>* class_methods, Klass* super);
static void add_new_mirandas_to_lists( static void add_new_mirandas_to_lists(
GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* new_mirandas,
@ -150,6 +150,8 @@ class klassVtable : public ResourceObj {
// from_compiled_code_entry_point -> nmethod entry point // from_compiled_code_entry_point -> nmethod entry point
// from_interpreter_entry_point -> i2cadapter // from_interpreter_entry_point -> i2cadapter
class vtableEntry VALUE_OBJ_CLASS_SPEC { class vtableEntry VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
public: public:
// size in words // size in words
static int size() { static int size() {
@ -288,12 +290,12 @@ class klassItable : public ResourceObj {
#endif // INCLUDE_JVMTI #endif // INCLUDE_JVMTI
// Setup of itable // 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 int compute_itable_size(Array<Klass*>* transitive_interfaces);
static void setup_itable_offset_table(instanceKlassHandle klass); static void setup_itable_offset_table(instanceKlassHandle klass);
// Resolving of method to index // 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); static Method* method_for_itable_index(Klass* klass, int itable_index);
// Debugging/Statistics // Debugging/Statistics

Some files were not shown because too many files have changed in this diff Show more