diff --git a/.hgtags b/.hgtags
index d063220672f..b6f1545f2b7 100644
--- a/.hgtags
+++ b/.hgtags
@@ -225,3 +225,5 @@ ea73f01b9053e7165e7ba80f242bafecbc6af712 jdk8-b96
edb01c460d4cab21ff0ff13512df7b746efaa0e7 jdk8-b101
bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102
30a1d677a20c6a95f98043d8f20ce570304e3818 jdk8-b103
+b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104
+589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 456aa0fa60e..505ac39fd54 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -225,3 +225,5 @@ d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100
9f74a220677dc265a724515d8e2617548cef62f1 jdk8-b101
5eb3c1dc348f72a7f84f7d9d07834e8bbe09a799 jdk8-b102
b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
+96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
+5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105
diff --git a/NewMakefile.gmk b/NewMakefile.gmk
index 101ebe06278..e15330f5d6b 100644
--- a/NewMakefile.gmk
+++ b/NewMakefile.gmk
@@ -69,11 +69,11 @@ else
# Run the makefile with an arbitraty SPEC using -p -q (quiet dry-run and dump rules) to find
# available PHONY targets. Use this list as valid targets to pass on to the repeated calls.
all_phony_targets=$(filter-out $(global_targets) bundles-only, $(strip $(shell \
- $(MAKE) -p -q -f common/makefiles/Main.gmk SPEC=$(firstword $(SPEC)) | \
+ $(MAKE) -p -q -f common/makefiles/Main.gmk FRC SPEC=$(firstword $(SPEC)) | \
grep ^.PHONY: | head -n 1 | cut -d " " -f 2-)))
$(all_phony_targets):
- $(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) \
+ @$(foreach spec,$(SPEC),($(MAKE) -f NewMakefile.gmk SPEC=$(spec) \
$(VERBOSE) VERBOSE=$(VERBOSE) LOG_LEVEL=$(LOG_LEVEL) $@) &&) true
.PHONY: $(all_phony_targets)
@@ -98,6 +98,7 @@ help:
$(info . # corba and jdk)
$(info . make all # Compile everything, all repos and images)
$(info . make images # Create complete j2sdk and j2re images)
+ $(info . make docs # Create javadocs)
$(info . make overlay-images # Create limited images for sparc 64 bit platforms)
$(info . make profiles # Create complete j2re compact profile images)
$(info . make bootcycle-images # Build images twice, second time with newly build JDK)
@@ -109,7 +110,7 @@ help:
$(info . make test # Run tests, default is all tests (see TEST below))
$(info )
$(info Targets for specific components)
- $(info (Component is any of langtools, corba, jaxp, jaxws, hotspot, jdk, images or overlay-images))
+ $(info (Component is any of langtools, corba, jaxp, jaxws, hotspot, jdk, nashorn, images, overlay-images, docs or test))
$(info . make # Build and everything it depends on. )
$(info . make -only # Build only, without dependencies. This)
$(info . # is faster but can result in incorrect build results!)
diff --git a/README-builds.html b/README-builds.html
index 5573c8cd2f1..71c05c0fbf4 100644
--- a/README-builds.html
+++ b/README-builds.html
@@ -154,7 +154,7 @@
Once you have all the repositories, keep in mind that each
- repository is it's own independent repository.
+ repository is its own independent repository.
You can also re-run ./get_source.sh anytime to
pull over all the latest changesets in all the repositories.
This set of nested repositories has been given the term
@@ -241,6 +241,14 @@
source code for the OpenJDK Corba functionality
+
+
+ nashorn
+
+
+ source code for the OpenJDK JavaScript implementation
+
+
@@ -386,7 +394,7 @@
--with-boot-jdk.
- Insure that GNU make, the Bootstrap JDK,
+ Ensure that GNU make, the Bootstrap JDK,
and the compilers are all
in your PATH environment variable
@@ -1202,19 +1210,18 @@
- Q: The configure file looks horrible!
+ Q: The generated-configure.sh file looks horrible!
How are you going to edit it?
- A: The configure file is generated (think
+ A: The generated-configure.sh file is generated (think
"compiled") by the autoconf tools. The source code is
- in configure.ac various .m4 files in common/autoconf,
- which are
- much more readable.
+ in configure.ac and various .m4 files in common/autoconf,
+ which are much more readable.
Q:
- Why is the configure file checked in,
+ Why is the generated-configure.sh file checked in,
if it is generated?
A:
@@ -1229,13 +1236,29 @@
Q:
Do you require a specific version of autoconf for regenerating
- configure?
+ generated-configure.sh?
A:
- Currently, no, but this will likely be the case when things have
- settled down a bit more. (The reason for this is to avoid
- large spurious changes in configure
- in commits that made small changes to configure.ac).
+ Yes, version 2.69 is required and should be easy
+ enough to aquire on all supported operating
+ systems. The reason for this is to avoid
+ large spurious changes in generated-configure.sh.
+
+
+
+ Q:
+ How do you regenerate generated-configure.sh
+ after making changes to the input files?
+
+ A:
+ Regnerating generated-configure.sh
+ should always be done using the
+ script common/autoconf/autogen.sh to
+ ensure that the correct files get updated. This
+ script should also be run after mercurial tries to
+ merge generated-configure.sh as a
+ merge of the generated file is not guaranteed to
+ be correct.
@@ -1307,9 +1330,9 @@
you will need to modify the makefiles. But for normal file
additions or removals, no changes are needed. There are certan
exceptions for some native libraries where the source files are spread
- over many directories which also contain courses for other
+ over many directories which also contain sources for other
libraries. In these cases it was simply easier to create include lists
- rather thane excludes.
+ rather than excludes.
@@ -1327,14 +1350,14 @@
Q:
configure provides OpenJDK-specific features such as
- --enable-jigsaw or --with-builddeps-server
- that are not described in this document. What about those?
+ --with-builddeps-server that are not
+ described in this document. What about those?
A:
Try them out if you like! But be aware that most of these are
experimental features.
Many of them don't do anything at all at the moment; the option
- is just a placeholder. Other depends on
+ is just a placeholder. Others depend on
pieces of code or infrastructure that is currently
not ready for prime time.
@@ -1385,24 +1408,6 @@
system and some will need to wait until after.
-
- Q: What is @GenerateNativeHeaders?
-
- A:
- To speed up compilation, we added a flag to javac which makes it
- do the job of javah as well, as a by-product; that is, generating
- native .h header files. These files are only generated
- if a class contains native methods. However, sometimes
- a class contains no native method,
- but still contains constants that native code needs to use.
- The new GenerateNativeHeaders annotation tells javac to
- force generation of a
- header file in these cases. (We don't want to generate
- native headers for all classes that contains constants
- but no native methods, since
- that would slow down the compilation process needlessly.)
-
-
Q:
Is anything able to use the results of the new build's default make target?
@@ -1429,10 +1434,9 @@
What should I do?
A:
- It might very well be that we have missed to add support for
+ It might very well be that we have neglected to add support for
an option that was actually used from outside the build system.
- Email us and we will
- add support for it!
+ Email us and we will add support for it!
diff --git a/common/autoconf/autogen.sh b/common/autoconf/autogen.sh
index 35ed2a5813a..96768aa06e2 100644
--- a/common/autoconf/autogen.sh
+++ b/common/autoconf/autogen.sh
@@ -44,10 +44,8 @@ fi
custom_hook=$custom_script_dir/custom-hook.m4
AUTOCONF="`which autoconf 2> /dev/null | grep -v '^no autoconf in'`"
-AUTOCONF_267="`which autoconf-2.67 2> /dev/null | grep -v '^no autoconf-2.67 in'`"
echo "Autoconf found: ${AUTOCONF}"
-echo "Autoconf-2.67 found: ${AUTOCONF_267}"
if test "x${AUTOCONF}" = x; then
echo You need autoconf installed to be able to regenerate the configure script
@@ -55,10 +53,6 @@ if test "x${AUTOCONF}" = x; then
exit 1
fi
-if test "x${AUTOCONF_267}" != x; then
- AUTOCONF=${AUTOCONF_267};
-fi
-
echo Generating generated-configure.sh with ${AUTOCONF}
cat $script_dir/configure.ac | sed -e "s|@DATE_WHEN_GENERATED@|$TIMESTAMP|" | ${AUTOCONF} -W all -I$script_dir - > $script_dir/generated-configure.sh
rm -rf autom4te.cache
diff --git a/common/autoconf/configure.ac b/common/autoconf/configure.ac
index fcaf12fc422..274f278fb3d 100644
--- a/common/autoconf/configure.ac
+++ b/common/autoconf/configure.ac
@@ -30,7 +30,7 @@
###############################################################################
-AC_PREREQ([2.61])
+AC_PREREQ([2.69])
AC_INIT(OpenJDK, jdk8, build-dev@openjdk.java.net,,http://openjdk.java.net)
AC_CONFIG_AUX_DIR([build-aux])
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 0e4c4d9194c..63e9354611c 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for OpenJDK jdk8.
+# Generated by GNU Autoconf 2.69 for OpenJDK jdk8.
#
# Report bugs to .
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -91,6 +89,7 @@ fi
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -135,6 +134,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -168,7 +192,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -213,14 +238,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -323,6 +359,14 @@ $as_echo X"$as_dir" |
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -444,6 +488,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -478,16 +526,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -499,28 +547,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -1462,7 +1490,7 @@ Try \`$0 --help' for more information"
$as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
$as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
esac
@@ -1513,8 +1541,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1898,9 +1924,9 @@ test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
OpenJDK configure jdk8
-generated by GNU Autoconf 2.67
+generated by GNU Autoconf 2.69
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1944,7 +1970,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_try_compile
@@ -1982,7 +2008,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_compile
@@ -2020,7 +2046,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_objc_try_compile
@@ -2057,7 +2083,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_try_cpp
@@ -2094,7 +2120,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_cpp
@@ -2107,10 +2133,10 @@ fi
ac_fn_cxx_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if eval "test \"\${$3+set}\"" = set; then :
+ if eval \${$3+:} false; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
@@ -2177,7 +2203,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
@@ -2186,7 +2212,7 @@ eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_cxx_check_header_mongrel
@@ -2227,7 +2253,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=$ac_status
fi
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_run
@@ -2241,7 +2267,7 @@ ac_fn_cxx_check_header_compile ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2259,7 +2285,7 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_cxx_check_header_compile
@@ -2280,7 +2306,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2296,7 +2323,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2322,7 +2350,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2338,7 +2367,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2372,7 +2402,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2436,7 +2467,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
rm -f conftest.val
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_compute_int
@@ -2468,7 +2499,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -2482,7 +2513,7 @@ fi
# interfere with the next link command; also delete a directory that is
# left behind by Apple's compiler. We do this before executing the actions.
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_cxx_try_link
@@ -2495,7 +2526,7 @@ ac_fn_cxx_check_func ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2550,7 +2581,7 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_cxx_check_func
@@ -2563,7 +2594,7 @@ ac_fn_c_check_header_compile ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2581,7 +2612,7 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_compile
cat >config.log <<_ACEOF
@@ -2589,7 +2620,7 @@ This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by OpenJDK $as_me jdk8, which was
-generated by GNU Autoconf 2.67. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2847,7 +2878,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;}
|| { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
done
@@ -3433,7 +3464,7 @@ apt_help() {
pulse)
PKGHANDLER_COMMAND="sudo apt-get install libpulse-dev" ;;
x11)
- PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev" ;;
+ PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
ccache)
PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
* )
@@ -3452,11 +3483,11 @@ yum_help() {
cups)
PKGHANDLER_COMMAND="sudo yum install cups-devel" ;;
freetype2)
- PKGHANDLER_COMMAND="sudo yum install freetype2-devel" ;;
+ PKGHANDLER_COMMAND="sudo yum install freetype-devel" ;;
pulse)
PKGHANDLER_COMMAND="sudo yum install pulseaudio-libs-devel" ;;
x11)
- PKGHANDLER_COMMAND="sudo yum install libXtst-devel" ;;
+ PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel" ;;
ccache)
PKGHANDLER_COMMAND="sudo yum install ccache" ;;
* )
@@ -3787,7 +3818,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1376579640
+DATE_WHEN_GENERATED=1377850299
###############################################################################
#
@@ -3825,7 +3856,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BASENAME+set}" = set; then :
+if ${ac_cv_path_BASENAME+:} false; then :
$as_echo_n "(cached) " >&6
else
case $BASENAME in
@@ -3839,7 +3870,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_BASENAME="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3884,7 +3915,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BASH+set}" = set; then :
+if ${ac_cv_path_BASH+:} false; then :
$as_echo_n "(cached) " >&6
else
case $BASH in
@@ -3898,7 +3929,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_BASH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3943,7 +3974,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CAT+set}" = set; then :
+if ${ac_cv_path_CAT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CAT in
@@ -3957,7 +3988,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4002,7 +4033,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHMOD+set}" = set; then :
+if ${ac_cv_path_CHMOD+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CHMOD in
@@ -4016,7 +4047,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CHMOD="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4061,7 +4092,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CMP+set}" = set; then :
+if ${ac_cv_path_CMP+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CMP in
@@ -4075,7 +4106,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CMP="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4120,7 +4151,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_COMM+set}" = set; then :
+if ${ac_cv_path_COMM+:} false; then :
$as_echo_n "(cached) " >&6
else
case $COMM in
@@ -4134,7 +4165,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4179,7 +4210,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CP+set}" = set; then :
+if ${ac_cv_path_CP+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CP in
@@ -4193,7 +4224,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4238,7 +4269,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CPIO+set}" = set; then :
+if ${ac_cv_path_CPIO+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CPIO in
@@ -4252,7 +4283,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CPIO="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4297,7 +4328,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CUT+set}" = set; then :
+if ${ac_cv_path_CUT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CUT in
@@ -4311,7 +4342,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CUT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4356,7 +4387,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DATE+set}" = set; then :
+if ${ac_cv_path_DATE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $DATE in
@@ -4370,7 +4401,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_DATE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4415,7 +4446,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DIFF+set}" = set; then :
+if ${ac_cv_path_DIFF+:} false; then :
$as_echo_n "(cached) " >&6
else
case $DIFF in
@@ -4429,7 +4460,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_DIFF="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4474,7 +4505,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DIRNAME+set}" = set; then :
+if ${ac_cv_path_DIRNAME+:} false; then :
$as_echo_n "(cached) " >&6
else
case $DIRNAME in
@@ -4488,7 +4519,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_DIRNAME="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4533,7 +4564,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ECHO+set}" = set; then :
+if ${ac_cv_path_ECHO+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ECHO in
@@ -4547,7 +4578,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ECHO="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4592,7 +4623,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_EXPR+set}" = set; then :
+if ${ac_cv_path_EXPR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $EXPR in
@@ -4606,7 +4637,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_EXPR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4651,7 +4682,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_FILE+set}" = set; then :
+if ${ac_cv_path_FILE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $FILE in
@@ -4665,7 +4696,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_FILE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4710,7 +4741,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_FIND+set}" = set; then :
+if ${ac_cv_path_FIND+:} false; then :
$as_echo_n "(cached) " >&6
else
case $FIND in
@@ -4724,7 +4755,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4769,7 +4800,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_HEAD+set}" = set; then :
+if ${ac_cv_path_HEAD+:} false; then :
$as_echo_n "(cached) " >&6
else
case $HEAD in
@@ -4783,7 +4814,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_HEAD="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4828,7 +4859,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LN+set}" = set; then :
+if ${ac_cv_path_LN+:} false; then :
$as_echo_n "(cached) " >&6
else
case $LN in
@@ -4842,7 +4873,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_LN="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4887,7 +4918,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LS+set}" = set; then :
+if ${ac_cv_path_LS+:} false; then :
$as_echo_n "(cached) " >&6
else
case $LS in
@@ -4901,7 +4932,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_LS="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4946,7 +4977,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MKDIR+set}" = set; then :
+if ${ac_cv_path_MKDIR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $MKDIR in
@@ -4960,7 +4991,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5005,7 +5036,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MKTEMP+set}" = set; then :
+if ${ac_cv_path_MKTEMP+:} false; then :
$as_echo_n "(cached) " >&6
else
case $MKTEMP in
@@ -5019,7 +5050,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_MKTEMP="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5064,7 +5095,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MV+set}" = set; then :
+if ${ac_cv_path_MV+:} false; then :
$as_echo_n "(cached) " >&6
else
case $MV in
@@ -5078,7 +5109,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5123,7 +5154,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_PRINTF+set}" = set; then :
+if ${ac_cv_path_PRINTF+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PRINTF in
@@ -5137,7 +5168,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PRINTF="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5182,7 +5213,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_RM+set}" = set; then :
+if ${ac_cv_path_RM+:} false; then :
$as_echo_n "(cached) " >&6
else
case $RM in
@@ -5196,7 +5227,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5241,7 +5272,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_SH+set}" = set; then :
+if ${ac_cv_path_SH+:} false; then :
$as_echo_n "(cached) " >&6
else
case $SH in
@@ -5255,7 +5286,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5300,7 +5331,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_SORT+set}" = set; then :
+if ${ac_cv_path_SORT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $SORT in
@@ -5314,7 +5345,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5359,7 +5390,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TAIL+set}" = set; then :
+if ${ac_cv_path_TAIL+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TAIL in
@@ -5373,7 +5404,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TAIL="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5418,7 +5449,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TAR+set}" = set; then :
+if ${ac_cv_path_TAR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TAR in
@@ -5432,7 +5463,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5477,7 +5508,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TEE+set}" = set; then :
+if ${ac_cv_path_TEE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TEE in
@@ -5491,7 +5522,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TEE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5536,7 +5567,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TOUCH+set}" = set; then :
+if ${ac_cv_path_TOUCH+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TOUCH in
@@ -5550,7 +5581,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TOUCH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5595,7 +5626,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TR+set}" = set; then :
+if ${ac_cv_path_TR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TR in
@@ -5609,7 +5640,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5654,7 +5685,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_UNAME+set}" = set; then :
+if ${ac_cv_path_UNAME+:} false; then :
$as_echo_n "(cached) " >&6
else
case $UNAME in
@@ -5668,7 +5699,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_UNAME="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5713,7 +5744,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_UNIQ+set}" = set; then :
+if ${ac_cv_path_UNIQ+:} false; then :
$as_echo_n "(cached) " >&6
else
case $UNIQ in
@@ -5727,7 +5758,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_UNIQ="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5772,7 +5803,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_WC+set}" = set; then :
+if ${ac_cv_path_WC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $WC in
@@ -5786,7 +5817,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_WC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5831,7 +5862,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_WHICH+set}" = set; then :
+if ${ac_cv_path_WHICH+:} false; then :
$as_echo_n "(cached) " >&6
else
case $WHICH in
@@ -5845,7 +5876,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_WHICH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5890,7 +5921,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_XARGS+set}" = set; then :
+if ${ac_cv_path_XARGS+:} false; then :
$as_echo_n "(cached) " >&6
else
case $XARGS in
@@ -5904,7 +5935,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_XARGS="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5950,7 +5981,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AWK"; then
@@ -5962,7 +5993,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6000,7 +6031,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+if ${ac_cv_path_GREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$GREP"; then
@@ -6014,7 +6045,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -6075,7 +6106,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
+if ${ac_cv_path_EGREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -6092,7 +6123,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -6154,7 +6185,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
$as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
+if ${ac_cv_path_FGREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
@@ -6171,7 +6202,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+ as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in
@@ -6233,7 +6264,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
+if ${ac_cv_path_SED+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
@@ -6253,7 +6284,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+ as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in
@@ -6319,7 +6350,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_NAWK+set}" = set; then :
+if ${ac_cv_path_NAWK+:} false; then :
$as_echo_n "(cached) " >&6
else
case $NAWK in
@@ -6333,7 +6364,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_NAWK="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6383,7 +6414,7 @@ THEPWDCMD=pwd
set dummy cygpath; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CYGPATH+set}" = set; then :
+if ${ac_cv_path_CYGPATH+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CYGPATH in
@@ -6397,7 +6428,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CYGPATH="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6423,7 +6454,7 @@ fi
set dummy readlink; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_READLINK+set}" = set; then :
+if ${ac_cv_path_READLINK+:} false; then :
$as_echo_n "(cached) " >&6
else
case $READLINK in
@@ -6437,7 +6468,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_READLINK="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6463,7 +6494,7 @@ fi
set dummy df; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_DF+set}" = set; then :
+if ${ac_cv_path_DF+:} false; then :
$as_echo_n "(cached) " >&6
else
case $DF in
@@ -6477,7 +6508,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_DF="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6503,7 +6534,7 @@ fi
set dummy SetFile; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_SETFILE+set}" = set; then :
+if ${ac_cv_path_SETFILE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $SETFILE in
@@ -6517,7 +6548,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_SETFILE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6549,7 +6580,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
$as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
+if ${ac_cv_build+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_build_alias=$build_alias
@@ -6565,7 +6596,7 @@ fi
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
@@ -6583,7 +6614,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
$as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
+if ${ac_cv_host+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "x$host_alias" = x; then
@@ -6598,7 +6629,7 @@ fi
$as_echo "$ac_cv_host" >&6; }
case $ac_cv_host in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
esac
host=$ac_cv_host
ac_save_IFS=$IFS; IFS='-'
@@ -6616,7 +6647,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
$as_echo_n "checking target system type... " >&6; }
-if test "${ac_cv_target+set}" = set; then :
+if ${ac_cv_target+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "x$target_alias" = x; then
@@ -6631,7 +6662,7 @@ fi
$as_echo "$ac_cv_target" >&6; }
case $ac_cv_target in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
esac
target=$ac_cv_target
ac_save_IFS=$IFS; IFS='-'
@@ -8157,7 +8188,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_PKGHANDLER+set}" = set; then :
+if ${ac_cv_prog_PKGHANDLER+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PKGHANDLER"; then
@@ -8169,7 +8200,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PKGHANDLER="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8522,7 +8553,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_GMAKE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CHECK_GMAKE in
@@ -8536,7 +8567,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CHECK_GMAKE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -8876,7 +8907,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_MAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_MAKE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CHECK_MAKE in
@@ -8890,7 +8921,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CHECK_MAKE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9235,7 +9266,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CHECK_TOOLSDIR_GMAKE in
@@ -9249,7 +9280,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CHECK_TOOLSDIR_GMAKE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9588,7 +9619,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then :
+if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CHECK_TOOLSDIR_MAKE in
@@ -9602,7 +9633,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CHECK_TOOLSDIR_MAKE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9984,7 +10015,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_UNZIP+set}" = set; then :
+if ${ac_cv_path_UNZIP+:} false; then :
$as_echo_n "(cached) " >&6
else
case $UNZIP in
@@ -9998,7 +10029,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_UNZIP="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10043,7 +10074,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ZIP+set}" = set; then :
+if ${ac_cv_path_ZIP+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ZIP in
@@ -10057,7 +10088,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ZIP="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10102,7 +10133,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
set dummy ldd; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LDD+set}" = set; then :
+if ${ac_cv_path_LDD+:} false; then :
$as_echo_n "(cached) " >&6
else
case $LDD in
@@ -10116,7 +10147,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_LDD="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10148,7 +10179,7 @@ fi
set dummy otool; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_OTOOL+set}" = set; then :
+if ${ac_cv_path_OTOOL+:} false; then :
$as_echo_n "(cached) " >&6
else
case $OTOOL in
@@ -10162,7 +10193,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10193,7 +10224,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_READELF+set}" = set; then :
+if ${ac_cv_path_READELF+:} false; then :
$as_echo_n "(cached) " >&6
else
case $READELF in
@@ -10207,7 +10238,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_READELF="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10236,7 +10267,7 @@ done
set dummy hg; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_HG+set}" = set; then :
+if ${ac_cv_path_HG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $HG in
@@ -10250,7 +10281,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_HG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10276,7 +10307,7 @@ fi
set dummy stat; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_STAT+set}" = set; then :
+if ${ac_cv_path_STAT+:} false; then :
$as_echo_n "(cached) " >&6
else
case $STAT in
@@ -10290,7 +10321,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_STAT="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10316,7 +10347,7 @@ fi
set dummy time; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TIME+set}" = set; then :
+if ${ac_cv_path_TIME+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TIME in
@@ -10330,7 +10361,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TIME="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10369,7 +10400,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_COMM+set}" = set; then :
+if ${ac_cv_path_COMM+:} false; then :
$as_echo_n "(cached) " >&6
else
case $COMM in
@@ -10383,7 +10414,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_COMM="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10431,7 +10462,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_XATTR+set}" = set; then :
+if ${ac_cv_path_XATTR+:} false; then :
$as_echo_n "(cached) " >&6
else
case $XATTR in
@@ -10445,7 +10476,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_XATTR="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10487,7 +10518,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
set dummy codesign; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CODESIGN+set}" = set; then :
+if ${ac_cv_path_CODESIGN+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CODESIGN in
@@ -10501,7 +10532,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CODESIGN="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10551,7 +10582,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PKG_CONFIG in
@@ -10565,7 +10596,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10594,7 +10625,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then
set dummy pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_PKG_CONFIG in
@@ -10608,7 +10639,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10767,7 +10798,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then :
+if ${ac_cv_prog_BDEPS_UNZIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$BDEPS_UNZIP"; then
@@ -10779,7 +10810,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_BDEPS_UNZIP="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10813,7 +10844,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then :
+if ${ac_cv_prog_BDEPS_FTP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$BDEPS_FTP"; then
@@ -10825,7 +10856,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_BDEPS_FTP="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12109,7 +12140,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; }
set dummy javac; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then :
+if ${ac_cv_path_JAVAC_CHECK+:} false; then :
$as_echo_n "(cached) " >&6
else
case $JAVAC_CHECK in
@@ -12123,7 +12154,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_JAVAC_CHECK="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12149,7 +12180,7 @@ fi
set dummy java; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_JAVA_CHECK+set}" = set; then :
+if ${ac_cv_path_JAVA_CHECK+:} false; then :
$as_echo_n "(cached) " >&6
else
case $JAVA_CHECK in
@@ -12163,7 +12194,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_JAVA_CHECK="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -16478,7 +16509,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_JTREGEXE+set}" = set; then :
+if ${ac_cv_path_JTREGEXE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $JTREGEXE in
@@ -16492,7 +16523,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_JTREGEXE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -16546,7 +16577,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
set dummy link; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then :
+if ${ac_cv_path_CYGWIN_LINK+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CYGWIN_LINK in
@@ -16560,7 +16591,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CYGWIN_LINK="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -17989,7 +18020,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BUILD_CC+set}" = set; then :
+if ${ac_cv_path_BUILD_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $BUILD_CC in
@@ -18003,7 +18034,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_BUILD_CC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -18300,7 +18331,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BUILD_CXX+set}" = set; then :
+if ${ac_cv_path_BUILD_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
case $BUILD_CXX in
@@ -18314,7 +18345,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_BUILD_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -18609,7 +18640,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;}
set dummy ld; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_BUILD_LD+set}" = set; then :
+if ${ac_cv_path_BUILD_LD+:} false; then :
$as_echo_n "(cached) " >&6
else
case $BUILD_LD in
@@ -18623,7 +18654,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_BUILD_LD="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -19116,7 +19147,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then :
+if ${ac_cv_path_TOOLS_DIR_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TOOLS_DIR_CC in
@@ -19130,7 +19161,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TOOLS_DIR_CC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -19168,7 +19199,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then :
+if ${ac_cv_path_POTENTIAL_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
case $POTENTIAL_CC in
@@ -19182,7 +19213,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_POTENTIAL_CC="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -19581,7 +19612,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; }
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then :
+if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PROPER_COMPILER_CC"; then
@@ -19593,7 +19624,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PROPER_COMPILER_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -19625,7 +19656,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_PROPER_COMPILER_CC"; then
@@ -19637,7 +19668,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_PROPER_COMPILER_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -20075,7 +20106,7 @@ if test -n "$ac_tool_prefix"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
@@ -20087,7 +20118,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -20119,7 +20150,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
@@ -20131,7 +20162,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -20172,7 +20203,7 @@ fi
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -20287,7 +20318,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -20330,7 +20361,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -20389,7 +20420,7 @@ $as_echo "$ac_try_echo"; } >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
@@ -20400,7 +20431,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20441,7 +20472,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -20451,7 +20482,7 @@ OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -20488,7 +20519,7 @@ ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_c_werror_flag=$ac_c_werror_flag
@@ -20566,7 +20597,7 @@ else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_prog_cc_c89=no
@@ -20575,8 +20606,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
-#include
-#include
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -20689,7 +20719,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then :
+if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
case $TOOLS_DIR_CXX in
@@ -20703,7 +20733,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_TOOLS_DIR_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -20741,7 +20771,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then :
+if ${ac_cv_path_POTENTIAL_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
case $POTENTIAL_CXX in
@@ -20755,7 +20785,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_POTENTIAL_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -21154,7 +21184,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; }
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then :
+if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PROPER_COMPILER_CXX"; then
@@ -21166,7 +21196,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PROPER_COMPILER_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -21198,7 +21228,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then :
+if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_PROPER_COMPILER_CXX"; then
@@ -21210,7 +21240,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_PROPER_COMPILER_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -21652,7 +21682,7 @@ if test -z "$CXX"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CXX+set}" = set; then :
+if ${ac_cv_prog_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CXX"; then
@@ -21664,7 +21694,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -21696,7 +21726,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CXX"; then
@@ -21708,7 +21738,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -21774,7 +21804,7 @@ done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -21811,7 +21841,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set}
ac_save_CXXFLAGS=$CXXFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if test "${ac_cv_prog_cxx_g+set}" = set; then :
+if ${ac_cv_prog_cxx_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_cxx_werror_flag=$ac_cxx_werror_flag
@@ -21909,7 +21939,7 @@ if test -n "$ac_tool_prefix"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJC+set}" = set; then :
+if ${ac_cv_prog_OBJC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OBJC"; then
@@ -21921,7 +21951,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -21953,7 +21983,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OBJC"; then
@@ -21965,7 +21995,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -22029,7 +22059,7 @@ done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5
$as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; }
-if test "${ac_cv_objc_compiler_gnu+set}" = set; then :
+if ${ac_cv_objc_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -22066,7 +22096,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set}
ac_save_OBJCFLAGS=$OBJCFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5
$as_echo_n "checking whether $OBJC accepts -g... " >&6; }
-if test "${ac_cv_prog_objc_g+set}" = set; then :
+if ${ac_cv_prog_objc_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_objc_werror_flag=$ac_objc_werror_flag
@@ -22442,7 +22472,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
+if ${ac_cv_prog_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AR"; then
@@ -22454,7 +22484,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -22482,7 +22512,7 @@ if test -z "$ac_cv_prog_AR"; then
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
@@ -22494,7 +22524,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -22824,7 +22854,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then :
set dummy link; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_WINLD+set}" = set; then :
+if ${ac_cv_prog_WINLD+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$WINLD"; then
@@ -22837,7 +22867,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "$CYGWIN_LINK"; then
ac_prog_rejected=yes
continue
@@ -23163,7 +23193,7 @@ $as_echo "yes" >&6; }
set dummy mt; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_MT+set}" = set; then :
+if ${ac_cv_prog_MT+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$MT"; then
@@ -23176,7 +23206,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/bin/mt"; then
ac_prog_rejected=yes
continue
@@ -23484,7 +23514,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;}
set dummy rc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RC+set}" = set; then :
+if ${ac_cv_prog_RC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$RC"; then
@@ -23497,7 +23527,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/bin/rc"; then
ac_prog_rejected=yes
continue
@@ -23876,7 +23906,7 @@ fi
set dummy lib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_WINAR+set}" = set; then :
+if ${ac_cv_prog_WINAR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$WINAR"; then
@@ -23888,7 +23918,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_WINAR="lib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -24182,7 +24212,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;}
set dummy dumpbin; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+if ${ac_cv_prog_DUMPBIN+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$DUMPBIN"; then
@@ -24194,7 +24224,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="dumpbin"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -24501,7 +24531,7 @@ if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
+ if ${ac_cv_prog_CPP+:} false; then :
$as_echo_n "(cached) " >&6
else
# Double quotes because CPP needs to be expanded
@@ -24617,7 +24647,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=cpp
@@ -24901,7 +24931,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then :
+ if ${ac_cv_prog_CXXCPP+:} false; then :
$as_echo_n "(cached) " >&6
else
# Double quotes because CXXCPP needs to be expanded
@@ -25017,7 +25047,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=cpp
@@ -25319,7 +25349,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
set dummy as; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_AS+set}" = set; then :
+if ${ac_cv_path_AS+:} false; then :
$as_echo_n "(cached) " >&6
else
case $AS in
@@ -25333,7 +25363,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_AS="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -25631,7 +25661,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
set dummy nm; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_NM+set}" = set; then :
+if ${ac_cv_path_NM+:} false; then :
$as_echo_n "(cached) " >&6
else
case $NM in
@@ -25645,7 +25675,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_NM="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -25937,7 +25967,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;}
set dummy gnm; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_GNM+set}" = set; then :
+if ${ac_cv_path_GNM+:} false; then :
$as_echo_n "(cached) " >&6
else
case $GNM in
@@ -25951,7 +25981,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_GNM="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -26243,7 +26273,7 @@ $as_echo "$as_me: Rewriting GNM to \"$new_complete\"" >&6;}
set dummy strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_STRIP+set}" = set; then :
+if ${ac_cv_path_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
case $STRIP in
@@ -26257,7 +26287,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -26549,7 +26579,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;}
set dummy mcs; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_MCS+set}" = set; then :
+if ${ac_cv_path_MCS+:} false; then :
$as_echo_n "(cached) " >&6
else
case $MCS in
@@ -26563,7 +26593,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_MCS="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -26857,7 +26887,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then
set dummy ${ac_tool_prefix}nm; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NM+set}" = set; then :
+if ${ac_cv_prog_NM+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$NM"; then
@@ -26869,7 +26899,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NM="${ac_tool_prefix}nm"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -26897,7 +26927,7 @@ if test -z "$ac_cv_prog_NM"; then
set dummy nm; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NM+set}" = set; then :
+if ${ac_cv_prog_ac_ct_NM+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_NM"; then
@@ -26909,7 +26939,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NM="nm"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27217,7 +27247,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;}
set dummy ${ac_tool_prefix}strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$STRIP"; then
@@ -27229,7 +27259,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27257,7 +27287,7 @@ if test -z "$ac_cv_prog_STRIP"; then
set dummy strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_STRIP"; then
@@ -27269,7 +27299,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27582,7 +27612,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux;
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJCOPY+set}" = set; then :
+if ${ac_cv_prog_OBJCOPY+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OBJCOPY"; then
@@ -27594,7 +27624,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJCOPY="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27626,7 +27656,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OBJCOPY"; then
@@ -27638,7 +27668,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJCOPY="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27953,7 +27983,7 @@ if test -n "$ac_tool_prefix"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_OBJDUMP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OBJDUMP"; then
@@ -27965,7 +27995,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -27997,7 +28027,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OBJDUMP"; then
@@ -28009,7 +28039,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -28321,7 +28351,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
set dummy lipo; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_LIPO+set}" = set; then :
+if ${ac_cv_path_LIPO+:} false; then :
$as_echo_n "(cached) " >&6
else
case $LIPO in
@@ -28335,7 +28365,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_LIPO="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -28638,7 +28668,7 @@ PATH="$OLD_PATH"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -28813,7 +28843,7 @@ fi
for ac_header in stdio.h
do :
ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default"
-if test "x$ac_cv_header_stdio_h" = x""yes; then :
+if test "x$ac_cv_header_stdio_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STDIO_H 1
_ACEOF
@@ -28842,7 +28872,7 @@ done
# This bug is HP SR number 8606223364.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5
$as_echo_n "checking size of int *... " >&6; }
-if test "${ac_cv_sizeof_int_p+set}" = set; then :
+if ${ac_cv_sizeof_int_p+:} false; then :
$as_echo_n "(cached) " >&6
else
if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then :
@@ -28852,7 +28882,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot compute sizeof (int *)
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
ac_cv_sizeof_int_p=0
fi
@@ -28899,7 +28929,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; }
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then :
+if ${ac_cv_c_bigendian+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_c_bigendian=unknown
@@ -29573,7 +29603,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DSOLARIS"
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
+ CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
# Setting these parameters makes it an error to link to macosx APIs that are
# newer than the given OS version and makes the linked binaries compatible even
# if built on a newer version of the OS.
@@ -30075,8 +30105,8 @@ if test "x$with_x" = xno; then
have_x=disabled
else
case $x_includes,$x_libraries in #(
- *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #(
- *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then :
+ *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
+ *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then :
$as_echo_n "(cached) " >&6
else
# One or both of the vars are not set, and there is no cached value.
@@ -30353,7 +30383,7 @@ if ac_fn_cxx_try_link "$LINENO"; then :
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5
$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; }
-if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then :
+if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30387,14 +30417,14 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5
$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; }
-if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then :
+if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then :
X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
fi
if test $ac_cv_lib_dnet_dnet_ntoa = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5
$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; }
-if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then :
+if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30428,7 +30458,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5
$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; }
-if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then :
+if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then :
X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
fi
@@ -30447,14 +30477,14 @@ rm -f core conftest.err conftest.$ac_objext \
# The functions gethostbyname, getservbyname, and inet_addr are
# in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking.
ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
-if test "x$ac_cv_func_gethostbyname" = x""yes; then :
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
fi
if test $ac_cv_func_gethostbyname = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
-if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then :
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30488,14 +30518,14 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
-if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then :
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
fi
if test $ac_cv_lib_nsl_gethostbyname = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5
$as_echo_n "checking for gethostbyname in -lbsd... " >&6; }
-if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then :
+if ${ac_cv_lib_bsd_gethostbyname+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30529,7 +30559,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5
$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; }
-if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then :
+if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then :
X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd"
fi
@@ -30544,14 +30574,14 @@ fi
# must be given before -lnsl if both are needed. We assume that
# if connect needs -lnsl, so does gethostbyname.
ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect"
-if test "x$ac_cv_func_connect" = x""yes; then :
+if test "x$ac_cv_func_connect" = xyes; then :
fi
if test $ac_cv_func_connect = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5
$as_echo_n "checking for connect in -lsocket... " >&6; }
-if test "${ac_cv_lib_socket_connect+set}" = set; then :
+if ${ac_cv_lib_socket_connect+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30585,7 +30615,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5
$as_echo "$ac_cv_lib_socket_connect" >&6; }
-if test "x$ac_cv_lib_socket_connect" = x""yes; then :
+if test "x$ac_cv_lib_socket_connect" = xyes; then :
X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
fi
@@ -30593,14 +30623,14 @@ fi
# Guillermo Gomez says -lposix is necessary on A/UX.
ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove"
-if test "x$ac_cv_func_remove" = x""yes; then :
+if test "x$ac_cv_func_remove" = xyes; then :
fi
if test $ac_cv_func_remove = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5
$as_echo_n "checking for remove in -lposix... " >&6; }
-if test "${ac_cv_lib_posix_remove+set}" = set; then :
+if ${ac_cv_lib_posix_remove+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30634,7 +30664,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5
$as_echo "$ac_cv_lib_posix_remove" >&6; }
-if test "x$ac_cv_lib_posix_remove" = x""yes; then :
+if test "x$ac_cv_lib_posix_remove" = xyes; then :
X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
fi
@@ -30642,14 +30672,14 @@ fi
# BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat"
-if test "x$ac_cv_func_shmat" = x""yes; then :
+if test "x$ac_cv_func_shmat" = xyes; then :
fi
if test $ac_cv_func_shmat = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5
$as_echo_n "checking for shmat in -lipc... " >&6; }
-if test "${ac_cv_lib_ipc_shmat+set}" = set; then :
+if ${ac_cv_lib_ipc_shmat+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30683,7 +30713,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5
$as_echo "$ac_cv_lib_ipc_shmat" >&6; }
-if test "x$ac_cv_lib_ipc_shmat" = x""yes; then :
+if test "x$ac_cv_lib_ipc_shmat" = xyes; then :
X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
fi
@@ -30701,7 +30731,7 @@ fi
# John Interrante, Karl Berry
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5
$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; }
-if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then :
+if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -30735,7 +30765,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5
$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; }
-if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then :
+if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then :
X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
fi
@@ -30816,7 +30846,7 @@ OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $X_CFLAGS"
# Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10
-for ac_header in X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h
+for ac_header in X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " # include
@@ -30869,7 +30899,7 @@ if test "x$X11_A_OK" = xno && test "x$X11_NOT_NEEDED" != xyes; then
HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
fi
- as_fn_error $? "Could not find all X11 headers (shape.h Xrender.h XTest.h). $HELP_MSG" "$LINENO" 5
+ as_fn_error $? "Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG" "$LINENO" 5
fi
@@ -31753,7 +31783,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; }
LDFLAGS="$FREETYPE2_LIBS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5
$as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; }
-if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then :
+if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -31787,7 +31817,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5
$as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; }
-if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then :
+if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then :
FREETYPE2_FOUND=true
else
as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5
@@ -32075,7 +32105,7 @@ fi
for ac_header in alsa/asoundlib.h
do :
ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then :
+if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_ALSA_ASOUNDLIB_H 1
_ACEOF
@@ -32134,7 +32164,7 @@ fi
USE_EXTERNAL_LIBJPEG=true
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5
$as_echo_n "checking for main in -ljpeg... " >&6; }
-if test "${ac_cv_lib_jpeg_main+set}" = set; then :
+if ${ac_cv_lib_jpeg_main+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -32162,7 +32192,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5
$as_echo "$ac_cv_lib_jpeg_main" >&6; }
-if test "x$ac_cv_lib_jpeg_main" = x""yes; then :
+if test "x$ac_cv_lib_jpeg_main" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBJPEG 1
_ACEOF
@@ -32211,7 +32241,7 @@ if test "x${with_giflib}" = "xbundled"; then
USE_EXTERNAL_LIBGIF=false
elif test "x${with_giflib}" = "xsystem"; then
ac_fn_cxx_check_header_mongrel "$LINENO" "gif_lib.h" "ac_cv_header_gif_lib_h" "$ac_includes_default"
-if test "x$ac_cv_header_gif_lib_h" = x""yes; then :
+if test "x$ac_cv_header_gif_lib_h" = xyes; then :
else
as_fn_error $? "--with-giflib=system specified, but gif_lib.h not found!" "$LINENO" 5
@@ -32220,7 +32250,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DGifGetCode in -lgif" >&5
$as_echo_n "checking for DGifGetCode in -lgif... " >&6; }
-if test "${ac_cv_lib_gif_DGifGetCode+set}" = set; then :
+if ${ac_cv_lib_gif_DGifGetCode+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -32254,7 +32284,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_DGifGetCode" >&5
$as_echo "$ac_cv_lib_gif_DGifGetCode" >&6; }
-if test "x$ac_cv_lib_gif_DGifGetCode" = x""yes; then :
+if test "x$ac_cv_lib_gif_DGifGetCode" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBGIF 1
_ACEOF
@@ -32286,7 +32316,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5
$as_echo_n "checking for compress in -lz... " >&6; }
-if test "${ac_cv_lib_z_compress+set}" = set; then :
+if ${ac_cv_lib_z_compress+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -32320,7 +32350,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5
$as_echo "$ac_cv_lib_z_compress" >&6; }
-if test "x$ac_cv_lib_z_compress" = x""yes; then :
+if test "x$ac_cv_lib_z_compress" = xyes; then :
ZLIB_FOUND=yes
else
ZLIB_FOUND=no
@@ -32413,7 +32443,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
$as_echo_n "checking for cos in -lm... " >&6; }
-if test "${ac_cv_lib_m_cos+set}" = set; then :
+if ${ac_cv_lib_m_cos+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -32447,7 +32477,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
$as_echo "$ac_cv_lib_m_cos" >&6; }
-if test "x$ac_cv_lib_m_cos" = x""yes; then :
+if test "x$ac_cv_lib_m_cos" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBM 1
_ACEOF
@@ -32471,7 +32501,7 @@ save_LIBS="$LIBS"
LIBS=""
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+if ${ac_cv_lib_dl_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -32505,7 +32535,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBDL 1
_ACEOF
@@ -32735,7 +32765,7 @@ and LIBFFI_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
To get pkg-config, see .
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS
LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS
@@ -32751,7 +32781,7 @@ if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then
set dummy llvm-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_LLVM_CONFIG+set}" = set; then :
+if ${ac_cv_prog_LLVM_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$LLVM_CONFIG"; then
@@ -32763,7 +32793,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LLVM_CONFIG="llvm-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -33367,7 +33397,7 @@ fi
set dummy ccache; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_CCACHE+set}" = set; then :
+if ${ac_cv_path_CCACHE+:} false; then :
$as_echo_n "(cached) " >&6
else
case $CCACHE in
@@ -33381,7 +33411,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CCACHE="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -33629,10 +33659,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
:end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
+ if test "x$cache_file" != "x/dev/null"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -33664,7 +33705,7 @@ LTLIBOBJS=$ac_ltlibobjs
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -33765,6 +33806,7 @@ fi
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -33960,16 +34002,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -34029,28 +34071,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -34072,7 +34102,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# values after options handling.
ac_log="
This file was extended by OpenJDK $as_me jdk8, which was
-generated by GNU Autoconf 2.67. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -34135,10 +34165,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
OpenJDK config.status jdk8
-configured by $0, generated by GNU Autoconf 2.67,
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -34227,7 +34257,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -34264,7 +34294,7 @@ do
"$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;;
"$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;;
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -34286,9 +34316,10 @@ fi
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
- tmp=
+ tmp= ac_tmp=
trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
@@ -34296,12 +34327,13 @@ $debug ||
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
+ test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
@@ -34323,7 +34355,7 @@ else
ac_cs_awk_cr=$ac_cr
fi
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF
@@ -34351,7 +34383,7 @@ done
rm -f conf$$subs.sh
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
h
@@ -34399,7 +34431,7 @@ t delim
rm -f conf$$subs.awk
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
FS = ""
@@ -34431,7 +34463,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
|| as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
@@ -34465,7 +34497,7 @@ fi # test -n "$CONFIG_FILES"
# No need to generate them if there are no CONFIG_HEADERS.
# This happens for instance with `./config.status Makefile'.
if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
BEGIN {
_ACEOF
@@ -34477,8 +34509,8 @@ _ACEOF
# handling of long lines.
ac_delim='%!_!# '
for ac_last_try in false false :; do
- ac_t=`sed -n "/$ac_delim/p" confdefs.h`
- if test -z "$ac_t"; then
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
break
elif $ac_last_try; then
as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
@@ -34579,7 +34611,7 @@ do
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -34598,7 +34630,7 @@ do
for ac_f
do
case $ac_f in
- -) ac_f="$tmp/stdin";;
+ -) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain `:'.
@@ -34607,7 +34639,7 @@ do
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -34633,8 +34665,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
esac
case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
@@ -34759,21 +34791,22 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
$ac_datarootdir_hack
"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&2;}
- rm -f "$tmp/stdin"
+ rm -f "$ac_tmp/stdin"
case $ac_file in
- -) cat "$tmp/out" && rm -f "$tmp/out";;
- *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
esac \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
;;
@@ -34784,20 +34817,20 @@ which seems to be undefined. Please make sure it is defined" >&2;}
if test x"$ac_file" != x-; then
{
$as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
- } >"$tmp/config.h" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
- if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
$as_echo "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
- mv "$tmp/config.h" "$ac_file" \
+ mv "$ac_tmp/config.h" "$ac_file" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
fi
else
$as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
|| as_fn_error $? "could not create -" "$LINENO" 5
fi
;;
diff --git a/common/autoconf/help.m4 b/common/autoconf/help.m4
index cf4a43e2dd1..15e8b955303 100644
--- a/common/autoconf/help.m4
+++ b/common/autoconf/help.m4
@@ -83,7 +83,7 @@ apt_help() {
pulse)
PKGHANDLER_COMMAND="sudo apt-get install libpulse-dev" ;;
x11)
- PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev" ;;
+ PKGHANDLER_COMMAND="sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev" ;;
ccache)
PKGHANDLER_COMMAND="sudo apt-get install ccache" ;;
* )
@@ -102,11 +102,11 @@ yum_help() {
cups)
PKGHANDLER_COMMAND="sudo yum install cups-devel" ;;
freetype2)
- PKGHANDLER_COMMAND="sudo yum install freetype2-devel" ;;
+ PKGHANDLER_COMMAND="sudo yum install freetype-devel" ;;
pulse)
PKGHANDLER_COMMAND="sudo yum install pulseaudio-libs-devel" ;;
x11)
- PKGHANDLER_COMMAND="sudo yum install libXtst-devel" ;;
+ PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel" ;;
ccache)
PKGHANDLER_COMMAND="sudo yum install ccache" ;;
* )
diff --git a/common/autoconf/libraries.m4 b/common/autoconf/libraries.m4
index 4502856d273..1d53f04d203 100644
--- a/common/autoconf/libraries.m4
+++ b/common/autoconf/libraries.m4
@@ -185,7 +185,7 @@ OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $X_CFLAGS"
# Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10
-AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h],
+AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h],
[X11_A_OK=yes],
[X11_A_OK=no; break],
[ # include
@@ -197,7 +197,7 @@ AC_LANG_POP(C)
if test "x$X11_A_OK" = xno && test "x$X11_NOT_NEEDED" != xyes; then
HELP_MSG_MISSING_DEPENDENCY([x11])
- AC_MSG_ERROR([Could not find all X11 headers (shape.h Xrender.h XTest.h). $HELP_MSG])
+ AC_MSG_ERROR([Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG])
fi
AC_SUBST(X_CFLAGS)
diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4
index b2b367f63c2..efaecc18960 100644
--- a/common/autoconf/toolchain.m4
+++ b/common/autoconf/toolchain.m4
@@ -905,7 +905,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DSOLARIS"
fi
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE"
+ CCXXFLAGS_JDK="$CCXXFLAGS_JDK -DMACOSX -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
# Setting these parameters makes it an error to link to macosx APIs that are
# newer than the given OS version and makes the linked binaries compatible even
# if built on a newer version of the OS.
diff --git a/common/makefiles/Main.gmk b/common/makefiles/Main.gmk
index dd99df2d526..f5f01fce1ba 100644
--- a/common/makefiles/Main.gmk
+++ b/common/makefiles/Main.gmk
@@ -183,7 +183,7 @@ bootcycle-images-only: start-make
test: images test-only
test-only: start-make
@$(call TargetEnter)
- @($(CD) $(SRC_ROOT)/test && $(BUILD_LOG_WRAPPER) $(MAKE) -j1 -k MAKEFLAGS= JT_HOME=$(JT_HOME) PRODUCT_HOME=$(JDK_IMAGE_DIR) JPRT_JAVA_HOME=$(JDK_IMAGE_DIR) ALT_OUTPUTDIR=$(OUTPUT_ROOT) CONCURRENCY=$(JOBS) $(TEST)) || true
+ @($(CD) $(SRC_ROOT)/test && $(BUILD_LOG_WRAPPER) $(MAKE) -j1 -k MAKEFLAGS= JT_HOME=$(JT_HOME) PRODUCT_HOME=$(JDK_IMAGE_DIR) ALT_OUTPUTDIR=$(OUTPUT_ROOT) CONCURRENCY=$(JOBS) $(TEST)) || true
@$(call TargetExit)
# Stores the tips for each repository. This file is be used when constructing the jdk image and can be
@@ -242,7 +242,7 @@ clean-test:
.PHONY: langtools corba jaxp jaxws hotspot jdk nashorn images overlay-images install test docs
.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only nashorn-only images-only overlay-images-only install-only test-only docs-only
-.PHONY: all clean dist-clean bootcycle-images start-make
+.PHONY: default all clean dist-clean bootcycle-images start-make
.PHONY: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-nashorn clean-images clean-docs clean-test clean-overlay-images clean-bootcycle-build
.PHONY: profiles profiles-only profiles-oscheck
diff --git a/corba/.hgtags b/corba/.hgtags
index 6aa967721af..8faf5f45228 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -225,3 +225,5 @@ c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101
528c7e76eaeee022817ee085668459bc97cf5665 jdk8-b102
49c4a777fdfd648d4c3fffc940fdb97a23108ca8 jdk8-b103
+d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
+4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index b58c3218710..56c23d248df 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -369,3 +369,7 @@ c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102
7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45
6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103
580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46
+104743074675359cfbf7f4dcd9ab2a5974a16627 jdk8-b104
+c1604d5885a6f2adc0bcea2fa142a8f6bafad2f0 hs25-b47
+acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105
+18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
index 80d5b795b3f..1cc2c8d910a 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
@@ -75,19 +75,19 @@ public class InstanceKlass extends Klass {
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
constants = new MetadataField(type.getAddressField("_constants"), 0);
classLoaderData = type.getAddressField("_class_loader_data");
- sourceFileName = type.getAddressField("_source_file_name");
sourceDebugExtension = type.getAddressField("_source_debug_extension");
innerClasses = type.getAddressField("_inner_classes");
+ sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), 0);
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), 0);
- staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
+ staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), 0);
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), 0);
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
initState = new CIntField(type.getCIntegerField("_init_state"), 0);
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), 0);
itableLen = new CIntField(type.getCIntegerField("_itable_len"), 0);
breakpoints = type.getAddressField("_breakpoints");
- genericSignature = type.getAddressField("_generic_signature");
+ genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
headerSize = Oop.alignObjectOffset(type.getSize());
@@ -134,9 +134,9 @@ public class InstanceKlass extends Klass {
private static CIntField javaFieldsCount;
private static MetadataField constants;
private static AddressField classLoaderData;
- private static AddressField sourceFileName;
private static AddressField sourceDebugExtension;
private static AddressField innerClasses;
+ private static CIntField sourceFileNameIndex;
private static CIntField nonstaticFieldSize;
private static CIntField staticFieldSize;
private static CIntField staticOopFieldCount;
@@ -146,7 +146,7 @@ public class InstanceKlass extends Klass {
private static CIntField vtableLen;
private static CIntField itableLen;
private static AddressField breakpoints;
- private static AddressField genericSignature;
+ private static CIntField genericSignatureIndex;
private static CIntField majorVersion;
private static CIntField minorVersion;
@@ -346,7 +346,7 @@ public class InstanceKlass extends Klass {
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
- public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
+ public Symbol getSourceFileName() { return getConstants().getSymbolAt(sourceFileNameIndex.getValue(this)); }
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
@@ -354,7 +354,7 @@ public class InstanceKlass extends Klass {
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.getValue(this); }
- public Symbol getGenericSignature() { return getSymbol(genericSignature); }
+ public Symbol getGenericSignature() { return getConstants().getSymbolAt(genericSignatureIndex.getValue(this)); }
public long majorVersion() { return majorVersion.getValue(this); }
public long minorVersion() { return minorVersion.getValue(this); }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
index 418bef9a086..afd7f9865b5 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java
@@ -92,8 +92,13 @@ public class ClassDump extends Tool {
System.err.println("Warning: Can not create class filter!");
}
}
- String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
- setOutputDirectory(outputDirectory);
+
+ // outputDirectory and jarStream are alternatives: setting one closes the other.
+ // If neither is set, use outputDirectory from the System property:
+ if (outputDirectory == null && jarStream == null) {
+ String dirName = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
+ setOutputDirectory(dirName);
+ }
// walk through the system dictionary
SystemDictionary dict = VM.getVM().getSystemDictionary();
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
index ec22e35e633..4253740369b 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
@@ -35,8 +35,9 @@ sapkg.c1 = sapkg.hotspot.c1;
sapkg.code = sapkg.hotspot.code;
sapkg.compiler = sapkg.hotspot.compiler;
-// 'debugger' is a JavaScript keyword :-(
-// sapkg.debugger = sapkg.hotspot.debugger;
+// 'debugger' is a JavaScript keyword, but ES5 relaxes the
+// restriction of using keywords as property name
+sapkg.debugger = sapkg.hotspot.debugger;
sapkg.interpreter = sapkg.hotspot.interpreter;
sapkg.jdi = sapkg.hotspot.jdi;
@@ -116,27 +117,36 @@ function main(globals, jvmarg) {
return args;
}
+ // Handle __has__ specially to avoid metacircularity problems
+ // when called from __get__.
+ // Calling
+ // this.__has__(name)
+ // will in turn call
+ // this.__call__('__has__', name)
+ // which is not handled below
+ function __has__(name) {
+ if (typeof(name) == 'number') {
+ return so["has(int)"](name);
+ } else {
+ if (name == '__wrapped__') {
+ return true;
+ } else if (so["has(java.lang.String)"](name)) {
+ return true;
+ } else if (name.equals('toString')) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
if (so instanceof sapkg.utilities.soql.ScriptObject) {
return new JSAdapter() {
- __getIds__: function() {
- return so.getIds();
+ __getIds__: function() {
+ return so.getIds();
},
- __has__ : function(name) {
- if (typeof(name) == 'number') {
- return so["has(int)"](name);
- } else {
- if (name == '__wrapped__') {
- return true;
- } else if (so["has(java.lang.String)"](name)) {
- return true;
- } else if (name.equals('toString')) {
- return true;
- } else {
- return false;
- }
- }
- },
+ __has__ : __has__,
__delete__ : function(name) {
if (typeof(name) == 'number') {
@@ -147,7 +157,8 @@ function main(globals, jvmarg) {
},
__get__ : function(name) {
- if (! this.__has__(name)) {
+ // don't call this.__has__(name); see comments above function __has__
+ if (! __has__.call(this, name)) {
return undefined;
}
if (typeof(name) == 'number') {
@@ -162,7 +173,7 @@ function main(globals, jvmarg) {
var args = prepareArgsArray(arguments);
var r;
try {
- r = value.call(args);
+ r = value.call(Java.to(args, 'java.lang.Object[]'));
} catch (e) {
println("call to " + name + " failed!");
throw e;
@@ -204,6 +215,18 @@ function main(globals, jvmarg) {
}
// define "writeln" and "write" if not defined
+ if (typeof(println) == 'undefined') {
+ println = function (str) {
+ java.lang.System.out.println(String(str));
+ }
+ }
+
+ if (typeof(print) == 'undefined') {
+ print = function (str) {
+ java.lang.System.out.print(String(str));
+ }
+ }
+
if (typeof(writeln) == 'undefined') {
writeln = println;
}
@@ -235,7 +258,7 @@ function main(globals, jvmarg) {
this.jclasses = function() {
forEachKlass(function (clazz) {
- writeln(clazz.getName().asString() + " @" + clazz.getHandle().toString());
+ writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString());
});
}
registerCommand("classes", "classes", "jclasses");
@@ -490,14 +513,14 @@ function systemLoader() {
function forEachKlass(callback) {
var VisitorClass = sapkg.memory.SystemDictionary.ClassVisitor;
var visitor = new VisitorClass() { visit: callback };
- sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary$ClassVisitor)"](visitor);
+ sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassVisitor)"](visitor);
}
// iterate system dictionary for each 'Klass' and initiating loader
function forEachKlassAndLoader(callback) {
var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
var visitor = new VisitorClass() { visit: callback };
- sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary$ClassAndLoaderVisitor)"](visitor);
+ sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassAndLoaderVisitor)"](visitor);
}
// iterate system dictionary for each primitive array klass
@@ -522,7 +545,12 @@ function obj2oop(obj) {
// iterates Java heap for each Oop
function forEachOop(callback) {
- sa.objHeap.iterate(new sapkg.oops.HeapVisitor() { doObj: callback });
+ function empty() { }
+ sa.objHeap.iterate(new sapkg.oops.HeapVisitor() {
+ prologue: empty,
+ doObj: callback,
+ epilogue: empty
+ });
}
// iterates Java heap for each Oop of given 'klass'.
@@ -536,8 +564,14 @@ function forEachOopOfKlass(callback, klass, includeSubtypes) {
if (includeSubtypes == undefined) {
includeSubtypes = true;
}
+
+ function empty() { }
sa.objHeap.iterateObjectsOfKlass(
- new sapkg.oops.HeapVisitor() { doObj: callback },
+ new sapkg.oops.HeapVisitor() {
+ prologue: empty,
+ doObj: callback,
+ epilogue: empty
+ },
klass, includeSubtypes);
}
@@ -746,9 +780,9 @@ while (tmp.itr.hasNext()) {
// ignore;
continue;
} else {
- // some type names have ':'. replace to make it as a
+ // some type names have ':', '<', '>', '*', ' '. replace to make it as a
// JavaScript identifier
- tmp.name = tmp.name.replace(':', '_').replace('<', '_').replace('>', '_').replace('*', '_').replace(' ', '_');
+ tmp.name = ("" + tmp.name).replace(/[:<>* ]/g, '_');
eval("function read" + tmp.name + "(addr) {" +
" return readVMType('" + tmp.name + "', addr);}");
eval("function print" + tmp.name + "(addr) {" +
diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make
index 36ba062651c..c2c96f9a18f 100644
--- a/hotspot/make/bsd/makefiles/gcc.make
+++ b/hotspot/make/bsd/makefiles/gcc.make
@@ -247,7 +247,7 @@ ifeq ($(USE_CLANG), true)
# Not yet supported by clang in Xcode 4.6.2
# WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
- WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
+ WARNINGS_ARE_ERRORS += -Wno-empty-body
endif
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index 2ec3b0aaf52..a16ed251dc6 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=46
+HS_BUILD_NUMBER=48
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
diff --git a/hotspot/make/linux/makefiles/amd64.make b/hotspot/make/linux/makefiles/amd64.make
index ecdac17ee3a..2b77dbab605 100644
--- a/hotspot/make/linux/makefiles/amd64.make
+++ b/hotspot/make/linux/makefiles/amd64.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,4 @@ CFLAGS += -DVM_LITTLE_ENDIAN
CFLAGS += -D_LP64=1
-# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
-ifndef USE_SUNCC
- CFLAGS += -fno-omit-frame-pointer
-endif
-
OPT_CFLAGS/compactingPermGenGen.o = -O1
diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make
index 38cf2c03492..a62ea4b52ee 100644
--- a/hotspot/make/linux/makefiles/gcc.make
+++ b/hotspot/make/linux/makefiles/gcc.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -398,3 +398,10 @@ endif
ifdef MINIMIZE_RAM_USAGE
CFLAGS += -DMINIMIZE_RAM_USAGE
endif
+
+# Stack walking in the JVM relies on frame pointer (%rbp) to walk thread stack.
+# Explicitly specify -fno-omit-frame-pointer because it is off by default
+# starting with gcc 4.6.
+ifndef USE_SUNCC
+ CFLAGS += -fno-omit-frame-pointer
+endif
diff --git a/hotspot/make/windows/build_vm_def.sh b/hotspot/make/windows/build_vm_def.sh
index c54a1803b93..fa82d26a81a 100644
--- a/hotspot/make/windows/build_vm_def.sh
+++ b/hotspot/make/windows/build_vm_def.sh
@@ -42,8 +42,6 @@ else
MKS_HOME=`dirname "$SH"`
fi
-echo "EXPORTS" > vm1.def
-
AWK="$MKS_HOME/awk.exe"
if [ ! -e $AWK ]; then
AWK="$MKS_HOME/gawk.exe"
@@ -55,6 +53,22 @@ CAT="$MKS_HOME/cat.exe"
RM="$MKS_HOME/rm.exe"
DUMPBIN="link.exe /dump"
+if [ "$1" = "-nosa" ]; then
+ echo EXPORTS > vm.def
+ echo ""
+ echo "***"
+ echo "*** Not building SA: BUILD_WIN_SA != 1"
+ echo "*** C++ Vtables NOT included in vm.def"
+ echo "*** This jvm.dll will NOT work properly with SA."
+ echo "***"
+ echo "*** When in doubt, set BUILD_WIN_SA=1, clean and rebuild."
+ echo "***"
+ echo ""
+ exit
+fi
+
+echo "EXPORTS" > vm1.def
+
# When called from IDE the first param should contain the link version, otherwise may be nill
if [ "x$1" != "x" ]; then
LD_VER="$1"
diff --git a/hotspot/make/windows/makefiles/debug.make b/hotspot/make/windows/makefiles/debug.make
index 2fca2182841..14a07083434 100644
--- a/hotspot/make/windows/makefiles/debug.make
+++ b/hotspot/make/windows/makefiles/debug.make
@@ -49,9 +49,6 @@ HS_BUILD_ID=$(HS_BUILD_VER)-debug
# Force resources to be rebuilt every time
$(Res_Files): FORCE
-vm.def: $(Obj_Files)
- sh $(WorkSpace)/make/windows/build_vm_def.sh
-
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
$(LD) @<<
$(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
diff --git a/hotspot/make/windows/makefiles/fastdebug.make b/hotspot/make/windows/makefiles/fastdebug.make
index cde98f214ea..a85e129cf6e 100644
--- a/hotspot/make/windows/makefiles/fastdebug.make
+++ b/hotspot/make/windows/makefiles/fastdebug.make
@@ -48,9 +48,6 @@ HS_BUILD_ID=$(HS_BUILD_VER)-fastdebug
# Force resources to be rebuilt every time
$(Res_Files): FORCE
-vm.def: $(Obj_Files)
- sh $(WorkSpace)/make/windows/build_vm_def.sh
-
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
$(LD) @<<
$(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
diff --git a/hotspot/make/windows/makefiles/product.make b/hotspot/make/windows/makefiles/product.make
index 407484cd46e..713ec0e54ca 100644
--- a/hotspot/make/windows/makefiles/product.make
+++ b/hotspot/make/windows/makefiles/product.make
@@ -51,9 +51,6 @@ HS_BUILD_ID=$(HS_BUILD_VER)
# Force resources to be rebuilt every time
$(Res_Files): FORCE
-vm.def: $(Obj_Files)
- sh $(WorkSpace)/make/windows/build_vm_def.sh
-
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
$(LD) @<<
$(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
diff --git a/hotspot/make/windows/makefiles/projectcreator.make b/hotspot/make/windows/makefiles/projectcreator.make
index a5336c6bf51..d512796f8fe 100644
--- a/hotspot/make/windows/makefiles/projectcreator.make
+++ b/hotspot/make/windows/makefiles/projectcreator.make
@@ -92,6 +92,10 @@ ProjectCreatorIDEOptions = \
-disablePch getThread_windows_$(Platform_arch).cpp \
-disablePch_compiler2 opcodes.cpp
+!if "$(BUILD_WIN_SA)" != "1"
+BUILD_VM_DEF_FLAG=-nosa
+!endif
+
# Common options for the IDE builds for c1, and c2
ProjectCreatorIDEOptions=\
$(ProjectCreatorIDEOptions) \
@@ -104,7 +108,7 @@ ProjectCreatorIDEOptions=\
-jdkTargetRoot $(HOTSPOTJDKDIST) \
-define ALIGN_STACK_FRAMES \
-define VM_LITTLE_ENDIAN \
- -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) set JAVA_HOME=$(HOTSPOTJDKDIST) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LD_VER)" \
+ -prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) set JAVA_HOME=$(HOTSPOTJDKDIST) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(BUILD_VM_DEF_FLAG) $(LD_VER)" \
-ignoreFile jsig.c \
-ignoreFile jvmtiEnvRecommended.cpp \
-ignoreFile jvmtiEnvStub.cpp \
diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make
index 8b5e23d4a28..229be6870a7 100644
--- a/hotspot/make/windows/makefiles/vm.make
+++ b/hotspot/make/windows/makefiles/vm.make
@@ -393,3 +393,11 @@ default::
_build_pch_file.obj:
@echo #include "precompiled.hpp" > ../generated/_build_pch_file.cpp
$(CXX) $(CXX_FLAGS) /Fp"vm.pch" /Yc"precompiled.hpp" /c ../generated/_build_pch_file.cpp
+
+!if "$(BUILD_WIN_SA)" != "1"
+BUILD_VM_DEF_FLAG=-nosa
+!endif
+
+vm.def: $(Obj_Files)
+ sh $(WorkSpace)/make/windows/build_vm_def.sh $(BUILD_VM_DEF_FLAG)
+
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
index 022e67ba203..d2c4e3b0261 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/cardTableModRefBS.hpp"
#include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -1145,7 +1146,7 @@ void MacroAssembler::set_narrow_klass(Klass* k, Register d) {
assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- narrowOop encoded_k = oopDesc::encode_klass(k);
+ narrowOop encoded_k = Klass::encode_klass(k);
assert_not_delayed();
// Relocation with special format (see relocInfo_sparc.hpp).
@@ -1419,7 +1420,6 @@ void MacroAssembler::verify_oop_subroutine() {
load_klass(O0_obj, O0_obj);
// assert((klass != NULL)
br_null_short(O0_obj, pn, fail);
- // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers
wrccr( O5_save_flags ); // Restore CCR's
@@ -4089,52 +4089,91 @@ void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
}
void MacroAssembler::encode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- if (Universe::narrow_klass_base() != NULL)
- sub(r, G6_heapbase, r);
- srlx(r, LogKlassAlignmentInBytes, r);
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ assert(r != G6_heapbase, "bad register choice");
+ set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
+ sub(r, G6_heapbase, r);
+ if (Universe::narrow_klass_shift() != 0) {
+ assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
+ srlx(r, LogKlassAlignmentInBytes, r);
+ }
+ reinit_heapbase();
}
void MacroAssembler::encode_klass_not_null(Register src, Register dst) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
- assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- if (Universe::narrow_klass_base() == NULL) {
- srlx(src, LogKlassAlignmentInBytes, dst);
+ if (src == dst) {
+ encode_klass_not_null(src);
} else {
- sub(src, G6_heapbase, dst);
- srlx(dst, LogKlassAlignmentInBytes, dst);
+ assert (UseCompressedKlassPointers, "must be compressed");
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ set((intptr_t)Universe::narrow_klass_base(), dst);
+ sub(src, dst, dst);
+ if (Universe::narrow_klass_shift() != 0) {
+ srlx(dst, LogKlassAlignmentInBytes, dst);
+ }
}
}
+// Function instr_size_for_decode_klass_not_null() counts the instructions
+// generated by decode_klass_not_null() and reinit_heapbase(). Hence, if
+// the instructions they generate change, then this method needs to be updated.
+int MacroAssembler::instr_size_for_decode_klass_not_null() {
+ assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
+ // set + add + set
+ int num_instrs = insts_for_internal_set((intptr_t)Universe::narrow_klass_base()) + 1 +
+ insts_for_internal_set((intptr_t)Universe::narrow_ptrs_base());
+ if (Universe::narrow_klass_shift() == 0) {
+ return num_instrs * BytesPerInstWord;
+ } else { // sllx
+ return (num_instrs + 1) * BytesPerInstWord;
+ }
+}
+
+// !!! If the instructions that get generated here change then function
+// instr_size_for_decode_klass_not_null() needs to get updated.
void MacroAssembler::decode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
// Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit.
assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- sllx(r, LogKlassAlignmentInBytes, r);
- if (Universe::narrow_klass_base() != NULL)
- add(r, G6_heapbase, r);
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ assert(r != G6_heapbase, "bad register choice");
+ set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
+ if (Universe::narrow_klass_shift() != 0)
+ sllx(r, LogKlassAlignmentInBytes, r);
+ add(r, G6_heapbase, r);
+ reinit_heapbase();
}
void MacroAssembler::decode_klass_not_null(Register src, Register dst) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
- // Do not add assert code to this unless you change vtableStubs_sparc.cpp
- // pd_code_size_limit.
- assert (UseCompressedKlassPointers, "must be compressed");
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- sllx(src, LogKlassAlignmentInBytes, dst);
- if (Universe::narrow_klass_base() != NULL)
- add(dst, G6_heapbase, dst);
+ if (src == dst) {
+ decode_klass_not_null(src);
+ } else {
+ // Do not add assert code to this unless you change vtableStubs_sparc.cpp
+ // pd_code_size_limit.
+ assert (UseCompressedKlassPointers, "must be compressed");
+ assert(Universe::narrow_klass_base() != NULL, "narrow_klass_base should be initialized");
+ if (Universe::narrow_klass_shift() != 0) {
+ assert((src != G6_heapbase) && (dst != G6_heapbase), "bad register choice");
+ set((intptr_t)Universe::narrow_klass_base(), G6_heapbase);
+ sllx(src, LogKlassAlignmentInBytes, dst);
+ add(dst, G6_heapbase, dst);
+ reinit_heapbase();
+ } else {
+ set((intptr_t)Universe::narrow_klass_base(), dst);
+ add(src, dst, dst);
+ }
+ }
}
void MacroAssembler::reinit_heapbase() {
if (UseCompressedOops || UseCompressedKlassPointers) {
- AddressLiteral base(Universe::narrow_ptrs_base_addr());
- load_ptr_contents(base, G6_heapbase);
+ if (Universe::heap() != NULL) {
+ set((intptr_t)Universe::narrow_ptrs_base(), G6_heapbase);
+ } else {
+ AddressLiteral base(Universe::narrow_ptrs_base_addr());
+ load_ptr_contents(base, G6_heapbase);
+ }
}
}
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
index 72fd61f52c2..f03dc8e5e72 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
@@ -1177,6 +1177,9 @@ public:
void push_CPU_state();
void pop_CPU_state();
+ // Returns the byte size of the instructions generated by decode_klass_not_null().
+ static int instr_size_for_decode_klass_not_null();
+
// if heap base register is used - reinit it with the correct value
void reinit_heapbase();
diff --git a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp
index 97bd2fcc692..e132c42d474 100644
--- a/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/relocInfo_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -97,7 +97,7 @@ void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
if (format() != 0) {
assert(type() == relocInfo::oop_type || type() == relocInfo::metadata_type, "only narrow oops or klasses case");
- jint np = type() == relocInfo::oop_type ? oopDesc::encode_heap_oop((oop)x) : oopDesc::encode_klass((Klass*)x);
+ jint np = type() == relocInfo::oop_type ? oopDesc::encode_heap_oop((oop)x) : Klass::encode_klass((Klass*)x);
inst &= ~Assembler::hi22(-1);
inst |= Assembler::hi22((intptr_t)np);
if (verify_only) {
diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad
index 932da4a5930..a72bffdadeb 100644
--- a/hotspot/src/cpu/sparc/vm/sparc.ad
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad
@@ -559,10 +559,7 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
int klass_load_size;
if (UseCompressedKlassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
- if (Universe::narrow_klass_base() == NULL)
- klass_load_size = 2*BytesPerInstWord; // see MacroAssembler::load_klass()
- else
- klass_load_size = 3*BytesPerInstWord;
+ klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else {
klass_load_size = 1*BytesPerInstWord;
}
@@ -1663,9 +1660,12 @@ void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
if (UseCompressedKlassPointers) {
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("\tSLL R_G5,3,R_G5");
- if (Universe::narrow_klass_base() != NULL)
- st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
+ st->print_cr("\tSET Universe::narrow_klass_base,R_G6_heap_base");
+ if (Universe::narrow_klass_shift() != 0) {
+ st->print_cr("\tSLL R_G5,3,R_G5");
+ }
+ st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
+ st->print_cr("\tSET Universe::narrow_ptrs_base,R_G6_heap_base");
} else {
st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
}
@@ -2563,10 +2563,7 @@ encode %{
int klass_load_size;
if (UseCompressedKlassPointers) {
assert(Universe::heap() != NULL, "java heap should be initialized");
- if (Universe::narrow_klass_base() == NULL)
- klass_load_size = 2*BytesPerInstWord;
- else
- klass_load_size = 3*BytesPerInstWord;
+ klass_load_size = MacroAssembler::instr_size_for_decode_klass_not_null() + 1*BytesPerInstWord;
} else {
klass_load_size = 1*BytesPerInstWord;
}
diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
index 3c4f24c3867..39663758035 100644
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -219,13 +219,13 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
const int basic = 5*BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based)
(UseCompressedKlassPointers ?
- ((Universe::narrow_klass_base() == NULL) ? BytesPerInstWord : 2*BytesPerInstWord) : 0);
+ MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return basic + slop;
} else {
const int basic = (28 LP64_ONLY(+ 6)) * BytesPerInstWord +
// shift;add for load_klass (only shift with zero heap based)
(UseCompressedKlassPointers ?
- ((Universe::narrow_klass_base() == NULL) ? BytesPerInstWord : 2*BytesPerInstWord) : 0);
+ MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
return (basic + slop);
}
}
diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
index 8aad6965156..b331f694959 100644
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
@@ -30,6 +30,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/cardTableModRefBS.hpp"
#include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -4810,23 +4811,8 @@ void MacroAssembler::load_klass(Register dst, Register src) {
}
void MacroAssembler::load_prototype_header(Register dst, Register src) {
-#ifdef _LP64
- if (UseCompressedKlassPointers) {
- assert (Universe::heap() != NULL, "java heap should be initialized");
- movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
- if (Universe::narrow_klass_shift() != 0) {
- assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
- movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset()));
- } else {
- movq(dst, Address(dst, Klass::prototype_header_offset()));
- }
- } else
-#endif
- {
- movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
- movptr(dst, Address(dst, Klass::prototype_header_offset()));
- }
+ load_klass(dst, src);
+ movptr(dst, Address(dst, Klass::prototype_header_offset()));
}
void MacroAssembler::store_klass(Register dst, Register src) {
@@ -4914,7 +4900,7 @@ void MacroAssembler::store_klass_gap(Register dst, Register src) {
#ifdef ASSERT
void MacroAssembler::verify_heapbase(const char* msg) {
- assert (UseCompressedOops || UseCompressedKlassPointers, "should be compressed");
+ assert (UseCompressedOops, "should be compressed");
assert (Universe::heap() != NULL, "java heap should be initialized");
if (CheckCompressedOops) {
Label ok;
@@ -5058,69 +5044,80 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
}
void MacroAssembler::encode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
-#ifdef ASSERT
- verify_heapbase("MacroAssembler::encode_klass_not_null: heap base corrupted?");
-#endif
- if (Universe::narrow_klass_base() != NULL) {
- subq(r, r12_heapbase);
- }
+ assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
+ // Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
+ assert(r != r12_heapbase, "Encoding a klass in r12");
+ mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
+ subq(r, r12_heapbase);
if (Universe::narrow_klass_shift() != 0) {
assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
shrq(r, LogKlassAlignmentInBytes);
}
+ reinit_heapbase();
}
void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
-#ifdef ASSERT
- verify_heapbase("MacroAssembler::encode_klass_not_null2: heap base corrupted?");
-#endif
- if (dst != src) {
- movq(dst, src);
- }
- if (Universe::narrow_klass_base() != NULL) {
- subq(dst, r12_heapbase);
- }
- if (Universe::narrow_klass_shift() != 0) {
- assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- shrq(dst, LogKlassAlignmentInBytes);
+ if (dst == src) {
+ encode_klass_not_null(src);
+ } else {
+ mov64(dst, (int64_t)Universe::narrow_klass_base());
+ negq(dst);
+ addq(dst, src);
+ if (Universe::narrow_klass_shift() != 0) {
+ assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
+ shrq(dst, LogKlassAlignmentInBytes);
+ }
}
}
+// Function instr_size_for_decode_klass_not_null() counts the instructions
+// generated by decode_klass_not_null(register r) and reinit_heapbase(),
+// when (Universe::heap() != NULL). Hence, if the instructions they
+// generate change, then this method needs to be updated.
+int MacroAssembler::instr_size_for_decode_klass_not_null() {
+ assert (UseCompressedKlassPointers, "only for compressed klass ptrs");
+ // mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
+ return (Universe::narrow_klass_shift() == 0 ? 20 : 24);
+}
+
+// !!! If the instructions that get generated here change then function
+// instr_size_for_decode_klass_not_null() needs to get updated.
void MacroAssembler::decode_klass_not_null(Register r) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
// Note: it will change flags
+ assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
+ assert(r != r12_heapbase, "Decoding a klass in r12");
// Cannot assert, unverified entry point counts instructions (see .ad file)
// vtableStubs also counts instructions in pd_code_size_limit.
// Also do not verify_oop as this is called by verify_oop.
if (Universe::narrow_klass_shift() != 0) {
assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
shlq(r, LogKlassAlignmentInBytes);
- if (Universe::narrow_klass_base() != NULL) {
- addq(r, r12_heapbase);
- }
- } else {
- assert (Universe::narrow_klass_base() == NULL, "sanity");
}
+ // Use r12 as a scratch register in which to temporarily load the narrow_klass_base.
+ mov64(r12_heapbase, (int64_t)Universe::narrow_klass_base());
+ addq(r, r12_heapbase);
+ reinit_heapbase();
}
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
- assert(Metaspace::is_initialized(), "metaspace should be initialized");
// Note: it will change flags
+ assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
assert (UseCompressedKlassPointers, "should only be used for compressed headers");
- // Cannot assert, unverified entry point counts instructions (see .ad file)
- // vtableStubs also counts instructions in pd_code_size_limit.
- // Also do not verify_oop as this is called by verify_oop.
- if (Universe::narrow_klass_shift() != 0) {
- assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
- assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
- leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
+ if (dst == src) {
+ decode_klass_not_null(dst);
} else {
- assert (Universe::narrow_klass_base() == NULL, "sanity");
- if (dst != src) {
- movq(dst, src);
+ // Cannot assert, unverified entry point counts instructions (see .ad file)
+ // vtableStubs also counts instructions in pd_code_size_limit.
+ // Also do not verify_oop as this is called by verify_oop.
+
+ mov64(dst, (int64_t)Universe::narrow_klass_base());
+ if (Universe::narrow_klass_shift() != 0) {
+ assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
+ assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
+ leaq(dst, Address(dst, src, Address::times_8, 0));
+ } else {
+ addq(dst, src);
}
}
}
@@ -5148,7 +5145,7 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ mov_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::set_narrow_klass(Address dst, Klass* k) {
@@ -5156,7 +5153,7 @@ void MacroAssembler::set_narrow_klass(Address dst, Klass* k) {
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- mov_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ mov_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::cmp_narrow_oop(Register dst, jobject obj) {
@@ -5182,7 +5179,7 @@ void MacroAssembler::cmp_narrow_klass(Register dst, Klass* k) {
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
@@ -5190,14 +5187,23 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) {
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
int klass_index = oop_recorder()->find_index(k);
RelocationHolder rspec = metadata_Relocation::spec(klass_index);
- Assembler::cmp_narrow_oop(dst, oopDesc::encode_klass(k), rspec);
+ Assembler::cmp_narrow_oop(dst, Klass::encode_klass(k), rspec);
}
void MacroAssembler::reinit_heapbase() {
if (UseCompressedOops || UseCompressedKlassPointers) {
- movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
+ if (Universe::heap() != NULL) {
+ if (Universe::narrow_oop_base() == NULL) {
+ MacroAssembler::xorptr(r12_heapbase, r12_heapbase);
+ } else {
+ mov64(r12_heapbase, (int64_t)Universe::narrow_ptrs_base());
+ }
+ } else {
+ movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
+ }
}
}
+
#endif // _LP64
diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
index 3acef073c0e..293b3b73a37 100644
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
@@ -371,6 +371,10 @@ class MacroAssembler: public Assembler {
void cmp_narrow_klass(Register dst, Klass* k);
void cmp_narrow_klass(Address dst, Klass* k);
+ // Returns the byte size of the instructions generated by decode_klass_not_null()
+ // when compressed klass pointers are being used.
+ static int instr_size_for_decode_klass_not_null();
+
// if heap base register is used - reinit it with the correct value
void reinit_heapbase();
diff --git a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp
index 4cb5c3f61ca..14868cb45a1 100644
--- a/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/relocInfo_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,9 +55,9 @@ void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
}
} else {
if (verify_only) {
- assert(*(uint32_t*) disp == oopDesc::encode_klass((Klass*)x), "instructions must match");
+ assert(*(uint32_t*) disp == Klass::encode_klass((Klass*)x), "instructions must match");
} else {
- *(int32_t*) disp = oopDesc::encode_klass((Klass*)x);
+ *(int32_t*) disp = Klass::encode_klass((Klass*)x);
}
}
} else {
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
index a8abfea6bcd..12fccf9ddd3 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
@@ -675,7 +675,6 @@ class StubGenerator: public StubCodeGenerator {
__ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
__ testptr(rax, rax);
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
- // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers
// return if everything seems ok
__ bind(exit);
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
index e38139d28ec..a16611280fb 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -1021,7 +1021,6 @@ class StubGenerator: public StubCodeGenerator {
__ load_klass(rax, rax); // get klass
__ testptr(rax, rax);
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
- // TODO: Future assert that klass is lower 4g memory for UseCompressedKlassPointers
// return if everything seems ok
__ bind(exit);
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 4ac85c49578..6648bcd08bf 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -849,9 +849,9 @@ address InterpreterGenerator::generate_CRC32_update_entry() {
address entry = __ pc();
// rbx,: Method*
- // rsi: senderSP must preserved for slow path, set SP to it on fast path
- // rdx: scratch
- // rdi: scratch
+ // r13: senderSP must preserved for slow path, set SP to it on fast path
+ // c_rarg0: scratch (rdi on non-Win64, rcx on Win64)
+ // c_rarg1: scratch (rsi on non-Win64, rdx on Win64)
Label slow_path;
// If we need a safepoint check, generate full interpreter entry.
@@ -865,8 +865,8 @@ address InterpreterGenerator::generate_CRC32_update_entry() {
// Load parameters
const Register crc = rax; // crc
- const Register val = rdx; // source java byte value
- const Register tbl = rdi; // scratch
+ const Register val = c_rarg0; // source java byte value
+ const Register tbl = c_rarg1; // scratch
// Arguments are reversed on java expression stack
__ movl(val, Address(rsp, wordSize)); // byte value
@@ -880,7 +880,7 @@ address InterpreterGenerator::generate_CRC32_update_entry() {
// _areturn
__ pop(rdi); // get return address
- __ mov(rsp, rsi); // set sp to sender sp
+ __ mov(rsp, r13); // set sp to sender sp
__ jmp(rdi);
// generate a vanilla native entry as the slow path
@@ -919,20 +919,24 @@ address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpret
const Register crc = c_rarg0; // crc
const Register buf = c_rarg1; // source java byte array address
const Register len = c_rarg2; // length
+ const Register off = len; // offset (never overlaps with 'len')
// Arguments are reversed on java expression stack
- __ movl(len, Address(rsp, wordSize)); // Length
// Calculate address of start element
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
__ movptr(buf, Address(rsp, 3*wordSize)); // long buf
- __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
+ __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
+ __ addq(buf, off); // + offset
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
} else {
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
- __ addptr(buf, Address(rsp, 2*wordSize)); // + offset
+ __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
+ __ addq(buf, off); // + offset
__ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
}
+ // Can now load 'len' since we're finished with 'off'
+ __ movl(len, Address(rsp, wordSize)); // Length
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
// result in rax
diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
index 0dc056cdbaf..518da23eb60 100644
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
@@ -211,11 +211,11 @@ int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
if (is_vtable_stub) {
// Vtable stub size
return (DebugVtables ? 512 : 24) + (CountCompiledCalls ? 13 : 0) +
- (UseCompressedKlassPointers ? 16 : 0); // 1 leaq can be 3 bytes + 1 long
+ (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
} else {
// Itable stub size
return (DebugVtables ? 512 : 74) + (CountCompiledCalls ? 13 : 0) +
- (UseCompressedKlassPointers ? 32 : 0); // 2 leaqs
+ (UseCompressedKlassPointers ? MacroAssembler::instr_size_for_decode_klass_not_null() : 0);
}
// In order to tune these parameters, run the JVM with VM options
// +PrintMiscellaneous and +WizardMode to see information about
diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad
index e47976270cd..f550208e94d 100644
--- a/hotspot/src/cpu/x86/vm/x86_64.ad
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad
@@ -1393,9 +1393,7 @@ void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
{
if (UseCompressedKlassPointers) {
st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
- if (Universe::narrow_klass_shift() != 0) {
- 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");
} else {
st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
@@ -4035,146 +4033,6 @@ operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 sca
%}
%}
-operand indirectNarrowKlass(rRegN reg)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(DecodeNKlass reg);
-
- format %{ "[$reg]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index(0x4);
- scale(0x0);
- disp(0x0);
- %}
-%}
-
-operand indOffset8NarrowKlass(rRegN reg, immL8 off)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) off);
-
- format %{ "[$reg + $off (8-bit)]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index(0x4);
- scale(0x0);
- disp($off);
- %}
-%}
-
-operand indOffset32NarrowKlass(rRegN reg, immL32 off)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) off);
-
- format %{ "[$reg + $off (32-bit)]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index(0x4);
- scale(0x0);
- disp($off);
- %}
-%}
-
-operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (AddP (DecodeNKlass reg) lreg) off);
-
- op_cost(10);
- format %{"[$reg + $off + $lreg]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale(0x0);
- disp($off);
- %}
-%}
-
-operand indIndexNarrowKlass(rRegN reg, rRegL lreg)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) lreg);
-
- op_cost(10);
- format %{"[$reg + $lreg]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale(0x0);
- disp(0x0);
- %}
-%}
-
-operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) (LShiftL lreg scale));
-
- op_cost(10);
- format %{"[$reg + $lreg << $scale]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale($scale);
- disp(0x0);
- %}
-%}
-
-operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
-%{
- predicate(Universe::narrow_klass_shift() == 0);
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off);
-
- op_cost(10);
- format %{"[$reg + $off + $lreg << $scale]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($lreg);
- scale($scale);
- disp($off);
- %}
-%}
-
-operand indCompressedKlassOffset(rRegN reg, immL32 off) %{
- predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8));
- constraint(ALLOC_IN_RC(ptr_reg));
- match(AddP (DecodeNKlass reg) off);
-
- op_cost(10);
- format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %}
- interface(MEMORY_INTER) %{
- base(0xc); // R12
- index($reg);
- scale(0x3);
- disp($off);
- %}
-%}
-
-operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale)
-%{
- constraint(ALLOC_IN_RC(ptr_reg));
- predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
- match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off);
-
- op_cost(10);
- format %{"[$reg + $off + $idx << $scale]" %}
- interface(MEMORY_INTER) %{
- base($reg);
- index($idx);
- scale($scale);
- disp($off);
- %}
-%}
-
//----------Special Memory Operands--------------------------------------------
// Stack Slot Operand - This operand is used for loading and storing temporary
// values on the stack where a match requires a value to
@@ -4345,11 +4203,7 @@ opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
indCompressedOopOffset,
indirectNarrow, indOffset8Narrow, indOffset32Narrow,
indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
- indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow,
- indCompressedKlassOffset,
- indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass,
- indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass,
- indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass);
+ indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
//----------PIPELINE-----------------------------------------------------------
// Rules which define the behavior of the target architectures pipeline.
@@ -6665,7 +6519,7 @@ instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
match(Set dst (EncodePKlass src));
effect(KILL cr);
- format %{ "encode_heap_oop_not_null $dst,$src" %}
+ format %{ "encode_klass_not_null $dst,$src" %}
ins_encode %{
__ encode_klass_not_null($dst$$Register, $src$$Register);
%}
@@ -6675,7 +6529,7 @@ instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
match(Set dst (DecodeNKlass src));
effect(KILL cr);
- format %{ "decode_heap_oop_not_null $dst,$src" %}
+ format %{ "decode_klass_not_null $dst,$src" %}
ins_encode %{
Register s = $src$$Register;
Register d = $dst$$Register;
diff --git a/hotspot/src/cpu/zero/vm/assembler_zero.cpp b/hotspot/src/cpu/zero/vm/assembler_zero.cpp
index ad1107ed12f..5438c9209b6 100644
--- a/hotspot/src/cpu/zero/vm/assembler_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/assembler_zero.cpp
@@ -50,6 +50,7 @@ int AbstractAssembler::code_fill_byte() {
#ifdef ASSERT
bool AbstractAssembler::pd_check_instruction_mark() {
ShouldNotCallThis();
+ return false;
}
#endif
@@ -73,6 +74,7 @@ void MacroAssembler::advance(int bytes) {
RegisterOrConstant MacroAssembler::delayed_value_impl(
intptr_t* delayed_value_addr, Register tmpl, int offset) {
ShouldNotCallThis();
+ return RegisterOrConstant();
}
void MacroAssembler::store_oop(jobject obj) {
diff --git a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
index 9a237998cfd..42e88a7374b 100644
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
@@ -1008,6 +1008,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState istate,
address CppInterpreter::return_entry(TosState state, int length) {
ShouldNotCallThis();
+ return NULL;
}
address CppInterpreter::deopt_entry(TosState state, int length) {
diff --git a/hotspot/src/cpu/zero/vm/frame_zero.cpp b/hotspot/src/cpu/zero/vm/frame_zero.cpp
index 56f2a7a1c71..c8623f9aade 100644
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp
@@ -116,6 +116,7 @@ void frame::patch_pc(Thread* thread, address pc) {
bool frame::safe_for_sender(JavaThread *thread) {
ShouldNotCallThis();
+ return false;
}
void frame::pd_gc_epilog() {
@@ -123,6 +124,7 @@ void frame::pd_gc_epilog() {
bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
ShouldNotCallThis();
+ return false;
}
BasicType frame::interpreter_frame_result(oop* oop_result,
@@ -184,9 +186,8 @@ BasicType frame::interpreter_frame_result(oop* oop_result,
int frame::frame_size(RegisterMap* map) const {
#ifdef PRODUCT
ShouldNotCallThis();
-#else
- return 0; // make javaVFrame::print_value work
#endif // PRODUCT
+ return 0; // make javaVFrame::print_value work
}
intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
diff --git a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
index 971560cd0d8..7f6ca09978c 100644
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
@@ -36,7 +36,7 @@ inline frame::frame() {
_deopt_state = unknown;
}
-inline address frame::sender_pc() const { ShouldNotCallThis(); }
+inline address frame::sender_pc() const { ShouldNotCallThis(); return NULL; }
inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_zeroframe = zf;
@@ -89,6 +89,7 @@ inline intptr_t* frame::real_fp() const {
inline intptr_t* frame::link() const {
ShouldNotCallThis();
+ return NULL;
}
#ifdef CC_INTERP
@@ -151,14 +152,17 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
inline oop frame::saved_oop_result(RegisterMap* map) const {
ShouldNotCallThis();
+ return NULL;
}
inline bool frame::is_older(intptr_t* id) const {
ShouldNotCallThis();
+ return false;
}
inline intptr_t* frame::entry_frame_argument_at(int offset) const {
ShouldNotCallThis();
+ return NULL;
}
inline intptr_t* frame::unextended_sp() const {
diff --git a/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp
index 95d0e115a66..bf2849b6ecc 100644
--- a/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp
@@ -49,8 +49,10 @@ void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin,
address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
// NB ic_stub_code_size() must return the size of the code we generate
ShouldNotCallThis();
+ return NULL;
}
void* InlineCacheBuffer::ic_buffer_cached_value(address code_begin) {
ShouldNotCallThis();
+ return NULL;
}
diff --git a/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp b/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp
index 493f0b7909d..97a105bea80 100644
--- a/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp
@@ -40,6 +40,7 @@ class InterpreterMacroAssembler : public MacroAssembler {
Register tmp,
int offset) {
ShouldNotCallThis();
+ return RegisterOrConstant();
}
};
diff --git a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp
index b838b8bcde5..371d65cf9bb 100644
--- a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp
@@ -64,6 +64,7 @@ address InterpreterGenerator::generate_math_entry(
return NULL;
Unimplemented();
+ return NULL;
}
address InterpreterGenerator::generate_abstract_entry() {
diff --git a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp
index 16d1d3f0dee..00599206126 100644
--- a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp
@@ -51,15 +51,18 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
public:
bool is_jump() {
ShouldNotCallThis();
+ return false;
}
bool is_safepoint_poll() {
ShouldNotCallThis();
+ return false;
}
};
inline NativeInstruction* nativeInstruction_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeCall : public NativeInstruction {
@@ -70,18 +73,22 @@ class NativeCall : public NativeInstruction {
address instruction_address() const {
ShouldNotCallThis();
+ return NULL;
}
address next_instruction_address() const {
ShouldNotCallThis();
+ return NULL;
}
address return_address() const {
ShouldNotCallThis();
+ return NULL;
}
address destination() const {
ShouldNotCallThis();
+ return NULL;
}
void set_destination_mt_safe(address dest) {
@@ -98,25 +105,30 @@ class NativeCall : public NativeInstruction {
static bool is_call_before(address return_address) {
ShouldNotCallThis();
+ return false;
}
};
inline NativeCall* nativeCall_before(address return_address) {
ShouldNotCallThis();
+ return NULL;
}
inline NativeCall* nativeCall_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeMovConstReg : public NativeInstruction {
public:
address next_instruction_address() const {
ShouldNotCallThis();
+ return NULL;
}
intptr_t data() const {
ShouldNotCallThis();
+ return 0;
}
void set_data(intptr_t x) {
@@ -126,12 +138,14 @@ class NativeMovConstReg : public NativeInstruction {
inline NativeMovConstReg* nativeMovConstReg_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeMovRegMem : public NativeInstruction {
public:
int offset() const {
ShouldNotCallThis();
+ return 0;
}
void set_offset(intptr_t x) {
@@ -145,6 +159,7 @@ class NativeMovRegMem : public NativeInstruction {
inline NativeMovRegMem* nativeMovRegMem_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeJump : public NativeInstruction {
@@ -155,6 +170,7 @@ class NativeJump : public NativeInstruction {
address jump_destination() const {
ShouldNotCallThis();
+ return NULL;
}
void set_jump_destination(address dest) {
@@ -172,12 +188,14 @@ class NativeJump : public NativeInstruction {
inline NativeJump* nativeJump_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
class NativeGeneralJump : public NativeInstruction {
public:
address jump_destination() const {
ShouldNotCallThis();
+ return NULL;
}
static void insert_unconditional(address code_pos, address entry) {
@@ -191,6 +209,7 @@ class NativeGeneralJump : public NativeInstruction {
inline NativeGeneralJump* nativeGeneralJump_at(address address) {
ShouldNotCallThis();
+ return NULL;
}
#endif // CPU_ZERO_VM_NATIVEINST_ZERO_HPP
diff --git a/hotspot/src/cpu/zero/vm/register_zero.cpp b/hotspot/src/cpu/zero/vm/register_zero.cpp
index 31bee7baf78..f11bf829aa6 100644
--- a/hotspot/src/cpu/zero/vm/register_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/register_zero.cpp
@@ -32,8 +32,10 @@ const int ConcreteRegisterImpl::max_fpr =
const char* RegisterImpl::name() const {
ShouldNotCallThis();
+ return NULL;
}
const char* FloatRegisterImpl::name() const {
ShouldNotCallThis();
+ return NULL;
}
diff --git a/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
index 5cd6c62a8de..f50190829c0 100644
--- a/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
@@ -37,6 +37,7 @@ void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
address Relocation::pd_call_destination(address orig_addr) {
ShouldNotCallThis();
+ return NULL;
}
void Relocation::pd_set_call_destination(address x) {
@@ -45,6 +46,7 @@ void Relocation::pd_set_call_destination(address x) {
address Relocation::pd_get_address_from_code() {
ShouldNotCallThis();
+ return NULL;
}
address* Relocation::pd_address_in_code() {
diff --git a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp
index 123d71ec044..2c419b14822 100644
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp
@@ -89,6 +89,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
ret_type);
#else
ShouldNotCallThis();
+ return NULL;
#endif // SHARK
}
@@ -99,6 +100,7 @@ int Deoptimization::last_frame_adjust(int callee_parameters,
uint SharedRuntime::out_preserve_stack_slots() {
ShouldNotCallThis();
+ return 0;
}
JRT_LEAF(void, zero_stub())
@@ -135,4 +137,5 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
VMRegPair *regs,
int total_args_passed) {
ShouldNotCallThis();
+ return 0;
}
diff --git a/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp b/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp
index e4ea32e44c1..67f0ea88839 100644
--- a/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp
@@ -39,16 +39,20 @@
VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
ShouldNotCallThis();
+ return NULL;
}
VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
ShouldNotCallThis();
+ return NULL;
}
int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
ShouldNotCallThis();
+ return 0;
}
int VtableStub::pd_code_alignment() {
ShouldNotCallThis();
+ return 0;
}
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 55043ad243a..6b636d379de 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -642,13 +642,14 @@ objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NU
#endif
#ifdef __APPLE__
-static uint64_t locate_unique_thread_id() {
+static uint64_t locate_unique_thread_id(mach_port_t mach_thread_port) {
// Additional thread_id used to correlate threads in SA
thread_identifier_info_data_t m_ident_info;
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- thread_info(::mach_thread_self(), THREAD_IDENTIFIER_INFO,
+ thread_info(mach_thread_port, THREAD_IDENTIFIER_INFO,
(thread_info_t) &m_ident_info, &count);
+
return m_ident_info.thread_id;
}
#endif
@@ -679,9 +680,14 @@ static void *java_start(Thread *thread) {
}
#ifdef __APPLE__
- // thread_id is mach thread on macos
- osthread->set_thread_id(::mach_thread_self());
- osthread->set_unique_thread_id(locate_unique_thread_id());
+ // thread_id is mach thread on macos, which pthreads graciously caches and provides for us
+ mach_port_t thread_id = ::pthread_mach_thread_np(::pthread_self());
+ guarantee(thread_id != 0, "thread id missing from pthreads");
+ osthread->set_thread_id(thread_id);
+
+ uint64_t unique_thread_id = locate_unique_thread_id(thread_id);
+ guarantee(unique_thread_id != 0, "unique thread id was not found");
+ osthread->set_unique_thread_id(unique_thread_id);
#else
// thread_id is pthread_id on BSD
osthread->set_thread_id(::pthread_self());
@@ -843,8 +849,14 @@ bool os::create_attached_thread(JavaThread* thread) {
// Store pthread info into the OSThread
#ifdef __APPLE__
- osthread->set_thread_id(::mach_thread_self());
- osthread->set_unique_thread_id(locate_unique_thread_id());
+ // thread_id is mach thread on macos, which pthreads graciously caches and provides for us
+ mach_port_t thread_id = ::pthread_mach_thread_np(::pthread_self());
+ guarantee(thread_id != 0, "just checking");
+ osthread->set_thread_id(thread_id);
+
+ uint64_t unique_thread_id = locate_unique_thread_id(thread_id);
+ guarantee(unique_thread_id != 0, "just checking");
+ osthread->set_unique_thread_id(unique_thread_id);
#else
osthread->set_thread_id(::pthread_self());
#endif
@@ -1115,7 +1127,7 @@ size_t os::lasterror(char *buf, size_t len) {
intx os::current_thread_id() {
#ifdef __APPLE__
- return (intx)::mach_thread_self();
+ return (intx)::pthread_mach_thread_np(::pthread_self());
#else
return (intx)::pthread_self();
#endif
@@ -2313,7 +2325,9 @@ void os::large_page_init() {
}
-char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
+char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+ fatal("This code is not used or maintained.");
+
// "exec" is passed in but not used. Creating the shared image for
// the code cache doesn't have an SHM_X executable permission to check.
assert(UseLargePages && UseSHM, "only for SHM large pages");
@@ -3275,11 +3289,15 @@ void os::Bsd::install_signal_handlers() {
// and if UserSignalHandler is installed all bets are off
if (CheckJNICalls) {
if (libjsig_is_loaded) {
- tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
+ if (PrintJNIResolving) {
+ tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
+ }
check_signals = false;
}
if (AllowUserSignalHandlers) {
- tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
+ if (PrintJNIResolving) {
+ tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
+ }
check_signals = false;
}
}
@@ -4736,3 +4754,8 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
return n;
}
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+ // No tests available for this platform
+}
+#endif
diff --git a/hotspot/src/os/linux/vm/globals_linux.hpp b/hotspot/src/os/linux/vm/globals_linux.hpp
index af4947b1b86..4dfccc3f6ee 100644
--- a/hotspot/src/os/linux/vm/globals_linux.hpp
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp
@@ -40,6 +40,9 @@
product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \
\
+ product(bool, UseTransparentHugePages, false, \
+ "Use MADV_HUGEPAGE for large pages") \
+ \
product(bool, LoadExecStackDllInVMThread, true, \
"Load DLLs with executable-stack attribute in the VM Thread") \
\
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index df58be635d1..23d3457046d 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -2720,36 +2720,7 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
int os::Linux::commit_memory_impl(char* addr, size_t size,
size_t alignment_hint, bool exec) {
- int err;
- if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
- int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
- uintptr_t res =
- (uintptr_t) ::mmap(addr, size, prot,
- MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
- -1, 0);
- if (res != (uintptr_t) MAP_FAILED) {
- if (UseNUMAInterleaving) {
- numa_make_global(addr, size);
- }
- return 0;
- }
-
- err = errno; // save errno from mmap() call above
-
- if (!recoverable_mmap_error(err)) {
- // However, it is not clear that this loss of our reserved mapping
- // happens with large pages on Linux or that we cannot recover
- // from the loss. For now, we just issue a warning and we don't
- // call vm_exit_out_of_memory(). This issue is being tracked by
- // JBS-8007074.
- warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
-// vm_exit_out_of_memory(size, OOM_MMAP_ERROR,
-// "committing reserved memory.");
- }
- // Fall through and try to use small pages
- }
-
- err = os::Linux::commit_memory_impl(addr, size, exec);
+ int err = os::Linux::commit_memory_impl(addr, size, exec);
if (err == 0) {
realign_memory(addr, size, alignment_hint);
}
@@ -2774,7 +2745,7 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size,
}
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
- if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
+ if (UseTransparentHugePages && alignment_hint > (size_t)vm_page_size()) {
// We don't check the return value: madvise(MADV_HUGEPAGE) may not
// be supported or the memory may already be backed by huge pages.
::madvise(addr, bytes, MADV_HUGEPAGE);
@@ -2787,7 +2758,7 @@ void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
// uncommitted at all. We don't do anything in this case to avoid creating a segment with
// small pages on top of the SHM segment. This method always works for small pages, so we
// allow that in any case.
- if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
+ if (alignment_hint <= (size_t)os::vm_page_size() || can_commit_large_page_memory()) {
commit_memory(addr, bytes, alignment_hint, !ExecMem);
}
}
@@ -3157,11 +3128,31 @@ bool os::unguard_memory(char* addr, size_t size) {
return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
}
+bool os::Linux::transparent_huge_pages_sanity_check(bool warn, size_t page_size) {
+ bool result = false;
+ void *p = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE,
+ -1, 0);
+ if (p != MAP_FAILED) {
+ void *aligned_p = align_ptr_up(p, page_size);
+
+ result = madvise(aligned_p, page_size, MADV_HUGEPAGE) == 0;
+
+ munmap(p, page_size * 2);
+ }
+
+ if (warn && !result) {
+ warning("TransparentHugePages is not supported by the operating system.");
+ }
+
+ return result;
+}
+
bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
bool result = false;
- void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
- MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
- -1, 0);
+ void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
+ -1, 0);
if (p != MAP_FAILED) {
// We don't know if this really is a huge page or not.
@@ -3182,12 +3173,10 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
}
fclose(fp);
}
- munmap (p, page_size);
- if (result)
- return true;
+ munmap(p, page_size);
}
- if (warn) {
+ if (warn && !result) {
warning("HugeTLBFS is not supported by the operating system.");
}
@@ -3235,82 +3224,114 @@ static void set_coredump_filter(void) {
static size_t _large_page_size = 0;
-void os::large_page_init() {
- if (!UseLargePages) {
- UseHugeTLBFS = false;
- UseSHM = false;
- return;
- }
+size_t os::Linux::find_large_page_size() {
+ size_t large_page_size = 0;
- if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
- // If UseLargePages is specified on the command line try both methods,
- // if it's default, then try only HugeTLBFS.
- if (FLAG_IS_DEFAULT(UseLargePages)) {
- UseHugeTLBFS = true;
- } else {
- UseHugeTLBFS = UseSHM = true;
- }
- }
-
- if (LargePageSizeInBytes) {
- _large_page_size = LargePageSizeInBytes;
- } else {
- // large_page_size on Linux is used to round up heap size. x86 uses either
- // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
- // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
- // page as large as 256M.
- //
- // Here we try to figure out page size by parsing /proc/meminfo and looking
- // for a line with the following format:
- // Hugepagesize: 2048 kB
- //
- // If we can't determine the value (e.g. /proc is not mounted, or the text
- // format has been changed), we'll use the largest page size supported by
- // the processor.
+ // large_page_size on Linux is used to round up heap size. x86 uses either
+ // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
+ // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
+ // page as large as 256M.
+ //
+ // Here we try to figure out page size by parsing /proc/meminfo and looking
+ // for a line with the following format:
+ // Hugepagesize: 2048 kB
+ //
+ // If we can't determine the value (e.g. /proc is not mounted, or the text
+ // format has been changed), we'll use the largest page size supported by
+ // the processor.
#ifndef ZERO
- _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
- ARM_ONLY(2 * M) PPC_ONLY(4 * M);
+ large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
+ ARM_ONLY(2 * M) PPC_ONLY(4 * M);
#endif // ZERO
- FILE *fp = fopen("/proc/meminfo", "r");
- if (fp) {
- while (!feof(fp)) {
- int x = 0;
- char buf[16];
- if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
- if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
- _large_page_size = x * K;
- break;
- }
- } else {
- // skip to next line
- for (;;) {
- int ch = fgetc(fp);
- if (ch == EOF || ch == (int)'\n') break;
- }
+ FILE *fp = fopen("/proc/meminfo", "r");
+ if (fp) {
+ while (!feof(fp)) {
+ int x = 0;
+ char buf[16];
+ if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
+ if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
+ large_page_size = x * K;
+ break;
+ }
+ } else {
+ // skip to next line
+ for (;;) {
+ int ch = fgetc(fp);
+ if (ch == EOF || ch == (int)'\n') break;
}
}
- fclose(fp);
}
+ fclose(fp);
}
- // print a warning if any large page related flag is specified on command line
- bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
+ if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) {
+ warning("Setting LargePageSizeInBytes has no effect on this OS. Large page size is "
+ SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size),
+ proper_unit_for_byte_size(large_page_size));
+ }
+ return large_page_size;
+}
+
+size_t os::Linux::setup_large_page_size() {
+ _large_page_size = Linux::find_large_page_size();
const size_t default_page_size = (size_t)Linux::page_size();
if (_large_page_size > default_page_size) {
_page_sizes[0] = _large_page_size;
_page_sizes[1] = default_page_size;
_page_sizes[2] = 0;
}
- UseHugeTLBFS = UseHugeTLBFS &&
- Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
- if (UseHugeTLBFS)
+ return _large_page_size;
+}
+
+bool os::Linux::setup_large_page_type(size_t page_size) {
+ if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
+ FLAG_IS_DEFAULT(UseSHM) &&
+ FLAG_IS_DEFAULT(UseTransparentHugePages)) {
+ // If UseLargePages is specified on the command line try all methods,
+ // if it's default, then try only UseTransparentHugePages.
+ if (FLAG_IS_DEFAULT(UseLargePages)) {
+ UseTransparentHugePages = true;
+ } else {
+ UseHugeTLBFS = UseTransparentHugePages = UseSHM = true;
+ }
+ }
+
+ if (UseTransparentHugePages) {
+ bool warn_on_failure = !FLAG_IS_DEFAULT(UseTransparentHugePages);
+ if (transparent_huge_pages_sanity_check(warn_on_failure, page_size)) {
+ UseHugeTLBFS = false;
+ UseSHM = false;
+ return true;
+ }
+ UseTransparentHugePages = false;
+ }
+
+ if (UseHugeTLBFS) {
+ bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
+ if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
+ UseSHM = false;
+ return true;
+ }
+ UseHugeTLBFS = false;
+ }
+
+ return UseSHM;
+}
+
+void os::large_page_init() {
+ if (!UseLargePages) {
+ UseHugeTLBFS = false;
+ UseTransparentHugePages = false;
UseSHM = false;
+ return;
+ }
- UseLargePages = UseHugeTLBFS || UseSHM;
+ size_t large_page_size = Linux::setup_large_page_size();
+ UseLargePages = Linux::setup_large_page_type(large_page_size);
set_coredump_filter();
}
@@ -3319,16 +3340,22 @@ void os::large_page_init() {
#define SHM_HUGETLB 04000
#endif
-char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
+char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec) {
// "exec" is passed in but not used. Creating the shared image for
// the code cache doesn't have an SHM_X executable permission to check.
assert(UseLargePages && UseSHM, "only for SHM large pages");
+ assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
+
+ if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
+ return NULL; // Fallback to small pages.
+ }
key_t key = IPC_PRIVATE;
char *addr;
bool warn_on_failure = UseLargePages &&
(!FLAG_IS_DEFAULT(UseLargePages) ||
+ !FLAG_IS_DEFAULT(UseSHM) ||
!FLAG_IS_DEFAULT(LargePageSizeInBytes)
);
char msg[128];
@@ -3376,42 +3403,219 @@ char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
return NULL;
}
- if ((addr != NULL) && UseNUMAInterleaving) {
- numa_make_global(addr, bytes);
+ return addr;
+}
+
+static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) {
+ assert(error == ENOMEM, "Only expect to fail if no memory is available");
+
+ bool warn_on_failure = UseLargePages &&
+ (!FLAG_IS_DEFAULT(UseLargePages) ||
+ !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
+ !FLAG_IS_DEFAULT(LargePageSizeInBytes));
+
+ if (warn_on_failure) {
+ char msg[128];
+ jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: "
+ PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
+ warning(msg);
+ }
+}
+
+char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec) {
+ assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
+ assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
+ assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
+
+ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+ char* addr = (char*)::mmap(req_addr, bytes, prot,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
+ -1, 0);
+
+ if (addr == MAP_FAILED) {
+ warn_on_large_pages_failure(req_addr, bytes, errno);
+ return NULL;
}
- // The memory is committed
- MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
+ assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
return addr;
}
+char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+ size_t large_page_size = os::large_page_size();
+
+ assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
+
+ // Allocate small pages.
+
+ char* start;
+ if (req_addr != NULL) {
+ assert(is_ptr_aligned(req_addr, alignment), "Must be");
+ assert(is_size_aligned(bytes, alignment), "Must be");
+ start = os::reserve_memory(bytes, req_addr);
+ assert(start == NULL || start == req_addr, "Must be");
+ } else {
+ start = os::reserve_memory_aligned(bytes, alignment);
+ }
+
+ if (start == NULL) {
+ return NULL;
+ }
+
+ assert(is_ptr_aligned(start, alignment), "Must be");
+
+ // os::reserve_memory_special will record this memory area.
+ // Need to release it here to prevent overlapping reservations.
+ MemTracker::record_virtual_memory_release((address)start, bytes);
+
+ char* end = start + bytes;
+
+ // Find the regions of the allocated chunk that can be promoted to large pages.
+ char* lp_start = (char*)align_ptr_up(start, large_page_size);
+ char* lp_end = (char*)align_ptr_down(end, large_page_size);
+
+ size_t lp_bytes = lp_end - lp_start;
+
+ assert(is_size_aligned(lp_bytes, large_page_size), "Must be");
+
+ if (lp_bytes == 0) {
+ // The mapped region doesn't even span the start and the end of a large page.
+ // Fall back to allocate a non-special area.
+ ::munmap(start, end - start);
+ return NULL;
+ }
+
+ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
+
+
+ void* result;
+
+ if (start != lp_start) {
+ result = ::mmap(start, lp_start - start, prot,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
+ -1, 0);
+ if (result == MAP_FAILED) {
+ ::munmap(lp_start, end - lp_start);
+ return NULL;
+ }
+ }
+
+ result = ::mmap(lp_start, lp_bytes, prot,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB,
+ -1, 0);
+ if (result == MAP_FAILED) {
+ warn_on_large_pages_failure(req_addr, bytes, errno);
+ // If the mmap above fails, the large pages region will be unmapped and we
+ // have regions before and after with small pages. Release these regions.
+ //
+ // | mapped | unmapped | mapped |
+ // ^ ^ ^ ^
+ // start lp_start lp_end end
+ //
+ ::munmap(start, lp_start - start);
+ ::munmap(lp_end, end - lp_end);
+ return NULL;
+ }
+
+ if (lp_end != end) {
+ result = ::mmap(lp_end, end - lp_end, prot,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
+ -1, 0);
+ if (result == MAP_FAILED) {
+ ::munmap(start, lp_end - start);
+ return NULL;
+ }
+ }
+
+ return start;
+}
+
+char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+ assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
+ assert(is_ptr_aligned(req_addr, alignment), "Must be");
+ assert(is_power_of_2(alignment), "Must be");
+ assert(is_power_of_2(os::large_page_size()), "Must be");
+ assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes");
+
+ if (is_size_aligned(bytes, os::large_page_size()) && alignment <= os::large_page_size()) {
+ return reserve_memory_special_huge_tlbfs_only(bytes, req_addr, exec);
+ } else {
+ return reserve_memory_special_huge_tlbfs_mixed(bytes, alignment, req_addr, exec);
+ }
+}
+
+char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
+ assert(UseLargePages, "only for large pages");
+
+ char* addr;
+ if (UseSHM) {
+ addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
+ } else {
+ assert(UseHugeTLBFS, "must be");
+ addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec);
+ }
+
+ if (addr != NULL) {
+ if (UseNUMAInterleaving) {
+ numa_make_global(addr, bytes);
+ }
+
+ // The memory is committed
+ MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
+ }
+
+ return addr;
+}
+
+bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
+ // detaching the SHM segment will also delete it, see reserve_memory_special_shm()
+ return shmdt(base) == 0;
+}
+
+bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
+ return pd_release_memory(base, bytes);
+}
+
bool os::release_memory_special(char* base, size_t bytes) {
+ assert(UseLargePages, "only for large pages");
+
MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
- // detaching the SHM segment will also delete it, see reserve_memory_special()
- int rslt = shmdt(base);
- if (rslt == 0) {
+
+ bool res;
+ if (UseSHM) {
+ res = os::Linux::release_memory_special_shm(base, bytes);
+ } else {
+ assert(UseHugeTLBFS, "must be");
+ res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
+ }
+
+ if (res) {
tkr.record((address)base, bytes);
- return true;
} else {
tkr.discard();
- return false;
}
+
+ return res;
}
size_t os::large_page_size() {
return _large_page_size;
}
-// HugeTLBFS allows application to commit large page memory on demand;
-// with SysV SHM the entire memory region must be allocated as shared
+// With SysV SHM the entire memory region must be allocated as shared
// memory.
+// HugeTLBFS allows application to commit large page memory on demand.
+// However, when committing memory with HugeTLBFS fails, the region
+// that was supposed to be committed will lose the old reservation
+// and allow other threads to steal that memory region. Because of this
+// behavior we can't commit HugeTLBFS memory.
bool os::can_commit_large_page_memory() {
- return UseHugeTLBFS;
+ return UseTransparentHugePages;
}
bool os::can_execute_large_page_memory() {
- return UseHugeTLBFS;
+ return UseTransparentHugePages || UseHugeTLBFS;
}
// Reserve memory at an arbitrary address, only if that area is
@@ -4563,21 +4767,23 @@ jint os::init_2(void)
UseNUMA = false;
}
}
- // With SHM large pages we cannot uncommit a page, so there's not way
+ // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
// we can make the adaptive lgrp chunk resizing work. If the user specified
- // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and
+ // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
// disable adaptive resizing.
- if (UseNUMA && UseLargePages && UseSHM) {
- if (!FLAG_IS_DEFAULT(UseNUMA)) {
- if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) {
+ if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
+ if (FLAG_IS_DEFAULT(UseNUMA)) {
+ UseNUMA = false;
+ } else {
+ if (FLAG_IS_DEFAULT(UseLargePages) &&
+ FLAG_IS_DEFAULT(UseSHM) &&
+ FLAG_IS_DEFAULT(UseHugeTLBFS)) {
UseLargePages = false;
} else {
- warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing");
+ warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing");
UseAdaptiveSizePolicy = false;
UseAdaptiveNUMAChunkSizing = false;
}
- } else {
- UseNUMA = false;
}
}
if (!UseNUMA && ForceNUMA) {
@@ -5848,3 +6054,149 @@ void MemNotifyThread::start() {
}
#endif // JAVASE_EMBEDDED
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+#define test_log(...) \
+ do {\
+ if (VerboseInternalVMTests) { \
+ tty->print_cr(__VA_ARGS__); \
+ tty->flush(); \
+ }\
+ } while (false)
+
+class TestReserveMemorySpecial : AllStatic {
+ public:
+ static void small_page_write(void* addr, size_t size) {
+ size_t page_size = os::vm_page_size();
+
+ char* end = (char*)addr + size;
+ for (char* p = (char*)addr; p < end; p += page_size) {
+ *p = 1;
+ }
+ }
+
+ static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
+ if (!UseHugeTLBFS) {
+ return;
+ }
+
+ test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size);
+
+ char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false);
+
+ if (addr != NULL) {
+ small_page_write(addr, size);
+
+ os::Linux::release_memory_special_huge_tlbfs(addr, size);
+ }
+ }
+
+ static void test_reserve_memory_special_huge_tlbfs_only() {
+ if (!UseHugeTLBFS) {
+ return;
+ }
+
+ size_t lp = os::large_page_size();
+
+ for (size_t size = lp; size <= lp * 10; size += lp) {
+ test_reserve_memory_special_huge_tlbfs_only(size);
+ }
+ }
+
+ static void test_reserve_memory_special_huge_tlbfs_mixed(size_t size, size_t alignment) {
+ if (!UseHugeTLBFS) {
+ return;
+ }
+
+ test_log("test_reserve_memory_special_huge_tlbfs_mixed(" SIZE_FORMAT ", " SIZE_FORMAT ")",
+ size, alignment);
+
+ assert(size >= os::large_page_size(), "Incorrect input to test");
+
+ char* addr = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
+
+ if (addr != NULL) {
+ small_page_write(addr, size);
+
+ os::Linux::release_memory_special_huge_tlbfs(addr, size);
+ }
+ }
+
+ static void test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(size_t size) {
+ size_t lp = os::large_page_size();
+ size_t ag = os::vm_allocation_granularity();
+
+ for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
+ test_reserve_memory_special_huge_tlbfs_mixed(size, alignment);
+ }
+ }
+
+ static void test_reserve_memory_special_huge_tlbfs_mixed() {
+ size_t lp = os::large_page_size();
+ size_t ag = os::vm_allocation_granularity();
+
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + lp / 2);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10);
+ test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10 + lp / 2);
+ }
+
+ static void test_reserve_memory_special_huge_tlbfs() {
+ if (!UseHugeTLBFS) {
+ return;
+ }
+
+ test_reserve_memory_special_huge_tlbfs_only();
+ test_reserve_memory_special_huge_tlbfs_mixed();
+ }
+
+ static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
+ if (!UseSHM) {
+ return;
+ }
+
+ test_log("test_reserve_memory_special_shm(" SIZE_FORMAT ", " SIZE_FORMAT ")", size, alignment);
+
+ char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
+
+ if (addr != NULL) {
+ assert(is_ptr_aligned(addr, alignment), "Check");
+ assert(is_ptr_aligned(addr, os::large_page_size()), "Check");
+
+ small_page_write(addr, size);
+
+ os::Linux::release_memory_special_shm(addr, size);
+ }
+ }
+
+ static void test_reserve_memory_special_shm() {
+ size_t lp = os::large_page_size();
+ size_t ag = os::vm_allocation_granularity();
+
+ for (size_t size = ag; size < lp * 3; size += ag) {
+ for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
+ test_reserve_memory_special_shm(size, alignment);
+ }
+ }
+ }
+
+ static void test() {
+ test_reserve_memory_special_huge_tlbfs();
+ test_reserve_memory_special_shm();
+ }
+};
+
+void TestReserveMemorySpecial_test() {
+ TestReserveMemorySpecial::test();
+}
+
+#endif
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index 8c5032fc23b..5fa24499319 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -32,6 +32,7 @@ typedef int (*pthread_getattr_func_type) (pthread_t, pthread_attr_t *);
class Linux {
friend class os;
+ friend class TestReserveMemorySpecial;
// For signal-chaining
#define MAXSIGNUM 32
@@ -92,8 +93,21 @@ class Linux {
static void rebuild_cpu_to_node_map();
static GrowableArray* cpu_to_node() { return _cpu_to_node; }
+ static size_t find_large_page_size();
+ static size_t setup_large_page_size();
+
+ static bool setup_large_page_type(size_t page_size);
+ static bool transparent_huge_pages_sanity_check(bool warn, size_t pages_size);
static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
+ static char* reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec);
+ static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec);
+ static char* reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec);
+ static char* reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec);
+
+ static bool release_memory_special_shm(char* base, size_t bytes);
+ static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
+
static void print_full_memory_info(outputStream* st);
static void print_distro_info(outputStream* st);
static void print_libversion_info(outputStream* st);
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
index bf6a1fafacd..d3ae881d931 100644
--- a/hotspot/src/os/posix/vm/os_posix.cpp
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -260,6 +260,55 @@ FILE* os::open(int fd, const char* mode) {
return ::fdopen(fd, mode);
}
+void* os::get_default_process_handle() {
+ return (void*)::dlopen(NULL, RTLD_LAZY);
+}
+
+// Builds a platform dependent Agent_OnLoad_ function name
+// which is used to find statically linked in agents.
+// Parameters:
+// sym_name: Symbol in library we are looking for
+// lib_name: Name of library to look in, NULL for shared libs.
+// is_absolute_path == true if lib_name is absolute path to agent
+// such as "/a/b/libL.so"
+// == false if only the base name of the library is passed in
+// such as "L"
+char* os::build_agent_function_name(const char *sym_name, const char *lib_name,
+ bool is_absolute_path) {
+ char *agent_entry_name;
+ size_t len;
+ size_t name_len;
+ size_t prefix_len = strlen(JNI_LIB_PREFIX);
+ size_t suffix_len = strlen(JNI_LIB_SUFFIX);
+ const char *start;
+
+ if (lib_name != NULL) {
+ len = name_len = strlen(lib_name);
+ if (is_absolute_path) {
+ // Need to strip path, prefix and suffix
+ if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {
+ lib_name = ++start;
+ }
+ if (len <= (prefix_len + suffix_len)) {
+ return NULL;
+ }
+ lib_name += prefix_len;
+ name_len = strlen(lib_name) - suffix_len;
+ }
+ }
+ len = (lib_name != NULL ? name_len : 0) + strlen(sym_name) + 2;
+ agent_entry_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtThread);
+ if (agent_entry_name == NULL) {
+ return NULL;
+ }
+ strcpy(agent_entry_name, sym_name);
+ if (lib_name != NULL) {
+ strcat(agent_entry_name, "_");
+ strncat(agent_entry_name, lib_name, name_len);
+ }
+ return agent_entry_name;
+}
+
os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
}
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index 0a94cb536ab..c3e6e879077 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -3385,7 +3385,7 @@ bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
return true;
}
-char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
+char* os::reserve_memory_special(size_t size, size_t alignment, char* addr, bool exec) {
fatal("os::reserve_memory_special should not be called on Solaris.");
return NULL;
}
@@ -6601,3 +6601,9 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
return strlen(buffer);
}
+
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+ // No tests available for this platform
+}
+#endif
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 0674e6f3c83..015f94d6662 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -3156,7 +3156,12 @@ bool os::can_execute_large_page_memory() {
return true;
}
-char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
+char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr, bool exec) {
+ assert(UseLargePages, "only for large pages");
+
+ if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
+ return NULL; // Fallback to small pages.
+ }
const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
@@ -5394,6 +5399,75 @@ inline BOOL os::Advapi32Dll::AdvapiAvailable() {
return true;
}
+void* os::get_default_process_handle() {
+ return (void*)GetModuleHandle(NULL);
+}
+
+// Builds a platform dependent Agent_OnLoad_ function name
+// which is used to find statically linked in agents.
+// Additionally for windows, takes into account __stdcall names.
+// Parameters:
+// sym_name: Symbol in library we are looking for
+// lib_name: Name of library to look in, NULL for shared libs.
+// is_absolute_path == true if lib_name is absolute path to agent
+// such as "C:/a/b/L.dll"
+// == false if only the base name of the library is passed in
+// such as "L"
+char* os::build_agent_function_name(const char *sym_name, const char *lib_name,
+ bool is_absolute_path) {
+ char *agent_entry_name;
+ size_t len;
+ size_t name_len;
+ size_t prefix_len = strlen(JNI_LIB_PREFIX);
+ size_t suffix_len = strlen(JNI_LIB_SUFFIX);
+ const char *start;
+
+ if (lib_name != NULL) {
+ len = name_len = strlen(lib_name);
+ if (is_absolute_path) {
+ // Need to strip path, prefix and suffix
+ if ((start = strrchr(lib_name, *os::file_separator())) != NULL) {
+ lib_name = ++start;
+ } else {
+ // Need to check for C:
+ if ((start = strchr(lib_name, ':')) != NULL) {
+ lib_name = ++start;
+ }
+ }
+ if (len <= (prefix_len + suffix_len)) {
+ return NULL;
+ }
+ lib_name += prefix_len;
+ name_len = strlen(lib_name) - suffix_len;
+ }
+ }
+ len = (lib_name != NULL ? name_len : 0) + strlen(sym_name) + 2;
+ agent_entry_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtThread);
+ if (agent_entry_name == NULL) {
+ return NULL;
+ }
+ if (lib_name != NULL) {
+ const char *p = strrchr(sym_name, '@');
+ if (p != NULL && p != sym_name) {
+ // sym_name == _Agent_OnLoad@XX
+ strncpy(agent_entry_name, sym_name, (p - sym_name));
+ agent_entry_name[(p-sym_name)] = '\0';
+ // agent_entry_name == _Agent_OnLoad
+ strcat(agent_entry_name, "_");
+ strncat(agent_entry_name, lib_name, name_len);
+ strcat(agent_entry_name, p);
+ // agent_entry_name == _Agent_OnLoad_lib_name@XX
+ } else {
+ strcpy(agent_entry_name, sym_name);
+ strcat(agent_entry_name, "_");
+ strncat(agent_entry_name, lib_name, name_len);
+ }
+ } else {
+ strcpy(agent_entry_name, sym_name);
+ }
+ return agent_entry_name;
+}
+
#else
// Kernel32 API
typedef BOOL (WINAPI* SwitchToThread_Fn)(void);
@@ -5638,3 +5712,9 @@ BOOL os::Advapi32Dll::AdvapiAvailable() {
}
#endif
+
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+ // No tests available for this platform
+}
+#endif
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp
index 8cb9d4a1451..c7459d5a514 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp
@@ -190,7 +190,7 @@ inline void OrderAccess::release_store_fence(volatile juint* p, juint v)
inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store_fence((volatile jlong*)p, (jlong)v); }
inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { *p = v; fence(); }
-inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jdouble_cast(v)); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store_fence((volatile jlong*)p, jlong_cast(v)); }
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) {
#ifdef AMD64
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
index 24f364e985f..ad3ebb2ead9 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
@@ -715,6 +715,7 @@ JVM_handle_bsd_signal(int sig,
err.report_and_die();
ShouldNotReachHere();
+ return false;
}
// From solaris_i486.s ported to bsd_i486.s
diff --git a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
index d2a8c247f0a..7903217291b 100644
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
@@ -66,6 +66,7 @@ address os::current_stack_pointer() {
frame os::get_sender_for_C_frame(frame* fr) {
ShouldNotCallThis();
+ return frame();
}
frame os::current_frame() {
@@ -103,16 +104,19 @@ void os::initialize_thread(Thread* thr) {
address os::Bsd::ucontext_get_pc(ucontext_t* uc) {
ShouldNotCallThis();
+ return NULL;
}
ExtendedPC os::fetch_frame_from_context(void* ucVoid,
intptr_t** ret_sp,
intptr_t** ret_fp) {
ShouldNotCallThis();
+ return ExtendedPC();
}
frame os::fetch_frame_from_context(void* ucVoid) {
ShouldNotCallThis();
+ return frame();
}
extern "C" JNIEXPORT int
@@ -240,6 +244,7 @@ JVM_handle_bsd_signal(int sig,
sprintf(buf, fmt, sig, info->si_addr);
fatal(buf);
+ return false;
}
void os::Bsd::init_thread_fpu_state(void) {
@@ -373,17 +378,7 @@ void os::print_register_info(outputStream *st, void *context) {
extern "C" {
int SpinPause() {
- }
-
- int SafeFetch32(int *adr, int errValue) {
- int value = errValue;
- value = *adr;
- return value;
- }
- intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
- intptr_t value = errValue;
- value = *adr;
- return value;
+ return 1;
}
void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
diff --git a/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp b/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp
index 12971a6a868..983aea1a2a6 100644
--- a/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp
+++ b/hotspot/src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp
@@ -110,6 +110,7 @@
void* ucontext,
bool isInJava) {
ShouldNotCallThis();
+ return false;
}
// These routines are only used on cpu architectures that
diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
index 908571f6cc4..9a1c4cce21f 100644
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
@@ -915,16 +915,6 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
// Return to the now deoptimized frame.
}
- // If we are patching in a non-perm oop, make sure the nmethod
- // is on the right list.
- if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) {
- MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
- nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
- guarantee(nm != NULL, "only nmethods can contain non-perm oops");
- if (!nm->on_scavenge_root_list())
- CodeCache::add_scavenge_root_nmethod(nm);
- }
-
// Now copy code back
{
@@ -1125,6 +1115,21 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i
}
}
}
+
+ // If we are patching in a non-perm oop, make sure the nmethod
+ // is on the right list.
+ if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) {
+ MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
+ guarantee(nm != NULL, "only nmethods can contain non-perm oops");
+ if (!nm->on_scavenge_root_list()) {
+ CodeCache::add_scavenge_root_nmethod(nm);
+ }
+
+ // Since we've patched some oops in the nmethod,
+ // (re)register it with the heap.
+ Universe::heap()->register_nmethod(nm);
+ }
JRT_END
//
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 3ffacd39aff..507bb477a88 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -2590,7 +2590,7 @@ void ClassFileParser::parse_classfile_sourcefile_attribute(TRAPS) {
valid_symbol_at(sourcefile_index),
"Invalid SourceFile attribute at constant pool index %u in class file %s",
sourcefile_index, CHECK);
- set_class_sourcefile(_cp->symbol_at(sourcefile_index));
+ set_class_sourcefile_index(sourcefile_index);
}
@@ -2728,7 +2728,7 @@ void ClassFileParser::parse_classfile_signature_attribute(TRAPS) {
valid_symbol_at(signature_index),
"Invalid constant pool index %u in Signature attribute in class file %s",
signature_index, CHECK);
- set_class_generic_signature(_cp->symbol_at(signature_index));
+ set_class_generic_signature_index(signature_index);
}
void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_byte_length, TRAPS) {
@@ -2975,13 +2975,11 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) {
if (_synthetic_flag)
k->set_is_synthetic();
- if (_sourcefile != NULL) {
- _sourcefile->increment_refcount();
- k->set_source_file_name(_sourcefile);
+ if (_sourcefile_index != 0) {
+ k->set_source_file_name_index(_sourcefile_index);
}
- if (_generic_signature != NULL) {
- _generic_signature->increment_refcount();
- k->set_generic_signature(_generic_signature);
+ if (_generic_signature_index != 0) {
+ k->set_generic_signature_index(_generic_signature_index);
}
if (_sde_buffer != NULL) {
k->set_source_debug_extension(_sde_buffer, _sde_length);
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index 8f070747250..1b5ed30c5a6 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -62,8 +62,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
bool _synthetic_flag;
int _sde_length;
char* _sde_buffer;
- Symbol* _sourcefile;
- Symbol* _generic_signature;
+ u2 _sourcefile_index;
+ u2 _generic_signature_index;
// Metadata created before the instance klass is created. Must be deallocated
// if not transferred to the InstanceKlass upon successful class loading
@@ -81,16 +81,16 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array* _fields_type_annotations;
InstanceKlass* _klass; // InstanceKlass once created.
- void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
- void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
- void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
- void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
+ void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
+ void set_class_sourcefile_index(u2 x) { _sourcefile_index = x; }
+ void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }
+ void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
void init_parsed_class_attributes(ClassLoaderData* loader_data) {
_loader_data = loader_data;
_synthetic_flag = false;
- _sourcefile = NULL;
- _generic_signature = NULL;
+ _sourcefile_index = 0;
+ _generic_signature_index = 0;
_sde_buffer = NULL;
_sde_length = 0;
// initialize the other flags too:
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 1dfc3ba8f07..9412feff709 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -687,6 +687,7 @@ nmethod::nmethod(
code_buffer->copy_values_to(this);
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
CodeCache::add_scavenge_root_nmethod(this);
+ Universe::heap()->register_nmethod(this);
}
debug_only(verify_scavenge_root_oops());
CodeCache::commit(this);
@@ -881,6 +882,7 @@ nmethod::nmethod(
dependencies->copy_to(this);
if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
CodeCache::add_scavenge_root_nmethod(this);
+ Universe::heap()->register_nmethod(this);
}
debug_only(verify_scavenge_root_oops());
@@ -1300,6 +1302,13 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
methodHandle the_method(method());
No_Safepoint_Verifier nsv;
+ // during patching, depending on the nmethod state we must notify the GC that
+ // code has been unloaded, unregistering it. We cannot do this right while
+ // holding the Patching_lock because we need to use the CodeCache_lock. This
+ // would be prone to deadlocks.
+ // This flag is used to remember whether we need to later lock and unregister.
+ bool nmethod_needs_unregister = false;
+
{
// invalidate osr nmethod before acquiring the patching lock since
// they both acquire leaf locks and we don't want a deadlock.
@@ -1332,6 +1341,13 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
inc_decompile_count();
}
+ // If the state is becoming a zombie, signal to unregister the nmethod with
+ // the heap.
+ // This nmethod may have already been unloaded during a full GC.
+ if ((state == zombie) && !is_unloaded()) {
+ nmethod_needs_unregister = true;
+ }
+
// Change state
_state = state;
@@ -1367,6 +1383,9 @@ bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
// safepoint can sneak in, otherwise the oops used by the
// dependency logic could have become stale.
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ if (nmethod_needs_unregister) {
+ Universe::heap()->unregister_nmethod(this);
+ }
flush_dependencies(NULL);
}
@@ -1817,21 +1836,10 @@ void nmethod::metadata_do(void f(Metadata*)) {
if (_method != NULL) f(_method);
}
-
-// This method is called twice during GC -- once while
-// tracing the "active" nmethods on thread stacks during
-// the (strong) marking phase, and then again when walking
-// the code cache contents during the weak roots processing
-// phase. The two uses are distinguished by means of the
-// 'do_strong_roots_only' flag, which is true in the first
-// case. We want to walk the weak roots in the nmethod
-// only in the second case. The weak roots in the nmethod
-// are the oops in the ExceptionCache and the InlineCache
-// oops.
-void nmethod::oops_do(OopClosure* f, bool do_strong_roots_only) {
+void nmethod::oops_do(OopClosure* f, bool allow_zombie) {
// make sure the oops ready to receive visitors
- assert(!is_zombie() && !is_unloaded(),
- "should not call follow on zombie or unloaded nmethod");
+ assert(allow_zombie || !is_zombie(), "should not call follow on zombie nmethod");
+ assert(!is_unloaded(), "should not call follow on unloaded nmethod");
// If the method is not entrant or zombie then a JMP is plastered over the
// first few bytes. If an oop in the old code was there, that oop
diff --git a/hotspot/src/share/vm/code/nmethod.hpp b/hotspot/src/share/vm/code/nmethod.hpp
index 477ceb6dcb6..3178e90d98a 100644
--- a/hotspot/src/share/vm/code/nmethod.hpp
+++ b/hotspot/src/share/vm/code/nmethod.hpp
@@ -566,7 +566,7 @@ public:
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
OopClosure* f);
void oops_do(OopClosure* f) { oops_do(f, false); }
- void oops_do(OopClosure* f, bool do_strong_roots_only);
+ void oops_do(OopClosure* f, bool allow_zombie);
bool detect_scavenge_root_oops();
void verify_scavenge_root_oops() PRODUCT_RETURN;
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 54ade2db111..04b550c718b 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -3460,7 +3460,9 @@ void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) {
void ConcurrentMarkSweepGeneration::shrink(size_t bytes) {
assert_locked_or_safepoint(Heap_lock);
size_t size = ReservedSpace::page_align_size_down(bytes);
- if (size > 0) {
+ // Only shrink if a compaction was done so that all the free space
+ // in the generation is in a contiguous block at the end.
+ if (size > 0 && did_compact()) {
shrink_by(size);
}
}
@@ -5478,40 +5480,42 @@ CMSParMarkTask::do_young_space_rescan(uint worker_id,
HandleMark hm;
SequentialSubTasksDone* pst = space->par_seq_tasks();
- assert(pst->valid(), "Uninitialized use?");
uint nth_task = 0;
uint n_tasks = pst->n_tasks();
- HeapWord *start, *end;
- while (!pst->is_task_claimed(/* reference */ nth_task)) {
- // We claimed task # nth_task; compute its boundaries.
- if (chunk_top == 0) { // no samples were taken
- assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
- start = space->bottom();
- end = space->top();
- } else if (nth_task == 0) {
- start = space->bottom();
- end = chunk_array[nth_task];
- } else if (nth_task < (uint)chunk_top) {
- assert(nth_task >= 1, "Control point invariant");
- start = chunk_array[nth_task - 1];
- end = chunk_array[nth_task];
- } else {
- assert(nth_task == (uint)chunk_top, "Control point invariant");
- start = chunk_array[chunk_top - 1];
- end = space->top();
+ if (n_tasks > 0) {
+ assert(pst->valid(), "Uninitialized use?");
+ HeapWord *start, *end;
+ while (!pst->is_task_claimed(/* reference */ nth_task)) {
+ // We claimed task # nth_task; compute its boundaries.
+ if (chunk_top == 0) { // no samples were taken
+ assert(nth_task == 0 && n_tasks == 1, "Can have only 1 EdenSpace task");
+ start = space->bottom();
+ end = space->top();
+ } else if (nth_task == 0) {
+ start = space->bottom();
+ end = chunk_array[nth_task];
+ } else if (nth_task < (uint)chunk_top) {
+ assert(nth_task >= 1, "Control point invariant");
+ start = chunk_array[nth_task - 1];
+ end = chunk_array[nth_task];
+ } else {
+ assert(nth_task == (uint)chunk_top, "Control point invariant");
+ start = chunk_array[chunk_top - 1];
+ end = space->top();
+ }
+ MemRegion mr(start, end);
+ // Verify that mr is in space
+ assert(mr.is_empty() || space->used_region().contains(mr),
+ "Should be in space");
+ // Verify that "start" is an object boundary
+ assert(mr.is_empty() || oop(mr.start())->is_oop(),
+ "Should be an oop");
+ space->par_oop_iterate(mr, cl);
}
- MemRegion mr(start, end);
- // Verify that mr is in space
- assert(mr.is_empty() || space->used_region().contains(mr),
- "Should be in space");
- // Verify that "start" is an object boundary
- assert(mr.is_empty() || oop(mr.start())->is_oop(),
- "Should be an oop");
- space->par_oop_iterate(mr, cl);
+ pst->all_tasks_completed();
}
- pst->all_tasks_completed();
}
void
@@ -5788,7 +5792,7 @@ initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
DefNewGeneration* dng = (DefNewGeneration*)_young_gen;
// Eden space
- {
+ if (!dng->eden()->is_empty()) {
SequentialSubTasksDone* pst = dng->eden()->par_seq_tasks();
assert(!pst->valid(), "Clobbering existing data?");
// Each valid entry in [0, _eden_chunk_index) represents a task.
@@ -8694,9 +8698,10 @@ void SweepClosure::lookahead_and_flush(FreeChunk* fc, size_t chunk_size) {
assert(inFreeRange(), "Should only be called if currently in a free range.");
HeapWord* const eob = ((HeapWord*)fc) + chunk_size;
assert(_sp->used_region().contains(eob - 1),
- err_msg("eob = " PTR_FORMAT " out of bounds wrt _sp = [" PTR_FORMAT "," PTR_FORMAT ")"
+ err_msg("eob = " PTR_FORMAT " eob-1 = " PTR_FORMAT " _limit = " PTR_FORMAT
+ " out of bounds wrt _sp = [" PTR_FORMAT "," PTR_FORMAT ")"
" when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")",
- _limit, _sp->bottom(), _sp->end(), fc, chunk_size));
+ eob, eob-1, _limit, _sp->bottom(), _sp->end(), fc, chunk_size));
if (eob >= _limit) {
assert(eob == _limit || fc->is_free(), "Only a free chunk should allow us to cross over the limit");
if (CMSTraceSweeper) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 13a34a45156..04f8ccd0fc7 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -4529,7 +4529,7 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
_total_prev_live_bytes(0), _total_next_live_bytes(0),
_hum_used_bytes(0), _hum_capacity_bytes(0),
_hum_prev_live_bytes(0), _hum_next_live_bytes(0),
- _total_remset_bytes(0) {
+ _total_remset_bytes(0), _total_strong_code_roots_bytes(0) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
MemRegion g1_committed = g1h->g1_committed();
MemRegion g1_reserved = g1h->g1_reserved();
@@ -4553,9 +4553,11 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT
G1PPRL_DOUBLE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT,
"type", "address-range",
- "used", "prev-live", "next-live", "gc-eff", "remset");
+ "used", "prev-live", "next-live", "gc-eff",
+ "remset", "code-roots");
_out->print_cr(G1PPRL_LINE_PREFIX
G1PPRL_TYPE_H_FORMAT
G1PPRL_ADDR_BASE_H_FORMAT
@@ -4563,9 +4565,11 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT
G1PPRL_DOUBLE_H_FORMAT
+ G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT,
"", "",
- "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)", "(bytes)");
+ "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
+ "(bytes)", "(bytes)");
}
// It takes as a parameter a reference to one of the _hum_* fields, it
@@ -4608,6 +4612,8 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
size_t next_live_bytes = r->next_live_bytes();
double gc_eff = r->gc_efficiency();
size_t remset_bytes = r->rem_set()->mem_size();
+ size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size();
+
if (r->used() == 0) {
type = "FREE";
} else if (r->is_survivor()) {
@@ -4642,6 +4648,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
_total_prev_live_bytes += prev_live_bytes;
_total_next_live_bytes += next_live_bytes;
_total_remset_bytes += remset_bytes;
+ _total_strong_code_roots_bytes += strong_code_roots_bytes;
// Print a line for this particular region.
_out->print_cr(G1PPRL_LINE_PREFIX
@@ -4651,9 +4658,11 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT
G1PPRL_DOUBLE_FORMAT
+ G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT,
type, bottom, end,
- used_bytes, prev_live_bytes, next_live_bytes, gc_eff , remset_bytes);
+ used_bytes, prev_live_bytes, next_live_bytes, gc_eff,
+ remset_bytes, strong_code_roots_bytes);
return false;
}
@@ -4669,7 +4678,8 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
G1PPRL_SUM_MB_PERC_FORMAT("used")
G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
G1PPRL_SUM_MB_PERC_FORMAT("next-live")
- G1PPRL_SUM_MB_FORMAT("remset"),
+ G1PPRL_SUM_MB_FORMAT("remset")
+ G1PPRL_SUM_MB_FORMAT("code-roots"),
bytes_to_mb(_total_capacity_bytes),
bytes_to_mb(_total_used_bytes),
perc(_total_used_bytes, _total_capacity_bytes),
@@ -4677,6 +4687,7 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
perc(_total_prev_live_bytes, _total_capacity_bytes),
bytes_to_mb(_total_next_live_bytes),
perc(_total_next_live_bytes, _total_capacity_bytes),
- bytes_to_mb(_total_remset_bytes));
+ bytes_to_mb(_total_remset_bytes),
+ bytes_to_mb(_total_strong_code_roots_bytes));
_out->cr();
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
index 794224b66a7..a01024fcb9f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -1257,6 +1257,9 @@ private:
// Accumulator for the remembered set size
size_t _total_remset_bytes;
+ // Accumulator for strong code roots memory size
+ size_t _total_strong_code_roots_bytes;
+
static double perc(size_t val, size_t total) {
if (total == 0) {
return 0.0;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index bdd3027b995..eb249a68a34 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
#include "gc_implementation/g1/bufferingOopClosure.hpp"
#include "gc_implementation/g1/concurrentG1Refine.hpp"
@@ -980,7 +981,8 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
if (should_try_gc) {
bool succeeded;
- result = do_collection_pause(word_size, gc_count_before, &succeeded);
+ result = do_collection_pause(word_size, gc_count_before, &succeeded,
+ GCCause::_g1_inc_collection_pause);
if (result != NULL) {
assert(succeeded, "only way to get back a non-NULL result");
return result;
@@ -1105,7 +1107,8 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
// enough space for the allocation to succeed after the pause.
bool succeeded;
- result = do_collection_pause(word_size, gc_count_before, &succeeded);
+ result = do_collection_pause(word_size, gc_count_before, &succeeded,
+ GCCause::_g1_humongous_allocation);
if (result != NULL) {
assert(succeeded, "only way to get back a non-NULL result");
return result;
@@ -1176,20 +1179,27 @@ class PostMCRemSetClearClosure: public HeapRegionClosure {
ModRefBarrierSet* _mr_bs;
public:
PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) :
- _g1h(g1h), _mr_bs(mr_bs) { }
+ _g1h(g1h), _mr_bs(mr_bs) {}
+
bool doHeapRegion(HeapRegion* r) {
+ HeapRegionRemSet* hrrs = r->rem_set();
+
if (r->continuesHumongous()) {
+ // We'll assert that the strong code root list and RSet is empty
+ assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
+ assert(hrrs->occupied() == 0, "RSet should be empty");
return false;
}
+
_g1h->reset_gc_time_stamps(r);
- HeapRegionRemSet* hrrs = r->rem_set();
- if (hrrs != NULL) hrrs->clear();
+ hrrs->clear();
// You might think here that we could clear just the cards
// corresponding to the used region. But no: if we leave a dirty card
// in a region we might allocate into, then it would prevent that card
// from being enqueued, and cause it to be missed.
// Re: the performance cost: we shouldn't be doing full GC anyway!
_mr_bs->clear(MemRegion(r->bottom(), r->end()));
+
return false;
}
};
@@ -1269,30 +1279,6 @@ void G1CollectedHeap::print_hrs_post_compaction() {
heap_region_iterate(&cl);
}
-double G1CollectedHeap::verify(bool guard, const char* msg) {
- double verify_time_ms = 0.0;
-
- if (guard && total_collections() >= VerifyGCStartAt) {
- double verify_start = os::elapsedTime();
- HandleMark hm; // Discard invalid handles created during verification
- prepare_for_verify();
- Universe::verify(VerifyOption_G1UsePrevMarking, msg);
- verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
- }
-
- return verify_time_ms;
-}
-
-void G1CollectedHeap::verify_before_gc() {
- double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
- g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
-}
-
-void G1CollectedHeap::verify_after_gc() {
- double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
- g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
-}
-
bool G1CollectedHeap::do_collection(bool explicit_gc,
bool clear_all_soft_refs,
size_t word_size) {
@@ -1433,7 +1419,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
// Delete metaspaces for unloaded class loaders and clean up loader_data graph
ClassLoaderDataGraph::purge();
- MetaspaceAux::verify_metrics();
+ MetaspaceAux::verify_metrics();
// Note: since we've just done a full GC, concurrent
// marking is no longer active. Therefore we need not
@@ -1504,6 +1490,9 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
heap_region_iterate(&rebuild_rs);
}
+ // Rebuild the strong code root lists for each region
+ rebuild_strong_code_roots();
+
if (true) { // FIXME
MetaspaceGC::compute_new_size();
}
@@ -2019,10 +2008,12 @@ jint G1CollectedHeap::initialize() {
size_t init_byte_size = collector_policy()->initial_heap_byte_size();
size_t max_byte_size = collector_policy()->max_heap_byte_size();
+ size_t heap_alignment = collector_policy()->max_alignment();
// Ensure that the sizes are properly aligned.
Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
+ Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap");
_cg1r = new ConcurrentG1Refine(this);
@@ -2039,12 +2030,8 @@ jint G1CollectedHeap::initialize() {
// If this happens then we could end up using a non-optimal
// compressed oops mode.
- // Since max_byte_size is aligned to the size of a heap region (checked
- // above).
- Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
-
ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size,
- HeapRegion::GrainBytes);
+ heap_alignment);
// It is important to do this in a way such that concurrent readers can't
// temporarily think something is in the heap. (I've actually seen this
@@ -3109,6 +3096,145 @@ const char* G1CollectedHeap::top_at_mark_start_str(VerifyOption vo) {
return NULL; // keep some compilers happy
}
+// TODO: VerifyRootsClosure extends OopsInGenClosure so that we can
+// pass it as the perm_blk to SharedHeap::process_strong_roots.
+// When process_strong_roots stop calling perm_blk->younger_refs_iterate
+// we can change this closure to extend the simpler OopClosure.
+class VerifyRootsClosure: public OopsInGenClosure {
+private:
+ G1CollectedHeap* _g1h;
+ VerifyOption _vo;
+ bool _failures;
+public:
+ // _vo == UsePrevMarking -> use "prev" marking information,
+ // _vo == UseNextMarking -> use "next" marking information,
+ // _vo == UseMarkWord -> use mark word from object header.
+ VerifyRootsClosure(VerifyOption vo) :
+ _g1h(G1CollectedHeap::heap()),
+ _vo(vo),
+ _failures(false) { }
+
+ bool failures() { return _failures; }
+
+ template void do_oop_nv(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ if (_g1h->is_obj_dead_cond(obj, _vo)) {
+ gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
+ "points to dead obj "PTR_FORMAT, p, (void*) obj);
+ if (_vo == VerifyOption_G1UseMarkWord) {
+ gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark()));
+ }
+ obj->print_on(gclog_or_tty);
+ _failures = true;
+ }
+ }
+ }
+
+ void do_oop(oop* p) { do_oop_nv(p); }
+ void do_oop(narrowOop* p) { do_oop_nv(p); }
+};
+
+class G1VerifyCodeRootOopClosure: public OopsInGenClosure {
+ G1CollectedHeap* _g1h;
+ OopClosure* _root_cl;
+ nmethod* _nm;
+ VerifyOption _vo;
+ bool _failures;
+
+ template void do_oop_work(T* p) {
+ // First verify that this root is live
+ _root_cl->do_oop(p);
+
+ if (!G1VerifyHeapRegionCodeRoots) {
+ // We're not verifying the code roots attached to heap region.
+ return;
+ }
+
+ // Don't check the code roots during marking verification in a full GC
+ if (_vo == VerifyOption_G1UseMarkWord) {
+ return;
+ }
+
+ // Now verify that the current nmethod (which contains p) is
+ // in the code root list of the heap region containing the
+ // object referenced by p.
+
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+ // Now fetch the region containing the object
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+ HeapRegionRemSet* hrrs = hr->rem_set();
+ // Verify that the strong code root list for this region
+ // contains the nmethod
+ if (!hrrs->strong_code_roots_list_contains(_nm)) {
+ gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
+ "from nmethod "PTR_FORMAT" not in strong "
+ "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
+ p, _nm, hr->bottom(), hr->end());
+ _failures = true;
+ }
+ }
+ }
+
+public:
+ G1VerifyCodeRootOopClosure(G1CollectedHeap* g1h, OopClosure* root_cl, VerifyOption vo):
+ _g1h(g1h), _root_cl(root_cl), _vo(vo), _nm(NULL), _failures(false) {}
+
+ void do_oop(oop* p) { do_oop_work(p); }
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+
+ void set_nmethod(nmethod* nm) { _nm = nm; }
+ bool failures() { return _failures; }
+};
+
+class G1VerifyCodeRootBlobClosure: public CodeBlobClosure {
+ G1VerifyCodeRootOopClosure* _oop_cl;
+
+public:
+ G1VerifyCodeRootBlobClosure(G1VerifyCodeRootOopClosure* oop_cl):
+ _oop_cl(oop_cl) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = cb->as_nmethod_or_null();
+ if (nm != NULL) {
+ _oop_cl->set_nmethod(nm);
+ nm->oops_do(_oop_cl);
+ }
+ }
+};
+
+class YoungRefCounterClosure : public OopClosure {
+ G1CollectedHeap* _g1h;
+ int _count;
+ public:
+ YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {}
+ void do_oop(oop* p) { if (_g1h->is_in_young(*p)) { _count++; } }
+ void do_oop(narrowOop* p) { ShouldNotReachHere(); }
+
+ int count() { return _count; }
+ void reset_count() { _count = 0; };
+};
+
+class VerifyKlassClosure: public KlassClosure {
+ YoungRefCounterClosure _young_ref_counter_closure;
+ OopClosure *_oop_closure;
+ public:
+ VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
+ void do_klass(Klass* k) {
+ k->oops_do(_oop_closure);
+
+ _young_ref_counter_closure.reset_count();
+ k->oops_do(&_young_ref_counter_closure);
+ if (_young_ref_counter_closure.count() > 0) {
+ guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k));
+ }
+ }
+};
+
class VerifyLivenessOopClosure: public OopClosure {
G1CollectedHeap* _g1h;
VerifyOption _vo;
@@ -3242,75 +3368,7 @@ public:
}
};
-class YoungRefCounterClosure : public OopClosure {
- G1CollectedHeap* _g1h;
- int _count;
- public:
- YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {}
- void do_oop(oop* p) { if (_g1h->is_in_young(*p)) { _count++; } }
- void do_oop(narrowOop* p) { ShouldNotReachHere(); }
-
- int count() { return _count; }
- void reset_count() { _count = 0; };
-};
-
-class VerifyKlassClosure: public KlassClosure {
- YoungRefCounterClosure _young_ref_counter_closure;
- OopClosure *_oop_closure;
- public:
- VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {}
- void do_klass(Klass* k) {
- k->oops_do(_oop_closure);
-
- _young_ref_counter_closure.reset_count();
- k->oops_do(&_young_ref_counter_closure);
- if (_young_ref_counter_closure.count() > 0) {
- guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k));
- }
- }
-};
-
-// TODO: VerifyRootsClosure extends OopsInGenClosure so that we can
-// pass it as the perm_blk to SharedHeap::process_strong_roots.
-// When process_strong_roots stop calling perm_blk->younger_refs_iterate
-// we can change this closure to extend the simpler OopClosure.
-class VerifyRootsClosure: public OopsInGenClosure {
-private:
- G1CollectedHeap* _g1h;
- VerifyOption _vo;
- bool _failures;
-public:
- // _vo == UsePrevMarking -> use "prev" marking information,
- // _vo == UseNextMarking -> use "next" marking information,
- // _vo == UseMarkWord -> use mark word from object header.
- VerifyRootsClosure(VerifyOption vo) :
- _g1h(G1CollectedHeap::heap()),
- _vo(vo),
- _failures(false) { }
-
- bool failures() { return _failures; }
-
- template void do_oop_nv(T* p) {
- T heap_oop = oopDesc::load_heap_oop(p);
- if (!oopDesc::is_null(heap_oop)) {
- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
- if (_g1h->is_obj_dead_cond(obj, _vo)) {
- gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
- "points to dead obj "PTR_FORMAT, p, (void*) obj);
- if (_vo == VerifyOption_G1UseMarkWord) {
- gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark()));
- }
- obj->print_on(gclog_or_tty);
- _failures = true;
- }
- }
- }
-
- void do_oop(oop* p) { do_oop_nv(p); }
- void do_oop(narrowOop* p) { do_oop_nv(p); }
-};
-
-// This is the task used for parallel heap verification.
+// This is the task used for parallel verification of the heap regions
class G1ParVerifyTask: public AbstractGangTask {
private:
@@ -3344,20 +3402,15 @@ public:
}
};
-void G1CollectedHeap::verify(bool silent) {
- verify(silent, VerifyOption_G1UsePrevMarking);
-}
-
-void G1CollectedHeap::verify(bool silent,
- VerifyOption vo) {
+void G1CollectedHeap::verify(bool silent, VerifyOption vo) {
if (SafepointSynchronize::is_at_safepoint()) {
- if (!silent) { gclog_or_tty->print("Roots "); }
- VerifyRootsClosure rootsCl(vo);
-
assert(Thread::current()->is_VM_thread(),
"Expected to be executed serially by the VM thread at this point");
- CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
+ if (!silent) { gclog_or_tty->print("Roots "); }
+ VerifyRootsClosure rootsCl(vo);
+ G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo);
+ G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
VerifyKlassClosure klassCl(this, &rootsCl);
// We apply the relevant closures to all the oops in the
@@ -3376,7 +3429,7 @@ void G1CollectedHeap::verify(bool silent,
&klassCl
);
- bool failures = rootsCl.failures();
+ bool failures = rootsCl.failures() || codeRootsCl.failures();
if (vo != VerifyOption_G1UseMarkWord) {
// If we're verifying during a full GC then the region sets
@@ -3445,6 +3498,34 @@ void G1CollectedHeap::verify(bool silent,
}
}
+void G1CollectedHeap::verify(bool silent) {
+ verify(silent, VerifyOption_G1UsePrevMarking);
+}
+
+double G1CollectedHeap::verify(bool guard, const char* msg) {
+ double verify_time_ms = 0.0;
+
+ if (guard && total_collections() >= VerifyGCStartAt) {
+ double verify_start = os::elapsedTime();
+ HandleMark hm; // Discard invalid handles created during verification
+ prepare_for_verify();
+ Universe::verify(VerifyOption_G1UsePrevMarking, msg);
+ verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
+ }
+
+ return verify_time_ms;
+}
+
+void G1CollectedHeap::verify_before_gc() {
+ double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
+ g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+}
+
+void G1CollectedHeap::verify_after_gc() {
+ double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
+ g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+}
+
class PrintRegionClosure: public HeapRegionClosure {
outputStream* _st;
public:
@@ -3619,14 +3700,15 @@ void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
HeapWord* G1CollectedHeap::do_collection_pause(size_t word_size,
unsigned int gc_count_before,
- bool* succeeded) {
+ bool* succeeded,
+ GCCause::Cause gc_cause) {
assert_heap_not_locked_and_not_at_safepoint();
g1_policy()->record_stop_world_start();
VM_G1IncCollectionPause op(gc_count_before,
word_size,
false, /* should_initiate_conc_mark */
g1_policy()->max_pause_time_ms(),
- GCCause::_g1_inc_collection_pause);
+ gc_cause);
VMThread::execute(&op);
HeapWord* result = op.result();
@@ -3866,8 +3948,9 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
append_secondary_free_list_if_not_empty_with_lock();
}
- assert(check_young_list_well_formed(),
- "young list should be well formed");
+ assert(check_young_list_well_formed(), "young list should be well formed");
+ assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
+ "sanity check");
// Don't dynamically change the number of GC threads this early. A value of
// 0 is used to indicate serial work. When parallel work is done,
@@ -4987,7 +5070,11 @@ public:
G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
- int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
+ // Don't scan the scavengable methods in the code cache as part
+ // of strong root scanning. The code roots that point into a
+ // region in the collection set are scanned when we scan the
+ // region's RSet.
+ int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings;
pss.start_strong_roots();
_g1h->g1_process_strong_roots(/* is scavenging */ true,
@@ -5029,67 +5116,6 @@ public:
// *** Common G1 Evacuation Stuff
-// Closures that support the filtering of CodeBlobs scanned during
-// external root scanning.
-
-// Closure applied to reference fields in code blobs (specifically nmethods)
-// to determine whether an nmethod contains references that point into
-// the collection set. Used as a predicate when walking code roots so
-// that only nmethods that point into the collection set are added to the
-// 'marked' list.
-
-class G1FilteredCodeBlobToOopClosure : public CodeBlobToOopClosure {
-
- class G1PointsIntoCSOopClosure : public OopClosure {
- G1CollectedHeap* _g1;
- bool _points_into_cs;
- public:
- G1PointsIntoCSOopClosure(G1CollectedHeap* g1) :
- _g1(g1), _points_into_cs(false) { }
-
- bool points_into_cs() const { return _points_into_cs; }
-
- template
- void do_oop_nv(T* p) {
- if (!_points_into_cs) {
- T heap_oop = oopDesc::load_heap_oop(p);
- if (!oopDesc::is_null(heap_oop) &&
- _g1->in_cset_fast_test(oopDesc::decode_heap_oop_not_null(heap_oop))) {
- _points_into_cs = true;
- }
- }
- }
-
- virtual void do_oop(oop* p) { do_oop_nv(p); }
- virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
- };
-
- G1CollectedHeap* _g1;
-
-public:
- G1FilteredCodeBlobToOopClosure(G1CollectedHeap* g1, OopClosure* cl) :
- CodeBlobToOopClosure(cl, true), _g1(g1) { }
-
- virtual void do_code_blob(CodeBlob* cb) {
- nmethod* nm = cb->as_nmethod_or_null();
- if (nm != NULL && !(nm->test_oops_do_mark())) {
- G1PointsIntoCSOopClosure predicate_cl(_g1);
- nm->oops_do(&predicate_cl);
-
- if (predicate_cl.points_into_cs()) {
- // At least one of the reference fields or the oop relocations
- // in the nmethod points into the collection set. We have to
- // 'mark' this nmethod.
- // Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
- // or MarkingCodeBlobClosure::do_code_blob() change.
- if (!nm->test_set_oops_do_mark()) {
- do_newly_marked_nmethod(nm);
- }
- }
- }
- }
-};
-
// This method is run in a GC worker.
void
@@ -5107,9 +5133,10 @@ g1_process_strong_roots(bool is_scavenging,
BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
- // Walk the code cache w/o buffering, because StarTask cannot handle
- // unaligned oop locations.
- G1FilteredCodeBlobToOopClosure eager_scan_code_roots(this, scan_non_heap_roots);
+ assert(so & SO_CodeCache || scan_rs != NULL, "must scan code roots somehow");
+ // Walk the code cache/strong code roots w/o buffering, because StarTask
+ // cannot handle unaligned oop locations.
+ CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, true /* do_marking */);
process_strong_roots(false, // no scoping; this is parallel code
is_scavenging, so,
@@ -5154,9 +5181,22 @@ g1_process_strong_roots(bool is_scavenging,
}
g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
+ // If this is an initial mark pause, and we're not scanning
+ // the entire code cache, we need to mark the oops in the
+ // strong code root lists for the regions that are not in
+ // the collection set.
+ // Note all threads participate in this set of root tasks.
+ double mark_strong_code_roots_ms = 0.0;
+ if (g1_policy()->during_initial_mark_pause() && !(so & SO_CodeCache)) {
+ double mark_strong_roots_start = os::elapsedTime();
+ mark_strong_code_roots(worker_i);
+ mark_strong_code_roots_ms = (os::elapsedTime() - mark_strong_roots_start) * 1000.0;
+ }
+ g1_policy()->phase_times()->record_strong_code_root_mark_time(worker_i, mark_strong_code_roots_ms);
+
// Now scan the complement of the collection set.
if (scan_rs != NULL) {
- g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i);
+ g1_rem_set()->oops_into_collection_set_do(scan_rs, &eager_scan_code_roots, worker_i);
}
_process_strong_tasks->all_tasks_completed();
}
@@ -5774,9 +5814,6 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
process_discovered_references(n_workers);
// Weak root processing.
- // Note: when JSR 292 is enabled and code blobs can contain
- // non-perm oops then we will need to process the code blobs
- // here too.
{
G1STWIsAliveClosure is_alive(this);
G1KeepAliveClosure keep_alive(this);
@@ -5792,6 +5829,17 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
hot_card_cache->reset_hot_cache();
hot_card_cache->set_use_cache(true);
+ // Migrate the strong code roots attached to each region in
+ // the collection set. Ideally we would like to do this
+ // after we have finished the scanning/evacuation of the
+ // strong code roots for a particular heap region.
+ migrate_strong_code_roots();
+
+ if (g1_policy()->during_initial_mark_pause()) {
+ // Reset the claim values set during marking the strong code roots
+ reset_heap_region_claim_values();
+ }
+
finalize_for_evac_failure();
if (evacuation_failed()) {
@@ -6588,3 +6636,208 @@ void G1CollectedHeap::verify_region_sets() {
_humongous_set.verify_end();
_free_list.verify_end();
}
+
+// Optimized nmethod scanning
+
+class RegisterNMethodOopClosure: public OopClosure {
+ G1CollectedHeap* _g1h;
+ nmethod* _nm;
+
+ template void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+ assert(!hr->isHumongous(), "code root in humongous region?");
+
+ // HeapRegion::add_strong_code_root() avoids adding duplicate
+ // entries but having duplicates is OK since we "mark" nmethods
+ // as visited when we scan the strong code root lists during the GC.
+ hr->add_strong_code_root(_nm);
+ assert(hr->rem_set()->strong_code_roots_list_contains(_nm), "add failed?");
+ }
+ }
+
+public:
+ RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) :
+ _g1h(g1h), _nm(nm) {}
+
+ void do_oop(oop* p) { do_oop_work(p); }
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
+class UnregisterNMethodOopClosure: public OopClosure {
+ G1CollectedHeap* _g1h;
+ nmethod* _nm;
+
+ template void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ HeapRegion* hr = _g1h->heap_region_containing(obj);
+ assert(!hr->isHumongous(), "code root in humongous region?");
+ hr->remove_strong_code_root(_nm);
+ assert(!hr->rem_set()->strong_code_roots_list_contains(_nm), "remove failed?");
+ }
+ }
+
+public:
+ UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) :
+ _g1h(g1h), _nm(nm) {}
+
+ void do_oop(oop* p) { do_oop_work(p); }
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
+void G1CollectedHeap::register_nmethod(nmethod* nm) {
+ CollectedHeap::register_nmethod(nm);
+
+ guarantee(nm != NULL, "sanity");
+ RegisterNMethodOopClosure reg_cl(this, nm);
+ nm->oops_do(®_cl);
+}
+
+void G1CollectedHeap::unregister_nmethod(nmethod* nm) {
+ CollectedHeap::unregister_nmethod(nm);
+
+ guarantee(nm != NULL, "sanity");
+ UnregisterNMethodOopClosure reg_cl(this, nm);
+ nm->oops_do(®_cl, true);
+}
+
+class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure {
+public:
+ bool doHeapRegion(HeapRegion *hr) {
+ assert(!hr->isHumongous(), "humongous region in collection set?");
+ hr->migrate_strong_code_roots();
+ return false;
+ }
+};
+
+void G1CollectedHeap::migrate_strong_code_roots() {
+ MigrateCodeRootsHeapRegionClosure cl;
+ double migrate_start = os::elapsedTime();
+ collection_set_iterate(&cl);
+ double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0;
+ g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms);
+}
+
+// Mark all the code roots that point into regions *not* in the
+// collection set.
+//
+// Note we do not want to use a "marking" CodeBlobToOopClosure while
+// walking the the code roots lists of regions not in the collection
+// set. Suppose we have an nmethod (M) that points to objects in two
+// separate regions - one in the collection set (R1) and one not (R2).
+// Using a "marking" CodeBlobToOopClosure here would result in "marking"
+// nmethod M when walking the code roots for R1. When we come to scan
+// the code roots for R2, we would see that M is already marked and it
+// would be skipped and the objects in R2 that are referenced from M
+// would not be evacuated.
+
+class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+
+ class MarkStrongCodeRootOopClosure: public OopClosure {
+ ConcurrentMark* _cm;
+ HeapRegion* _hr;
+ uint _worker_id;
+
+ template void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ // Only mark objects in the region (which is assumed
+ // to be not in the collection set).
+ if (_hr->is_in(obj)) {
+ _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
+ }
+ }
+ }
+
+ public:
+ MarkStrongCodeRootOopClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id) :
+ _cm(cm), _hr(hr), _worker_id(worker_id) {
+ assert(!_hr->in_collection_set(), "sanity");
+ }
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+ };
+
+ MarkStrongCodeRootOopClosure _oop_cl;
+
+public:
+ MarkStrongCodeRootCodeBlobClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id):
+ _oop_cl(cm, hr, worker_id) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+ if (nm != NULL) {
+ nm->oops_do(&_oop_cl);
+ }
+ }
+};
+
+class MarkStrongCodeRootsHRClosure: public HeapRegionClosure {
+ G1CollectedHeap* _g1h;
+ uint _worker_id;
+
+public:
+ MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) :
+ _g1h(g1h), _worker_id(worker_id) {}
+
+ bool doHeapRegion(HeapRegion *hr) {
+ HeapRegionRemSet* hrrs = hr->rem_set();
+ if (hr->isHumongous()) {
+ // Code roots should never be attached to a humongous region
+ assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
+ return false;
+ }
+
+ if (hr->in_collection_set()) {
+ // Don't mark code roots into regions in the collection set here.
+ // They will be marked when we scan them.
+ return false;
+ }
+
+ MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id);
+ hr->strong_code_roots_do(&cb_cl);
+ return false;
+ }
+};
+
+void G1CollectedHeap::mark_strong_code_roots(uint worker_id) {
+ MarkStrongCodeRootsHRClosure cl(this, worker_id);
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ heap_region_par_iterate_chunked(&cl,
+ worker_id,
+ workers()->active_workers(),
+ HeapRegion::ParMarkRootClaimValue);
+ } else {
+ heap_region_iterate(&cl);
+ }
+}
+
+class RebuildStrongCodeRootClosure: public CodeBlobClosure {
+ G1CollectedHeap* _g1h;
+
+public:
+ RebuildStrongCodeRootClosure(G1CollectedHeap* g1h) :
+ _g1h(g1h) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = (cb != NULL) ? cb->as_nmethod_or_null() : NULL;
+ if (nm == NULL) {
+ return;
+ }
+
+ if (ScavengeRootsInCode && nm->detect_scavenge_root_oops()) {
+ _g1h->register_nmethod(nm);
+ }
+ }
+};
+
+void G1CollectedHeap::rebuild_strong_code_roots() {
+ RebuildStrongCodeRootClosure blob_cl(this);
+ CodeCache::blobs_do(&blob_cl);
+}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 9b52304c996..aecaa5e97ac 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -46,6 +46,7 @@
// may combine concurrent marking with parallel, incremental compaction of
// heap subsets that will yield large amounts of garbage.
+// Forward declarations
class HeapRegion;
class HRRSCleanupTask;
class GenerationSpec;
@@ -69,6 +70,7 @@ class STWGCTimer;
class G1NewTracer;
class G1OldTracer;
class EvacuationFailedInfo;
+class nmethod;
typedef OverflowTaskQueue RefToScanQueue;
typedef GenericTaskQueueSet RefToScanQueueSet;
@@ -163,18 +165,6 @@ public:
: G1AllocRegion("Mutator Alloc Region", false /* bot_updates */) { }
};
-// The G1 STW is alive closure.
-// An instance is embedded into the G1CH and used as the
-// (optional) _is_alive_non_header closure in the STW
-// reference processor. It is also extensively used during
-// reference processing during STW evacuation pauses.
-class G1STWIsAliveClosure: public BoolObjectClosure {
- G1CollectedHeap* _g1;
-public:
- G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
- bool do_object_b(oop p);
-};
-
class SurvivorGCAllocRegion : public G1AllocRegion {
protected:
virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
@@ -193,6 +183,18 @@ public:
: G1AllocRegion("Old GC Alloc Region", true /* bot_updates */) { }
};
+// The G1 STW is alive closure.
+// An instance is embedded into the G1CH and used as the
+// (optional) _is_alive_non_header closure in the STW
+// reference processor. It is also extensively used during
+// reference processing during STW evacuation pauses.
+class G1STWIsAliveClosure: public BoolObjectClosure {
+ G1CollectedHeap* _g1;
+public:
+ G1STWIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {}
+ bool do_object_b(oop p);
+};
+
class RefineCardTableEntryClosure;
class G1CollectedHeap : public SharedHeap {
@@ -774,9 +776,10 @@ protected:
// it has to be read while holding the Heap_lock. Currently, both
// methods that call do_collection_pause() release the Heap_lock
// before the call, so it's easy to read gc_count_before just before.
- HeapWord* do_collection_pause(size_t word_size,
- unsigned int gc_count_before,
- bool* succeeded);
+ HeapWord* do_collection_pause(size_t word_size,
+ unsigned int gc_count_before,
+ bool* succeeded,
+ GCCause::Cause gc_cause);
// The guts of the incremental collection pause, executed by the vm
// thread. It returns false if it is unable to do the collection due
@@ -1549,42 +1552,6 @@ public:
virtual jlong millis_since_last_gc();
- // Perform any cleanup actions necessary before allowing a verification.
- virtual void prepare_for_verify();
-
- // Perform verification.
-
- // vo == UsePrevMarking -> use "prev" marking information,
- // vo == UseNextMarking -> use "next" marking information
- // vo == UseMarkWord -> use the mark word in the object header
- //
- // NOTE: Only the "prev" marking information is guaranteed to be
- // consistent most of the time, so most calls to this should use
- // vo == UsePrevMarking.
- // Currently, there is only one case where this is called with
- // vo == UseNextMarking, which is to verify the "next" marking
- // information at the end of remark.
- // Currently there is only one place where this is called with
- // vo == UseMarkWord, which is to verify the marking during a
- // full GC.
- void verify(bool silent, VerifyOption vo);
-
- // Override; it uses the "prev" marking information
- virtual void verify(bool silent);
-
- virtual void print_on(outputStream* st) const;
- virtual void print_extended_on(outputStream* st) const;
- virtual void print_on_error(outputStream* st) const;
-
- virtual void print_gc_threads_on(outputStream* st) const;
- virtual void gc_threads_do(ThreadClosure* tc) const;
-
- // Override
- void print_tracing_info() const;
-
- // The following two methods are helpful for debugging RSet issues.
- void print_cset_rsets() PRODUCT_RETURN;
- void print_all_rsets() PRODUCT_RETURN;
// Convenience function to be used in situations where the heap type can be
// asserted to be this type.
@@ -1661,13 +1628,86 @@ public:
else return is_obj_ill(obj, hr);
}
+ bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
+ HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
+ bool is_marked(oop obj, VerifyOption vo);
+ const char* top_at_mark_start_str(VerifyOption vo);
+
+ ConcurrentMark* concurrent_mark() const { return _cm; }
+
+ // Refinement
+
+ ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+
+ // The dirty cards region list is used to record a subset of regions
+ // whose cards need clearing. The list if populated during the
+ // remembered set scanning and drained during the card table
+ // cleanup. Although the methods are reentrant, population/draining
+ // phases must not overlap. For synchronization purposes the last
+ // element on the list points to itself.
+ HeapRegion* _dirty_cards_region_list;
+ void push_dirty_cards_region(HeapRegion* hr);
+ HeapRegion* pop_dirty_cards_region();
+
+ // Optimized nmethod scanning support routines
+
+ // Register the given nmethod with the G1 heap
+ virtual void register_nmethod(nmethod* nm);
+
+ // Unregister the given nmethod from the G1 heap
+ virtual void unregister_nmethod(nmethod* nm);
+
+ // Migrate the nmethods in the code root lists of the regions
+ // in the collection set to regions in to-space. In the event
+ // of an evacuation failure, nmethods that reference objects
+ // that were not successfullly evacuated are not migrated.
+ void migrate_strong_code_roots();
+
+ // During an initial mark pause, mark all the code roots that
+ // point into regions *not* in the collection set.
+ void mark_strong_code_roots(uint worker_id);
+
+ // Rebuild the stong code root lists for each region
+ // after a full GC
+ void rebuild_strong_code_roots();
+
+ // Verification
+
+ // The following is just to alert the verification code
+ // that a full collection has occurred and that the
+ // remembered sets are no longer up to date.
+ bool _full_collection;
+ void set_full_collection() { _full_collection = true;}
+ void clear_full_collection() {_full_collection = false;}
+ bool full_collection() {return _full_collection;}
+
+ // Perform any cleanup actions necessary before allowing a verification.
+ virtual void prepare_for_verify();
+
+ // Perform verification.
+
+ // vo == UsePrevMarking -> use "prev" marking information,
+ // vo == UseNextMarking -> use "next" marking information
+ // vo == UseMarkWord -> use the mark word in the object header
+ //
+ // NOTE: Only the "prev" marking information is guaranteed to be
+ // consistent most of the time, so most calls to this should use
+ // vo == UsePrevMarking.
+ // Currently, there is only one case where this is called with
+ // vo == UseNextMarking, which is to verify the "next" marking
+ // information at the end of remark.
+ // Currently there is only one place where this is called with
+ // vo == UseMarkWord, which is to verify the marking during a
+ // full GC.
+ void verify(bool silent, VerifyOption vo);
+
+ // Override; it uses the "prev" marking information
+ virtual void verify(bool silent);
+
// The methods below are here for convenience and dispatch the
// appropriate method depending on value of the given VerifyOption
- // parameter. The options for that parameter are:
- //
- // vo == UsePrevMarking -> use "prev" marking information,
- // vo == UseNextMarking -> use "next" marking information,
- // vo == UseMarkWord -> use mark word from object header
+ // parameter. The values for that parameter, and their meanings,
+ // are the same as those above.
bool is_obj_dead_cond(const oop obj,
const HeapRegion* hr,
@@ -1692,31 +1732,21 @@ public:
return false; // keep some compilers happy
}
- bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
- HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
- bool is_marked(oop obj, VerifyOption vo);
- const char* top_at_mark_start_str(VerifyOption vo);
+ // Printing
- // The following is just to alert the verification code
- // that a full collection has occurred and that the
- // remembered sets are no longer up to date.
- bool _full_collection;
- void set_full_collection() { _full_collection = true;}
- void clear_full_collection() {_full_collection = false;}
- bool full_collection() {return _full_collection;}
+ virtual void print_on(outputStream* st) const;
+ virtual void print_extended_on(outputStream* st) const;
+ virtual void print_on_error(outputStream* st) const;
- ConcurrentMark* concurrent_mark() const { return _cm; }
- ConcurrentG1Refine* concurrent_g1_refine() const { return _cg1r; }
+ virtual void print_gc_threads_on(outputStream* st) const;
+ virtual void gc_threads_do(ThreadClosure* tc) const;
- // The dirty cards region list is used to record a subset of regions
- // whose cards need clearing. The list if populated during the
- // remembered set scanning and drained during the card table
- // cleanup. Although the methods are reentrant, population/draining
- // phases must not overlap. For synchronization purposes the last
- // element on the list points to itself.
- HeapRegion* _dirty_cards_region_list;
- void push_dirty_cards_region(HeapRegion* hr);
- HeapRegion* pop_dirty_cards_region();
+ // Override
+ void print_tracing_info() const;
+
+ // The following two methods are helpful for debugging RSet issues.
+ void print_cset_rsets() PRODUCT_RETURN;
+ void print_all_rsets() PRODUCT_RETURN;
public:
void stop_conc_gc_threads();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index 4c6d2bbf877..75497e7c37f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -313,7 +313,8 @@ G1CollectorPolicy::G1CollectorPolicy() :
void G1CollectorPolicy::initialize_flags() {
set_min_alignment(HeapRegion::GrainBytes);
size_t card_table_alignment = GenRemSet::max_alignment_constraint(rem_set_name());
- set_max_alignment(MAX2(card_table_alignment, min_alignment()));
+ size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
+ set_max_alignment(MAX3(card_table_alignment, min_alignment(), page_size));
if (SurvivorRatio < 1) {
vm_exit_during_initialization("Invalid survivor ratio specified");
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
index f6d3b6f4bd9..0eda4b35d71 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
@@ -161,6 +161,8 @@ G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
_last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
_last_update_rs_processed_buffers(_max_gc_threads, "%d"),
_last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_strong_code_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+ _last_strong_code_root_mark_times_ms(_max_gc_threads, "%.1lf"),
_last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
_last_termination_times_ms(_max_gc_threads, "%.1lf"),
_last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
@@ -182,6 +184,8 @@ void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
_last_update_rs_times_ms.reset();
_last_update_rs_processed_buffers.reset();
_last_scan_rs_times_ms.reset();
+ _last_strong_code_root_scan_times_ms.reset();
+ _last_strong_code_root_mark_times_ms.reset();
_last_obj_copy_times_ms.reset();
_last_termination_times_ms.reset();
_last_termination_attempts.reset();
@@ -197,6 +201,8 @@ void G1GCPhaseTimes::note_gc_end() {
_last_update_rs_times_ms.verify();
_last_update_rs_processed_buffers.verify();
_last_scan_rs_times_ms.verify();
+ _last_strong_code_root_scan_times_ms.verify();
+ _last_strong_code_root_mark_times_ms.verify();
_last_obj_copy_times_ms.verify();
_last_termination_times_ms.verify();
_last_termination_attempts.verify();
@@ -210,6 +216,8 @@ void G1GCPhaseTimes::note_gc_end() {
_last_satb_filtering_times_ms.get(i) +
_last_update_rs_times_ms.get(i) +
_last_scan_rs_times_ms.get(i) +
+ _last_strong_code_root_scan_times_ms.get(i) +
+ _last_strong_code_root_mark_times_ms.get(i) +
_last_obj_copy_times_ms.get(i) +
_last_termination_times_ms.get(i);
@@ -239,6 +247,9 @@ double G1GCPhaseTimes::accounted_time_ms() {
// Now subtract the time taken to fix up roots in generated code
misc_time_ms += _cur_collection_code_root_fixup_time_ms;
+ // Strong code root migration time
+ misc_time_ms += _cur_strong_code_root_migration_time_ms;
+
// Subtract the time taken to clean the card table from the
// current value of "other time"
misc_time_ms += _cur_clear_ct_time_ms;
@@ -257,9 +268,13 @@ void G1GCPhaseTimes::print(double pause_time_sec) {
if (_last_satb_filtering_times_ms.sum() > 0.0) {
_last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
}
+ if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+ _last_strong_code_root_mark_times_ms.print(2, "Code Root Marking (ms)");
+ }
_last_update_rs_times_ms.print(2, "Update RS (ms)");
_last_update_rs_processed_buffers.print(3, "Processed Buffers");
_last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+ _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
_last_obj_copy_times_ms.print(2, "Object Copy (ms)");
_last_termination_times_ms.print(2, "Termination (ms)");
if (G1Log::finest()) {
@@ -273,12 +288,17 @@ void G1GCPhaseTimes::print(double pause_time_sec) {
if (_last_satb_filtering_times_ms.sum() > 0.0) {
_last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
}
+ if (_last_strong_code_root_mark_times_ms.sum() > 0.0) {
+ _last_strong_code_root_mark_times_ms.print(1, "Code Root Marking (ms)");
+ }
_last_update_rs_times_ms.print(1, "Update RS (ms)");
_last_update_rs_processed_buffers.print(2, "Processed Buffers");
_last_scan_rs_times_ms.print(1, "Scan RS (ms)");
+ _last_strong_code_root_scan_times_ms.print(1, "Code Root Scanning (ms)");
_last_obj_copy_times_ms.print(1, "Object Copy (ms)");
}
print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+ print_stats(1, "Code Root Migration", _cur_strong_code_root_migration_time_ms);
print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
print_stats(1, "Other", misc_time_ms);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
index a1c5739f1ae..b2de97dc4b6 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
@@ -119,6 +119,8 @@ class G1GCPhaseTimes : public CHeapObj {
WorkerDataArray _last_update_rs_times_ms;
WorkerDataArray _last_update_rs_processed_buffers;
WorkerDataArray _last_scan_rs_times_ms;
+ WorkerDataArray _last_strong_code_root_scan_times_ms;
+ WorkerDataArray _last_strong_code_root_mark_times_ms;
WorkerDataArray _last_obj_copy_times_ms;
WorkerDataArray _last_termination_times_ms;
WorkerDataArray _last_termination_attempts;
@@ -128,6 +130,7 @@ class G1GCPhaseTimes : public CHeapObj {
double _cur_collection_par_time_ms;
double _cur_collection_code_root_fixup_time_ms;
+ double _cur_strong_code_root_migration_time_ms;
double _cur_clear_ct_time_ms;
double _cur_ref_proc_time_ms;
@@ -179,6 +182,14 @@ class G1GCPhaseTimes : public CHeapObj {
_last_scan_rs_times_ms.set(worker_i, ms);
}
+ void record_strong_code_root_scan_time(uint worker_i, double ms) {
+ _last_strong_code_root_scan_times_ms.set(worker_i, ms);
+ }
+
+ void record_strong_code_root_mark_time(uint worker_i, double ms) {
+ _last_strong_code_root_mark_times_ms.set(worker_i, ms);
+ }
+
void record_obj_copy_time(uint worker_i, double ms) {
_last_obj_copy_times_ms.set(worker_i, ms);
}
@@ -208,6 +219,10 @@ class G1GCPhaseTimes : public CHeapObj {
_cur_collection_code_root_fixup_time_ms = ms;
}
+ void record_strong_code_root_migration_time(double ms) {
+ _cur_strong_code_root_migration_time_ms = ms;
+ }
+
void record_ref_proc_time(double ms) {
_cur_ref_proc_time_ms = ms;
}
@@ -294,6 +309,14 @@ class G1GCPhaseTimes : public CHeapObj {
return _last_scan_rs_times_ms.average();
}
+ double average_last_strong_code_root_scan_time(){
+ return _last_strong_code_root_scan_times_ms.average();
+ }
+
+ double average_last_strong_code_root_mark_time(){
+ return _last_strong_code_root_mark_times_ms.average();
+ }
+
double average_last_obj_copy_time() {
return _last_obj_copy_times_ms.average();
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp
index 16839dcb29a..01bb43bef45 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp
@@ -262,6 +262,7 @@ void G1MonitoringSupport::update_sizes() {
old_collection_counters()->update_all();
young_collection_counters()->update_all();
MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
}
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
index 673814ce971..5a1b92d3422 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
@@ -104,15 +104,25 @@ void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) {
class ScanRSClosure : public HeapRegionClosure {
size_t _cards_done, _cards;
G1CollectedHeap* _g1h;
+
OopsInHeapRegionClosure* _oc;
+ CodeBlobToOopClosure* _code_root_cl;
+
G1BlockOffsetSharedArray* _bot_shared;
CardTableModRefBS *_ct_bs;
- int _worker_i;
- int _block_size;
- bool _try_claimed;
+
+ double _strong_code_root_scan_time_sec;
+ int _worker_i;
+ int _block_size;
+ bool _try_claimed;
+
public:
- ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
+ ScanRSClosure(OopsInHeapRegionClosure* oc,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i) :
_oc(oc),
+ _code_root_cl(code_root_cl),
+ _strong_code_root_scan_time_sec(0.0),
_cards(0),
_cards_done(0),
_worker_i(worker_i),
@@ -160,6 +170,12 @@ public:
card_start, card_start + G1BlockOffsetSharedArray::N_words);
}
+ void scan_strong_code_roots(HeapRegion* r) {
+ double scan_start = os::elapsedTime();
+ r->strong_code_roots_do(_code_root_cl);
+ _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
+ }
+
bool doHeapRegion(HeapRegion* r) {
assert(r->in_collection_set(), "should only be called on elements of CS.");
HeapRegionRemSet* hrrs = r->rem_set();
@@ -173,6 +189,7 @@ public:
// _try_claimed || r->claim_iter()
// is true: either we're supposed to work on claimed-but-not-complete
// regions, or we successfully claimed the region.
+
HeapRegionRemSetIterator iter(hrrs);
size_t card_index;
@@ -205,30 +222,43 @@ public:
}
}
if (!_try_claimed) {
+ // Scan the strong code root list attached to the current region
+ scan_strong_code_roots(r);
+
hrrs->set_iter_complete();
}
return false;
}
+
+ double strong_code_root_scan_time_sec() {
+ return _strong_code_root_scan_time_sec;
+ }
+
size_t cards_done() { return _cards_done;}
size_t cards_looked_up() { return _cards;}
};
-void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
+void G1RemSet::scanRS(OopsInHeapRegionClosure* oc,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i) {
double rs_time_start = os::elapsedTime();
HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i);
- ScanRSClosure scanRScl(oc, worker_i);
+ ScanRSClosure scanRScl(oc, code_root_cl, worker_i);
_g1->collection_set_iterate_from(startRegion, &scanRScl);
scanRScl.set_try_claimed();
_g1->collection_set_iterate_from(startRegion, &scanRScl);
- double scan_rs_time_sec = os::elapsedTime() - rs_time_start;
+ double scan_rs_time_sec = (os::elapsedTime() - rs_time_start)
+ - scanRScl.strong_code_root_scan_time_sec();
- assert( _cards_scanned != NULL, "invariant" );
+ assert(_cards_scanned != NULL, "invariant");
_cards_scanned[worker_i] = scanRScl.cards_done();
_g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
+ _g1p->phase_times()->record_strong_code_root_scan_time(worker_i,
+ scanRScl.strong_code_root_scan_time_sec() * 1000.0);
}
// Closure used for updating RSets and recording references that
@@ -288,7 +318,8 @@ void G1RemSet::cleanupHRRS() {
}
void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
- int worker_i) {
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i) {
#if CARD_REPEAT_HISTO
ct_freq_update_histo_and_reset();
#endif
@@ -328,7 +359,7 @@ void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
_g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
}
if (G1UseParallelRSetScanning || (worker_i == 0)) {
- scanRS(oc, worker_i);
+ scanRS(oc, code_root_cl, worker_i);
} else {
_g1p->phase_times()->record_scan_rs_time(worker_i, 0.0);
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
index 954381f9138..513945609fc 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
@@ -81,14 +81,23 @@ public:
G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs);
~G1RemSet();
- // Invoke "blk->do_oop" on all pointers into the CS in objects in regions
- // outside the CS (having invoked "blk->set_region" to set the "from"
- // region correctly beforehand.) The "worker_i" param is for the
- // parallel case where the number of the worker thread calling this
- // function can be helpful in partitioning the work to be done. It
- // should be the same as the "i" passed to the calling thread's
- // work(i) function. In the sequential case this param will be ingored.
- void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, int worker_i);
+ // Invoke "blk->do_oop" on all pointers into the collection set
+ // from objects in regions outside the collection set (having
+ // invoked "blk->set_region" to set the "from" region correctly
+ // beforehand.)
+ //
+ // Invoke code_root_cl->do_code_blob on the unmarked nmethods
+ // on the strong code roots list for each region in the
+ // collection set.
+ //
+ // The "worker_i" param is for the parallel case where the id
+ // of the worker thread calling this function can be helpful in
+ // partitioning the work to be done. It should be the same as
+ // the "i" passed to the calling thread's work(i) function.
+ // In the sequential case this param will be ignored.
+ void oops_into_collection_set_do(OopsInHeapRegionClosure* blk,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i);
// Prepare for and cleanup after an oops_into_collection_set_do
// call. Must call each of these once before and after (in sequential
@@ -98,7 +107,10 @@ public:
void prepare_for_oops_into_collection_set_do();
void cleanup_after_oops_into_collection_set_do();
- void scanRS(OopsInHeapRegionClosure* oc, int worker_i);
+ void scanRS(OopsInHeapRegionClosure* oc,
+ CodeBlobToOopClosure* code_root_cl,
+ int worker_i);
+
void updateRS(DirtyCardQueue* into_cset_dcq, int worker_i);
CardTableModRefBS* ct_bs() { return _ct_bs; }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp
index 13acd1b0da8..4a6b37654d7 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp
@@ -127,32 +127,55 @@ void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
class HRRSStatsIter: public HeapRegionClosure {
size_t _occupied;
- size_t _total_mem_sz;
- size_t _max_mem_sz;
- HeapRegion* _max_mem_sz_region;
+
+ size_t _total_rs_mem_sz;
+ size_t _max_rs_mem_sz;
+ HeapRegion* _max_rs_mem_sz_region;
+
+ size_t _total_code_root_mem_sz;
+ size_t _max_code_root_mem_sz;
+ HeapRegion* _max_code_root_mem_sz_region;
public:
HRRSStatsIter() :
_occupied(0),
- _total_mem_sz(0),
- _max_mem_sz(0),
- _max_mem_sz_region(NULL)
+ _total_rs_mem_sz(0),
+ _max_rs_mem_sz(0),
+ _max_rs_mem_sz_region(NULL),
+ _total_code_root_mem_sz(0),
+ _max_code_root_mem_sz(0),
+ _max_code_root_mem_sz_region(NULL)
{}
bool doHeapRegion(HeapRegion* r) {
- size_t mem_sz = r->rem_set()->mem_size();
- if (mem_sz > _max_mem_sz) {
- _max_mem_sz = mem_sz;
- _max_mem_sz_region = r;
+ HeapRegionRemSet* hrrs = r->rem_set();
+
+ // HeapRegionRemSet::mem_size() includes the
+ // size of the strong code roots
+ size_t rs_mem_sz = hrrs->mem_size();
+ if (rs_mem_sz > _max_rs_mem_sz) {
+ _max_rs_mem_sz = rs_mem_sz;
+ _max_rs_mem_sz_region = r;
}
- _total_mem_sz += mem_sz;
- size_t occ = r->rem_set()->occupied();
+ _total_rs_mem_sz += rs_mem_sz;
+
+ size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size();
+ if (code_root_mem_sz > _max_code_root_mem_sz) {
+ _max_code_root_mem_sz = code_root_mem_sz;
+ _max_code_root_mem_sz_region = r;
+ }
+ _total_code_root_mem_sz += code_root_mem_sz;
+
+ size_t occ = hrrs->occupied();
_occupied += occ;
return false;
}
- size_t total_mem_sz() { return _total_mem_sz; }
- size_t max_mem_sz() { return _max_mem_sz; }
+ size_t total_rs_mem_sz() { return _total_rs_mem_sz; }
+ size_t max_rs_mem_sz() { return _max_rs_mem_sz; }
+ HeapRegion* max_rs_mem_sz_region() { return _max_rs_mem_sz_region; }
+ size_t total_code_root_mem_sz() { return _total_code_root_mem_sz; }
+ size_t max_code_root_mem_sz() { return _max_code_root_mem_sz; }
+ HeapRegion* max_code_root_mem_sz_region() { return _max_code_root_mem_sz_region; }
size_t occupied() { return _occupied; }
- HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
};
double calc_percentage(size_t numerator, size_t denominator) {
@@ -184,22 +207,33 @@ void G1RemSetSummary::print_on(outputStream* out) {
HRRSStatsIter blk;
G1CollectedHeap::heap()->heap_region_iterate(&blk);
+ // RemSet stats
out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K."
" Max = "SIZE_FORMAT"K.",
- blk.total_mem_sz()/K, blk.max_mem_sz()/K);
+ blk.total_rs_mem_sz()/K, blk.max_rs_mem_sz()/K);
out->print_cr(" Static structures = "SIZE_FORMAT"K,"
" free_lists = "SIZE_FORMAT"K.",
HeapRegionRemSet::static_mem_size() / K,
HeapRegionRemSet::fl_mem_size() / K);
out->print_cr(" "SIZE_FORMAT" occupied cards represented.",
blk.occupied());
- HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
- HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
+ HeapRegion* max_rs_mem_sz_region = blk.max_rs_mem_sz_region();
+ HeapRegionRemSet* max_rs_rem_set = max_rs_mem_sz_region->rem_set();
out->print_cr(" Max size region = "HR_FORMAT", "
"size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
- HR_FORMAT_PARAMS(max_mem_sz_region),
- (rem_set->mem_size() + K - 1)/K,
- (rem_set->occupied() + K - 1)/K);
-
+ HR_FORMAT_PARAMS(max_rs_mem_sz_region),
+ (max_rs_rem_set->mem_size() + K - 1)/K,
+ (max_rs_rem_set->occupied() + K - 1)/K);
out->print_cr(" Did %d coarsenings.", num_coarsenings());
+ // Strong code root stats
+ out->print_cr(" Total heap region code-root set sizes = "SIZE_FORMAT"K."
+ " Max = "SIZE_FORMAT"K.",
+ blk.total_code_root_mem_sz()/K, blk.max_code_root_mem_sz()/K);
+ HeapRegion* max_code_root_mem_sz_region = blk.max_code_root_mem_sz_region();
+ HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region->rem_set();
+ out->print_cr(" Max size region = "HR_FORMAT", "
+ "size = "SIZE_FORMAT "K, num_elems = "SIZE_FORMAT".",
+ HR_FORMAT_PARAMS(max_code_root_mem_sz_region),
+ (max_code_root_rem_set->strong_code_roots_mem_size() + K - 1)/K,
+ (max_code_root_rem_set->strong_code_roots_list_length()));
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
index 3387dc44f0a..c7d8049fea0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
@@ -319,7 +319,10 @@
\
diagnostic(bool, G1VerifyRSetsDuringFullGC, false, \
"If true, perform verification of each heap region's " \
- "remembered set when verifying the heap during a full GC.")
+ "remembered set when verifying the heap during a full GC.") \
+ \
+ diagnostic(bool, G1VerifyHeapRegionCodeRoots, false, \
+ "Verify the code root lists attached to each heap region.")
G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
index 9486d208dc9..3a3c99a5edd 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "code/nmethod.hpp"
#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -50,144 +51,6 @@ FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r,
OopClosure* oc) :
_r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
-class VerifyLiveClosure: public OopClosure {
-private:
- G1CollectedHeap* _g1h;
- CardTableModRefBS* _bs;
- oop _containing_obj;
- bool _failures;
- int _n_failures;
- VerifyOption _vo;
-public:
- // _vo == UsePrevMarking -> use "prev" marking information,
- // _vo == UseNextMarking -> use "next" marking information,
- // _vo == UseMarkWord -> use mark word from object header.
- VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
- _g1h(g1h), _bs(NULL), _containing_obj(NULL),
- _failures(false), _n_failures(0), _vo(vo)
- {
- BarrierSet* bs = _g1h->barrier_set();
- if (bs->is_a(BarrierSet::CardTableModRef))
- _bs = (CardTableModRefBS*)bs;
- }
-
- void set_containing_obj(oop obj) {
- _containing_obj = obj;
- }
-
- bool failures() { return _failures; }
- int n_failures() { return _n_failures; }
-
- virtual void do_oop(narrowOop* p) { do_oop_work(p); }
- virtual void do_oop( oop* p) { do_oop_work(p); }
-
- void print_object(outputStream* out, oop obj) {
-#ifdef PRODUCT
- Klass* k = obj->klass();
- const char* class_name = InstanceKlass::cast(k)->external_name();
- out->print_cr("class name %s", class_name);
-#else // PRODUCT
- obj->print_on(out);
-#endif // PRODUCT
- }
-
- template
- void do_oop_work(T* p) {
- assert(_containing_obj != NULL, "Precondition");
- assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
- "Precondition");
- T heap_oop = oopDesc::load_heap_oop(p);
- if (!oopDesc::is_null(heap_oop)) {
- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
- bool failed = false;
- if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
- MutexLockerEx x(ParGCRareEvent_lock,
- Mutex::_no_safepoint_check_flag);
-
- if (!_failures) {
- gclog_or_tty->print_cr("");
- gclog_or_tty->print_cr("----------");
- }
- if (!_g1h->is_in_closed_subset(obj)) {
- HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
- gclog_or_tty->print_cr("Field "PTR_FORMAT
- " of live obj "PTR_FORMAT" in region "
- "["PTR_FORMAT", "PTR_FORMAT")",
- p, (void*) _containing_obj,
- from->bottom(), from->end());
- print_object(gclog_or_tty, _containing_obj);
- gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
- (void*) obj);
- } else {
- HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
- HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
- gclog_or_tty->print_cr("Field "PTR_FORMAT
- " of live obj "PTR_FORMAT" in region "
- "["PTR_FORMAT", "PTR_FORMAT")",
- p, (void*) _containing_obj,
- from->bottom(), from->end());
- print_object(gclog_or_tty, _containing_obj);
- gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
- "["PTR_FORMAT", "PTR_FORMAT")",
- (void*) obj, to->bottom(), to->end());
- print_object(gclog_or_tty, obj);
- }
- gclog_or_tty->print_cr("----------");
- gclog_or_tty->flush();
- _failures = true;
- failed = true;
- _n_failures++;
- }
-
- if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
- HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
- HeapRegion* to = _g1h->heap_region_containing(obj);
- if (from != NULL && to != NULL &&
- from != to &&
- !to->isHumongous()) {
- jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
- jbyte cv_field = *_bs->byte_for_const(p);
- const jbyte dirty = CardTableModRefBS::dirty_card_val();
-
- bool is_bad = !(from->is_young()
- || to->rem_set()->contains_reference(p)
- || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
- (_containing_obj->is_objArray() ?
- cv_field == dirty
- : cv_obj == dirty || cv_field == dirty));
- if (is_bad) {
- MutexLockerEx x(ParGCRareEvent_lock,
- Mutex::_no_safepoint_check_flag);
-
- if (!_failures) {
- gclog_or_tty->print_cr("");
- gclog_or_tty->print_cr("----------");
- }
- gclog_or_tty->print_cr("Missing rem set entry:");
- gclog_or_tty->print_cr("Field "PTR_FORMAT" "
- "of obj "PTR_FORMAT", "
- "in region "HR_FORMAT,
- p, (void*) _containing_obj,
- HR_FORMAT_PARAMS(from));
- _containing_obj->print_on(gclog_or_tty);
- gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
- "in region "HR_FORMAT,
- (void*) obj,
- HR_FORMAT_PARAMS(to));
- obj->print_on(gclog_or_tty);
- gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
- cv_obj, cv_field);
- gclog_or_tty->print_cr("----------");
- gclog_or_tty->flush();
- _failures = true;
- if (!failed) _n_failures++;
- }
- }
- }
- }
- }
-};
-
template
HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
HeapRegion* hr,
@@ -368,7 +231,7 @@ void HeapRegion::hr_clear(bool par, bool clear_space) {
if (!par) {
// If this is parallel, this will be done later.
HeapRegionRemSet* hrrs = rem_set();
- if (hrrs != NULL) hrrs->clear();
+ hrrs->clear();
_claimed = InitialClaimValue;
}
zero_marked_bytes();
@@ -505,6 +368,7 @@ HeapRegion::HeapRegion(uint hrs_index,
_rem_set(NULL), _recorded_rs_length(0), _predicted_elapsed_time_ms(0),
_predicted_bytes_to_copy(0)
{
+ _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
_orig_end = mr.end();
// Note that initialize() will set the start of the unmarked area of the
// region.
@@ -512,8 +376,6 @@ HeapRegion::HeapRegion(uint hrs_index,
set_top(bottom());
set_saved_mark();
- _rem_set = new HeapRegionRemSet(sharedOffsetArray, this);
-
assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
}
@@ -733,6 +595,160 @@ oops_on_card_seq_iterate_careful(MemRegion mr,
return NULL;
}
+// Code roots support
+
+void HeapRegion::add_strong_code_root(nmethod* nm) {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->add_strong_code_root(nm);
+}
+
+void HeapRegion::remove_strong_code_root(nmethod* nm) {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->remove_strong_code_root(nm);
+}
+
+void HeapRegion::migrate_strong_code_roots() {
+ assert(in_collection_set(), "only collection set regions");
+ assert(!isHumongous(), "not humongous regions");
+
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->migrate_strong_code_roots();
+}
+
+void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const {
+ HeapRegionRemSet* hrrs = rem_set();
+ hrrs->strong_code_roots_do(blk);
+}
+
+class VerifyStrongCodeRootOopClosure: public OopClosure {
+ const HeapRegion* _hr;
+ nmethod* _nm;
+ bool _failures;
+ bool _has_oops_in_region;
+
+ template void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+
+ // Note: not all the oops embedded in the nmethod are in the
+ // current region. We only look at those which are.
+ if (_hr->is_in(obj)) {
+ // Object is in the region. Check that its less than top
+ if (_hr->top() <= (HeapWord*)obj) {
+ // Object is above top
+ gclog_or_tty->print_cr("Object "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT") is above "
+ "top "PTR_FORMAT,
+ obj, _hr->bottom(), _hr->end(), _hr->top());
+ _failures = true;
+ return;
+ }
+ // Nmethod has at least one oop in the current region
+ _has_oops_in_region = true;
+ }
+ }
+ }
+
+public:
+ VerifyStrongCodeRootOopClosure(const HeapRegion* hr, nmethod* nm):
+ _hr(hr), _failures(false), _has_oops_in_region(false) {}
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+
+ bool failures() { return _failures; }
+ bool has_oops_in_region() { return _has_oops_in_region; }
+};
+
+class VerifyStrongCodeRootCodeBlobClosure: public CodeBlobClosure {
+ const HeapRegion* _hr;
+ bool _failures;
+public:
+ VerifyStrongCodeRootCodeBlobClosure(const HeapRegion* hr) :
+ _hr(hr), _failures(false) {}
+
+ void do_code_blob(CodeBlob* cb) {
+ nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null();
+ if (nm != NULL) {
+ // Verify that the nemthod is live
+ if (!nm->is_alive()) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has dead nmethod "
+ PTR_FORMAT" in its strong code roots",
+ _hr->bottom(), _hr->end(), nm);
+ _failures = true;
+ } else {
+ VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
+ nm->oops_do(&oop_cl);
+ if (!oop_cl.has_oops_in_region()) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has nmethod "
+ PTR_FORMAT" in its strong code roots "
+ "with no pointers into region",
+ _hr->bottom(), _hr->end(), nm);
+ _failures = true;
+ } else if (oop_cl.failures()) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] has other "
+ "failures for nmethod "PTR_FORMAT,
+ _hr->bottom(), _hr->end(), nm);
+ _failures = true;
+ }
+ }
+ }
+ }
+
+ bool failures() { return _failures; }
+};
+
+void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const {
+ if (!G1VerifyHeapRegionCodeRoots) {
+ // We're not verifying code roots.
+ return;
+ }
+ if (vo == VerifyOption_G1UseMarkWord) {
+ // Marking verification during a full GC is performed after class
+ // unloading, code cache unloading, etc so the strong code roots
+ // attached to each heap region are in an inconsistent state. They won't
+ // be consistent until the strong code roots are rebuilt after the
+ // actual GC. Skip verifying the strong code roots in this particular
+ // time.
+ assert(VerifyDuringGC, "only way to get here");
+ return;
+ }
+
+ HeapRegionRemSet* hrrs = rem_set();
+ int strong_code_roots_length = hrrs->strong_code_roots_list_length();
+
+ // if this region is empty then there should be no entries
+ // on its strong code root list
+ if (is_empty()) {
+ if (strong_code_roots_length > 0) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty "
+ "but has "INT32_FORMAT" code root entries",
+ bottom(), end(), strong_code_roots_length);
+ *failures = true;
+ }
+ return;
+ }
+
+ // An H-region should have an empty strong code root list
+ if (isHumongous()) {
+ if (strong_code_roots_length > 0) {
+ gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous "
+ "but has "INT32_FORMAT" code root entries",
+ bottom(), end(), strong_code_roots_length);
+ *failures = true;
+ }
+ return;
+ }
+
+ VerifyStrongCodeRootCodeBlobClosure cb_cl(this);
+ strong_code_roots_do(&cb_cl);
+
+ if (cb_cl.failures()) {
+ *failures = true;
+ }
+}
+
void HeapRegion::print() const { print_on(gclog_or_tty); }
void HeapRegion::print_on(outputStream* st) const {
if (isHumongous()) {
@@ -761,10 +777,143 @@ void HeapRegion::print_on(outputStream* st) const {
G1OffsetTableContigSpace::print_on(st);
}
-void HeapRegion::verify() const {
- bool dummy = false;
- verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
-}
+class VerifyLiveClosure: public OopClosure {
+private:
+ G1CollectedHeap* _g1h;
+ CardTableModRefBS* _bs;
+ oop _containing_obj;
+ bool _failures;
+ int _n_failures;
+ VerifyOption _vo;
+public:
+ // _vo == UsePrevMarking -> use "prev" marking information,
+ // _vo == UseNextMarking -> use "next" marking information,
+ // _vo == UseMarkWord -> use mark word from object header.
+ VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
+ _g1h(g1h), _bs(NULL), _containing_obj(NULL),
+ _failures(false), _n_failures(0), _vo(vo)
+ {
+ BarrierSet* bs = _g1h->barrier_set();
+ if (bs->is_a(BarrierSet::CardTableModRef))
+ _bs = (CardTableModRefBS*)bs;
+ }
+
+ void set_containing_obj(oop obj) {
+ _containing_obj = obj;
+ }
+
+ bool failures() { return _failures; }
+ int n_failures() { return _n_failures; }
+
+ virtual void do_oop(narrowOop* p) { do_oop_work(p); }
+ virtual void do_oop( oop* p) { do_oop_work(p); }
+
+ void print_object(outputStream* out, oop obj) {
+#ifdef PRODUCT
+ Klass* k = obj->klass();
+ const char* class_name = InstanceKlass::cast(k)->external_name();
+ out->print_cr("class name %s", class_name);
+#else // PRODUCT
+ obj->print_on(out);
+#endif // PRODUCT
+ }
+
+ template
+ void do_oop_work(T* p) {
+ assert(_containing_obj != NULL, "Precondition");
+ assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
+ "Precondition");
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ bool failed = false;
+ if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) {
+ MutexLockerEx x(ParGCRareEvent_lock,
+ Mutex::_no_safepoint_check_flag);
+
+ if (!_failures) {
+ gclog_or_tty->print_cr("");
+ gclog_or_tty->print_cr("----------");
+ }
+ if (!_g1h->is_in_closed_subset(obj)) {
+ HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+ gclog_or_tty->print_cr("Field "PTR_FORMAT
+ " of live obj "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT")",
+ p, (void*) _containing_obj,
+ from->bottom(), from->end());
+ print_object(gclog_or_tty, _containing_obj);
+ gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap",
+ (void*) obj);
+ } else {
+ HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+ HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
+ gclog_or_tty->print_cr("Field "PTR_FORMAT
+ " of live obj "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT")",
+ p, (void*) _containing_obj,
+ from->bottom(), from->end());
+ print_object(gclog_or_tty, _containing_obj);
+ gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region "
+ "["PTR_FORMAT", "PTR_FORMAT")",
+ (void*) obj, to->bottom(), to->end());
+ print_object(gclog_or_tty, obj);
+ }
+ gclog_or_tty->print_cr("----------");
+ gclog_or_tty->flush();
+ _failures = true;
+ failed = true;
+ _n_failures++;
+ }
+
+ if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) {
+ HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
+ HeapRegion* to = _g1h->heap_region_containing(obj);
+ if (from != NULL && to != NULL &&
+ from != to &&
+ !to->isHumongous()) {
+ jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
+ jbyte cv_field = *_bs->byte_for_const(p);
+ const jbyte dirty = CardTableModRefBS::dirty_card_val();
+
+ bool is_bad = !(from->is_young()
+ || to->rem_set()->contains_reference(p)
+ || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
+ (_containing_obj->is_objArray() ?
+ cv_field == dirty
+ : cv_obj == dirty || cv_field == dirty));
+ if (is_bad) {
+ MutexLockerEx x(ParGCRareEvent_lock,
+ Mutex::_no_safepoint_check_flag);
+
+ if (!_failures) {
+ gclog_or_tty->print_cr("");
+ gclog_or_tty->print_cr("----------");
+ }
+ gclog_or_tty->print_cr("Missing rem set entry:");
+ gclog_or_tty->print_cr("Field "PTR_FORMAT" "
+ "of obj "PTR_FORMAT", "
+ "in region "HR_FORMAT,
+ p, (void*) _containing_obj,
+ HR_FORMAT_PARAMS(from));
+ _containing_obj->print_on(gclog_or_tty);
+ gclog_or_tty->print_cr("points to obj "PTR_FORMAT" "
+ "in region "HR_FORMAT,
+ (void*) obj,
+ HR_FORMAT_PARAMS(to));
+ obj->print_on(gclog_or_tty);
+ gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
+ cv_obj, cv_field);
+ gclog_or_tty->print_cr("----------");
+ gclog_or_tty->flush();
+ _failures = true;
+ if (!failed) _n_failures++;
+ }
+ }
+ }
+ }
+ }
+};
// This really ought to be commoned up into OffsetTableContigSpace somehow.
// We would need a mechanism to make that code skip dead objects.
@@ -904,6 +1053,13 @@ void HeapRegion::verify(VerifyOption vo,
*failures = true;
return;
}
+
+ verify_strong_code_roots(vo, failures);
+}
+
+void HeapRegion::verify() const {
+ bool dummy = false;
+ verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
}
// G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
index 7c79195d3e5..68e58d680c9 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
@@ -52,6 +52,7 @@ class HeapRegionRemSet;
class HeapRegionRemSetIterator;
class HeapRegion;
class HeapRegionSetBase;
+class nmethod;
#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
#define HR_FORMAT_PARAMS(_hr_) \
@@ -371,7 +372,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
RebuildRSClaimValue = 5,
ParEvacFailureClaimValue = 6,
AggregateCountClaimValue = 7,
- VerifyCountClaimValue = 8
+ VerifyCountClaimValue = 8,
+ ParMarkRootClaimValue = 9
};
inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
@@ -796,6 +798,25 @@ class HeapRegion: public G1OffsetTableContigSpace {
virtual void reset_after_compaction();
+ // Routines for managing a list of code roots (attached to the
+ // this region's RSet) that point into this heap region.
+ void add_strong_code_root(nmethod* nm);
+ void remove_strong_code_root(nmethod* nm);
+
+ // During a collection, migrate the successfully evacuated
+ // strong code roots that referenced into this region to the
+ // new regions that they now point into. Unsuccessfully
+ // evacuated code roots are not migrated.
+ void migrate_strong_code_roots();
+
+ // Applies blk->do_code_blob() to each of the entries in
+ // the strong code roots list for this region
+ void strong_code_roots_do(CodeBlobClosure* blk) const;
+
+ // Verify that the entries on the strong code root list for this
+ // region are live and include at least one pointer into this region.
+ void verify_strong_code_roots(VerifyOption vo, bool* failures) const;
+
void print() const;
void print_on(outputStream* st) const;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
index 635babcbb30..69eaa53c31a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -33,6 +33,7 @@
#include "oops/oop.inline.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
class PerRegionTable: public CHeapObj {
friend class OtherRegionsTable;
@@ -849,7 +850,7 @@ int HeapRegionRemSet::num_par_rem_sets() {
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
HeapRegion* hr)
- : _bosa(bosa), _other_regions(hr) {
+ : _bosa(bosa), _strong_code_roots_list(NULL), _other_regions(hr) {
reset_for_par_iteration();
}
@@ -908,6 +909,12 @@ void HeapRegionRemSet::cleanup() {
}
void HeapRegionRemSet::clear() {
+ if (_strong_code_roots_list != NULL) {
+ delete _strong_code_roots_list;
+ }
+ _strong_code_roots_list = new (ResourceObj::C_HEAP, mtGC)
+ GrowableArray(10, 0, NULL, true);
+
_other_regions.clear();
assert(occupied() == 0, "Should be clear.");
reset_for_par_iteration();
@@ -925,6 +932,121 @@ void HeapRegionRemSet::scrub(CardTableModRefBS* ctbs,
_other_regions.scrub(ctbs, region_bm, card_bm);
}
+
+// Code roots support
+
+void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
+ assert(nm != NULL, "sanity");
+ // Search for the code blob from the RHS to avoid
+ // duplicate entries as much as possible
+ if (_strong_code_roots_list->find_from_end(nm) < 0) {
+ // Code blob isn't already in the list
+ _strong_code_roots_list->push(nm);
+ }
+}
+
+void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) {
+ assert(nm != NULL, "sanity");
+ int idx = _strong_code_roots_list->find(nm);
+ if (idx >= 0) {
+ _strong_code_roots_list->remove_at(idx);
+ }
+ // Check that there were no duplicates
+ guarantee(_strong_code_roots_list->find(nm) < 0, "duplicate entry found");
+}
+
+class NMethodMigrationOopClosure : public OopClosure {
+ G1CollectedHeap* _g1h;
+ HeapRegion* _from;
+ nmethod* _nm;
+
+ uint _num_self_forwarded;
+
+ template void do_oop_work(T* p) {
+ T heap_oop = oopDesc::load_heap_oop(p);
+ if (!oopDesc::is_null(heap_oop)) {
+ oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
+ if (_from->is_in(obj)) {
+ // Reference still points into the source region.
+ // Since roots are immediately evacuated this means that
+ // we must have self forwarded the object
+ assert(obj->is_forwarded(),
+ err_msg("code roots should be immediately evacuated. "
+ "Ref: "PTR_FORMAT", "
+ "Obj: "PTR_FORMAT", "
+ "Region: "HR_FORMAT,
+ p, (void*) obj, HR_FORMAT_PARAMS(_from)));
+ assert(obj->forwardee() == obj,
+ err_msg("not self forwarded? obj = "PTR_FORMAT, (void*)obj));
+
+ // The object has been self forwarded.
+ // Note, if we're during an initial mark pause, there is
+ // no need to explicitly mark object. It will be marked
+ // during the regular evacuation failure handling code.
+ _num_self_forwarded++;
+ } else {
+ // The reference points into a promotion or to-space region
+ HeapRegion* to = _g1h->heap_region_containing(obj);
+ to->rem_set()->add_strong_code_root(_nm);
+ }
+ }
+ }
+
+public:
+ NMethodMigrationOopClosure(G1CollectedHeap* g1h, HeapRegion* from, nmethod* nm):
+ _g1h(g1h), _from(from), _nm(nm), _num_self_forwarded(0) {}
+
+ void do_oop(narrowOop* p) { do_oop_work(p); }
+ void do_oop(oop* p) { do_oop_work(p); }
+
+ uint retain() { return _num_self_forwarded > 0; }
+};
+
+void HeapRegionRemSet::migrate_strong_code_roots() {
+ assert(hr()->in_collection_set(), "only collection set regions");
+ assert(!hr()->isHumongous(), "not humongous regions");
+
+ ResourceMark rm;
+
+ // List of code blobs to retain for this region
+ GrowableArray to_be_retained(10);
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+ while (_strong_code_roots_list->is_nonempty()) {
+ nmethod *nm = _strong_code_roots_list->pop();
+ if (nm != NULL) {
+ NMethodMigrationOopClosure oop_cl(g1h, hr(), nm);
+ nm->oops_do(&oop_cl);
+ if (oop_cl.retain()) {
+ to_be_retained.push(nm);
+ }
+ }
+ }
+
+ // Now push any code roots we need to retain
+ assert(to_be_retained.is_empty() || hr()->evacuation_failed(),
+ "Retained nmethod list must be empty or "
+ "evacuation of this region failed");
+
+ while (to_be_retained.is_nonempty()) {
+ nmethod* nm = to_be_retained.pop();
+ assert(nm != NULL, "sanity");
+ add_strong_code_root(nm);
+ }
+}
+
+void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const {
+ for (int i = 0; i < _strong_code_roots_list->length(); i += 1) {
+ nmethod* nm = _strong_code_roots_list->at(i);
+ blk->do_code_blob(nm);
+ }
+}
+
+size_t HeapRegionRemSet::strong_code_roots_mem_size() {
+ return sizeof(GrowableArray) +
+ _strong_code_roots_list->max_length() * sizeof(nmethod*);
+}
+
//-------------------- Iteration --------------------
HeapRegionRemSetIterator:: HeapRegionRemSetIterator(const HeapRegionRemSet* hrrs) :
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
index 1b9e5f46aa5..e40f6195a12 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
@@ -37,6 +37,7 @@ class HeapRegion;
class HeapRegionRemSetIterator;
class PerRegionTable;
class SparsePRT;
+class nmethod;
// Essentially a wrapper around SparsePRTCleanupTask. See
// sparsePRT.hpp for more details.
@@ -191,6 +192,10 @@ private:
G1BlockOffsetSharedArray* _bosa;
G1BlockOffsetSharedArray* bosa() const { return _bosa; }
+ // A list of code blobs (nmethods) whose code contains pointers into
+ // the region that owns this RSet.
+ GrowableArray* _strong_code_roots_list;
+
OtherRegionsTable _other_regions;
enum ParIterState { Unclaimed, Claimed, Complete };
@@ -282,11 +287,13 @@ public:
}
// The actual # of bytes this hr_remset takes up.
+ // Note also includes the strong code root set.
size_t mem_size() {
return _other_regions.mem_size()
// This correction is necessary because the above includes the second
// part.
- + sizeof(this) - sizeof(OtherRegionsTable);
+ + (sizeof(this) - sizeof(OtherRegionsTable))
+ + strong_code_roots_mem_size();
}
// Returns the memory occupancy of all static data structures associated
@@ -304,6 +311,37 @@ public:
bool contains_reference(OopOrNarrowOopStar from) const {
return _other_regions.contains_reference(from);
}
+
+ // Routines for managing the list of code roots that point into
+ // the heap region that owns this RSet.
+ void add_strong_code_root(nmethod* nm);
+ void remove_strong_code_root(nmethod* nm);
+
+ // During a collection, migrate the successfully evacuated strong
+ // code roots that referenced into the region that owns this RSet
+ // to the RSets of the new regions that they now point into.
+ // Unsuccessfully evacuated code roots are not migrated.
+ void migrate_strong_code_roots();
+
+ // Applies blk->do_code_blob() to each of the entries in
+ // the strong code roots list
+ void strong_code_roots_do(CodeBlobClosure* blk) const;
+
+ // Returns the number of elements in the strong code roots list
+ int strong_code_roots_list_length() {
+ return _strong_code_roots_list->length();
+ }
+
+ // Returns true if the strong code roots contains the given
+ // nmethod.
+ bool strong_code_roots_list_contains(nmethod* nm) {
+ return _strong_code_roots_list->contains(nm);
+ }
+
+ // Returns the amount of memory, in bytes, currently
+ // consumed by the strong code roots.
+ size_t strong_code_roots_mem_size();
+
void print() const;
// Called during a stop-world phase to perform any deferred cleanups.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
index 3be06e6ae10..9f298da3873 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
@@ -70,9 +70,6 @@ VM_G1IncCollectionPause::VM_G1IncCollectionPause(
guarantee(target_pause_time_ms > 0.0,
err_msg("target_pause_time_ms = %1.6lf should be positive",
target_pause_time_ms));
- guarantee(word_size == 0 || gc_cause == GCCause::_g1_inc_collection_pause,
- "we can only request an allocation if the GC cause is for "
- "an incremental GC pause");
_gc_cause = gc_cause;
}
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
index d5b6c054005..e5d5229d30c 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
@@ -216,6 +216,7 @@ void ParallelScavengeHeap::update_counters() {
young_gen()->update_counters();
old_gen()->update_counters();
MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
}
size_t ParallelScavengeHeap::capacity() const {
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
index dfc963c3bc4..3af380049bb 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
@@ -118,6 +118,14 @@ void CollectedHeap::print_heap_after_gc() {
}
}
+void CollectedHeap::register_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+}
+
+void CollectedHeap::unregister_nmethod(nmethod* nm) {
+ assert_locked_or_safepoint(CodeCache_lock);
+}
+
void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
const GCHeapSummary& heap_summary = create_heap_summary();
const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
index 1f42cfe4839..c26ca77a8b8 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
@@ -49,6 +49,7 @@ class MetaspaceSummary;
class Thread;
class ThreadClosure;
class VirtualSpaceSummary;
+class nmethod;
class GCMessage : public FormatBuffer<1024> {
public:
@@ -603,6 +604,11 @@ class CollectedHeap : public CHeapObj {
void print_heap_before_gc();
void print_heap_after_gc();
+ // Registering and unregistering an nmethod (compiled code) with the heap.
+ // Override with specific mechanism for each specialized heap type.
+ virtual void register_nmethod(nmethod* nm);
+ virtual void unregister_nmethod(nmethod* nm);
+
void trace_heap_before_gc(GCTracer* gc_tracer);
void trace_heap_after_gc(GCTracer* gc_tracer);
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index aa916660d8b..d61bc7dcea5 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -666,7 +666,7 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
NEW_RESOURCE_ARRAY_RETURN_NULL(type, 1)
#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail)\
- (type*) AllocateHeap(size * sizeof(type), memflags, pc, allocfail)
+ (type*) AllocateHeap((size) * sizeof(type), memflags, pc, allocfail)
#define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
(type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
@@ -675,16 +675,16 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
(type*) (AllocateHeap((size) * sizeof(type), memflags))
#define NEW_C_HEAP_ARRAY2_RETURN_NULL(type, size, memflags, pc)\
- NEW_C_HEAP_ARRAY3(type, size, memflags, pc, AllocFailStrategy::RETURN_NULL)
+ NEW_C_HEAP_ARRAY3(type, (size), memflags, pc, AllocFailStrategy::RETURN_NULL)
#define NEW_C_HEAP_ARRAY_RETURN_NULL(type, size, memflags)\
- NEW_C_HEAP_ARRAY3(type, size, memflags, (address)0, AllocFailStrategy::RETURN_NULL)
+ NEW_C_HEAP_ARRAY3(type, (size), memflags, (address)0, AllocFailStrategy::RETURN_NULL)
#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
- (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
+ (type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags))
#define REALLOC_C_HEAP_ARRAY_RETURN_NULL(type, old, size, memflags)\
- (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
+ (type*) (ReallocateHeap((char*)(old), (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
#define FREE_C_HEAP_ARRAY(type, old, memflags) \
FreeHeap((char*)(old), memflags)
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index cba14a01459..6a1967daeda 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -193,6 +193,8 @@ size_t GenCollectorPolicy::compute_max_alignment() {
alignment = lcm(os::large_page_size(), alignment);
}
+ assert(alignment >= min_alignment(), "Must be");
+
return alignment;
}
diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp
index 5dfaf6f9701..d036266b00f 100644
--- a/hotspot/src/share/vm/memory/filemap.cpp
+++ b/hotspot/src/share/vm/memory/filemap.cpp
@@ -362,15 +362,12 @@ bool FileMapInfo::remap_shared_readonly_as_readwrite() {
ReservedSpace FileMapInfo::reserve_shared_memory() {
struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[0];
char* requested_addr = si->_base;
- size_t alignment = os::vm_allocation_granularity();
- size_t size = align_size_up(SharedReadOnlySize + SharedReadWriteSize +
- SharedMiscDataSize + SharedMiscCodeSize,
- alignment);
+ size_t size = FileMapInfo::shared_spaces_size();
// Reserve the space first, then map otherwise map will go right over some
// other reserved memory (like the code cache).
- ReservedSpace rs(size, alignment, false, requested_addr);
+ ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
if (!rs.is_reserved()) {
fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr));
return rs;
@@ -559,3 +556,19 @@ void FileMapInfo::print_shared_spaces() {
si->_base, si->_base + si->_used);
}
}
+
+// Unmap mapped regions of shared space.
+void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
+ FileMapInfo *map_info = FileMapInfo::current_info();
+ if (map_info) {
+ map_info->fail_continue(msg);
+ for (int i = 0; i < MetaspaceShared::n_regions; i++) {
+ if (map_info->_header._space[i]._base != NULL) {
+ map_info->unmap_region(i);
+ map_info->_header._space[i]._base = NULL;
+ }
+ }
+ } else if (DumpSharedSpaces) {
+ fail_stop(msg, NULL);
+ }
+}
diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp
index ee4ccec5bfe..8d7535ed990 100644
--- a/hotspot/src/share/vm/memory/filemap.hpp
+++ b/hotspot/src/share/vm/memory/filemap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -150,6 +150,15 @@ public:
// Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
void print_shared_spaces() NOT_CDS_RETURN;
+
+ static size_t shared_spaces_size() {
+ return align_size_up(SharedReadOnlySize + SharedReadWriteSize +
+ SharedMiscDataSize + SharedMiscCodeSize,
+ os::vm_allocation_granularity());
+ }
+
+ // Stop CDS sharing and unmap CDS regions.
+ static void stop_sharing_and_unmap(const char* msg);
};
#endif // SHARE_VM_MEMORY_FILEMAP_HPP
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
index 2faed4cc818..3a5ab210c83 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
@@ -95,13 +95,13 @@ jint GenCollectedHeap::initialize() {
guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");
// The heap must be at least as aligned as generations.
- size_t alignment = Generation::GenGrain;
+ size_t gen_alignment = Generation::GenGrain;
_gen_specs = gen_policy()->generations();
// Make sure the sizes are all aligned.
for (i = 0; i < _n_gens; i++) {
- _gen_specs[i]->align(alignment);
+ _gen_specs[i]->align(gen_alignment);
}
// Allocate space for the heap.
@@ -109,9 +109,11 @@ jint GenCollectedHeap::initialize() {
char* heap_address;
size_t total_reserved = 0;
int n_covered_regions = 0;
- ReservedSpace heap_rs(0);
+ ReservedSpace heap_rs;
- heap_address = allocate(alignment, &total_reserved,
+ size_t heap_alignment = collector_policy()->max_alignment();
+
+ heap_address = allocate(heap_alignment, &total_reserved,
&n_covered_regions, &heap_rs);
if (!heap_rs.is_reserved()) {
@@ -168,6 +170,8 @@ char* GenCollectedHeap::allocate(size_t alignment,
const size_t pageSize = UseLargePages ?
os::large_page_size() : os::vm_page_size();
+ assert(alignment % pageSize == 0, "Must be");
+
for (int i = 0; i < _n_gens; i++) {
total_reserved += _gen_specs[i]->max_size();
if (total_reserved < _gen_specs[i]->max_size()) {
@@ -175,24 +179,17 @@ char* GenCollectedHeap::allocate(size_t alignment,
}
n_covered_regions += _gen_specs[i]->n_covered_regions();
}
- assert(total_reserved % pageSize == 0,
- err_msg("Gen size; total_reserved=" SIZE_FORMAT ", pageSize="
- SIZE_FORMAT, total_reserved, pageSize));
+ assert(total_reserved % alignment == 0,
+ err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
+ SIZE_FORMAT, total_reserved, alignment));
// Needed until the cardtable is fixed to have the right number
// of covered regions.
n_covered_regions += 2;
- if (UseLargePages) {
- assert(total_reserved != 0, "total_reserved cannot be 0");
- total_reserved = round_to(total_reserved, os::large_page_size());
- if (total_reserved < os::large_page_size()) {
- vm_exit_during_initialization(overflow_msg);
- }
- }
+ *_total_reserved = total_reserved;
+ *_n_covered_regions = n_covered_regions;
- *_total_reserved = total_reserved;
- *_n_covered_regions = n_covered_regions;
*heap_rs = Universe::reserve_heap(total_reserved, alignment);
return heap_rs->base();
}
@@ -1211,6 +1208,7 @@ void GenCollectedHeap::gc_epilogue(bool full) {
}
MetaspaceCounters::update_performance_counters();
+ CompressedClassSpaceCounters::update_performance_counters();
always_do_update_barrier = UseConcMarkSweepGC;
};
diff --git a/hotspot/src/share/vm/memory/heap.cpp b/hotspot/src/share/vm/memory/heap.cpp
index 727690b5c7f..f00709684b4 100644
--- a/hotspot/src/share/vm/memory/heap.cpp
+++ b/hotspot/src/share/vm/memory/heap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,9 +118,12 @@ bool CodeHeap::reserve(size_t reserved_size, size_t committed_size,
_number_of_committed_segments = size_to_segments(_memory.committed_size());
_number_of_reserved_segments = size_to_segments(_memory.reserved_size());
assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
+ const size_t reserved_segments_alignment = MAX2((size_t)os::vm_page_size(), granularity);
+ const size_t reserved_segments_size = align_size_up(_number_of_reserved_segments, reserved_segments_alignment);
+ const size_t committed_segments_size = align_to_page_size(_number_of_committed_segments);
// reserve space for _segmap
- if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) {
+ if (!_segmap.initialize(reserved_segments_size, committed_segments_size)) {
return false;
}
diff --git a/hotspot/src/share/vm/memory/iterator.cpp b/hotspot/src/share/vm/memory/iterator.cpp
index e33a5614d63..545ab921363 100644
--- a/hotspot/src/share/vm/memory/iterator.cpp
+++ b/hotspot/src/share/vm/memory/iterator.cpp
@@ -64,7 +64,7 @@ void MarkingCodeBlobClosure::do_code_blob(CodeBlob* cb) {
}
void CodeBlobToOopClosure::do_newly_marked_nmethod(nmethod* nm) {
- nm->oops_do(_cl, /*do_strong_roots_only=*/ true);
+ nm->oops_do(_cl, /*allow_zombie=*/ false);
}
void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index f230dcf791d..cd46888c9c2 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -35,6 +35,7 @@
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "runtime/globals.hpp"
+#include "runtime/java.hpp"
#include "runtime/mutex.hpp"
#include "runtime/orderAccess.hpp"
#include "services/memTracker.hpp"
@@ -54,6 +55,8 @@ size_t const allocation_from_dictionary_limit = 64 * K;
MetaWord* last_allocated = 0;
+size_t Metaspace::_class_metaspace_size;
+
// Used in declarations in SpaceManager and ChunkManager
enum ChunkIndex {
ZeroIndex = 0,
@@ -261,10 +264,6 @@ class VirtualSpaceNode : public CHeapObj {
// count of chunks contained in this VirtualSpace
uintx _container_count;
- // Convenience functions for logical bottom and end
- MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
- MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
-
// Convenience functions to access the _virtual_space
char* low() const { return virtual_space()->low(); }
char* high() const { return virtual_space()->high(); }
@@ -284,6 +283,10 @@ class VirtualSpaceNode : public CHeapObj {
VirtualSpaceNode(ReservedSpace rs) : _top(NULL), _next(NULL), _rs(rs), _container_count(0) {}
~VirtualSpaceNode();
+ // Convenience functions for logical bottom and end
+ MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); }
+ MetaWord* end() const { return (MetaWord*) _virtual_space.high(); }
+
// address of next available space in _virtual_space;
// Accessors
VirtualSpaceNode* next() { return _next; }
@@ -342,7 +345,7 @@ class VirtualSpaceNode : public CHeapObj {
};
// byte_size is the size of the associated virtualspace.
-VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), _rs(0), _container_count(0) {
+VirtualSpaceNode::VirtualSpaceNode(size_t byte_size) : _top(NULL), _next(NULL), _rs(), _container_count(0) {
// align up to vm allocation granularity
byte_size = align_size_up(byte_size, os::vm_allocation_granularity());
@@ -1313,7 +1316,8 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) {
// Class virtual space should always be expanded. Call GC for the other
// metadata virtual space.
- if (vsl == Metaspace::class_space_list()) return true;
+ if (Metaspace::using_class_space() &&
+ (vsl == Metaspace::class_space_list())) return true;
// If this is part of an allocation after a GC, expand
// unconditionally.
@@ -2257,7 +2261,7 @@ void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
size_t raw_word_size = get_raw_word_size(word_size);
size_t min_size = TreeChunk::min_size();
assert(raw_word_size >= min_size,
- err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size));
+ err_msg("Should not deallocate dark matter " SIZE_FORMAT "<" SIZE_FORMAT, word_size, min_size));
block_freelists()->return_block(p, raw_word_size);
}
@@ -2374,7 +2378,7 @@ MetaWord* SpaceManager::allocate_work(size_t word_size) {
if (result == NULL) {
result = grow_and_allocate(word_size);
}
- if (result > 0) {
+ if (result != 0) {
inc_used_metrics(word_size);
assert(result != (MetaWord*) chunks_in_use(MediumIndex),
"Head of the list is being allocated");
@@ -2476,15 +2480,13 @@ void SpaceManager::mangle_freed_chunks() {
size_t MetaspaceAux::_allocated_capacity_words[] = {0, 0};
size_t MetaspaceAux::_allocated_used_words[] = {0, 0};
+size_t MetaspaceAux::free_bytes(Metaspace::MetadataType mdtype) {
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ return list == NULL ? 0 : list->free_bytes();
+}
+
size_t MetaspaceAux::free_bytes() {
- size_t result = 0;
- if (Metaspace::class_space_list() != NULL) {
- result = result + Metaspace::class_space_list()->free_bytes();
- }
- if (Metaspace::space_list() != NULL) {
- result = result + Metaspace::space_list()->free_bytes();
- }
- return result;
+ return free_bytes(Metaspace::ClassType) + free_bytes(Metaspace::NonClassType);
}
void MetaspaceAux::dec_capacity(Metaspace::MetadataType mdtype, size_t words) {
@@ -2549,6 +2551,9 @@ size_t MetaspaceAux::free_in_bytes(Metaspace::MetadataType mdtype) {
}
size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
+ if ((mdtype == Metaspace::ClassType) && !Metaspace::using_class_space()) {
+ return 0;
+ }
// Don't count the space in the freelists. That space will be
// added to the capacity calculation as needed.
size_t capacity = 0;
@@ -2563,18 +2568,18 @@ size_t MetaspaceAux::capacity_bytes_slow(Metaspace::MetadataType mdtype) {
}
size_t MetaspaceAux::reserved_in_bytes(Metaspace::MetadataType mdtype) {
- size_t reserved = (mdtype == Metaspace::ClassType) ?
- Metaspace::class_space_list()->virtual_space_total() :
- Metaspace::space_list()->virtual_space_total();
- return reserved * BytesPerWord;
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ return list == NULL ? 0 : list->virtual_space_total();
}
size_t MetaspaceAux::min_chunk_size() { return Metaspace::first_chunk_word_size(); }
size_t MetaspaceAux::free_chunks_total(Metaspace::MetadataType mdtype) {
- ChunkManager* chunk = (mdtype == Metaspace::ClassType) ?
- Metaspace::class_space_list()->chunk_manager() :
- Metaspace::space_list()->chunk_manager();
+ VirtualSpaceList* list = Metaspace::get_space_list(mdtype);
+ if (list == NULL) {
+ return 0;
+ }
+ ChunkManager* chunk = list->chunk_manager();
chunk->slow_verify();
return chunk->free_chunks_total();
}
@@ -2615,7 +2620,6 @@ void MetaspaceAux::print_metaspace_change(size_t prev_metadata_used) {
// This is printed when PrintGCDetails
void MetaspaceAux::print_on(outputStream* out) {
- Metaspace::MetadataType ct = Metaspace::ClassType;
Metaspace::MetadataType nct = Metaspace::NonClassType;
out->print_cr(" Metaspace total "
@@ -2629,12 +2633,15 @@ void MetaspaceAux::print_on(outputStream* out) {
allocated_capacity_bytes(nct)/K,
allocated_used_bytes(nct)/K,
reserved_in_bytes(nct)/K);
- out->print_cr(" class space "
- SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
- " reserved " SIZE_FORMAT "K",
- allocated_capacity_bytes(ct)/K,
- allocated_used_bytes(ct)/K,
- reserved_in_bytes(ct)/K);
+ if (Metaspace::using_class_space()) {
+ Metaspace::MetadataType ct = Metaspace::ClassType;
+ out->print_cr(" class space "
+ SIZE_FORMAT "K, used " SIZE_FORMAT "K,"
+ " reserved " SIZE_FORMAT "K",
+ allocated_capacity_bytes(ct)/K,
+ allocated_used_bytes(ct)/K,
+ reserved_in_bytes(ct)/K);
+ }
}
// Print information for class space and data space separately.
@@ -2659,13 +2666,37 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) {
assert(!SafepointSynchronize::is_at_safepoint() || used_and_free == capacity_bytes, "Accounting is wrong");
}
-// Print total fragmentation for class and data metaspaces separately
-void MetaspaceAux::print_waste(outputStream* out) {
-
- size_t specialized_waste = 0, small_waste = 0, medium_waste = 0;
- size_t specialized_count = 0, small_count = 0, medium_count = 0, humongous_count = 0;
+// Print total fragmentation for class metaspaces
+void MetaspaceAux::print_class_waste(outputStream* out) {
+ assert(Metaspace::using_class_space(), "class metaspace not used");
size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0;
size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0;
+ ClassLoaderDataGraphMetaspaceIterator iter;
+ while (iter.repeat()) {
+ Metaspace* msp = iter.get_next();
+ if (msp != NULL) {
+ cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
+ cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
+ cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex);
+ cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex);
+ cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex);
+ cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex);
+ cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
+ }
+ }
+ out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
+ SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
+ SIZE_FORMAT " medium(s) " SIZE_FORMAT ", "
+ "large count " SIZE_FORMAT,
+ cls_specialized_count, cls_specialized_waste,
+ cls_small_count, cls_small_waste,
+ cls_medium_count, cls_medium_waste, cls_humongous_count);
+}
+
+// Print total fragmentation for data and class metaspaces separately
+void MetaspaceAux::print_waste(outputStream* out) {
+ size_t specialized_waste = 0, small_waste = 0, medium_waste = 0;
+ size_t specialized_count = 0, small_count = 0, medium_count = 0, humongous_count = 0;
ClassLoaderDataGraphMetaspaceIterator iter;
while (iter.repeat()) {
@@ -2678,14 +2709,6 @@ void MetaspaceAux::print_waste(outputStream* out) {
medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex);
medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex);
humongous_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex);
-
- cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex);
- cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex);
- cls_small_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SmallIndex);
- cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex);
- cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex);
- cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex);
- cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex);
}
}
out->print_cr("Total fragmentation waste (words) doesn't count free space");
@@ -2695,13 +2718,9 @@ void MetaspaceAux::print_waste(outputStream* out) {
"large count " SIZE_FORMAT,
specialized_count, specialized_waste, small_count,
small_waste, medium_count, medium_waste, humongous_count);
- out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", "
- SIZE_FORMAT " small(s) " SIZE_FORMAT ", "
- SIZE_FORMAT " medium(s) " SIZE_FORMAT ", "
- "large count " SIZE_FORMAT,
- cls_specialized_count, cls_specialized_waste,
- cls_small_count, cls_small_waste,
- cls_medium_count, cls_medium_waste, cls_humongous_count);
+ if (Metaspace::using_class_space()) {
+ print_class_waste(out);
+ }
}
// Dump global metaspace things from the end of ClassLoaderDataGraph
@@ -2714,7 +2733,9 @@ void MetaspaceAux::dump(outputStream* out) {
void MetaspaceAux::verify_free_chunks() {
Metaspace::space_list()->chunk_manager()->verify();
- Metaspace::class_space_list()->chunk_manager()->verify();
+ if (Metaspace::using_class_space()) {
+ Metaspace::class_space_list()->chunk_manager()->verify();
+ }
}
void MetaspaceAux::verify_capacity() {
@@ -2776,7 +2797,9 @@ Metaspace::Metaspace(Mutex* lock, MetaspaceType type) {
Metaspace::~Metaspace() {
delete _vsm;
- delete _class_vsm;
+ if (using_class_space()) {
+ delete _class_vsm;
+ }
}
VirtualSpaceList* Metaspace::_space_list = NULL;
@@ -2784,9 +2807,123 @@ VirtualSpaceList* Metaspace::_class_space_list = NULL;
#define VIRTUALSPACEMULTIPLIER 2
+#ifdef _LP64
+void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address cds_base) {
+ // Figure out the narrow_klass_base and the narrow_klass_shift. The
+ // narrow_klass_base is the lower of the metaspace base and the cds base
+ // (if cds is enabled). The narrow_klass_shift depends on the distance
+ // between the lower base and higher address.
+ address lower_base;
+ address higher_address;
+ if (UseSharedSpaces) {
+ higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
+ (address)(metaspace_base + class_metaspace_size()));
+ lower_base = MIN2(metaspace_base, cds_base);
+ } else {
+ higher_address = metaspace_base + class_metaspace_size();
+ lower_base = metaspace_base;
+ }
+ Universe::set_narrow_klass_base(lower_base);
+ if ((uint64_t)(higher_address - lower_base) < (uint64_t)max_juint) {
+ Universe::set_narrow_klass_shift(0);
+ } else {
+ assert(!UseSharedSpaces, "Cannot shift with UseSharedSpaces");
+ Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes);
+ }
+}
+
+// Return TRUE if the specified metaspace_base and cds_base are close enough
+// to work with compressed klass pointers.
+bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base) {
+ assert(cds_base != 0 && UseSharedSpaces, "Only use with CDS");
+ assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
+ address lower_base = MIN2((address)metaspace_base, cds_base);
+ address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
+ (address)(metaspace_base + class_metaspace_size()));
+ return ((uint64_t)(higher_address - lower_base) < (uint64_t)max_juint);
+}
+
+// Try to allocate the metaspace at the requested addr.
+void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base) {
+ assert(using_class_space(), "called improperly");
+ assert(UseCompressedKlassPointers, "Only use with CompressedKlassPtrs");
+ assert(class_metaspace_size() < KlassEncodingMetaspaceMax,
+ "Metaspace size is too big");
+
+ ReservedSpace metaspace_rs = ReservedSpace(class_metaspace_size(),
+ os::vm_allocation_granularity(),
+ false, requested_addr, 0);
+ if (!metaspace_rs.is_reserved()) {
+ if (UseSharedSpaces) {
+ // Keep trying to allocate the metaspace, increasing the requested_addr
+ // by 1GB each time, until we reach an address that will no longer allow
+ // use of CDS with compressed klass pointers.
+ char *addr = requested_addr;
+ while (!metaspace_rs.is_reserved() && (addr + 1*G > addr) &&
+ can_use_cds_with_metaspace_addr(addr + 1*G, cds_base)) {
+ addr = addr + 1*G;
+ metaspace_rs = ReservedSpace(class_metaspace_size(),
+ os::vm_allocation_granularity(), false, addr, 0);
+ }
+ }
+
+ // If no successful allocation then try to allocate the space anywhere. If
+ // that fails then OOM doom. At this point we cannot try allocating the
+ // metaspace as if UseCompressedKlassPointers is off because too much
+ // initialization has happened that depends on UseCompressedKlassPointers.
+ // So, UseCompressedKlassPointers cannot be turned off at this point.
+ if (!metaspace_rs.is_reserved()) {
+ metaspace_rs = ReservedSpace(class_metaspace_size(),
+ os::vm_allocation_granularity(), false);
+ if (!metaspace_rs.is_reserved()) {
+ vm_exit_during_initialization(err_msg("Could not allocate metaspace: %d bytes",
+ class_metaspace_size()));
+ }
+ }
+ }
+
+ // If we got here then the metaspace got allocated.
+ MemTracker::record_virtual_memory_type((address)metaspace_rs.base(), mtClass);
+
+ // Verify that we can use shared spaces. Otherwise, turn off CDS.
+ if (UseSharedSpaces && !can_use_cds_with_metaspace_addr(metaspace_rs.base(), cds_base)) {
+ FileMapInfo::stop_sharing_and_unmap(
+ "Could not allocate metaspace at a compatible address");
+ }
+
+ set_narrow_klass_base_and_shift((address)metaspace_rs.base(),
+ UseSharedSpaces ? (address)cds_base : 0);
+
+ initialize_class_space(metaspace_rs);
+
+ if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
+ gclog_or_tty->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: " SIZE_FORMAT,
+ Universe::narrow_klass_base(), Universe::narrow_klass_shift());
+ gclog_or_tty->print_cr("Metaspace Size: " SIZE_FORMAT " Address: " PTR_FORMAT " Req Addr: " PTR_FORMAT,
+ class_metaspace_size(), metaspace_rs.base(), requested_addr);
+ }
+}
+
+// For UseCompressedKlassPointers the class space is reserved above the top of
+// the Java heap. The argument passed in is at the base of the compressed space.
+void Metaspace::initialize_class_space(ReservedSpace rs) {
+ // The reserved space size may be bigger because of alignment, esp with UseLargePages
+ assert(rs.size() >= ClassMetaspaceSize,
+ err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
+ assert(using_class_space(), "Must be using class space");
+ _class_space_list = new VirtualSpaceList(rs);
+}
+
+#endif
+
void Metaspace::global_initialize() {
// Initialize the alignment for shared spaces.
int max_alignment = os::vm_page_size();
+ size_t cds_total = 0;
+
+ set_class_metaspace_size(align_size_up(ClassMetaspaceSize,
+ os::vm_allocation_granularity()));
+
MetaspaceShared::set_max_alignment(max_alignment);
if (DumpSharedSpaces) {
@@ -2798,15 +2935,31 @@ void Metaspace::global_initialize() {
// Initialize with the sum of the shared space sizes. The read-only
// and read write metaspace chunks will be allocated out of this and the
// remainder is the misc code and data chunks.
- size_t total = align_size_up(SharedReadOnlySize + SharedReadWriteSize +
- SharedMiscDataSize + SharedMiscCodeSize,
- os::vm_allocation_granularity());
- size_t word_size = total/wordSize;
- _space_list = new VirtualSpaceList(word_size);
+ cds_total = FileMapInfo::shared_spaces_size();
+ _space_list = new VirtualSpaceList(cds_total/wordSize);
+
+#ifdef _LP64
+ // Set the compressed klass pointer base so that decoding of these pointers works
+ // properly when creating the shared archive.
+ assert(UseCompressedOops && UseCompressedKlassPointers,
+ "UseCompressedOops and UseCompressedKlassPointers must be set");
+ Universe::set_narrow_klass_base((address)_space_list->current_virtual_space()->bottom());
+ if (TraceMetavirtualspaceAllocation && Verbose) {
+ gclog_or_tty->print_cr("Setting_narrow_klass_base to Address: " PTR_FORMAT,
+ _space_list->current_virtual_space()->bottom());
+ }
+
+ // Set the shift to zero.
+ assert(class_metaspace_size() < (uint64_t)(max_juint) - cds_total,
+ "CDS region is too large");
+ Universe::set_narrow_klass_shift(0);
+#endif
+
} else {
// If using shared space, open the file that contains the shared space
// and map in the memory before initializing the rest of metaspace (so
// the addresses don't conflict)
+ address cds_address = NULL;
if (UseSharedSpaces) {
FileMapInfo* mapinfo = new FileMapInfo();
memset(mapinfo, 0, sizeof(FileMapInfo));
@@ -2821,8 +2974,22 @@ void Metaspace::global_initialize() {
assert(!mapinfo->is_open() && !UseSharedSpaces,
"archive file not closed or shared spaces not disabled.");
}
+ cds_total = FileMapInfo::shared_spaces_size();
+ cds_address = (address)mapinfo->region_base(0);
}
+#ifdef _LP64
+ // If UseCompressedKlassPointers is set then allocate the metaspace area
+ // above the heap and above the CDS area (if it exists).
+ if (using_class_space()) {
+ if (UseSharedSpaces) {
+ allocate_metaspace_compressed_klass_ptrs((char *)(cds_address + cds_total), cds_address);
+ } else {
+ allocate_metaspace_compressed_klass_ptrs((char *)CompressedKlassPointersBase, 0);
+ }
+ }
+#endif
+
// Initialize these before initializing the VirtualSpaceList
_first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
_first_chunk_word_size = align_word_size_up(_first_chunk_word_size);
@@ -2840,39 +3007,28 @@ void Metaspace::global_initialize() {
}
}
-// For UseCompressedKlassPointers the class space is reserved as a piece of the
-// Java heap because the compression algorithm is the same for each. The
-// argument passed in is at the top of the compressed space
-void Metaspace::initialize_class_space(ReservedSpace rs) {
- // The reserved space size may be bigger because of alignment, esp with UseLargePages
- assert(rs.size() >= ClassMetaspaceSize,
- err_msg(SIZE_FORMAT " != " UINTX_FORMAT, rs.size(), ClassMetaspaceSize));
- _class_space_list = new VirtualSpaceList(rs);
-}
-
-void Metaspace::initialize(Mutex* lock,
- MetaspaceType type) {
+void Metaspace::initialize(Mutex* lock, MetaspaceType type) {
assert(space_list() != NULL,
"Metadata VirtualSpaceList has not been initialized");
- _vsm = new SpaceManager(Metaspace::NonClassType, lock, space_list());
+ _vsm = new SpaceManager(NonClassType, lock, space_list());
if (_vsm == NULL) {
return;
}
size_t word_size;
size_t class_word_size;
- vsm()->get_initial_chunk_sizes(type,
- &word_size,
- &class_word_size);
+ vsm()->get_initial_chunk_sizes(type, &word_size, &class_word_size);
- assert(class_space_list() != NULL,
- "Class VirtualSpaceList has not been initialized");
+ if (using_class_space()) {
+ assert(class_space_list() != NULL,
+ "Class VirtualSpaceList has not been initialized");
- // Allocate SpaceManager for classes.
- _class_vsm = new SpaceManager(Metaspace::ClassType, lock, class_space_list());
- if (_class_vsm == NULL) {
- return;
+ // Allocate SpaceManager for classes.
+ _class_vsm = new SpaceManager(ClassType, lock, class_space_list());
+ if (_class_vsm == NULL) {
+ return;
+ }
}
MutexLockerEx cl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
@@ -2888,11 +3044,13 @@ void Metaspace::initialize(Mutex* lock,
}
// Allocate chunk for class metadata objects
- Metachunk* class_chunk =
- class_space_list()->get_initialization_chunk(class_word_size,
- class_vsm()->medium_chunk_bunch());
- if (class_chunk != NULL) {
- class_vsm()->add_chunk(class_chunk, true);
+ if (using_class_space()) {
+ Metachunk* class_chunk =
+ class_space_list()->get_initialization_chunk(class_word_size,
+ class_vsm()->medium_chunk_bunch());
+ if (class_chunk != NULL) {
+ class_vsm()->add_chunk(class_chunk, true);
+ }
}
_alloc_record_head = NULL;
@@ -2906,7 +3064,8 @@ size_t Metaspace::align_word_size_up(size_t word_size) {
MetaWord* Metaspace::allocate(size_t word_size, MetadataType mdtype) {
// DumpSharedSpaces doesn't use class metadata area (yet)
- if (mdtype == ClassType && !DumpSharedSpaces) {
+ // Also, don't use class_vsm() unless UseCompressedKlassPointers is true.
+ if (mdtype == ClassType && using_class_space()) {
return class_vsm()->allocate(word_size);
} else {
return vsm()->allocate(word_size);
@@ -2937,14 +3096,19 @@ char* Metaspace::bottom() const {
}
size_t Metaspace::used_words_slow(MetadataType mdtype) const {
- // return vsm()->allocated_used_words();
- return mdtype == ClassType ? class_vsm()->sum_used_in_chunks_in_use() :
- vsm()->sum_used_in_chunks_in_use(); // includes overhead!
+ if (mdtype == ClassType) {
+ return using_class_space() ? class_vsm()->sum_used_in_chunks_in_use() : 0;
+ } else {
+ return vsm()->sum_used_in_chunks_in_use(); // includes overhead!
+ }
}
size_t Metaspace::free_words(MetadataType mdtype) const {
- return mdtype == ClassType ? class_vsm()->sum_free_in_chunks_in_use() :
- vsm()->sum_free_in_chunks_in_use();
+ if (mdtype == ClassType) {
+ return using_class_space() ? class_vsm()->sum_free_in_chunks_in_use() : 0;
+ } else {
+ return vsm()->sum_free_in_chunks_in_use();
+ }
}
// Space capacity in the Metaspace. It includes
@@ -2953,8 +3117,11 @@ size_t Metaspace::free_words(MetadataType mdtype) const {
// in the space available in the dictionary which
// is already counted in some chunk.
size_t Metaspace::capacity_words_slow(MetadataType mdtype) const {
- return mdtype == ClassType ? class_vsm()->sum_capacity_in_chunks_in_use() :
- vsm()->sum_capacity_in_chunks_in_use();
+ if (mdtype == ClassType) {
+ return using_class_space() ? class_vsm()->sum_capacity_in_chunks_in_use() : 0;
+ } else {
+ return vsm()->sum_capacity_in_chunks_in_use();
+ }
}
size_t Metaspace::used_bytes_slow(MetadataType mdtype) const {
@@ -2977,8 +3144,8 @@ void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
#endif
return;
}
- if (is_class) {
- class_vsm()->deallocate(ptr, word_size);
+ if (is_class && using_class_space()) {
+ class_vsm()->deallocate(ptr, word_size);
} else {
vsm()->deallocate(ptr, word_size);
}
@@ -2992,7 +3159,7 @@ void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
#endif
return;
}
- if (is_class) {
+ if (is_class && using_class_space()) {
class_vsm()->deallocate(ptr, word_size);
} else {
vsm()->deallocate(ptr, word_size);
@@ -3101,14 +3268,18 @@ void Metaspace::purge() {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
space_list()->purge();
- class_space_list()->purge();
+ if (using_class_space()) {
+ class_space_list()->purge();
+ }
}
void Metaspace::print_on(outputStream* out) const {
// Print both class virtual space counts and metaspace.
if (Verbose) {
- vsm()->print_on(out);
+ vsm()->print_on(out);
+ if (using_class_space()) {
class_vsm()->print_on(out);
+ }
}
}
@@ -3122,17 +3293,21 @@ bool Metaspace::contains(const void * ptr) {
// be needed. Note, locking this can cause inversion problems with the
// caller in MetaspaceObj::is_metadata() function.
return space_list()->contains(ptr) ||
- class_space_list()->contains(ptr);
+ (using_class_space() && class_space_list()->contains(ptr));
}
void Metaspace::verify() {
vsm()->verify();
- class_vsm()->verify();
+ if (using_class_space()) {
+ class_vsm()->verify();
+ }
}
void Metaspace::dump(outputStream* const out) const {
out->print_cr("\nVirtual space manager: " INTPTR_FORMAT, vsm());
vsm()->dump(out);
- out->print_cr("\nClass space manager: " INTPTR_FORMAT, class_vsm());
- class_vsm()->dump(out);
+ if (using_class_space()) {
+ out->print_cr("\nClass space manager: " INTPTR_FORMAT, class_vsm());
+ class_vsm()->dump(out);
+ }
}
diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp
index cd499341c1d..88f089494d3 100644
--- a/hotspot/src/share/vm/memory/metaspace.hpp
+++ b/hotspot/src/share/vm/memory/metaspace.hpp
@@ -105,6 +105,16 @@ class Metaspace : public CHeapObj {
// Align up the word size to the allocation word size
static size_t align_word_size_up(size_t);
+ // Aligned size of the metaspace.
+ static size_t _class_metaspace_size;
+
+ static size_t class_metaspace_size() {
+ return _class_metaspace_size;
+ }
+ static void set_class_metaspace_size(size_t metaspace_size) {
+ _class_metaspace_size = metaspace_size;
+ }
+
static size_t _first_chunk_word_size;
static size_t _first_class_chunk_word_size;
@@ -126,11 +136,26 @@ class Metaspace : public CHeapObj {
static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; }
+ static VirtualSpaceList* get_space_list(MetadataType mdtype) {
+ assert(mdtype != MetadataTypeCount, "MetadaTypeCount can't be used as mdtype");
+ return mdtype == ClassType ? class_space_list() : space_list();
+ }
// This is used by DumpSharedSpaces only, where only _vsm is used. So we will
// maintain a single list for now.
void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
+#ifdef _LP64
+ static void set_narrow_klass_base_and_shift(address metaspace_base, address cds_base);
+
+ // Returns true if can use CDS with metaspace allocated as specified address.
+ static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base);
+
+ static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base);
+
+ static void initialize_class_space(ReservedSpace rs);
+#endif
+
class AllocRecord : public CHeapObj {
public:
AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
@@ -151,7 +176,6 @@ class Metaspace : public CHeapObj {
// Initialize globals for Metaspace
static void global_initialize();
- static void initialize_class_space(ReservedSpace rs);
static size_t first_chunk_word_size() { return _first_chunk_word_size; }
static size_t first_class_chunk_word_size() { return _first_class_chunk_word_size; }
@@ -172,8 +196,6 @@ class Metaspace : public CHeapObj {
MetaWord* expand_and_allocate(size_t size,
MetadataType mdtype);
- static bool is_initialized() { return _class_space_list != NULL; }
-
static bool contains(const void *ptr);
void dump(outputStream* const out) const;
@@ -190,11 +212,16 @@ class Metaspace : public CHeapObj {
};
void iterate(AllocRecordClosure *closure);
+
+ // Return TRUE only if UseCompressedKlassPointers is True and DumpSharedSpaces is False.
+ static bool using_class_space() {
+ return NOT_LP64(false) LP64_ONLY(UseCompressedKlassPointers && !DumpSharedSpaces);
+ }
+
};
class MetaspaceAux : AllStatic {
static size_t free_chunks_total(Metaspace::MetadataType mdtype);
- static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
public:
// Statistics for class space and data space in metaspace.
@@ -238,13 +265,15 @@ class MetaspaceAux : AllStatic {
// Used by MetaspaceCounters
static size_t free_chunks_total();
static size_t free_chunks_total_in_bytes();
+ static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
static size_t allocated_capacity_words(Metaspace::MetadataType mdtype) {
return _allocated_capacity_words[mdtype];
}
static size_t allocated_capacity_words() {
- return _allocated_capacity_words[Metaspace::ClassType] +
- _allocated_capacity_words[Metaspace::NonClassType];
+ return _allocated_capacity_words[Metaspace::NonClassType] +
+ (Metaspace::using_class_space() ?
+ _allocated_capacity_words[Metaspace::ClassType] : 0);
}
static size_t allocated_capacity_bytes(Metaspace::MetadataType mdtype) {
return allocated_capacity_words(mdtype) * BytesPerWord;
@@ -257,8 +286,9 @@ class MetaspaceAux : AllStatic {
return _allocated_used_words[mdtype];
}
static size_t allocated_used_words() {
- return _allocated_used_words[Metaspace::ClassType] +
- _allocated_used_words[Metaspace::NonClassType];
+ return _allocated_used_words[Metaspace::NonClassType] +
+ (Metaspace::using_class_space() ?
+ _allocated_used_words[Metaspace::ClassType] : 0);
}
static size_t allocated_used_bytes(Metaspace::MetadataType mdtype) {
return allocated_used_words(mdtype) * BytesPerWord;
@@ -268,6 +298,7 @@ class MetaspaceAux : AllStatic {
}
static size_t free_bytes();
+ static size_t free_bytes(Metaspace::MetadataType mdtype);
// Total capacity in all Metaspaces
static size_t capacity_bytes_slow() {
@@ -300,6 +331,7 @@ class MetaspaceAux : AllStatic {
static void print_on(outputStream * out);
static void print_on(outputStream * out, Metaspace::MetadataType mdtype);
+ static void print_class_waste(outputStream* out);
static void print_waste(outputStream* out);
static void dump(outputStream* out);
static void verify_free_chunks();
diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.cpp b/hotspot/src/share/vm/memory/metaspaceCounters.cpp
index b2be29bca2f..eb7bebd28b6 100644
--- a/hotspot/src/share/vm/memory/metaspaceCounters.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.cpp
@@ -25,11 +25,47 @@
#include "precompiled.hpp"
#include "memory/metaspaceCounters.hpp"
#include "memory/resourceArea.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/perfData.hpp"
#include "utilities/exceptions.hpp"
-MetaspaceCounters* MetaspaceCounters::_metaspace_counters = NULL;
+class MetaspacePerfCounters: public CHeapObj {
+ friend class VMStructs;
+ PerfVariable* _capacity;
+ PerfVariable* _used;
+ PerfVariable* _max_capacity;
-size_t MetaspaceCounters::calc_total_capacity() {
+ PerfVariable* create_variable(const char *ns, const char *name, size_t value, TRAPS) {
+ const char *path = PerfDataManager::counter_name(ns, name);
+ return PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value, THREAD);
+ }
+
+ void create_constant(const char *ns, const char *name, size_t value, TRAPS) {
+ const char *path = PerfDataManager::counter_name(ns, name);
+ PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, THREAD);
+ }
+
+ public:
+ MetaspacePerfCounters(const char* ns, size_t min_capacity, size_t curr_capacity, size_t max_capacity, size_t used) {
+ EXCEPTION_MARK;
+ ResourceMark rm;
+
+ create_constant(ns, "minCapacity", min_capacity, THREAD);
+ _capacity = create_variable(ns, "capacity", curr_capacity, THREAD);
+ _max_capacity = create_variable(ns, "maxCapacity", max_capacity, THREAD);
+ _used = create_variable(ns, "used", used, THREAD);
+ }
+
+ void update(size_t capacity, size_t max_capacity, size_t used) {
+ _capacity->set_value(capacity);
+ _max_capacity->set_value(max_capacity);
+ _used->set_value(used);
+ }
+};
+
+MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
+
+size_t MetaspaceCounters::calculate_capacity() {
// The total capacity is the sum of
// 1) capacity of Metachunks in use by all Metaspaces
// 2) unused space at the end of each Metachunk
@@ -39,95 +75,65 @@ size_t MetaspaceCounters::calc_total_capacity() {
return total_capacity;
}
-MetaspaceCounters::MetaspaceCounters() :
- _capacity(NULL),
- _used(NULL),
- _max_capacity(NULL) {
- if (UsePerfData) {
- size_t min_capacity = MetaspaceAux::min_chunk_size();
- size_t max_capacity = MetaspaceAux::reserved_in_bytes();
- size_t curr_capacity = calc_total_capacity();
- size_t used = MetaspaceAux::allocated_used_bytes();
-
- initialize(min_capacity, max_capacity, curr_capacity, used);
- }
-}
-
-static PerfVariable* create_ms_variable(const char *ns,
- const char *name,
- size_t value,
- TRAPS) {
- const char *path = PerfDataManager::counter_name(ns, name);
- PerfVariable *result =
- PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value,
- CHECK_NULL);
- return result;
-}
-
-static void create_ms_constant(const char *ns,
- const char *name,
- size_t value,
- TRAPS) {
- const char *path = PerfDataManager::counter_name(ns, name);
- PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, CHECK);
-}
-
-void MetaspaceCounters::initialize(size_t min_capacity,
- size_t max_capacity,
- size_t curr_capacity,
- size_t used) {
-
- if (UsePerfData) {
- EXCEPTION_MARK;
- ResourceMark rm;
-
- const char *ms = "metaspace";
-
- create_ms_constant(ms, "minCapacity", min_capacity, CHECK);
- _max_capacity = create_ms_variable(ms, "maxCapacity", max_capacity, CHECK);
- _capacity = create_ms_variable(ms, "capacity", curr_capacity, CHECK);
- _used = create_ms_variable(ms, "used", used, CHECK);
- }
-}
-
-void MetaspaceCounters::update_capacity() {
- assert(UsePerfData, "Should not be called unless being used");
- size_t total_capacity = calc_total_capacity();
- _capacity->set_value(total_capacity);
-}
-
-void MetaspaceCounters::update_used() {
- assert(UsePerfData, "Should not be called unless being used");
- size_t used_in_bytes = MetaspaceAux::allocated_used_bytes();
- _used->set_value(used_in_bytes);
-}
-
-void MetaspaceCounters::update_max_capacity() {
- assert(UsePerfData, "Should not be called unless being used");
- assert(_max_capacity != NULL, "Should be initialized");
- size_t reserved_in_bytes = MetaspaceAux::reserved_in_bytes();
- _max_capacity->set_value(reserved_in_bytes);
-}
-
-void MetaspaceCounters::update_all() {
- if (UsePerfData) {
- update_used();
- update_capacity();
- update_max_capacity();
- }
-}
-
void MetaspaceCounters::initialize_performance_counters() {
if (UsePerfData) {
- assert(_metaspace_counters == NULL, "Should only be initialized once");
- _metaspace_counters = new MetaspaceCounters();
+ assert(_perf_counters == NULL, "Should only be initialized once");
+
+ size_t min_capacity = MetaspaceAux::min_chunk_size();
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes();
+ size_t used = MetaspaceAux::allocated_used_bytes();
+
+ _perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
}
}
void MetaspaceCounters::update_performance_counters() {
if (UsePerfData) {
- assert(_metaspace_counters != NULL, "Should be initialized");
- _metaspace_counters->update_all();
+ assert(_perf_counters != NULL, "Should be initialized");
+
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes();
+ size_t used = MetaspaceAux::allocated_used_bytes();
+
+ _perf_counters->update(capacity, max_capacity, used);
}
}
+MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
+
+size_t CompressedClassSpaceCounters::calculate_capacity() {
+ return MetaspaceAux::allocated_capacity_bytes(_class_type) +
+ MetaspaceAux::free_bytes(_class_type) +
+ MetaspaceAux::free_chunks_total_in_bytes(_class_type);
+}
+
+void CompressedClassSpaceCounters::update_performance_counters() {
+ if (UsePerfData && UseCompressedKlassPointers) {
+ assert(_perf_counters != NULL, "Should be initialized");
+
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
+ size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
+
+ _perf_counters->update(capacity, max_capacity, used);
+ }
+}
+
+void CompressedClassSpaceCounters::initialize_performance_counters() {
+ if (UsePerfData) {
+ assert(_perf_counters == NULL, "Should only be initialized once");
+ const char* ns = "compressedclassspace";
+
+ if (UseCompressedKlassPointers) {
+ size_t min_capacity = MetaspaceAux::min_chunk_size();
+ size_t capacity = calculate_capacity();
+ size_t max_capacity = MetaspaceAux::reserved_in_bytes(_class_type);
+ size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
+
+ _perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
+ } else {
+ _perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
+ }
+ }
+}
diff --git a/hotspot/src/share/vm/memory/metaspaceCounters.hpp b/hotspot/src/share/vm/memory/metaspaceCounters.hpp
index 46a9308888a..5b481d59b4d 100644
--- a/hotspot/src/share/vm/memory/metaspaceCounters.hpp
+++ b/hotspot/src/share/vm/memory/metaspaceCounters.hpp
@@ -25,31 +25,27 @@
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
-#include "runtime/perfData.hpp"
+#include "memory/metaspace.hpp"
+
+class MetaspacePerfCounters;
+
+class MetaspaceCounters: public AllStatic {
+ static MetaspacePerfCounters* _perf_counters;
+ static size_t calculate_capacity();
-class MetaspaceCounters: public CHeapObj {
- friend class VMStructs;
- PerfVariable* _capacity;
- PerfVariable* _used;
- PerfVariable* _max_capacity;
- static MetaspaceCounters* _metaspace_counters;
- void initialize(size_t min_capacity,
- size_t max_capacity,
- size_t curr_capacity,
- size_t used);
- size_t calc_total_capacity();
public:
- MetaspaceCounters();
- ~MetaspaceCounters();
-
- void update_capacity();
- void update_used();
- void update_max_capacity();
-
- void update_all();
-
static void initialize_performance_counters();
static void update_performance_counters();
-
};
+
+class CompressedClassSpaceCounters: public AllStatic {
+ static MetaspacePerfCounters* _perf_counters;
+ static size_t calculate_capacity();
+ static const Metaspace::MetadataType _class_type = Metaspace::ClassType;
+
+ public:
+ static void initialize_performance_counters();
+ static void update_performance_counters();
+};
+
#endif // SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
index c7d61f7b732..2a9873957a8 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
@@ -52,7 +52,6 @@ void MetaspaceShared::serialize(SerializeClosure* soc) {
int tag = 0;
soc->do_tag(--tag);
- assert(!UseCompressedOops, "UseCompressedOops doesn't work with shared archive");
// Verify the sizes of various metadata in the system.
soc->do_tag(sizeof(Method));
soc->do_tag(sizeof(ConstMethod));
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 33a857f2a7e..143c0c00c45 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -145,8 +145,6 @@ NarrowPtrStruct Universe::_narrow_oop = { NULL, 0, true };
NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true };
address Universe::_narrow_ptrs_base;
-size_t Universe::_class_metaspace_size;
-
void Universe::basic_type_classes_do(void f(Klass*)) {
f(boolArrayKlassObj());
f(byteArrayKlassObj());
@@ -641,6 +639,8 @@ jint universe_init() {
return status;
}
+ Metaspace::global_initialize();
+
// Create memory for metadata. Must be after initializing heap for
// DumpSharedSpaces.
ClassLoaderData::init_null_class_loader_data();
@@ -681,25 +681,27 @@ static const uint64_t NarrowOopHeapMax = (uint64_t(max_juint) + 1);
// 32Gb
// OopEncodingHeapMax == NarrowOopHeapMax << LogMinObjAlignmentInBytes;
-char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
+char* Universe::preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode) {
+ assert(is_size_aligned((size_t)OopEncodingHeapMax, alignment), "Must be");
+ assert(is_size_aligned((size_t)NarrowOopHeapMax, alignment), "Must be");
+ assert(is_size_aligned(heap_size, alignment), "Must be");
+
+ uintx heap_base_min_address_aligned = align_size_up(HeapBaseMinAddress, alignment);
+
size_t base = 0;
#ifdef _LP64
if (UseCompressedOops) {
assert(mode == UnscaledNarrowOop ||
mode == ZeroBasedNarrowOop ||
mode == HeapBasedNarrowOop, "mode is invalid");
- const size_t total_size = heap_size + HeapBaseMinAddress;
+ const size_t total_size = heap_size + heap_base_min_address_aligned;
// Return specified base for the first request.
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {
- base = HeapBaseMinAddress;
+ base = heap_base_min_address_aligned;
- // If the total size and the metaspace size are small enough to allow
- // UnscaledNarrowOop then just use UnscaledNarrowOop.
- } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop) &&
- (!UseCompressedKlassPointers ||
- (((OopEncodingHeapMax - heap_size) + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax))) {
- // We don't need to check the metaspace size here because it is always smaller
- // than total_size.
+ // If the total size is small enough to allow UnscaledNarrowOop then
+ // just use UnscaledNarrowOop.
+ } else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) {
if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) &&
(Universe::narrow_oop_shift() == 0)) {
// Use 32-bits oops without encoding and
@@ -716,13 +718,6 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
base = (OopEncodingHeapMax - heap_size);
}
}
-
- // See if ZeroBaseNarrowOop encoding will work for a heap based at
- // (KlassEncodingMetaspaceMax - class_metaspace_size()).
- } else if (UseCompressedKlassPointers && (mode != HeapBasedNarrowOop) &&
- (Universe::class_metaspace_size() + HeapBaseMinAddress <= KlassEncodingMetaspaceMax) &&
- (KlassEncodingMetaspaceMax + heap_size - Universe::class_metaspace_size() <= OopEncodingHeapMax)) {
- base = (KlassEncodingMetaspaceMax - Universe::class_metaspace_size());
} else {
// UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or
// HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb.
@@ -732,8 +727,7 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
// Set narrow_oop_base and narrow_oop_use_implicit_null_checks
// used in ReservedHeapSpace() constructors.
// The final values will be set in initialize_heap() below.
- if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax) &&
- (!UseCompressedKlassPointers || (base + Universe::class_metaspace_size()) <= KlassEncodingMetaspaceMax)) {
+ if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax)) {
// Use zero based compressed oops
Universe::set_narrow_oop_base(NULL);
// Don't need guard page for implicit checks in indexed
@@ -754,6 +748,8 @@ char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) {
}
}
#endif
+
+ assert(is_ptr_aligned((char*)base, alignment), "Must be");
return (char*)base; // also return NULL (don't care) for 32-bit VM
}
@@ -816,9 +812,7 @@ jint Universe::initialize_heap() {
tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M);
}
- if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) ||
- (UseCompressedKlassPointers &&
- ((uint64_t)Universe::heap()->base() + Universe::class_metaspace_size() > KlassEncodingMetaspaceMax))) {
+ if (((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax)) {
// Can't reserve heap below 32Gb.
// keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
@@ -849,20 +843,16 @@ jint Universe::initialize_heap() {
}
}
}
+
if (verbose) {
tty->cr();
tty->cr();
}
- if (UseCompressedKlassPointers) {
- Universe::set_narrow_klass_base(Universe::narrow_oop_base());
- Universe::set_narrow_klass_shift(MIN2(Universe::narrow_oop_shift(), LogKlassAlignmentInBytes));
- }
Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
}
- // Universe::narrow_oop_base() is one page below the metaspace
- // base. The actual metaspace base depends on alignment constraints
- // so we don't know its exact location here.
- assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() - os::vm_page_size() - ClassMetaspaceSize) ||
+ // Universe::narrow_oop_base() is one page below the heap.
+ assert((intptr_t)Universe::narrow_oop_base() <= (intptr_t)(Universe::heap()->base() -
+ os::vm_page_size()) ||
Universe::narrow_oop_base() == NULL, "invalid value");
assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes ||
Universe::narrow_oop_shift() == 0, "invalid value");
@@ -882,35 +872,36 @@ jint Universe::initialize_heap() {
// Reserve the Java heap, which is now the same for all GCs.
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
- // Add in the class metaspace area so the classes in the headers can
- // be compressed the same as instances.
- // Need to round class space size up because it's below the heap and
- // the actual alignment depends on its size.
- Universe::set_class_metaspace_size(align_size_up(ClassMetaspaceSize, alignment));
- size_t total_reserved = align_size_up(heap_size + Universe::class_metaspace_size(), alignment);
+ size_t total_reserved = align_size_up(heap_size, alignment);
assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),
"heap size is too big for compressed oops");
- char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
- ReservedHeapSpace total_rs(total_reserved, alignment, UseLargePages, addr);
+ bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size());
+ assert(!UseLargePages
+ || UseParallelOldGC
+ || use_large_pages, "Wrong alignment to use large pages");
+
+ char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop);
+
+ ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages, addr);
if (UseCompressedOops) {
if (addr != NULL && !total_rs.is_reserved()) {
// Failed to reserve at specified address - the requested memory
// region is taken already, for example, by 'java' launcher.
// Try again to reserver heap higher.
- addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop);
+ addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::ZeroBasedNarrowOop);
ReservedHeapSpace total_rs0(total_reserved, alignment,
- UseLargePages, addr);
+ use_large_pages, addr);
if (addr != NULL && !total_rs0.is_reserved()) {
// Failed to reserve at specified address again - give up.
- addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop);
+ addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::HeapBasedNarrowOop);
assert(addr == NULL, "");
ReservedHeapSpace total_rs1(total_reserved, alignment,
- UseLargePages, addr);
+ use_large_pages, addr);
total_rs = total_rs1;
} else {
total_rs = total_rs0;
@@ -923,28 +914,17 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
return total_rs;
}
- // Split the reserved space into main Java heap and a space for
- // classes so that they can be compressed using the same algorithm
- // as compressed oops. If compress oops and compress klass ptrs are
- // used we need the meta space first: if the alignment used for
- // compressed oops is greater than the one used for compressed klass
- // ptrs, a metadata space on top of the heap could become
- // unreachable.
- ReservedSpace class_rs = total_rs.first_part(Universe::class_metaspace_size());
- ReservedSpace heap_rs = total_rs.last_part(Universe::class_metaspace_size(), alignment);
- Metaspace::initialize_class_space(class_rs);
-
if (UseCompressedOops) {
// Universe::initialize_heap() will reset this to NULL if unscaled
// or zero-based narrow oops are actually used.
address base = (address)(total_rs.base() - os::vm_page_size());
Universe::set_narrow_oop_base(base);
}
- return heap_rs;
+ return total_rs;
}
-// It's the caller's repsonsibility to ensure glitch-freedom
+// It's the caller's responsibility to ensure glitch-freedom
// (if required).
void Universe::update_heap_info_at_gc() {
_heap_capacity_at_last_gc = heap()->capacity();
@@ -1135,6 +1115,8 @@ bool universe_post_init() {
// Initialize performance counters for metaspaces
MetaspaceCounters::initialize_performance_counters();
+ CompressedClassSpaceCounters::initialize_performance_counters();
+
MemoryService::add_metaspace_memory_pools();
GC_locker::unlock(); // allow gc after bootstrapping
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index 69998434380..a8b541d03a1 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -75,10 +75,10 @@ class LatestMethodCache : public CHeapObj {
};
-// For UseCompressedOops and UseCompressedKlassPointers.
+// For UseCompressedOops.
struct NarrowPtrStruct {
- // Base address for oop/klass-within-java-object materialization.
- // NULL if using wide oops/klasses or zero based narrow oops/klasses.
+ // Base address for oop-within-java-object materialization.
+ // NULL if using wide oops or zero based narrow oops.
address _base;
// Number of shift bits for encoding/decoding narrow ptrs.
// 0 if using wide ptrs or zero based unscaled narrow ptrs,
@@ -106,6 +106,7 @@ class Universe: AllStatic {
friend class SystemDictionary;
friend class VMStructs;
friend class VM_PopulateDumpSharedSpace;
+ friend class Metaspace;
friend jint universe_init();
friend void universe2_init();
@@ -184,9 +185,6 @@ class Universe: AllStatic {
static struct NarrowPtrStruct _narrow_klass;
static address _narrow_ptrs_base;
- // Aligned size of the metaspace.
- static size_t _class_metaspace_size;
-
// array of dummy objects used with +FullGCAlot
debug_only(static objArrayOop _fullgc_alot_dummy_array;)
// index of next entry to clear
@@ -238,15 +236,6 @@ class Universe: AllStatic {
assert(UseCompressedOops, "no compressed ptrs?");
_narrow_oop._use_implicit_null_checks = use;
}
- static bool reserve_metaspace_helper(bool with_base = false);
- static ReservedHeapSpace reserve_heap_metaspace(size_t heap_size, size_t alignment, bool& contiguous);
-
- static size_t class_metaspace_size() {
- return _class_metaspace_size;
- }
- static void set_class_metaspace_size(size_t metaspace_size) {
- _class_metaspace_size = metaspace_size;
- }
// Debugging
static int _verify_count; // number of verifies done
@@ -357,7 +346,7 @@ class Universe: AllStatic {
};
static NARROW_OOP_MODE narrow_oop_mode();
static const char* narrow_oop_mode_to_string(NARROW_OOP_MODE mode);
- static char* preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode);
+ static char* preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode);
static char* preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode);
static address narrow_oop_base() { return _narrow_oop._base; }
static bool is_narrow_oop_base(void* addr) { return (narrow_oop_base() == (address)addr); }
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index a2684d84bb1..29c77a07ccb 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -269,7 +269,7 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_fields(NULL, 0);
set_constants(NULL);
set_class_loader_data(NULL);
- set_source_file_name(NULL);
+ set_source_file_name_index(0);
set_source_debug_extension(NULL, 0);
set_array_name(NULL);
set_inner_classes(NULL);
@@ -284,7 +284,7 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_osr_nmethods_head(NULL);
set_breakpoints(NULL);
init_previous_versions();
- set_generic_signature(NULL);
+ set_generic_signature_index(0);
release_set_methods_jmethod_ids(NULL);
release_set_methods_cached_itable_indices(NULL);
set_annotations(NULL);
@@ -2368,18 +2368,12 @@ void InstanceKlass::release_C_heap_structures() {
// unreference array name derived from this class name (arrays of an unloaded
// class can't be referenced anymore).
if (_array_name != NULL) _array_name->decrement_refcount();
- if (_source_file_name != NULL) _source_file_name->decrement_refcount();
if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
assert(_total_instanceKlass_count >= 1, "Sanity check");
Atomic::dec(&_total_instanceKlass_count);
}
-void InstanceKlass::set_source_file_name(Symbol* n) {
- _source_file_name = n;
- if (_source_file_name != NULL) _source_file_name->increment_refcount();
-}
-
void InstanceKlass::set_source_debug_extension(char* array, int length) {
if (array == NULL) {
_source_debug_extension = NULL;
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index b82b2f83af5..123f6b17911 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -201,14 +201,10 @@ class InstanceKlass: public Klass {
// number_of_inner_classes * 4 + enclosing_method_attribute_size.
Array* _inner_classes;
- // Name of source file containing this klass, NULL if not specified.
- Symbol* _source_file_name;
// the source debug extension for this klass, NULL if not specified.
// Specified as UTF-8 string without terminating zero byte in the classfile,
// it is stored in the instanceklass as a NULL-terminated UTF-8 string
char* _source_debug_extension;
- // Generic signature, or null if none.
- Symbol* _generic_signature;
// Array name derived from this class which needs unreferencing
// if this class is unloaded.
Symbol* _array_name;
@@ -217,6 +213,12 @@ class InstanceKlass: public Klass {
// (including inherited fields but after header_size()).
int _nonstatic_field_size;
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
+ // Constant pool index to the utf8 entry of the Generic signature,
+ // or 0 if none.
+ u2 _generic_signature_index;
+ // Constant pool index to the utf8 entry for the name of source file
+ // containing this klass, 0 if not specified.
+ u2 _source_file_name_index;
u2 _static_oop_field_count;// number of static oop fields in this klass
u2 _java_fields_count; // The number of declared Java fields
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
@@ -570,8 +572,16 @@ class InstanceKlass: public Klass {
}
// source file name
- Symbol* source_file_name() const { return _source_file_name; }
- void set_source_file_name(Symbol* n);
+ Symbol* source_file_name() const {
+ return (_source_file_name_index == 0) ?
+ (Symbol*)NULL : _constants->symbol_at(_source_file_name_index);
+ }
+ u2 source_file_name_index() const {
+ return _source_file_name_index;
+ }
+ void set_source_file_name_index(u2 sourcefile_index) {
+ _source_file_name_index = sourcefile_index;
+ }
// minor and major version numbers of class file
u2 minor_version() const { return _minor_version; }
@@ -648,8 +658,16 @@ class InstanceKlass: public Klass {
void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; }
// generics support
- Symbol* generic_signature() const { return _generic_signature; }
- void set_generic_signature(Symbol* sig) { _generic_signature = sig; }
+ Symbol* generic_signature() const {
+ return (_generic_signature_index == 0) ?
+ (Symbol*)NULL : _constants->symbol_at(_generic_signature_index);
+ }
+ u2 generic_signature_index() const {
+ return _generic_signature_index;
+ }
+ void set_generic_signature_index(u2 sig_index) {
+ _generic_signature_index = sig_index;
+ }
u2 enclosing_method_data(int offset);
u2 enclosing_method_class_index() {
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index 1ca027a3762..9e96dafe235 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -352,7 +352,8 @@ class Klass : public Metadata {
static int layout_helper_log2_element_size(jint lh) {
assert(lh < (jint)_lh_neutral_value, "must be array");
int l2esz = (lh >> _lh_log2_element_size_shift) & _lh_log2_element_size_mask;
- assert(l2esz <= LogBitsPerLong, "sanity");
+ assert(l2esz <= LogBitsPerLong,
+ err_msg("sanity. l2esz: 0x%x for lh: 0x%x", (uint)l2esz, (uint)lh));
return l2esz;
}
static jint array_layout_helper(jint tag, int hsize, BasicType etype, int log2_esize) {
@@ -703,6 +704,16 @@ class Klass : public Metadata {
virtual void oop_verify_on(oop obj, outputStream* st);
+ static bool is_null(narrowKlass obj);
+ static bool is_null(Klass* obj);
+
+ // klass encoding for klass pointer in objects.
+ static narrowKlass encode_klass_not_null(Klass* v);
+ static narrowKlass encode_klass(Klass* v);
+
+ static Klass* decode_klass_not_null(narrowKlass v);
+ static Klass* decode_klass(narrowKlass v);
+
private:
// barriers used by klass_oop_store
void klass_update_barrier_set(oop v);
diff --git a/hotspot/src/share/vm/oops/klass.inline.hpp b/hotspot/src/share/vm/oops/klass.inline.hpp
index 3eb62afe827..841a4873a32 100644
--- a/hotspot/src/share/vm/oops/klass.inline.hpp
+++ b/hotspot/src/share/vm/oops/klass.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_OOPS_KLASS_INLINE_HPP
#define SHARE_VM_OOPS_KLASS_INLINE_HPP
+#include "memory/universe.hpp"
#include "oops/klass.hpp"
#include "oops/markOop.hpp"
@@ -33,4 +34,41 @@ inline void Klass::set_prototype_header(markOop header) {
_prototype_header = header;
}
+inline bool Klass::is_null(Klass* obj) { return obj == NULL; }
+inline bool Klass::is_null(narrowKlass obj) { return obj == 0; }
+
+// Encoding and decoding for klass field.
+
+inline bool check_klass_alignment(Klass* obj) {
+ return (intptr_t)obj % KlassAlignmentInBytes == 0;
+}
+
+inline narrowKlass Klass::encode_klass_not_null(Klass* v) {
+ assert(!is_null(v), "klass value can never be zero");
+ assert(check_klass_alignment(v), "Address not aligned");
+ int shift = Universe::narrow_klass_shift();
+ uint64_t pd = (uint64_t)(pointer_delta((void*)v, Universe::narrow_klass_base(), 1));
+ assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
+ uint64_t result = pd >> shift;
+ assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
+ assert(decode_klass(result) == v, "reversibility");
+ return (narrowKlass)result;
+}
+
+inline narrowKlass Klass::encode_klass(Klass* v) {
+ return is_null(v) ? (narrowKlass)0 : encode_klass_not_null(v);
+}
+
+inline Klass* Klass::decode_klass_not_null(narrowKlass v) {
+ assert(!is_null(v), "narrow klass value can never be zero");
+ int shift = Universe::narrow_klass_shift();
+ Klass* result = (Klass*)(void*)((uintptr_t)Universe::narrow_klass_base() + ((uintptr_t)v << shift));
+ assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
+ return result;
+}
+
+inline Klass* Klass::decode_klass(narrowKlass v) {
+ return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
+}
+
#endif // SHARE_VM_OOPS_KLASS_INLINE_HPP
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index 07cc1aa09cc..7082e72510e 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -747,6 +747,7 @@ void Method::set_not_compilable(int comp_level, bool report, const char* reason)
set_not_c2_compilable();
}
CompilationPolicy::policy()->disable_compilation(this);
+ assert(!CompilationPolicy::can_be_compiled(this, comp_level), "sanity check");
}
bool Method::is_not_osr_compilable(int comp_level) const {
@@ -773,6 +774,7 @@ void Method::set_not_osr_compilable(int comp_level, bool report, const char* rea
set_not_c2_osr_compilable();
}
CompilationPolicy::policy()->disable_compilation(this);
+ assert(!CompilationPolicy::can_be_osr_compiled(this, comp_level), "sanity check");
}
// Revert to using the interpreter and clear out the nmethod
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
index 94e68ed3263..66a62eaab23 100644
--- a/hotspot/src/share/vm/oops/oop.hpp
+++ b/hotspot/src/share/vm/oops/oop.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@ class oopDesc {
volatile markOop _mark;
union _metadata {
Klass* _klass;
- narrowOop _compressed_klass;
+ narrowKlass _compressed_klass;
} _metadata;
// Fast access to barrier set. Must be initialized.
@@ -84,7 +84,7 @@ class oopDesc {
Klass* klass() const;
Klass* klass_or_null() const volatile;
Klass** klass_addr();
- narrowOop* compressed_klass_addr();
+ narrowKlass* compressed_klass_addr();
void set_klass(Klass* k);
@@ -189,13 +189,6 @@ class oopDesc {
oop compare_value,
bool prebarrier = false);
- // klass encoding for klass pointer in objects.
- static narrowOop encode_klass_not_null(Klass* v);
- static narrowOop encode_klass(Klass* v);
-
- static Klass* decode_klass_not_null(narrowOop v);
- static Klass* decode_klass(narrowOop v);
-
// Access to fields in a instanceOop through these methods.
oop obj_field(int offset) const;
volatile oop obj_field_volatile(int offset) const;
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
index 3c71e15f87c..9a6c1e1787b 100644
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
@@ -35,7 +35,7 @@
#include "memory/specialized_oop_closures.hpp"
#include "oops/arrayKlass.hpp"
#include "oops/arrayOop.hpp"
-#include "oops/klass.hpp"
+#include "oops/klass.inline.hpp"
#include "oops/markOop.inline.hpp"
#include "oops/oop.hpp"
#include "runtime/atomic.hpp"
@@ -70,7 +70,7 @@ inline markOop oopDesc::cas_set_mark(markOop new_mark, markOop old_mark) {
inline Klass* oopDesc::klass() const {
if (UseCompressedKlassPointers) {
- return decode_klass_not_null(_metadata._compressed_klass);
+ return Klass::decode_klass_not_null(_metadata._compressed_klass);
} else {
return _metadata._klass;
}
@@ -79,7 +79,7 @@ inline Klass* oopDesc::klass() const {
inline Klass* oopDesc::klass_or_null() const volatile {
// can be NULL in CMS
if (UseCompressedKlassPointers) {
- return decode_klass(_metadata._compressed_klass);
+ return Klass::decode_klass(_metadata._compressed_klass);
} else {
return _metadata._klass;
}
@@ -87,7 +87,7 @@ inline Klass* oopDesc::klass_or_null() const volatile {
inline int oopDesc::klass_gap_offset_in_bytes() {
assert(UseCompressedKlassPointers, "only applicable to compressed klass pointers");
- return oopDesc::klass_offset_in_bytes() + sizeof(narrowOop);
+ return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
}
inline Klass** oopDesc::klass_addr() {
@@ -97,9 +97,9 @@ inline Klass** oopDesc::klass_addr() {
return (Klass**) &_metadata._klass;
}
-inline narrowOop* oopDesc::compressed_klass_addr() {
+inline narrowKlass* oopDesc::compressed_klass_addr() {
assert(UseCompressedKlassPointers, "only called by compressed klass pointers");
- return (narrowOop*) &_metadata._compressed_klass;
+ return &_metadata._compressed_klass;
}
inline void oopDesc::set_klass(Klass* k) {
@@ -107,7 +107,7 @@ inline void oopDesc::set_klass(Klass* k) {
assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
if (UseCompressedKlassPointers) {
- *compressed_klass_addr() = encode_klass_not_null(k);
+ *compressed_klass_addr() = Klass::encode_klass_not_null(k);
} else {
*klass_addr() = k;
}
@@ -127,7 +127,7 @@ inline void oopDesc::set_klass_to_list_ptr(oop k) {
// This is only to be used during GC, for from-space objects, so no
// barrier is needed.
if (UseCompressedKlassPointers) {
- _metadata._compressed_klass = encode_heap_oop(k); // may be null (parnew overflow handling)
+ _metadata._compressed_klass = (narrowKlass)encode_heap_oop(k); // may be null (parnew overflow handling)
} else {
_metadata._klass = (Klass*)(address)k;
}
@@ -136,7 +136,7 @@ inline void oopDesc::set_klass_to_list_ptr(oop k) {
inline oop oopDesc::list_ptr_from_klass() {
// This is only to be used during GC, for from-space objects.
if (UseCompressedKlassPointers) {
- return decode_heap_oop(_metadata._compressed_klass);
+ return decode_heap_oop((narrowOop)_metadata._compressed_klass);
} else {
// Special case for GC
return (oop)(address)_metadata._klass;
@@ -176,7 +176,6 @@ inline address* oopDesc::address_field_addr(int offset) const { return (address
// the right type and inlines the appopriate code).
inline bool oopDesc::is_null(oop obj) { return obj == NULL; }
-inline bool oopDesc::is_null(Klass* obj) { return obj == NULL; }
inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
// Algorithm for encoding and decoding oops from 64 bit pointers to 32 bit
@@ -186,9 +185,6 @@ inline bool oopDesc::is_null(narrowOop obj) { return obj == 0; }
inline bool check_obj_alignment(oop obj) {
return (intptr_t)obj % MinObjAlignmentInBytes == 0;
}
-inline bool check_klass_alignment(Klass* obj) {
- return (intptr_t)obj % KlassAlignmentInBytes == 0;
-}
inline narrowOop oopDesc::encode_heap_oop_not_null(oop v) {
assert(!is_null(v), "oop value can never be zero");
@@ -224,39 +220,6 @@ inline oop oopDesc::decode_heap_oop(narrowOop v) {
inline oop oopDesc::decode_heap_oop_not_null(oop v) { return v; }
inline oop oopDesc::decode_heap_oop(oop v) { return v; }
-// Encoding and decoding for klass field. It is copied code, but someday
-// might not be the same as oop.
-
-inline narrowOop oopDesc::encode_klass_not_null(Klass* v) {
- assert(!is_null(v), "klass value can never be zero");
- assert(check_klass_alignment(v), "Address not aligned");
- address base = Universe::narrow_klass_base();
- int shift = Universe::narrow_klass_shift();
- uint64_t pd = (uint64_t)(pointer_delta((void*)v, (void*)base, 1));
- assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
- uint64_t result = pd >> shift;
- assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
- assert(decode_klass(result) == v, "reversibility");
- return (narrowOop)result;
-}
-
-inline narrowOop oopDesc::encode_klass(Klass* v) {
- return (is_null(v)) ? (narrowOop)0 : encode_klass_not_null(v);
-}
-
-inline Klass* oopDesc::decode_klass_not_null(narrowOop v) {
- assert(!is_null(v), "narrow oop value can never be zero");
- address base = Universe::narrow_klass_base();
- int shift = Universe::narrow_klass_shift();
- Klass* result = (Klass*)(void*)((uintptr_t)base + ((uintptr_t)v << shift));
- assert(check_klass_alignment(result), err_msg("address not aligned: " PTR_FORMAT, (void*) result));
- return result;
-}
-
-inline Klass* oopDesc::decode_klass(narrowOop v) {
- return is_null(v) ? (Klass*)NULL : decode_klass_not_null(v);
-}
-
// Load an oop out of the Java heap as is without decoding.
// Called by GC to check for null before decoding.
inline oop oopDesc::load_heap_oop(oop* p) { return *p; }
diff --git a/hotspot/src/share/vm/oops/oopsHierarchy.hpp b/hotspot/src/share/vm/oops/oopsHierarchy.hpp
index d599b1bae64..ccf7a5f99e2 100644
--- a/hotspot/src/share/vm/oops/oopsHierarchy.hpp
+++ b/hotspot/src/share/vm/oops/oopsHierarchy.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,10 @@
// of B, A's representation is a prefix of B's representation.
typedef juint narrowOop; // Offset instead of address for an oop within a java object
+
+// If compressed klass pointers then use narrowKlass.
+typedef juint narrowKlass;
+
typedef void* OopOrNarrowOopStar;
typedef class markOopDesc* markOop;
diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp
index 9153d070886..5a6b791b24a 100644
--- a/hotspot/src/share/vm/opto/block.cpp
+++ b/hotspot/src/share/vm/opto/block.cpp
@@ -35,10 +35,6 @@
#include "opto/rootnode.hpp"
#include "utilities/copy.hpp"
-// Optimization - Graph Style
-
-
-//-----------------------------------------------------------------------------
void Block_Array::grow( uint i ) {
assert(i >= Max(), "must be an overflow");
debug_only(_limit = i+1);
@@ -54,7 +50,6 @@ void Block_Array::grow( uint i ) {
Copy::zero_to_bytes( &_blocks[old], (_size-old)*sizeof(Block*) );
}
-//=============================================================================
void Block_List::remove(uint i) {
assert(i < _cnt, "index out of bounds");
Copy::conjoint_words_to_lower((HeapWord*)&_blocks[i+1], (HeapWord*)&_blocks[i], ((_cnt-i-1)*sizeof(Block*)));
@@ -76,8 +71,6 @@ void Block_List::print() {
}
#endif
-//=============================================================================
-
uint Block::code_alignment() {
// Check for Root block
if (_pre_order == 0) return CodeEntryAlignment;
@@ -113,7 +106,6 @@ uint Block::compute_loop_alignment() {
return unit_sz; // no particular alignment
}
-//-----------------------------------------------------------------------------
// Compute the size of first 'inst_cnt' instructions in this block.
// Return the number of instructions left to compute if the block has
// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
@@ -138,7 +130,6 @@ uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
return inst_cnt;
}
-//-----------------------------------------------------------------------------
uint Block::find_node( const Node *n ) const {
for( uint i = 0; i < _nodes.size(); i++ ) {
if( _nodes[i] == n )
@@ -153,7 +144,6 @@ void Block::find_remove( const Node *n ) {
_nodes.remove(find_node(n));
}
-//------------------------------is_Empty---------------------------------------
// Return empty status of a block. Empty blocks contain only the head, other
// ideal nodes, and an optional trailing goto.
int Block::is_Empty() const {
@@ -192,7 +182,6 @@ int Block::is_Empty() const {
return not_empty;
}
-//------------------------------has_uncommon_code------------------------------
// Return true if the block's code implies that it is likely to be
// executed infrequently. Check to see if the block ends in a Halt or
// a low probability call.
@@ -218,7 +207,6 @@ bool Block::has_uncommon_code() const {
return op == Op_Halt;
}
-//------------------------------is_uncommon------------------------------------
// True if block is low enough frequency or guarded by a test which
// mostly does not go here.
bool Block::is_uncommon(PhaseCFG* cfg) const {
@@ -271,7 +259,6 @@ bool Block::is_uncommon(PhaseCFG* cfg) const {
return false;
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void Block::dump_bidx(const Block* orig, outputStream* st) const {
if (_pre_order) st->print("B%d",_pre_order);
@@ -364,13 +351,12 @@ void Block::dump(const PhaseCFG* cfg) const {
}
#endif
-//=============================================================================
-//------------------------------PhaseCFG---------------------------------------
PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
: Phase(CFG)
, _block_arena(arena)
-, _node_to_block_mapping(arena)
, _root(root)
+, _matcher(matcher)
+, _node_to_block_mapping(arena)
, _node_latency(NULL)
#ifndef PRODUCT
, _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
@@ -390,11 +376,10 @@ PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
_goto->set_req(0,_goto);
// Build the CFG in Reverse Post Order
- _num_blocks = build_cfg();
- _broot = get_block_for_node(_root);
+ _number_of_blocks = build_cfg();
+ _root_block = get_block_for_node(_root);
}
-//------------------------------build_cfg--------------------------------------
// Build a proper looking CFG. Make every block begin with either a StartNode
// or a RegionNode. Make every block end with either a Goto, If or Return.
// The RootNode both starts and ends it's own block. Do this with a recursive
@@ -496,13 +481,12 @@ uint PhaseCFG::build_cfg() {
return sum;
}
-//------------------------------insert_goto_at---------------------------------
// Inserts a goto & corresponding basic block between
// block[block_no] and its succ_no'th successor block
void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
// get block with block_no
- assert(block_no < _num_blocks, "illegal block number");
- Block* in = _blocks[block_no];
+ assert(block_no < number_of_blocks(), "illegal block number");
+ Block* in = get_block(block_no);
// get successor block succ_no
assert(succ_no < in->_num_succs, "illegal successor number");
Block* out = in->_succs[succ_no];
@@ -537,11 +521,9 @@ void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
// Set the frequency of the new block
block->_freq = freq;
// add new basic block to basic block list
- _blocks.insert(block_no + 1, block);
- _num_blocks++;
+ add_block_at(block_no + 1, block);
}
-//------------------------------no_flip_branch---------------------------------
// Does this block end in a multiway branch that cannot have the default case
// flipped for another case?
static bool no_flip_branch( Block *b ) {
@@ -560,7 +542,6 @@ static bool no_flip_branch( Block *b ) {
return false;
}
-//------------------------------convert_NeverBranch_to_Goto--------------------
// Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that always
// goes the same direction for most of the optimizer and are used to give a
@@ -598,7 +579,6 @@ void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) {
dead->_nodes[k]->del_req(j);
}
-//------------------------------move_to_next-----------------------------------
// Helper function to move block bx to the slot following b_index. Return
// true if the move is successful, otherwise false
bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
@@ -606,20 +586,22 @@ bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
// Return false if bx is already scheduled.
uint bx_index = bx->_pre_order;
- if ((bx_index <= b_index) && (_blocks[bx_index] == bx)) {
+ if ((bx_index <= b_index) && (get_block(bx_index) == bx)) {
return false;
}
// Find the current index of block bx on the block list
bx_index = b_index + 1;
- while( bx_index < _num_blocks && _blocks[bx_index] != bx ) bx_index++;
- assert(_blocks[bx_index] == bx, "block not found");
+ while (bx_index < number_of_blocks() && get_block(bx_index) != bx) {
+ bx_index++;
+ }
+ assert(get_block(bx_index) == bx, "block not found");
// If the previous block conditionally falls into bx, return false,
// because moving bx will create an extra jump.
for(uint k = 1; k < bx->num_preds(); k++ ) {
Block* pred = get_block_for_node(bx->pred(k));
- if (pred == _blocks[bx_index-1]) {
+ if (pred == get_block(bx_index - 1)) {
if (pred->_num_succs != 1) {
return false;
}
@@ -632,7 +614,6 @@ bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
return true;
}
-//------------------------------move_to_end------------------------------------
// Move empty and uncommon blocks to the end.
void PhaseCFG::move_to_end(Block *b, uint i) {
int e = b->is_Empty();
@@ -650,31 +631,31 @@ void PhaseCFG::move_to_end(Block *b, uint i) {
_blocks.push(b);
}
-//---------------------------set_loop_alignment--------------------------------
// Set loop alignment for every block
void PhaseCFG::set_loop_alignment() {
- uint last = _num_blocks;
- assert( _blocks[0] == _broot, "" );
+ uint last = number_of_blocks();
+ assert(get_block(0) == get_root_block(), "");
- for (uint i = 1; i < last; i++ ) {
- Block *b = _blocks[i];
- if (b->head()->is_Loop()) {
- b->set_loop_alignment(b);
+ for (uint i = 1; i < last; i++) {
+ Block* block = get_block(i);
+ if (block->head()->is_Loop()) {
+ block->set_loop_alignment(block);
}
}
}
-//-----------------------------remove_empty------------------------------------
// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
// to the end.
-void PhaseCFG::remove_empty() {
+void PhaseCFG::remove_empty_blocks() {
// Move uncommon blocks to the end
- uint last = _num_blocks;
- assert( _blocks[0] == _broot, "" );
+ uint last = number_of_blocks();
+ assert(get_block(0) == get_root_block(), "");
for (uint i = 1; i < last; i++) {
- Block *b = _blocks[i];
- if (b->is_connector()) break;
+ Block* block = get_block(i);
+ if (block->is_connector()) {
+ break;
+ }
// Check for NeverBranch at block end. This needs to become a GOTO to the
// true target. NeverBranch are treated as a conditional branch that
@@ -682,124 +663,127 @@ void PhaseCFG::remove_empty() {
// to give a fake exit path to infinite loops. At this late stage they
// need to turn into Goto's so that when you enter the infinite loop you
// indeed hang.
- if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch )
- convert_NeverBranch_to_Goto(b);
+ if (block->_nodes[block->end_idx()]->Opcode() == Op_NeverBranch) {
+ convert_NeverBranch_to_Goto(block);
+ }
// Look for uncommon blocks and move to end.
if (!C->do_freq_based_layout()) {
- if (b->is_uncommon(this)) {
- move_to_end(b, i);
+ if (block->is_uncommon(this)) {
+ move_to_end(block, i);
last--; // No longer check for being uncommon!
- if( no_flip_branch(b) ) { // Fall-thru case must follow?
- b = _blocks[i]; // Find the fall-thru block
- move_to_end(b, i);
+ if (no_flip_branch(block)) { // Fall-thru case must follow?
+ // Find the fall-thru block
+ block = get_block(i);
+ move_to_end(block, i);
last--;
}
- i--; // backup block counter post-increment
+ // backup block counter post-increment
+ i--;
}
}
}
// Move empty blocks to the end
- last = _num_blocks;
+ last = number_of_blocks();
for (uint i = 1; i < last; i++) {
- Block *b = _blocks[i];
- if (b->is_Empty() != Block::not_empty) {
- move_to_end(b, i);
+ Block* block = get_block(i);
+ if (block->is_Empty() != Block::not_empty) {
+ move_to_end(block, i);
last--;
i--;
}
} // End of for all blocks
}
-//-----------------------------fixup_flow--------------------------------------
// Fix up the final control flow for basic blocks.
void PhaseCFG::fixup_flow() {
// Fixup final control flow for the blocks. Remove jump-to-next
// block. If neither arm of a IF follows the conditional branch, we
// have to add a second jump after the conditional. We place the
// TRUE branch target in succs[0] for both GOTOs and IFs.
- for (uint i=0; i < _num_blocks; i++) {
- Block *b = _blocks[i];
- b->_pre_order = i; // turn pre-order into block-index
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ block->_pre_order = i; // turn pre-order into block-index
// Connector blocks need no further processing.
- if (b->is_connector()) {
- assert((i+1) == _num_blocks || _blocks[i+1]->is_connector(),
- "All connector blocks should sink to the end");
+ if (block->is_connector()) {
+ assert((i+1) == number_of_blocks() || get_block(i + 1)->is_connector(), "All connector blocks should sink to the end");
continue;
}
- assert(b->is_Empty() != Block::completely_empty,
- "Empty blocks should be connectors");
+ assert(block->is_Empty() != Block::completely_empty, "Empty blocks should be connectors");
- Block *bnext = (i < _num_blocks-1) ? _blocks[i+1] : NULL;
- Block *bs0 = b->non_connector_successor(0);
+ Block* bnext = (i < number_of_blocks() - 1) ? get_block(i + 1) : NULL;
+ Block* bs0 = block->non_connector_successor(0);
// Check for multi-way branches where I cannot negate the test to
// exchange the true and false targets.
- if( no_flip_branch( b ) ) {
+ if (no_flip_branch(block)) {
// Find fall through case - if must fall into its target
- int branch_idx = b->_nodes.size() - b->_num_succs;
- for (uint j2 = 0; j2 < b->_num_succs; j2++) {
- const ProjNode* p = b->_nodes[branch_idx + j2]->as_Proj();
+ int branch_idx = block->_nodes.size() - block->_num_succs;
+ for (uint j2 = 0; j2 < block->_num_succs; j2++) {
+ const ProjNode* p = block->_nodes[branch_idx + j2]->as_Proj();
if (p->_con == 0) {
// successor j2 is fall through case
- if (b->non_connector_successor(j2) != bnext) {
+ if (block->non_connector_successor(j2) != bnext) {
// but it is not the next block => insert a goto
insert_goto_at(i, j2);
}
// Put taken branch in slot 0
- if( j2 == 0 && b->_num_succs == 2) {
+ if (j2 == 0 && block->_num_succs == 2) {
// Flip targets in succs map
- Block *tbs0 = b->_succs[0];
- Block *tbs1 = b->_succs[1];
- b->_succs.map( 0, tbs1 );
- b->_succs.map( 1, tbs0 );
+ Block *tbs0 = block->_succs[0];
+ Block *tbs1 = block->_succs[1];
+ block->_succs.map(0, tbs1);
+ block->_succs.map(1, tbs0);
}
break;
}
}
- // Remove all CatchProjs
- for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
- } else if (b->_num_succs == 1) {
+ // Remove all CatchProjs
+ for (uint j = 0; j < block->_num_succs; j++) {
+ block->_nodes.pop();
+ }
+
+ } else if (block->_num_succs == 1) {
// Block ends in a Goto?
if (bnext == bs0) {
// We fall into next block; remove the Goto
- b->_nodes.pop();
+ block->_nodes.pop();
}
- } else if( b->_num_succs == 2 ) { // Block ends in a If?
+ } else if(block->_num_succs == 2) { // Block ends in a If?
// Get opcode of 1st projection (matches _succs[0])
// Note: Since this basic block has 2 exits, the last 2 nodes must
// be projections (in any order), the 3rd last node must be
// the IfNode (we have excluded other 2-way exits such as
// CatchNodes already).
- MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
- ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
- ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+ MachNode* iff = block->_nodes[block->_nodes.size() - 3]->as_Mach();
+ ProjNode* proj0 = block->_nodes[block->_nodes.size() - 2]->as_Proj();
+ ProjNode* proj1 = block->_nodes[block->_nodes.size() - 1]->as_Proj();
// Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1].
- assert(proj0->raw_out(0) == b->_succs[0]->head(), "Mismatch successor 0");
- assert(proj1->raw_out(0) == b->_succs[1]->head(), "Mismatch successor 1");
+ assert(proj0->raw_out(0) == block->_succs[0]->head(), "Mismatch successor 0");
+ assert(proj1->raw_out(0) == block->_succs[1]->head(), "Mismatch successor 1");
- Block *bs1 = b->non_connector_successor(1);
+ Block* bs1 = block->non_connector_successor(1);
// Check for neither successor block following the current
// block ending in a conditional. If so, move one of the
// successors after the current one, provided that the
// successor was previously unscheduled, but moveable
// (i.e., all paths to it involve a branch).
- if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
+ if (!C->do_freq_based_layout() && bnext != bs0 && bnext != bs1) {
// Choose the more common successor based on the probability
// of the conditional branch.
- Block *bx = bs0;
- Block *by = bs1;
+ Block* bx = bs0;
+ Block* by = bs1;
// _prob is the probability of taking the true path. Make
// p the probability of taking successor #1.
float p = iff->as_MachIf()->_prob;
- if( proj0->Opcode() == Op_IfTrue ) {
+ if (proj0->Opcode() == Op_IfTrue) {
p = 1.0 - p;
}
@@ -826,14 +810,16 @@ void PhaseCFG::fixup_flow() {
// succs[1].
if (bnext == bs0) {
// Fall-thru case in succs[0], so flip targets in succs map
- Block *tbs0 = b->_succs[0];
- Block *tbs1 = b->_succs[1];
- b->_succs.map( 0, tbs1 );
- b->_succs.map( 1, tbs0 );
+ Block* tbs0 = block->_succs[0];
+ Block* tbs1 = block->_succs[1];
+ block->_succs.map(0, tbs1);
+ block->_succs.map(1, tbs0);
// Flip projection for each target
- { ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
+ ProjNode* tmp = proj0;
+ proj0 = proj1;
+ proj1 = tmp;
- } else if( bnext != bs1 ) {
+ } else if(bnext != bs1) {
// Need a double-branch
// The existing conditional branch need not change.
// Add a unconditional branch to the false target.
@@ -843,12 +829,12 @@ void PhaseCFG::fixup_flow() {
}
// Make sure we TRUE branch to the target
- if( proj0->Opcode() == Op_IfFalse ) {
+ if (proj0->Opcode() == Op_IfFalse) {
iff->as_MachIf()->negate();
}
- b->_nodes.pop(); // Remove IfFalse & IfTrue projections
- b->_nodes.pop();
+ block->_nodes.pop(); // Remove IfFalse & IfTrue projections
+ block->_nodes.pop();
} else {
// Multi-exit block, e.g. a switch statement
@@ -858,7 +844,6 @@ void PhaseCFG::fixup_flow() {
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited ) const {
const Node *x = end->is_block_proj();
@@ -884,10 +869,11 @@ void PhaseCFG::_dump_cfg( const Node *end, VectorSet &visited ) const {
}
void PhaseCFG::dump( ) const {
- tty->print("\n--- CFG --- %d BBs\n",_num_blocks);
+ tty->print("\n--- CFG --- %d BBs\n", number_of_blocks());
if (_blocks.size()) { // Did we do basic-block layout?
- for (uint i = 0; i < _num_blocks; i++) {
- _blocks[i]->dump(this);
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ const Block* block = get_block(i);
+ block->dump(this);
}
} else { // Else do it with a DFS
VectorSet visited(_block_arena);
@@ -896,27 +882,26 @@ void PhaseCFG::dump( ) const {
}
void PhaseCFG::dump_headers() {
- for( uint i = 0; i < _num_blocks; i++ ) {
- if (_blocks[i]) {
- _blocks[i]->dump_head(this);
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ if (block != NULL) {
+ block->dump_head(this);
}
}
}
-void PhaseCFG::verify( ) const {
+void PhaseCFG::verify() const {
#ifdef ASSERT
// Verify sane CFG
- for (uint i = 0; i < _num_blocks; i++) {
- Block *b = _blocks[i];
- uint cnt = b->_nodes.size();
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ uint cnt = block->_nodes.size();
uint j;
for (j = 0; j < cnt; j++) {
- Node *n = b->_nodes[j];
- assert(get_block_for_node(n) == b, "");
- if (j >= 1 && n->is_Mach() &&
- n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
- assert(j == 1 || b->_nodes[j-1]->is_Phi(),
- "CreateEx must be first instruction in block");
+ Node *n = block->_nodes[j];
+ assert(get_block_for_node(n) == block, "");
+ if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
+ assert(j == 1 || block->_nodes[j-1]->is_Phi(), "CreateEx must be first instruction in block");
}
for (uint k = 0; k < n->req(); k++) {
Node *def = n->in(k);
@@ -926,8 +911,7 @@ void PhaseCFG::verify( ) const {
// Uses must follow their definition if they are at the same block.
// Mostly done to check that MachSpillCopy nodes are placed correctly
// when CreateEx node is moved in build_ifg_physical().
- if (get_block_for_node(def) == b &&
- !(b->head()->is_Loop() && n->is_Phi()) &&
+ if (get_block_for_node(def) == block && !(block->head()->is_Loop() && n->is_Phi()) &&
// See (+++) comment in reg_split.cpp
!(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) {
bool is_loop = false;
@@ -939,29 +923,29 @@ void PhaseCFG::verify( ) const {
}
}
}
- assert(is_loop || b->find_node(def) < j, "uses must follow definitions");
+ assert(is_loop || block->find_node(def) < j, "uses must follow definitions");
}
}
}
}
- j = b->end_idx();
- Node *bp = (Node*)b->_nodes[b->_nodes.size()-1]->is_block_proj();
- assert( bp, "last instruction must be a block proj" );
- assert( bp == b->_nodes[j], "wrong number of successors for this block" );
+ j = block->end_idx();
+ Node* bp = (Node*)block->_nodes[block->_nodes.size() - 1]->is_block_proj();
+ assert(bp, "last instruction must be a block proj");
+ assert(bp == block->_nodes[j], "wrong number of successors for this block");
if (bp->is_Catch()) {
- while (b->_nodes[--j]->is_MachProj()) ;
- assert(b->_nodes[j]->is_MachCall(), "CatchProj must follow call");
+ while (block->_nodes[--j]->is_MachProj()) {
+ ;
+ }
+ assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call");
} else if (bp->is_Mach() && bp->as_Mach()->ideal_Opcode() == Op_If) {
- assert(b->_num_succs == 2, "Conditional branch must have two targets");
+ assert(block->_num_succs == 2, "Conditional branch must have two targets");
}
}
#endif
}
#endif
-//=============================================================================
-//------------------------------UnionFind--------------------------------------
UnionFind::UnionFind( uint max ) : _cnt(max), _max(max), _indices(NEW_RESOURCE_ARRAY(uint,max)) {
Copy::zero_to_bytes( _indices, sizeof(uint)*max );
}
@@ -986,7 +970,6 @@ void UnionFind::reset( uint max ) {
for( uint i=0; ifreq();
@@ -1087,7 +1065,6 @@ static int edge_order(CFGEdge **e0, CFGEdge **e1) {
return dist1 - dist0;
}
-//------------------------------trace_frequency_order--------------------------
// Comparison function for edges
extern "C" int trace_frequency_order(const void *p0, const void *p1) {
Trace *tr0 = *(Trace **) p0;
@@ -1113,17 +1090,15 @@ extern "C" int trace_frequency_order(const void *p0, const void *p1) {
return diff;
}
-//------------------------------find_edges-------------------------------------
// Find edges of interest, i.e, those which can fall through. Presumes that
// edges which don't fall through are of low frequency and can be generally
// ignored. Initialize the list of traces.
-void PhaseBlockLayout::find_edges()
-{
+void PhaseBlockLayout::find_edges() {
// Walk the blocks, creating edges and Traces
uint i;
Trace *tr = NULL;
- for (i = 0; i < _cfg._num_blocks; i++) {
- Block *b = _cfg._blocks[i];
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* b = _cfg.get_block(i);
tr = new Trace(b, next, prev);
traces[tr->id()] = tr;
@@ -1147,7 +1122,7 @@ void PhaseBlockLayout::find_edges()
if (n->num_preds() != 1) break;
i++;
- assert(n = _cfg._blocks[i], "expecting next block");
+ assert(n = _cfg.get_block(i), "expecting next block");
tr->append(n);
uf->map(n->_pre_order, tr->id());
traces[n->_pre_order] = NULL;
@@ -1171,8 +1146,8 @@ void PhaseBlockLayout::find_edges()
}
// Group connector blocks into one trace
- for (i++; i < _cfg._num_blocks; i++) {
- Block *b = _cfg._blocks[i];
+ for (i++; i < _cfg.number_of_blocks(); i++) {
+ Block *b = _cfg.get_block(i);
assert(b->is_connector(), "connector blocks at the end");
tr->append(b);
uf->map(b->_pre_order, tr->id());
@@ -1180,10 +1155,8 @@ void PhaseBlockLayout::find_edges()
}
}
-//------------------------------union_traces----------------------------------
// Union two traces together in uf, and null out the trace in the list
-void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
-{
+void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace) {
uint old_id = old_trace->id();
uint updated_id = updated_trace->id();
@@ -1207,10 +1180,8 @@ void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
traces[hi_id] = NULL;
}
-//------------------------------grow_traces-------------------------------------
// Append traces together via the most frequently executed edges
-void PhaseBlockLayout::grow_traces()
-{
+void PhaseBlockLayout::grow_traces() {
// Order the edges, and drive the growth of Traces via the most
// frequently executed edges.
edges->sort(edge_order);
@@ -1252,11 +1223,9 @@ void PhaseBlockLayout::grow_traces()
}
}
-//------------------------------merge_traces-----------------------------------
// Embed one trace into another, if the fork or join points are sufficiently
// balanced.
-void PhaseBlockLayout::merge_traces(bool fall_thru_only)
-{
+void PhaseBlockLayout::merge_traces(bool fall_thru_only) {
// Walk the edge list a another time, looking at unprocessed edges.
// Fold in diamonds
for (int i = 0; i < edges->length(); i++) {
@@ -1310,7 +1279,7 @@ void PhaseBlockLayout::merge_traces(bool fall_thru_only)
src_trace->insert_after(src_block, targ_trace);
union_traces(src_trace, targ_trace);
} else if (src_at_tail) {
- if (src_trace != trace(_cfg._broot)) {
+ if (src_trace != trace(_cfg.get_root_block())) {
e->set_state(CFGEdge::connected);
targ_trace->insert_before(targ_block, src_trace);
union_traces(targ_trace, src_trace);
@@ -1319,7 +1288,7 @@ void PhaseBlockLayout::merge_traces(bool fall_thru_only)
} else if (e->state() == CFGEdge::open) {
// Append traces, even without a fall-thru connection.
// But leave root entry at the beginning of the block list.
- if (targ_trace != trace(_cfg._broot)) {
+ if (targ_trace != trace(_cfg.get_root_block())) {
e->set_state(CFGEdge::connected);
src_trace->append(targ_trace);
union_traces(src_trace, targ_trace);
@@ -1328,11 +1297,9 @@ void PhaseBlockLayout::merge_traces(bool fall_thru_only)
}
}
-//----------------------------reorder_traces-----------------------------------
// Order the sequence of the traces in some desirable way, and fixup the
// jumps at the end of each block.
-void PhaseBlockLayout::reorder_traces(int count)
-{
+void PhaseBlockLayout::reorder_traces(int count) {
ResourceArea *area = Thread::current()->resource_area();
Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
Block_List worklist;
@@ -1347,15 +1314,14 @@ void PhaseBlockLayout::reorder_traces(int count)
}
// The entry block should be first on the new trace list.
- Trace *tr = trace(_cfg._broot);
+ Trace *tr = trace(_cfg.get_root_block());
assert(tr == new_traces[0], "entry trace misplaced");
// Sort the new trace list by frequency
qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
// Patch up the successor blocks
- _cfg._blocks.reset();
- _cfg._num_blocks = 0;
+ _cfg.clear_blocks();
for (int i = 0; i < new_count; i++) {
Trace *tr = new_traces[i];
if (tr != NULL) {
@@ -1364,17 +1330,15 @@ void PhaseBlockLayout::reorder_traces(int count)
}
}
-//------------------------------PhaseBlockLayout-------------------------------
// Order basic blocks based on frequency
-PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
- Phase(BlockLayout),
- _cfg(cfg)
-{
+PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg)
+: Phase(BlockLayout)
+, _cfg(cfg) {
ResourceMark rm;
ResourceArea *area = Thread::current()->resource_area();
// List of traces
- int size = _cfg._num_blocks + 1;
+ int size = _cfg.number_of_blocks() + 1;
traces = NEW_ARENA_ARRAY(area, Trace *, size);
memset(traces, 0, size*sizeof(Trace*));
next = NEW_ARENA_ARRAY(area, Block *, size);
@@ -1407,11 +1371,10 @@ PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
// Re-order all the remaining traces by frequency
reorder_traces(size);
- assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
+ assert(_cfg.number_of_blocks() >= (uint) (size - 1), "number of blocks can not shrink");
}
-//------------------------------backedge---------------------------------------
// Edge e completes a loop in a trace. If the target block is head of the
// loop, rotate the loop block so that the loop ends in a conditional branch.
bool Trace::backedge(CFGEdge *e) {
@@ -1463,14 +1426,12 @@ bool Trace::backedge(CFGEdge *e) {
return loop_rotated;
}
-//------------------------------fixup_blocks-----------------------------------
// push blocks onto the CFG list
// ensure that blocks have the correct two-way branch sense
void Trace::fixup_blocks(PhaseCFG &cfg) {
Block *last = last_block();
for (Block *b = first_block(); b != NULL; b = next(b)) {
- cfg._blocks.push(b);
- cfg._num_blocks++;
+ cfg.add_block(b);
if (!b->is_connector()) {
int nfallthru = b->num_fall_throughs();
if (b != last) {
diff --git a/hotspot/src/share/vm/opto/block.hpp b/hotspot/src/share/vm/opto/block.hpp
index cb9384de2ee..7cc566cf007 100644
--- a/hotspot/src/share/vm/opto/block.hpp
+++ b/hotspot/src/share/vm/opto/block.hpp
@@ -348,20 +348,77 @@ class Block : public CFGElement {
class PhaseCFG : public Phase {
friend class VMStructs;
private:
+
+ // Root of whole program
+ RootNode* _root;
+
+ // The block containing the root node
+ Block* _root_block;
+
+ // List of basic blocks that are created during CFG creation
+ Block_List _blocks;
+
+ // Count of basic blocks
+ uint _number_of_blocks;
+
// Arena for the blocks to be stored in
Arena* _block_arena;
+ // The matcher for this compilation
+ Matcher& _matcher;
+
// Map nodes to owning basic block
Block_Array _node_to_block_mapping;
+ // Loop from the root
+ CFGLoop* _root_loop;
+
+ // Outmost loop frequency
+ float _outer_loop_frequency;
+
+ // Per node latency estimation, valid only during GCM
+ GrowableArray* _node_latency;
+
// Build a proper looking cfg. Return count of basic blocks
uint build_cfg();
- // Perform DFS search.
+ // Build the dominator tree so that we know where we can move instructions
+ void build_dominator_tree();
+
+ // Estimate block frequencies based on IfNode probabilities, so that we know where we want to move instructions
+ void estimate_block_frequency();
+
+ // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
+ // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
+ // Move nodes to ensure correctness from GVN and also try to move nodes out of loops.
+ void global_code_motion();
+
+ // Schedule Nodes early in their basic blocks.
+ bool schedule_early(VectorSet &visited, Node_List &roots);
+
+ // For each node, find the latest block it can be scheduled into
+ // and then select the cheapest block between the latest and earliest
+ // block to place the node.
+ void schedule_late(VectorSet &visited, Node_List &stack);
+
+ // Compute the (backwards) latency of a node from a single use
+ int latency_from_use(Node *n, const Node *def, Node *use);
+
+ // Compute the (backwards) latency of a node from the uses of this instruction
+ void partial_latency_of_defs(Node *n);
+
+ // Compute the instruction global latency with a backwards walk
+ void compute_latencies_backwards(VectorSet &visited, Node_List &stack);
+
+ // Pick a block between early and late that is a cheaper alternative
+ // to late. Helper for schedule_late.
+ Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
+
+ // Perform a Depth First Search (DFS).
// Setup 'vertex' as DFS to vertex mapping.
// Setup 'semi' as vertex to DFS mapping.
// Set 'parent' to DFS parent.
- uint DFS( Tarjan *tarjan );
+ uint do_DFS(Tarjan* tarjan, uint rpo_counter);
// Helper function to insert a node into a block
void schedule_node_into_block( Node *n, Block *b );
@@ -372,7 +429,8 @@ class PhaseCFG : public Phase {
void schedule_pinned_nodes( VectorSet &visited );
// I'll need a few machine-specific GotoNodes. Clone from this one.
- MachNode *_goto;
+ // Used when building the CFG and creating end nodes for blocks.
+ MachNode* _goto;
Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
void verify_anti_dependences(Block* LCA, Node* load) {
@@ -380,17 +438,77 @@ class PhaseCFG : public Phase {
insert_anti_dependences(LCA, load, true);
}
+ bool move_to_next(Block* bx, uint b_index);
+ void move_to_end(Block* bx, uint b_index);
+
+ void insert_goto_at(uint block_no, uint succ_no);
+
+ // Check for NeverBranch at block end. This needs to become a GOTO to the
+ // true target. NeverBranch are treated as a conditional branch that always
+ // goes the same direction for most of the optimizer and are used to give a
+ // fake exit path to infinite loops. At this late stage they need to turn
+ // into Goto's so that when you enter the infinite loop you indeed hang.
+ void convert_NeverBranch_to_Goto(Block *b);
+
+ CFGLoop* create_loop_tree();
+
+ #ifndef PRODUCT
+ bool _trace_opto_pipelining; // tracing flag
+ #endif
+
public:
PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher);
- uint _num_blocks; // Count of basic blocks
- Block_List _blocks; // List of basic blocks
- RootNode *_root; // Root of whole program
- Block *_broot; // Basic block of root
- uint _rpo_ctr;
- CFGLoop* _root_loop;
- float _outer_loop_freq; // Outmost loop frequency
+ void set_latency_for_node(Node* node, int latency) {
+ _node_latency->at_put_grow(node->_idx, latency);
+ }
+ uint get_latency_for_node(Node* node) {
+ return _node_latency->at_grow(node->_idx);
+ }
+
+ // Get the outer most frequency
+ float get_outer_loop_frequency() const {
+ return _outer_loop_frequency;
+ }
+
+ // Get the root node of the CFG
+ RootNode* get_root_node() const {
+ return _root;
+ }
+
+ // Get the block of the root node
+ Block* get_root_block() const {
+ return _root_block;
+ }
+
+ // Add a block at a position and moves the later ones one step
+ void add_block_at(uint pos, Block* block) {
+ _blocks.insert(pos, block);
+ _number_of_blocks++;
+ }
+
+ // Adds a block to the top of the block list
+ void add_block(Block* block) {
+ _blocks.push(block);
+ _number_of_blocks++;
+ }
+
+ // Clear the list of blocks
+ void clear_blocks() {
+ _blocks.reset();
+ _number_of_blocks = 0;
+ }
+
+ // Get the block at position pos in _blocks
+ Block* get_block(uint pos) const {
+ return _blocks[pos];
+ }
+
+ // Number of blocks
+ uint number_of_blocks() const {
+ return _number_of_blocks;
+ }
// set which block this node should reside in
void map_node_to_block(const Node* node, Block* block) {
@@ -412,72 +530,26 @@ class PhaseCFG : public Phase {
return (_node_to_block_mapping.lookup(node->_idx) != NULL);
}
- // Per node latency estimation, valid only during GCM
- GrowableArray *_node_latency;
-
-#ifndef PRODUCT
- bool _trace_opto_pipelining; // tracing flag
-#endif
-
#ifdef ASSERT
Unique_Node_List _raw_oops;
#endif
- // Build dominators
- void Dominators();
-
- // Estimate block frequencies based on IfNode probabilities
- void Estimate_Block_Frequency();
-
- // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
- // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
- void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list );
+ // Do global code motion by first building dominator tree and estimate block frequency
+ // Returns true on success
+ bool do_global_code_motion();
// Compute the (backwards) latency of a node from the uses
void latency_from_uses(Node *n);
- // Compute the (backwards) latency of a node from a single use
- int latency_from_use(Node *n, const Node *def, Node *use);
-
- // Compute the (backwards) latency of a node from the uses of this instruction
- void partial_latency_of_defs(Node *n);
-
- // Schedule Nodes early in their basic blocks.
- bool schedule_early(VectorSet &visited, Node_List &roots);
-
- // For each node, find the latest block it can be scheduled into
- // and then select the cheapest block between the latest and earliest
- // block to place the node.
- void schedule_late(VectorSet &visited, Node_List &stack);
-
- // Pick a block between early and late that is a cheaper alternative
- // to late. Helper for schedule_late.
- Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
-
- // Compute the instruction global latency with a backwards walk
- void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
-
// Set loop alignment
void set_loop_alignment();
// Remove empty basic blocks
- void remove_empty();
+ void remove_empty_blocks();
void fixup_flow();
- bool move_to_next(Block* bx, uint b_index);
- void move_to_end(Block* bx, uint b_index);
- void insert_goto_at(uint block_no, uint succ_no);
- // Check for NeverBranch at block end. This needs to become a GOTO to the
- // true target. NeverBranch are treated as a conditional branch that always
- // goes the same direction for most of the optimizer and are used to give a
- // fake exit path to infinite loops. At this late stage they need to turn
- // into Goto's so that when you enter the infinite loop you indeed hang.
- void convert_NeverBranch_to_Goto(Block *b);
-
- CFGLoop* create_loop_tree();
-
- // Insert a node into a block, and update the _bbs
- void insert( Block *b, uint idx, Node *n ) {
+ // Insert a node into a block at index and map the node to the block
+ void insert(Block *b, uint idx, Node *n) {
b->_nodes.insert( idx, n );
map_node_to_block(n, b);
}
diff --git a/hotspot/src/share/vm/opto/buildOopMap.cpp b/hotspot/src/share/vm/opto/buildOopMap.cpp
index 884142d57df..746511114a7 100644
--- a/hotspot/src/share/vm/opto/buildOopMap.cpp
+++ b/hotspot/src/share/vm/opto/buildOopMap.cpp
@@ -87,7 +87,6 @@
// OptoReg::Bad for not-callee-saved.
-//------------------------------OopFlow----------------------------------------
// Structure to pass around
struct OopFlow : public ResourceObj {
short *_callees; // Array mapping register to callee-saved
@@ -119,7 +118,6 @@ struct OopFlow : public ResourceObj {
OopMap *build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live );
};
-//------------------------------compute_reach----------------------------------
// Given reaching-defs for this block start, compute it for this block end
void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehash ) {
@@ -177,7 +175,6 @@ void OopFlow::compute_reach( PhaseRegAlloc *regalloc, int max_reg, Dict *safehas
}
}
-//------------------------------merge------------------------------------------
// Merge the given flow into the 'this' flow
void OopFlow::merge( OopFlow *flow, int max_reg ) {
assert( _b == NULL, "merging into a happy flow" );
@@ -197,14 +194,12 @@ void OopFlow::merge( OopFlow *flow, int max_reg ) {
}
-//------------------------------clone------------------------------------------
void OopFlow::clone( OopFlow *flow, int max_size ) {
_b = flow->_b;
memcpy( _callees, flow->_callees, sizeof(short)*max_size);
memcpy( _defs , flow->_defs , sizeof(Node*)*max_size);
}
-//------------------------------make-------------------------------------------
OopFlow *OopFlow::make( Arena *A, int max_size, Compile* C ) {
short *callees = NEW_ARENA_ARRAY(A,short,max_size+1);
Node **defs = NEW_ARENA_ARRAY(A,Node*,max_size+1);
@@ -215,7 +210,6 @@ OopFlow *OopFlow::make( Arena *A, int max_size, Compile* C ) {
return flow;
}
-//------------------------------bit twiddlers----------------------------------
static int get_live_bit( int *live, int reg ) {
return live[reg>>LogBitsPerInt] & (1<<(reg&(BitsPerInt-1))); }
static void set_live_bit( int *live, int reg ) {
@@ -223,7 +217,6 @@ static void set_live_bit( int *live, int reg ) {
static void clr_live_bit( int *live, int reg ) {
live[reg>>LogBitsPerInt] &= ~(1<<(reg&(BitsPerInt-1))); }
-//------------------------------build_oop_map----------------------------------
// Build an oopmap from the current flow info
OopMap *OopFlow::build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, int* live ) {
int framesize = regalloc->_framesize;
@@ -412,19 +405,18 @@ OopMap *OopFlow::build_oop_map( Node *n, int max_reg, PhaseRegAlloc *regalloc, i
return omap;
}
-//------------------------------do_liveness------------------------------------
// Compute backwards liveness on registers
-static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *worklist, int max_reg_ints, Arena *A, Dict *safehash ) {
- int *live = NEW_ARENA_ARRAY(A, int, (cfg->_num_blocks+1) * max_reg_ints);
- int *tmp_live = &live[cfg->_num_blocks * max_reg_ints];
- Node *root = cfg->C->root();
+static void do_liveness(PhaseRegAlloc* regalloc, PhaseCFG* cfg, Block_List* worklist, int max_reg_ints, Arena* A, Dict* safehash) {
+ int* live = NEW_ARENA_ARRAY(A, int, (cfg->number_of_blocks() + 1) * max_reg_ints);
+ int* tmp_live = &live[cfg->number_of_blocks() * max_reg_ints];
+ Node* root = cfg->get_root_node();
// On CISC platforms, get the node representing the stack pointer that regalloc
// used for spills
Node *fp = NodeSentinel;
if (UseCISCSpill && root->req() > 1) {
fp = root->in(1)->in(TypeFunc::FramePtr);
}
- memset( live, 0, cfg->_num_blocks * (max_reg_ints<number_of_blocks() * (max_reg_ints << LogBytesPerInt));
// Push preds onto worklist
for (uint i = 1; i < root->req(); i++) {
Block* block = cfg->get_block_for_node(root->in(i));
@@ -549,29 +541,32 @@ static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *wor
// Scan for any missing safepoints. Happens to infinite loops
// ala ZKM.jar
uint i;
- for( i=1; i_num_blocks; i++ ) {
- Block *b = cfg->_blocks[i];
+ for (i = 1; i < cfg->number_of_blocks(); i++) {
+ Block* block = cfg->get_block(i);
uint j;
- for( j=1; j_nodes.size(); j++ )
- if( b->_nodes[j]->jvms() &&
- (*safehash)[b->_nodes[j]] == NULL )
+ for (j = 1; j < block->_nodes.size(); j++) {
+ if (block->_nodes[j]->jvms() && (*safehash)[block->_nodes[j]] == NULL) {
break;
- if( j_nodes.size() ) break;
+ }
+ }
+ if (j < block->_nodes.size()) {
+ break;
+ }
}
- if( i == cfg->_num_blocks )
+ if (i == cfg->number_of_blocks()) {
break; // Got 'em all
+ }
#ifndef PRODUCT
if( PrintOpto && Verbose )
tty->print_cr("retripping live calc");
#endif
// Force the issue (expensively): recheck everybody
- for( i=1; i_num_blocks; i++ )
- worklist->push(cfg->_blocks[i]);
+ for (i = 1; i < cfg->number_of_blocks(); i++) {
+ worklist->push(cfg->get_block(i));
+ }
}
-
}
-//------------------------------BuildOopMaps-----------------------------------
// Collect GC mask info - where are all the OOPs?
void Compile::BuildOopMaps() {
NOT_PRODUCT( TracePhase t3("bldOopMaps", &_t_buildOopMaps, TimeCompiler); )
@@ -592,12 +587,12 @@ void Compile::BuildOopMaps() {
OopFlow *free_list = NULL; // Free, unused
// Array mapping blocks to completed oopflows
- OopFlow **flows = NEW_ARENA_ARRAY(A, OopFlow*, _cfg->_num_blocks);
- memset( flows, 0, _cfg->_num_blocks*sizeof(OopFlow*) );
+ OopFlow **flows = NEW_ARENA_ARRAY(A, OopFlow*, _cfg->number_of_blocks());
+ memset( flows, 0, _cfg->number_of_blocks() * sizeof(OopFlow*) );
// Do the first block 'by hand' to prime the worklist
- Block *entry = _cfg->_blocks[1];
+ Block *entry = _cfg->get_block(1);
OopFlow *rootflow = OopFlow::make(A,max_reg,this);
// Initialize to 'bottom' (not 'top')
memset( rootflow->_callees, OptoReg::Bad, max_reg*sizeof(short) );
@@ -623,7 +618,9 @@ void Compile::BuildOopMaps() {
Block *b = worklist.pop();
// Ignore root block
- if( b == _cfg->_broot ) continue;
+ if (b == _cfg->get_root_block()) {
+ continue;
+ }
// Block is already done? Happens if block has several predecessors,
// he can get on the worklist more than once.
if( flows[b->_pre_order] ) continue;
diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp
index 4fc254f40ca..c2f8d40b202 100644
--- a/hotspot/src/share/vm/opto/chaitin.cpp
+++ b/hotspot/src/share/vm/opto/chaitin.cpp
@@ -40,10 +40,8 @@
#include "opto/opcodes.hpp"
#include "opto/rootnode.hpp"
-//=============================================================================
-
#ifndef PRODUCT
-void LRG::dump( ) const {
+void LRG::dump() const {
ttyLocker ttyl;
tty->print("%d ",num_regs());
_mask.dump();
@@ -94,7 +92,6 @@ void LRG::dump( ) const {
}
#endif
-//------------------------------score------------------------------------------
// Compute score from cost and area. Low score is best to spill.
static double raw_score( double cost, double area ) {
return cost - (area*RegisterCostAreaRatio) * 1.52588e-5;
@@ -125,7 +122,6 @@ double LRG::score() const {
return score;
}
-//------------------------------LRG_List---------------------------------------
LRG_List::LRG_List( uint max ) : _cnt(max), _max(max), _lidxs(NEW_RESOURCE_ARRAY(uint,max)) {
memset( _lidxs, 0, sizeof(uint)*max );
}
@@ -211,7 +207,6 @@ uint LiveRangeMap::find_const(uint lrg) const {
return next;
}
-//------------------------------Chaitin----------------------------------------
PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
: PhaseRegAlloc(unique, cfg, matcher,
#ifndef PRODUCT
@@ -232,31 +227,31 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
{
NOT_PRODUCT( Compile::TracePhase t3("ctorChaitin", &_t_ctorChaitin, TimeCompiler); )
- _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg._outer_loop_freq);
+ _high_frequency_lrg = MIN2(float(OPTO_LRG_HIGH_FREQ), _cfg.get_outer_loop_frequency());
// Build a list of basic blocks, sorted by frequency
- _blks = NEW_RESOURCE_ARRAY( Block *, _cfg._num_blocks );
+ _blks = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
// Experiment with sorting strategies to speed compilation
double cutoff = BLOCK_FREQUENCY(1.0); // Cutoff for high frequency bucket
Block **buckets[NUMBUCKS]; // Array of buckets
uint buckcnt[NUMBUCKS]; // Array of bucket counters
double buckval[NUMBUCKS]; // Array of bucket value cutoffs
for (uint i = 0; i < NUMBUCKS; i++) {
- buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg._num_blocks);
+ buckets[i] = NEW_RESOURCE_ARRAY(Block *, _cfg.number_of_blocks());
buckcnt[i] = 0;
// Bump by three orders of magnitude each time
cutoff *= 0.001;
buckval[i] = cutoff;
- for (uint j = 0; j < _cfg._num_blocks; j++) {
+ for (uint j = 0; j < _cfg.number_of_blocks(); j++) {
buckets[i][j] = NULL;
}
}
// Sort blocks into buckets
- for (uint i = 0; i < _cfg._num_blocks; i++) {
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
for (uint j = 0; j < NUMBUCKS; j++) {
- if ((j == NUMBUCKS - 1) || (_cfg._blocks[i]->_freq > buckval[j])) {
+ if ((j == NUMBUCKS - 1) || (_cfg.get_block(i)->_freq > buckval[j])) {
// Assign block to end of list for appropriate bucket
- buckets[j][buckcnt[j]++] = _cfg._blocks[i];
+ buckets[j][buckcnt[j]++] = _cfg.get_block(i);
break; // kick out of inner loop
}
}
@@ -269,10 +264,9 @@ PhaseChaitin::PhaseChaitin(uint unique, PhaseCFG &cfg, Matcher &matcher)
}
}
- assert(blkcnt == _cfg._num_blocks, "Block array not totally filled");
+ assert(blkcnt == _cfg.number_of_blocks(), "Block array not totally filled");
}
-//------------------------------Union------------------------------------------
// union 2 sets together.
void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
uint src = _lrg_map.find(src_n);
@@ -285,7 +279,6 @@ void PhaseChaitin::Union( const Node *src_n, const Node *dst_n ) {
_lrg_map.uf_map(dst, src);
}
-//------------------------------new_lrg----------------------------------------
void PhaseChaitin::new_lrg(const Node *x, uint lrg) {
// Make the Node->LRG mapping
_lrg_map.extend(x->_idx,lrg);
@@ -294,24 +287,28 @@ void PhaseChaitin::new_lrg(const Node *x, uint lrg) {
}
-bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) {
- Block* bcon = _cfg.get_block_for_node(con);
- uint cindex = bcon->find_node(con);
- Node *con_next = bcon->_nodes[cindex+1];
- if (con_next->in(0) != con || !con_next->is_MachProj()) {
- return false; // No MachProj's follow
+int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
+ assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
+ DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); )
+ int found_projs = 0;
+ uint cnt = orig->outcnt();
+ for (uint i = 0; i < cnt; i++) {
+ Node* proj = orig->raw_out(i);
+ if (proj->is_MachProj()) {
+ assert(proj->outcnt() == 0, "only kill projections are expected here");
+ assert(_cfg.get_block_for_node(proj) == borig, "incorrect block for kill projections");
+ found_projs++;
+ // Copy kill projections after the cloned node
+ Node* kills = proj->clone();
+ kills->set_req(0, copy);
+ b->_nodes.insert(idx++, kills);
+ _cfg.map_node_to_block(kills, b);
+ new_lrg(kills, max_lrg_id++);
+ }
}
-
- // Copy kills after the cloned constant
- Node *kills = con_next->clone();
- kills->set_req(0, copy);
- b->_nodes.insert(idx, kills);
- _cfg.map_node_to_block(kills, b);
- new_lrg(kills, max_lrg_id);
- return true;
+ return found_projs;
}
-//------------------------------compact----------------------------------------
// Renumber the live ranges to compact them. Makes the IFG smaller.
void PhaseChaitin::compact() {
// Current the _uf_map contains a series of short chains which are headed
@@ -677,20 +674,19 @@ void PhaseChaitin::Register_Allocate() {
C->set_indexSet_arena(NULL); // ResourceArea is at end of scope
}
-//------------------------------de_ssa-----------------------------------------
void PhaseChaitin::de_ssa() {
// Set initial Names for all Nodes. Most Nodes get the virtual register
// number. A few get the ZERO live range number. These do not
// get allocated, but instead rely on correct scheduling to ensure that
// only one instance is simultaneously live at a time.
uint lr_counter = 1;
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- uint cnt = b->_nodes.size();
+ for( uint i = 0; i < _cfg.number_of_blocks(); i++ ) {
+ Block* block = _cfg.get_block(i);
+ uint cnt = block->_nodes.size();
// Handle all the normal Nodes in the block
for( uint j = 0; j < cnt; j++ ) {
- Node *n = b->_nodes[j];
+ Node *n = block->_nodes[j];
// Pre-color to the zero live range, or pick virtual register
const RegMask &rm = n->out_RegMask();
_lrg_map.map(n->_idx, rm.is_NotEmpty() ? lr_counter++ : 0);
@@ -701,52 +697,55 @@ void PhaseChaitin::de_ssa() {
}
-//------------------------------gather_lrg_masks-------------------------------
// Gather LiveRanGe information, including register masks. Modification of
// cisc spillable in_RegMasks should not be done before AggressiveCoalesce.
void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
// Nail down the frame pointer live range
- uint fp_lrg = _lrg_map.live_range_id(_cfg._root->in(1)->in(TypeFunc::FramePtr));
+ uint fp_lrg = _lrg_map.live_range_id(_cfg.get_root_node()->in(1)->in(TypeFunc::FramePtr));
lrgs(fp_lrg)._cost += 1e12; // Cost is infinite
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// For all instructions
- for( uint j = 1; j < b->_nodes.size(); j++ ) {
- Node *n = b->_nodes[j];
+ for (uint j = 1; j < block->_nodes.size(); j++) {
+ Node* n = block->_nodes[j];
uint input_edge_start =1; // Skip control most nodes
- if( n->is_Mach() ) input_edge_start = n->as_Mach()->oper_input_base();
+ if (n->is_Mach()) {
+ input_edge_start = n->as_Mach()->oper_input_base();
+ }
uint idx = n->is_Copy();
// Get virtual register number, same as LiveRanGe index
uint vreg = _lrg_map.live_range_id(n);
- LRG &lrg = lrgs(vreg);
- if( vreg ) { // No vreg means un-allocable (e.g. memory)
+ LRG& lrg = lrgs(vreg);
+ if (vreg) { // No vreg means un-allocable (e.g. memory)
// Collect has-copy bit
- if( idx ) {
+ if (idx) {
lrg._has_copy = 1;
uint clidx = _lrg_map.live_range_id(n->in(idx));
- LRG ©_src = lrgs(clidx);
+ LRG& copy_src = lrgs(clidx);
copy_src._has_copy = 1;
}
// Check for float-vs-int live range (used in register-pressure
// calculations)
const Type *n_type = n->bottom_type();
- if (n_type->is_floatingpoint())
+ if (n_type->is_floatingpoint()) {
lrg._is_float = 1;
+ }
// Check for twice prior spilling. Once prior spilling might have
// spilled 'soft', 2nd prior spill should have spilled 'hard' and
// further spilling is unlikely to make progress.
- if( _spilled_once.test(n->_idx) ) {
+ if (_spilled_once.test(n->_idx)) {
lrg._was_spilled1 = 1;
- if( _spilled_twice.test(n->_idx) )
+ if (_spilled_twice.test(n->_idx)) {
lrg._was_spilled2 = 1;
+ }
}
#ifndef PRODUCT
@@ -783,16 +782,18 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
// Check for bound register masks
const RegMask &lrgmask = lrg.mask();
- if (lrgmask.is_bound(ireg))
+ if (lrgmask.is_bound(ireg)) {
lrg._is_bound = 1;
+ }
// Check for maximum frequency value
- if (lrg._maxfreq < b->_freq)
- lrg._maxfreq = b->_freq;
+ if (lrg._maxfreq < block->_freq) {
+ lrg._maxfreq = block->_freq;
+ }
// Check for oop-iness, or long/double
// Check for multi-kill projection
- switch( ireg ) {
+ switch (ireg) {
case MachProjNode::fat_proj:
// Fat projections have size equal to number of registers killed
lrg.set_num_regs(rm.Size());
@@ -962,7 +963,7 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
// AggressiveCoalesce. This effectively pre-virtual-splits
// around uncommon uses of common defs.
const RegMask &rm = n->in_RegMask(k);
- if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * b->_freq) {
+ if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * block->_freq) {
// Since we are BEFORE aggressive coalesce, leave the register
// mask untrimmed by the call. This encourages more coalescing.
// Later, AFTER aggressive, this live range will have to spill
@@ -1006,8 +1007,9 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
}
// Check for maximum frequency value
- if( lrg._maxfreq < b->_freq )
- lrg._maxfreq = b->_freq;
+ if (lrg._maxfreq < block->_freq) {
+ lrg._maxfreq = block->_freq;
+ }
} // End for all allocated inputs
} // end for all instructions
@@ -1029,7 +1031,6 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
}
}
-//------------------------------set_was_low------------------------------------
// Set the was-lo-degree bit. Conservative coalescing should not change the
// colorability of the graph. If any live range was of low-degree before
// coalescing, it should Simplify. This call sets the was-lo-degree bit.
@@ -1066,7 +1067,6 @@ void PhaseChaitin::set_was_low() {
#define REGISTER_CONSTRAINED 16
-//------------------------------cache_lrg_info---------------------------------
// Compute cost/area ratio, in case we spill. Build the lo-degree list.
void PhaseChaitin::cache_lrg_info( ) {
@@ -1100,7 +1100,6 @@ void PhaseChaitin::cache_lrg_info( ) {
}
}
-//------------------------------Pre-Simplify-----------------------------------
// Simplify the IFG by removing LRGs of low degree that have NO copies
void PhaseChaitin::Pre_Simplify( ) {
@@ -1151,7 +1150,6 @@ void PhaseChaitin::Pre_Simplify( ) {
// No more lo-degree no-copy live ranges to simplify
}
-//------------------------------Simplify---------------------------------------
// Simplify the IFG by removing LRGs of low degree.
void PhaseChaitin::Simplify( ) {
@@ -1288,7 +1286,6 @@ void PhaseChaitin::Simplify( ) {
}
-//------------------------------is_legal_reg-----------------------------------
// Is 'reg' register legal for 'lrg'?
static bool is_legal_reg(LRG &lrg, OptoReg::Name reg, int chunk) {
if (reg >= chunk && reg < (chunk + RegMask::CHUNK_SIZE) &&
@@ -1315,7 +1312,6 @@ static bool is_legal_reg(LRG &lrg, OptoReg::Name reg, int chunk) {
return false;
}
-//------------------------------bias_color-------------------------------------
// Choose a color using the biasing heuristic
OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
@@ -1377,7 +1373,6 @@ OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
return OptoReg::add( reg, chunk );
}
-//------------------------------choose_color-----------------------------------
// Choose a color in the current chunk
OptoReg::Name PhaseChaitin::choose_color( LRG &lrg, int chunk ) {
assert( C->in_preserve_stack_slots() == 0 || chunk != 0 || lrg._is_bound || lrg.mask().is_bound1() || !lrg.mask().Member(OptoReg::Name(_matcher._old_SP-1)), "must not allocate stack0 (inside preserve area)");
@@ -1399,7 +1394,6 @@ OptoReg::Name PhaseChaitin::choose_color( LRG &lrg, int chunk ) {
return lrg.mask().find_last_elem();
}
-//------------------------------Select-----------------------------------------
// Select colors by re-inserting LRGs back into the IFG. LRGs are re-inserted
// in reverse order of removal. As long as nothing of hi-degree was yanked,
// everything going back is guaranteed a color. Select that color. If some
@@ -1574,8 +1568,6 @@ uint PhaseChaitin::Select( ) {
return spill_reg-LRG::SPILL_REG; // Return number of spills
}
-
-//------------------------------copy_was_spilled-------------------------------
// Copy 'was_spilled'-edness from the source Node to the dst Node.
void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
if( _spilled_once.test(src->_idx) ) {
@@ -1588,14 +1580,12 @@ void PhaseChaitin::copy_was_spilled( Node *src, Node *dst ) {
}
}
-//------------------------------set_was_spilled--------------------------------
// Set the 'spilled_once' or 'spilled_twice' flag on a node.
void PhaseChaitin::set_was_spilled( Node *n ) {
if( _spilled_once.test_set(n->_idx) )
_spilled_twice.set(n->_idx);
}
-//------------------------------fixup_spills-----------------------------------
// Convert Ideal spill instructions into proper FramePtr + offset Loads and
// Stores. Use-def chains are NOT preserved, but Node->LRG->reg maps are.
void PhaseChaitin::fixup_spills() {
@@ -1605,16 +1595,16 @@ void PhaseChaitin::fixup_spills() {
NOT_PRODUCT( Compile::TracePhase t3("fixupSpills", &_t_fixupSpills, TimeCompiler); )
// Grab the Frame Pointer
- Node *fp = _cfg._broot->head()->in(1)->in(TypeFunc::FramePtr);
+ Node *fp = _cfg.get_root_block()->head()->in(1)->in(TypeFunc::FramePtr);
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// For all instructions in block
- uint last_inst = b->end_idx();
- for( uint j = 1; j <= last_inst; j++ ) {
- Node *n = b->_nodes[j];
+ uint last_inst = block->end_idx();
+ for (uint j = 1; j <= last_inst; j++) {
+ Node* n = block->_nodes[j];
// Dead instruction???
assert( n->outcnt() != 0 ||// Nothing dead after post alloc
@@ -1651,7 +1641,7 @@ void PhaseChaitin::fixup_spills() {
assert( cisc->oper_input_base() == 2, "Only adding one edge");
cisc->ins_req(1,src); // Requires a memory edge
}
- b->_nodes.map(j,cisc); // Insert into basic block
+ block->_nodes.map(j,cisc); // Insert into basic block
n->subsume_by(cisc, C); // Correct graph
//
++_used_cisc_instructions;
@@ -1677,7 +1667,6 @@ void PhaseChaitin::fixup_spills() {
} // End of for all blocks
}
-//------------------------------find_base_for_derived--------------------------
// Helper to stretch above; recursively discover the base Node for a
// given derived Node. Easy for AddP-related machine nodes, but needs
// to be recursive for derived Phis.
@@ -1707,7 +1696,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive
// Initialize it once and make it shared:
// set control to _root and place it into Start block
// (where top() node is placed).
- base->init_req(0, _cfg._root);
+ base->init_req(0, _cfg.get_root_node());
Block *startb = _cfg.get_block_for_node(C->top());
startb->_nodes.insert(startb->find_node(C->top()), base );
_cfg.map_node_to_block(base, startb);
@@ -1716,7 +1705,7 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive
if (_lrg_map.live_range_id(base) == 0) {
new_lrg(base, maxlrg++);
}
- assert(base->in(0) == _cfg._root && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared");
+ assert(base->in(0) == _cfg.get_root_node() && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared");
derived_base_map[derived->_idx] = base;
return base;
}
@@ -1779,8 +1768,6 @@ Node *PhaseChaitin::find_base_for_derived( Node **derived_base_map, Node *derive
return base;
}
-
-//------------------------------stretch_base_pointer_live_ranges---------------
// At each Safepoint, insert extra debug edges for each pair of derived value/
// base pointer that is live across the Safepoint for oopmap building. The
// edge pairs get added in after sfpt->jvmtail()->oopoff(), but are in the
@@ -1792,14 +1779,14 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
memset( derived_base_map, 0, sizeof(Node*)*C->unique() );
// For all blocks in RPO do...
- for( uint i=0; i<_cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// Note use of deep-copy constructor. I cannot hammer the original
// liveout bits, because they are needed by the following coalesce pass.
- IndexSet liveout(_live->live(b));
+ IndexSet liveout(_live->live(block));
- for( uint j = b->end_idx() + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j-1];
+ for (uint j = block->end_idx() + 1; j > 1; j--) {
+ Node* n = block->_nodes[j - 1];
// Pre-split compares of loop-phis. Loop-phis form a cycle we would
// like to see in the same register. Compare uses the loop-phi and so
@@ -1814,7 +1801,7 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
Node *phi = n->in(1);
if( phi->is_Phi() && phi->as_Phi()->region()->is_Loop() ) {
Block *phi_block = _cfg.get_block_for_node(phi);
- if (_cfg.get_block_for_node(phi_block->pred(2)) == b) {
+ if (_cfg.get_block_for_node(phi_block->pred(2)) == block) {
const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI];
Node *spill = new (C) MachSpillCopyNode( phi, *mask, *mask );
insert_proj( phi_block, 1, spill, maxlrg++ );
@@ -1868,7 +1855,7 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or
!liveout.member(_lrg_map.live_range_id(base))) && // not live) AND
(_lrg_map.live_range_id(base) > 0) && // not a constant
- _cfg.get_block_for_node(base) != b) { // base not def'd in blk)
+ _cfg.get_block_for_node(base) != block) { // base not def'd in blk)
// Base pointer is not currently live. Since I stretched
// the base pointer to here and it crosses basic-block
// boundaries, the global live info is now incorrect.
@@ -1903,15 +1890,12 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
return must_recompute_live != 0;
}
-
-//------------------------------add_reference----------------------------------
// Extend the node to LRG mapping
void PhaseChaitin::add_reference(const Node *node, const Node *old_node) {
_lrg_map.extend(node->_idx, _lrg_map.live_range_id(old_node));
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void PhaseChaitin::dump(const Node *n) const {
uint r = (n->_idx < _lrg_map.size()) ? _lrg_map.find_const(n) : 0;
@@ -2017,8 +2001,9 @@ void PhaseChaitin::dump() const {
_matcher._new_SP, _framesize );
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ )
- dump(_cfg._blocks[i]);
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ dump(_cfg.get_block(i));
+ }
// End of per-block dump
tty->print("\n");
@@ -2059,7 +2044,6 @@ void PhaseChaitin::dump() const {
tty->print_cr("");
}
-//------------------------------dump_degree_lists------------------------------
void PhaseChaitin::dump_degree_lists() const {
// Dump lo-degree list
tty->print("Lo degree: ");
@@ -2080,7 +2064,6 @@ void PhaseChaitin::dump_degree_lists() const {
tty->print_cr("");
}
-//------------------------------dump_simplified--------------------------------
void PhaseChaitin::dump_simplified() const {
tty->print("Simplified: ");
for( uint i = _simplified; i; i = lrgs(i)._next )
@@ -2099,7 +2082,6 @@ static char *print_reg( OptoReg::Name reg, const PhaseChaitin *pc, char *buf ) {
return buf+strlen(buf);
}
-//------------------------------dump_register----------------------------------
// Dump a register name into a buffer. Be intelligent if we get called
// before allocation is complete.
char *PhaseChaitin::dump_register( const Node *n, char *buf ) const {
@@ -2133,7 +2115,6 @@ char *PhaseChaitin::dump_register( const Node *n, char *buf ) const {
return buf+strlen(buf);
}
-//----------------------dump_for_spill_split_recycle--------------------------
void PhaseChaitin::dump_for_spill_split_recycle() const {
if( WizardMode && (PrintCompilation || PrintOpto) ) {
// Display which live ranges need to be split and the allocator's state
@@ -2149,7 +2130,6 @@ void PhaseChaitin::dump_for_spill_split_recycle() const {
}
}
-//------------------------------dump_frame------------------------------------
void PhaseChaitin::dump_frame() const {
const char *fp = OptoReg::regname(OptoReg::c_frame_pointer);
const TypeTuple *domain = C->tf()->domain();
@@ -2255,17 +2235,16 @@ void PhaseChaitin::dump_frame() const {
tty->print_cr("#");
}
-//------------------------------dump_bb----------------------------------------
void PhaseChaitin::dump_bb( uint pre_order ) const {
tty->print_cr("---dump of B%d---",pre_order);
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- if( b->_pre_order == pre_order )
- dump(b);
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
+ if (block->_pre_order == pre_order) {
+ dump(block);
+ }
}
}
-//------------------------------dump_lrg---------------------------------------
void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
tty->print_cr("---dump of L%d---",lidx);
@@ -2287,17 +2266,17 @@ void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
tty->cr();
}
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
int dump_once = 0;
// For all instructions
- for( uint j = 0; j < b->_nodes.size(); j++ ) {
- Node *n = b->_nodes[j];
+ for( uint j = 0; j < block->_nodes.size(); j++ ) {
+ Node *n = block->_nodes[j];
if (_lrg_map.find_const(n) == lidx) {
if (!dump_once++) {
tty->cr();
- b->dump_head(&_cfg);
+ block->dump_head(&_cfg);
}
dump(n);
continue;
@@ -2312,7 +2291,7 @@ void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
if (_lrg_map.find_const(m) == lidx) {
if (!dump_once++) {
tty->cr();
- b->dump_head(&_cfg);
+ block->dump_head(&_cfg);
}
dump(n);
}
@@ -2324,7 +2303,6 @@ void PhaseChaitin::dump_lrg( uint lidx, bool defs_only ) const {
}
#endif // not PRODUCT
-//------------------------------print_chaitin_statistics-------------------------------
int PhaseChaitin::_final_loads = 0;
int PhaseChaitin::_final_stores = 0;
int PhaseChaitin::_final_memoves= 0;
diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp
index 3455005f330..c951024ee75 100644
--- a/hotspot/src/share/vm/opto/chaitin.hpp
+++ b/hotspot/src/share/vm/opto/chaitin.hpp
@@ -412,33 +412,22 @@ class PhaseChaitin : public PhaseRegAlloc {
uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray splits, int slidx );
uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray splits, int slidx );
- bool clone_projs(Block *b, uint idx, Node *con, Node *copy, LiveRangeMap &lrg_map) {
- bool found_projs = clone_projs_shared(b, idx, con, copy, lrg_map.max_lrg_id());
-
- if(found_projs) {
- uint max_lrg_id = lrg_map.max_lrg_id();
- lrg_map.set_max_lrg_id(max_lrg_id + 1);
- }
-
- return found_projs;
- }
-
//------------------------------clone_projs------------------------------------
// After cloning some rematerialized instruction, clone any MachProj's that
// follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
// use G3 as an address temp.
- bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) {
- bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id);
+ int clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id);
- if(found_projs) {
- max_lrg_id++;
+ int clone_projs(Block* b, uint idx, Node* orig, Node* copy, LiveRangeMap& lrg_map) {
+ uint max_lrg_id = lrg_map.max_lrg_id();
+ int found_projs = clone_projs(b, idx, orig, copy, max_lrg_id);
+ if (found_projs > 0) {
+ // max_lrg_id is updated during call above
+ lrg_map.set_max_lrg_id(max_lrg_id);
}
-
return found_projs;
}
- bool clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id);
-
Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray splits,
int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
// True if lidx is used before any real register is def'd in the block
diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp
index d1f880a6493..66fd988c273 100644
--- a/hotspot/src/share/vm/opto/coalesce.cpp
+++ b/hotspot/src/share/vm/opto/coalesce.cpp
@@ -34,8 +34,6 @@
#include "opto/matcher.hpp"
#include "opto/regmask.hpp"
-//=============================================================================
-//------------------------------Dump-------------------------------------------
#ifndef PRODUCT
void PhaseCoalesce::dump(Node *n) const {
// Being a const function means I cannot use 'Find'
@@ -43,12 +41,11 @@ void PhaseCoalesce::dump(Node *n) const {
tty->print("L%d/N%d ",r,n->_idx);
}
-//------------------------------dump-------------------------------------------
void PhaseCoalesce::dump() const {
// I know I have a block layout now, so I can print blocks in a loop
- for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
+ for( uint i=0; i<_phc._cfg.number_of_blocks(); i++ ) {
uint j;
- Block *b = _phc._cfg._blocks[i];
+ Block* b = _phc._cfg.get_block(i);
// Print a nice block header
tty->print("B%d: ",b->_pre_order);
for( j=1; jnum_preds(); j++ )
@@ -85,7 +82,6 @@ void PhaseCoalesce::dump() const {
}
#endif
-//------------------------------combine_these_two------------------------------
// Combine the live ranges def'd by these 2 Nodes. N2 is an input to N1.
void PhaseCoalesce::combine_these_two(Node *n1, Node *n2) {
uint lr1 = _phc._lrg_map.find(n1);
@@ -127,18 +123,15 @@ void PhaseCoalesce::combine_these_two(Node *n1, Node *n2) {
}
}
-//------------------------------coalesce_driver--------------------------------
// Copy coalescing
-void PhaseCoalesce::coalesce_driver( ) {
-
+void PhaseCoalesce::coalesce_driver() {
verify();
// Coalesce from high frequency to low
- for( uint i=0; i<_phc._cfg._num_blocks; i++ )
- coalesce( _phc._blks[i] );
-
+ for (uint i = 0; i < _phc._cfg.number_of_blocks(); i++) {
+ coalesce(_phc._blks[i]);
+ }
}
-//------------------------------insert_copy_with_overlap-----------------------
// I am inserting copies to come out of SSA form. In the general case, I am
// doing a parallel renaming. I'm in the Named world now, so I can't do a
// general parallel renaming. All the copies now use "names" (live-ranges)
@@ -216,7 +209,6 @@ void PhaseAggressiveCoalesce::insert_copy_with_overlap( Block *b, Node *copy, ui
b->_nodes.insert(last_use_idx+1,copy);
}
-//------------------------------insert_copies----------------------------------
void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
// We do LRGs compressing and fix a liveout data only here since the other
// place in Split() is guarded by the assert which we never hit.
@@ -225,8 +217,8 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
for (uint lrg = 1; lrg < _phc._lrg_map.max_lrg_id(); lrg++) {
uint compressed_lrg = _phc._lrg_map.find(lrg);
if (lrg != compressed_lrg) {
- for (uint bidx = 0; bidx < _phc._cfg._num_blocks; bidx++) {
- IndexSet *liveout = _phc._live->live(_phc._cfg._blocks[bidx]);
+ for (uint bidx = 0; bidx < _phc._cfg.number_of_blocks(); bidx++) {
+ IndexSet *liveout = _phc._live->live(_phc._cfg.get_block(bidx));
if (liveout->member(lrg)) {
liveout->remove(lrg);
liveout->insert(compressed_lrg);
@@ -239,10 +231,10 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
// Nodes with index less than '_unique' are original, non-virtual Nodes.
_unique = C->unique();
- for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
+ for (uint i = 0; i < _phc._cfg.number_of_blocks(); i++) {
C->check_node_count(NodeLimitFudgeFactor, "out of nodes in coalesce");
if (C->failing()) return;
- Block *b = _phc._cfg._blocks[i];
+ Block *b = _phc._cfg.get_block(i);
uint cnt = b->num_preds(); // Number of inputs to the Phi
for( uint l = 1; l_nodes.size(); l++ ) {
@@ -330,9 +322,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
copy = m->clone();
// Insert the copy in the basic block, just before us
b->_nodes.insert(l++, copy);
- if(_phc.clone_projs(b, l, m, copy, _phc._lrg_map)) {
- l++;
- }
+ l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
} else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
copy = new (C) MachSpillCopyNode(m, *rm, *rm);
@@ -403,8 +393,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
} // End of for all blocks
}
-//=============================================================================
-//------------------------------coalesce---------------------------------------
+
// Aggressive (but pessimistic) copy coalescing of a single block
// The following coalesce pass represents a single round of aggressive
@@ -464,20 +453,16 @@ void PhaseAggressiveCoalesce::coalesce( Block *b ) {
} // End of for all instructions in block
}
-//=============================================================================
-//------------------------------PhaseConservativeCoalesce----------------------
PhaseConservativeCoalesce::PhaseConservativeCoalesce(PhaseChaitin &chaitin) : PhaseCoalesce(chaitin) {
_ulr.initialize(_phc._lrg_map.max_lrg_id());
}
-//------------------------------verify-----------------------------------------
void PhaseConservativeCoalesce::verify() {
#ifdef ASSERT
_phc.set_was_low();
#endif
}
-//------------------------------union_helper-----------------------------------
void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, uint lr1, uint lr2, Node *src_def, Node *dst_copy, Node *src_copy, Block *b, uint bindex ) {
// Join live ranges. Merge larger into smaller. Union lr2 into lr1 in the
// union-find tree
@@ -520,7 +505,6 @@ void PhaseConservativeCoalesce::union_helper( Node *lr1_node, Node *lr2_node, ui
}
}
-//------------------------------compute_separating_interferences---------------
// Factored code from copy_copy that computes extra interferences from
// lengthening a live range by double-coalescing.
uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy, Node *src_copy, Block *b, uint bindex, RegMask &rm, uint reg_degree, uint rm_size, uint lr1, uint lr2 ) {
@@ -586,7 +570,6 @@ uint PhaseConservativeCoalesce::compute_separating_interferences(Node *dst_copy,
return reg_degree;
}
-//------------------------------update_ifg-------------------------------------
void PhaseConservativeCoalesce::update_ifg(uint lr1, uint lr2, IndexSet *n_lr1, IndexSet *n_lr2) {
// Some original neighbors of lr1 might have gone away
// because the constrained register mask prevented them.
@@ -616,7 +599,6 @@ void PhaseConservativeCoalesce::update_ifg(uint lr1, uint lr2, IndexSet *n_lr1,
lrgs(neighbor).inc_degree( lrg1.compute_degree(lrgs(neighbor)) );
}
-//------------------------------record_bias------------------------------------
static void record_bias( const PhaseIFG *ifg, int lr1, int lr2 ) {
// Tag copy bias here
if( !ifg->lrgs(lr1)._copy_bias )
@@ -625,7 +607,6 @@ static void record_bias( const PhaseIFG *ifg, int lr1, int lr2 ) {
ifg->lrgs(lr2)._copy_bias = lr1;
}
-//------------------------------copy_copy--------------------------------------
// See if I can coalesce a series of multiple copies together. I need the
// final dest copy and the original src copy. They can be the same Node.
// Compute the compatible register masks.
@@ -785,7 +766,6 @@ bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block
return true;
}
-//------------------------------coalesce---------------------------------------
// Conservative (but pessimistic) copy coalescing of a single block
void PhaseConservativeCoalesce::coalesce( Block *b ) {
// Bail out on infrequent blocks
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index f7cadda849b..39ebf9d0483 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -2136,7 +2136,9 @@ void Compile::Optimize() {
//------------------------------Code_Gen---------------------------------------
// Given a graph, generate code for it
void Compile::Code_Gen() {
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
// Perform instruction selection. You might think we could reclaim Matcher
// memory PDQ, but actually the Matcher is used in generating spill code.
@@ -2148,12 +2150,11 @@ void Compile::Code_Gen() {
// nodes. Mapping is only valid at the root of each matched subtree.
NOT_PRODUCT( verify_graph_edges(); )
- Node_List proj_list;
- Matcher m(proj_list);
- _matcher = &m;
+ Matcher matcher;
+ _matcher = &matcher;
{
TracePhase t2("matcher", &_t_matcher, true);
- m.match();
+ matcher.match();
}
// In debug mode can dump m._nodes.dump() for mapping of ideal to machine
// nodes. Mapping is only valid at the root of each matched subtree.
@@ -2161,31 +2162,26 @@ void Compile::Code_Gen() {
// If you have too many nodes, or if matching has failed, bail out
check_node_count(0, "out of nodes matching instructions");
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
// Build a proper-looking CFG
- PhaseCFG cfg(node_arena(), root(), m);
+ PhaseCFG cfg(node_arena(), root(), matcher);
_cfg = &cfg;
{
NOT_PRODUCT( TracePhase t2("scheduler", &_t_scheduler, TimeCompiler); )
- cfg.Dominators();
- if (failing()) return;
-
- NOT_PRODUCT( verify_graph_edges(); )
-
- cfg.Estimate_Block_Frequency();
- cfg.GlobalCodeMotion(m,unique(),proj_list);
- if (failing()) return;
+ bool success = cfg.do_global_code_motion();
+ if (!success) {
+ return;
+ }
print_method(PHASE_GLOBAL_CODE_MOTION, 2);
-
NOT_PRODUCT( verify_graph_edges(); )
-
debug_only( cfg.verify(); )
}
- NOT_PRODUCT( verify_graph_edges(); )
- PhaseChaitin regalloc(unique(), cfg, m);
+ PhaseChaitin regalloc(unique(), cfg, matcher);
_regalloc = ®alloc;
{
TracePhase t2("regalloc", &_t_registerAllocation, true);
@@ -2206,7 +2202,7 @@ void Compile::Code_Gen() {
// can now safely remove it.
{
NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
- cfg.remove_empty();
+ cfg.remove_empty_blocks();
if (do_freq_based_layout()) {
PhaseBlockLayout layout(cfg);
} else {
@@ -2253,38 +2249,50 @@ void Compile::dump_asm(int *pcs, uint pc_limit) {
_regalloc->dump_frame();
Node *n = NULL;
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- if (VMThread::should_terminate()) { cut_short = true; break; }
- Block *b = _cfg->_blocks[i];
- if (b->is_connector() && !Verbose) continue;
- n = b->_nodes[0];
- if (pcs && n->_idx < pc_limit)
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ if (VMThread::should_terminate()) {
+ cut_short = true;
+ break;
+ }
+ Block* block = _cfg->get_block(i);
+ if (block->is_connector() && !Verbose) {
+ continue;
+ }
+ n = block->_nodes[0];
+ if (pcs && n->_idx < pc_limit) {
tty->print("%3.3x ", pcs[n->_idx]);
- else
+ } else {
tty->print(" ");
- b->dump_head(_cfg);
- if (b->is_connector()) {
+ }
+ block->dump_head(_cfg);
+ if (block->is_connector()) {
tty->print_cr(" # Empty connector block");
- } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
+ } else if (block->num_preds() == 2 && block->pred(1)->is_CatchProj() && block->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
tty->print_cr(" # Block is sole successor of call");
}
// For all instructions
Node *delay = NULL;
- for( uint j = 0; j_nodes.size(); j++ ) {
- if (VMThread::should_terminate()) { cut_short = true; break; }
- n = b->_nodes[j];
+ for (uint j = 0; j < block->_nodes.size(); j++) {
+ if (VMThread::should_terminate()) {
+ cut_short = true;
+ break;
+ }
+ n = block->_nodes[j];
if (valid_bundle_info(n)) {
- Bundle *bundle = node_bundling(n);
+ Bundle* bundle = node_bundling(n);
if (bundle->used_in_unconditional_delay()) {
delay = n;
continue;
}
- if (bundle->starts_bundle())
+ if (bundle->starts_bundle()) {
starts_bundle = '+';
+ }
}
- if (WizardMode) n->dump();
+ if (WizardMode) {
+ n->dump();
+ }
if( !n->is_Region() && // Dont print in the Assembly
!n->is_Phi() && // a few noisely useless nodes
diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp
index b64e291e7ca..9a98aef28e9 100644
--- a/hotspot/src/share/vm/opto/domgraph.cpp
+++ b/hotspot/src/share/vm/opto/domgraph.cpp
@@ -32,9 +32,6 @@
// Portions of code courtesy of Clifford Click
-// Optimization - Graph Style
-
-//------------------------------Tarjan-----------------------------------------
// A data structure that holds all the information needed to find dominators.
struct Tarjan {
Block *_block; // Basic block for this info
@@ -60,23 +57,21 @@ struct Tarjan {
};
-//------------------------------Dominator--------------------------------------
// Compute the dominator tree of the CFG. The CFG must already have been
// constructed. This is the Lengauer & Tarjan O(E-alpha(E,V)) algorithm.
-void PhaseCFG::Dominators( ) {
+void PhaseCFG::build_dominator_tree() {
// Pre-grow the blocks array, prior to the ResourceMark kicking in
- _blocks.map(_num_blocks,0);
+ _blocks.map(number_of_blocks(), 0);
ResourceMark rm;
// Setup mappings from my Graph to Tarjan's stuff and back
// Note: Tarjan uses 1-based arrays
- Tarjan *tarjan = NEW_RESOURCE_ARRAY(Tarjan,_num_blocks+1);
+ Tarjan* tarjan = NEW_RESOURCE_ARRAY(Tarjan, number_of_blocks() + 1);
// Tarjan's algorithm, almost verbatim:
// Step 1:
- _rpo_ctr = _num_blocks;
- uint dfsnum = DFS( tarjan );
- if( dfsnum-1 != _num_blocks ) {// Check for unreachable loops!
+ uint dfsnum = do_DFS(tarjan, number_of_blocks());
+ if (dfsnum - 1 != number_of_blocks()) { // Check for unreachable loops!
// If the returned dfsnum does not match the number of blocks, then we
// must have some unreachable loops. These can be made at any time by
// IterGVN. They are cleaned up by CCP or the loop opts, but the last
@@ -93,14 +88,13 @@ void PhaseCFG::Dominators( ) {
C->record_method_not_compilable("unreachable loop");
return;
}
- _blocks._cnt = _num_blocks;
+ _blocks._cnt = number_of_blocks();
// Tarjan is using 1-based arrays, so these are some initialize flags
tarjan[0]._size = tarjan[0]._semi = 0;
tarjan[0]._label = &tarjan[0];
- uint i;
- for( i=_num_blocks; i>=2; i-- ) { // For all vertices in DFS order
+ for (uint i = number_of_blocks(); i >= 2; i--) { // For all vertices in DFS order
Tarjan *w = &tarjan[i]; // Get vertex from DFS
// Step 2:
@@ -130,19 +124,19 @@ void PhaseCFG::Dominators( ) {
}
// Step 4:
- for( i=2; i <= _num_blocks; i++ ) {
+ for (uint i = 2; i <= number_of_blocks(); i++) {
Tarjan *w = &tarjan[i];
if( w->_dom != &tarjan[w->_semi] )
w->_dom = w->_dom->_dom;
w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later
}
// No immediate dominator for the root
- Tarjan *w = &tarjan[_broot->_pre_order];
+ Tarjan *w = &tarjan[get_root_block()->_pre_order];
w->_dom = NULL;
w->_dom_next = w->_dom_child = NULL; // Initialize for building tree later
// Convert the dominator tree array into my kind of graph
- for( i=1; i<=_num_blocks;i++){// For all Tarjan vertices
+ for(uint i = 1; i <= number_of_blocks(); i++){ // For all Tarjan vertices
Tarjan *t = &tarjan[i]; // Handy access
Tarjan *tdom = t->_dom; // Handy access to immediate dominator
if( tdom ) { // Root has no immediate dominator
@@ -152,11 +146,10 @@ void PhaseCFG::Dominators( ) {
} else
t->_block->_idom = NULL; // Root
}
- w->setdepth( _num_blocks+1 ); // Set depth in dominator tree
+ w->setdepth(number_of_blocks() + 1); // Set depth in dominator tree
}
-//----------------------------Block_Stack--------------------------------------
class Block_Stack {
private:
struct Block_Descr {
@@ -214,7 +207,6 @@ class Block_Stack {
}
};
-//-------------------------most_frequent_successor-----------------------------
// Find the index into the b->succs[] array of the most frequent successor.
uint Block_Stack::most_frequent_successor( Block *b ) {
uint freq_idx = 0;
@@ -258,40 +250,38 @@ uint Block_Stack::most_frequent_successor( Block *b ) {
return freq_idx;
}
-//------------------------------DFS--------------------------------------------
// Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup
// 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent.
-uint PhaseCFG::DFS( Tarjan *tarjan ) {
- Block *b = _broot;
+uint PhaseCFG::do_DFS(Tarjan *tarjan, uint rpo_counter) {
+ Block* root_block = get_root_block();
uint pre_order = 1;
- // Allocate stack of size _num_blocks+1 to avoid frequent realloc
- Block_Stack bstack(tarjan, _num_blocks+1);
+ // Allocate stack of size number_of_blocks() + 1 to avoid frequent realloc
+ Block_Stack bstack(tarjan, number_of_blocks() + 1);
// Push on stack the state for the first block
- bstack.push(pre_order, b);
+ bstack.push(pre_order, root_block);
++pre_order;
while (bstack.is_nonempty()) {
if (!bstack.last_successor()) {
// Walk over all successors in pre-order (DFS).
- Block *s = bstack.next_successor();
- if (s->_pre_order == 0) { // Check for no-pre-order, not-visited
+ Block* next_block = bstack.next_successor();
+ if (next_block->_pre_order == 0) { // Check for no-pre-order, not-visited
// Push on stack the state of successor
- bstack.push(pre_order, s);
+ bstack.push(pre_order, next_block);
++pre_order;
}
}
else {
// Build a reverse post-order in the CFG _blocks array
Block *stack_top = bstack.pop();
- stack_top->_rpo = --_rpo_ctr;
+ stack_top->_rpo = --rpo_counter;
_blocks.map(stack_top->_rpo, stack_top);
}
}
return pre_order;
}
-//------------------------------COMPRESS---------------------------------------
void Tarjan::COMPRESS()
{
assert( _ancestor != 0, "" );
@@ -303,14 +293,12 @@ void Tarjan::COMPRESS()
}
}
-//------------------------------EVAL-------------------------------------------
Tarjan *Tarjan::EVAL() {
if( !_ancestor ) return _label;
COMPRESS();
return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
}
-//------------------------------LINK-------------------------------------------
void Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) {
Tarjan *s = w;
while( w->_label->_semi < s->_child->_label->_semi ) {
@@ -333,7 +321,6 @@ void Tarjan::LINK( Tarjan *w, Tarjan *tarjan0 ) {
}
}
-//------------------------------setdepth---------------------------------------
void Tarjan::setdepth( uint stack_size ) {
Tarjan **top = NEW_RESOURCE_ARRAY(Tarjan*, stack_size);
Tarjan **next = top;
@@ -362,8 +349,7 @@ void Tarjan::setdepth( uint stack_size ) {
} while (last < top);
}
-//*********************** DOMINATORS ON THE SEA OF NODES***********************
-//------------------------------NTarjan----------------------------------------
+// Compute dominators on the Sea of Nodes form
// A data structure that holds all the information needed to find dominators.
struct NTarjan {
Node *_control; // Control node associated with this info
@@ -396,7 +382,6 @@ struct NTarjan {
#endif
};
-//------------------------------Dominator--------------------------------------
// Compute the dominator tree of the sea of nodes. This version walks all CFG
// nodes (using the is_CFG() call) and places them in a dominator tree. Thus,
// it needs a count of the CFG nodes for the mapping table. This is the
@@ -517,7 +502,6 @@ void PhaseIdealLoop::Dominators() {
}
}
-//------------------------------DFS--------------------------------------------
// Perform DFS search. Setup 'vertex' as DFS to vertex mapping. Setup
// 'semi' as vertex to DFS mapping. Set 'parent' to DFS parent.
int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uint *dfsorder) {
@@ -560,7 +544,6 @@ int NTarjan::DFS( NTarjan *ntarjan, VectorSet &visited, PhaseIdealLoop *pil, uin
return dfsnum;
}
-//------------------------------COMPRESS---------------------------------------
void NTarjan::COMPRESS()
{
assert( _ancestor != 0, "" );
@@ -572,14 +555,12 @@ void NTarjan::COMPRESS()
}
}
-//------------------------------EVAL-------------------------------------------
NTarjan *NTarjan::EVAL() {
if( !_ancestor ) return _label;
COMPRESS();
return (_ancestor->_label->_semi >= _label->_semi) ? _label : _ancestor->_label;
}
-//------------------------------LINK-------------------------------------------
void NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) {
NTarjan *s = w;
while( w->_label->_semi < s->_child->_label->_semi ) {
@@ -602,7 +583,6 @@ void NTarjan::LINK( NTarjan *w, NTarjan *ntarjan0 ) {
}
}
-//------------------------------setdepth---------------------------------------
void NTarjan::setdepth( uint stack_size, uint *dom_depth ) {
NTarjan **top = NEW_RESOURCE_ARRAY(NTarjan*, stack_size);
NTarjan **next = top;
@@ -631,7 +611,6 @@ void NTarjan::setdepth( uint stack_size, uint *dom_depth ) {
} while (last < top);
}
-//------------------------------dump-------------------------------------------
#ifndef PRODUCT
void NTarjan::dump(int offset) const {
// Dump the data from this node
diff --git a/hotspot/src/share/vm/opto/gcm.cpp b/hotspot/src/share/vm/opto/gcm.cpp
index 9ded635f65f..3e95535b73e 100644
--- a/hotspot/src/share/vm/opto/gcm.cpp
+++ b/hotspot/src/share/vm/opto/gcm.cpp
@@ -121,27 +121,30 @@ void PhaseCFG::replace_block_proj_ctrl( Node *n ) {
//------------------------------schedule_pinned_nodes--------------------------
// Set the basic block for Nodes pinned into blocks
-void PhaseCFG::schedule_pinned_nodes( VectorSet &visited ) {
+void PhaseCFG::schedule_pinned_nodes(VectorSet &visited) {
// Allocate node stack of size C->unique()+8 to avoid frequent realloc
- GrowableArray spstack(C->unique()+8);
+ GrowableArray spstack(C->unique() + 8);
spstack.push(_root);
- while ( spstack.is_nonempty() ) {
- Node *n = spstack.pop();
- if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
- if( n->pinned() && !has_block(n)) { // Pinned? Nail it down!
- assert( n->in(0), "pinned Node must have Control" );
+ while (spstack.is_nonempty()) {
+ Node* node = spstack.pop();
+ if (!visited.test_set(node->_idx)) { // Test node and flag it as visited
+ if (node->pinned() && !has_block(node)) { // Pinned? Nail it down!
+ assert(node->in(0), "pinned Node must have Control");
// Before setting block replace block_proj control edge
- replace_block_proj_ctrl(n);
- Node *input = n->in(0);
+ replace_block_proj_ctrl(node);
+ Node* input = node->in(0);
while (!input->is_block_start()) {
input = input->in(0);
}
- Block *b = get_block_for_node(input); // Basic block of controlling input
- schedule_node_into_block(n, b);
+ Block* block = get_block_for_node(input); // Basic block of controlling input
+ schedule_node_into_block(node, block);
}
- for( int i = n->req() - 1; i >= 0; --i ) { // For all inputs
- if( n->in(i) != NULL )
- spstack.push(n->in(i));
+
+ // process all inputs that are non NULL
+ for (int i = node->req() - 1; i >= 0; --i) {
+ if (node->in(i) != NULL) {
+ spstack.push(node->in(i));
+ }
}
}
}
@@ -205,32 +208,29 @@ static Block* find_deepest_input(Node* n, const PhaseCFG* cfg) {
// which all their inputs occur.
bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
// Allocate stack with enough space to avoid frequent realloc
- Node_Stack nstack(roots.Size() + 8); // (unique >> 1) + 24 from Java2D stats
- // roots.push(_root); _root will be processed among C->top() inputs
+ Node_Stack nstack(roots.Size() + 8);
+ // _root will be processed among C->top() inputs
roots.push(C->top());
visited.set(C->top()->_idx);
while (roots.size() != 0) {
// Use local variables nstack_top_n & nstack_top_i to cache values
// on stack's top.
- Node *nstack_top_n = roots.pop();
- uint nstack_top_i = 0;
-//while_nstack_nonempty:
- while (true) {
- // Get parent node and next input's index from stack's top.
- Node *n = nstack_top_n;
- uint i = nstack_top_i;
+ Node* parent_node = roots.pop();
+ uint input_index = 0;
- if (i == 0) {
+ while (true) {
+ if (input_index == 0) {
// Fixup some control. Constants without control get attached
// to root and nodes that use is_block_proj() nodes should be attached
// to the region that starts their block.
- const Node *in0 = n->in(0);
- if (in0 != NULL) { // Control-dependent?
- replace_block_proj_ctrl(n);
- } else { // n->in(0) == NULL
- if (n->req() == 1) { // This guy is a constant with NO inputs?
- n->set_req(0, _root);
+ const Node* control_input = parent_node->in(0);
+ if (control_input != NULL) {
+ replace_block_proj_ctrl(parent_node);
+ } else {
+ // Is a constant with NO inputs?
+ if (parent_node->req() == 1) {
+ parent_node->set_req(0, _root);
}
}
}
@@ -239,37 +239,47 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
// input is already in a block we quit following inputs (to avoid
// cycles). Instead we put that Node on a worklist to be handled
// later (since IT'S inputs may not have a block yet).
- bool done = true; // Assume all n's inputs will be processed
- while (i < n->len()) { // For all inputs
- Node *in = n->in(i); // Get input
- ++i;
- if (in == NULL) continue; // Ignore NULL, missing inputs
+
+ // Assume all n's inputs will be processed
+ bool done = true;
+
+ while (input_index < parent_node->len()) {
+ Node* in = parent_node->in(input_index++);
+ if (in == NULL) {
+ continue;
+ }
+
int is_visited = visited.test_set(in->_idx);
- if (!has_block(in)) { // Missing block selection?
+ if (!has_block(in)) {
if (is_visited) {
- // assert( !visited.test(in->_idx), "did not schedule early" );
return false;
}
- nstack.push(n, i); // Save parent node and next input's index.
- nstack_top_n = in; // Process current input now.
- nstack_top_i = 0;
- done = false; // Not all n's inputs processed.
- break; // continue while_nstack_nonempty;
- } else if (!is_visited) { // Input not yet visited?
- roots.push(in); // Visit this guy later, using worklist
+ // Save parent node and next input's index.
+ nstack.push(parent_node, input_index);
+ // Process current input now.
+ parent_node = in;
+ input_index = 0;
+ // Not all n's inputs processed.
+ done = false;
+ break;
+ } else if (!is_visited) {
+ // Visit this guy later, using worklist
+ roots.push(in);
}
}
+
if (done) {
// All of n's inputs have been processed, complete post-processing.
// Some instructions are pinned into a block. These include Region,
// Phi, Start, Return, and other control-dependent instructions and
// any projections which depend on them.
- if (!n->pinned()) {
+ if (!parent_node->pinned()) {
// Set earliest legal block.
- map_node_to_block(n, find_deepest_input(n, this));
+ Block* earliest_block = find_deepest_input(parent_node, this);
+ map_node_to_block(parent_node, earliest_block);
} else {
- assert(get_block_for_node(n) == get_block_for_node(n->in(0)), "Pinned Node should be at the same block as its control edge");
+ assert(get_block_for_node(parent_node) == get_block_for_node(parent_node->in(0)), "Pinned Node should be at the same block as its control edge");
}
if (nstack.is_empty()) {
@@ -278,12 +288,12 @@ bool PhaseCFG::schedule_early(VectorSet &visited, Node_List &roots) {
break;
}
// Get saved parent node and next input's index.
- nstack_top_n = nstack.node();
- nstack_top_i = nstack.index();
+ parent_node = nstack.node();
+ input_index = nstack.index();
nstack.pop();
- } // if (done)
- } // while (true)
- } // while (roots.size() != 0)
+ }
+ }
+ }
return true;
}
@@ -847,7 +857,7 @@ Node *Node_Backward_Iterator::next() {
//------------------------------ComputeLatenciesBackwards----------------------
// Compute the latency of all the instructions.
-void PhaseCFG::ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack) {
+void PhaseCFG::compute_latencies_backwards(VectorSet &visited, Node_List &stack) {
#ifndef PRODUCT
if (trace_opto_pipelining())
tty->print("\n#---- ComputeLatenciesBackwards ----\n");
@@ -870,31 +880,34 @@ void PhaseCFG::partial_latency_of_defs(Node *n) {
// Set the latency for this instruction
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print("# latency_to_inputs: node_latency[%d] = %d for node",
- n->_idx, _node_latency->at_grow(n->_idx));
+ tty->print("# latency_to_inputs: node_latency[%d] = %d for node", n->_idx, get_latency_for_node(n));
dump();
}
#endif
- if (n->is_Proj())
+ if (n->is_Proj()) {
n = n->in(0);
+ }
- if (n->is_Root())
+ if (n->is_Root()) {
return;
+ }
uint nlen = n->len();
- uint use_latency = _node_latency->at_grow(n->_idx);
+ uint use_latency = get_latency_for_node(n);
uint use_pre_order = get_block_for_node(n)->_pre_order;
- for ( uint j=0; jin(j);
- if (!def || def == n)
+ if (!def || def == n) {
continue;
+ }
// Walk backwards thru projections
- if (def->is_Proj())
+ if (def->is_Proj()) {
def = def->in(0);
+ }
#ifndef PRODUCT
if (trace_opto_pipelining()) {
@@ -907,22 +920,20 @@ void PhaseCFG::partial_latency_of_defs(Node *n) {
Block *def_block = get_block_for_node(def);
uint def_pre_order = def_block ? def_block->_pre_order : 0;
- if ( (use_pre_order < def_pre_order) ||
- (use_pre_order == def_pre_order && n->is_Phi()) )
+ if ((use_pre_order < def_pre_order) || (use_pre_order == def_pre_order && n->is_Phi())) {
continue;
+ }
uint delta_latency = n->latency(j);
uint current_latency = delta_latency + use_latency;
- if (_node_latency->at_grow(def->_idx) < current_latency) {
- _node_latency->at_put_grow(def->_idx, current_latency);
+ if (get_latency_for_node(def) < current_latency) {
+ set_latency_for_node(def, current_latency);
}
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print_cr("# %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d",
- use_latency, j, delta_latency, current_latency, def->_idx,
- _node_latency->at_grow(def->_idx));
+ tty->print_cr("# %d + edge_latency(%d) == %d -> %d, node_latency[%d] = %d", use_latency, j, delta_latency, current_latency, def->_idx, get_latency_for_node(def));
}
#endif
}
@@ -957,7 +968,7 @@ int PhaseCFG::latency_from_use(Node *n, const Node *def, Node *use) {
return 0;
uint nlen = use->len();
- uint nl = _node_latency->at_grow(use->_idx);
+ uint nl = get_latency_for_node(use);
for ( uint j=0; jin(j) == n) {
@@ -992,8 +1003,7 @@ void PhaseCFG::latency_from_uses(Node *n) {
// Set the latency for this instruction
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print("# latency_from_outputs: node_latency[%d] = %d for node",
- n->_idx, _node_latency->at_grow(n->_idx));
+ tty->print("# latency_from_outputs: node_latency[%d] = %d for node", n->_idx, get_latency_for_node(n));
dump();
}
#endif
@@ -1006,7 +1016,7 @@ void PhaseCFG::latency_from_uses(Node *n) {
if (latency < l) latency = l;
}
- _node_latency->at_put_grow(n->_idx, latency);
+ set_latency_for_node(n, latency);
}
//------------------------------hoist_to_cheaper_block-------------------------
@@ -1016,9 +1026,9 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) {
const double delta = 1+PROB_UNLIKELY_MAG(4);
Block* least = LCA;
double least_freq = least->_freq;
- uint target = _node_latency->at_grow(self->_idx);
- uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx);
- uint end_latency = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
+ uint target = get_latency_for_node(self);
+ uint start_latency = get_latency_for_node(LCA->_nodes[0]);
+ uint end_latency = get_latency_for_node(LCA->_nodes[LCA->end_idx()]);
bool in_latency = (target <= start_latency);
const Block* root_block = get_block_for_node(_root);
@@ -1035,8 +1045,7 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) {
#ifndef PRODUCT
if (trace_opto_pipelining()) {
- tty->print("# Find cheaper block for latency %d: ",
- _node_latency->at_grow(self->_idx));
+ tty->print("# Find cheaper block for latency %d: ", get_latency_for_node(self));
self->dump();
tty->print_cr("# B%d: start latency for [%4d]=%d, end latency for [%4d]=%d, freq=%g",
LCA->_pre_order,
@@ -1065,9 +1074,9 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) {
if (mach && LCA == root_block)
break;
- uint start_lat = _node_latency->at_grow(LCA->_nodes[0]->_idx);
+ uint start_lat = get_latency_for_node(LCA->_nodes[0]);
uint end_idx = LCA->end_idx();
- uint end_lat = _node_latency->at_grow(LCA->_nodes[end_idx]->_idx);
+ uint end_lat = get_latency_for_node(LCA->_nodes[end_idx]);
double LCA_freq = LCA->_freq;
#ifndef PRODUCT
if (trace_opto_pipelining()) {
@@ -1109,7 +1118,7 @@ Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) {
tty->print_cr("# Change latency for [%4d] from %d to %d", self->_idx, target, end_latency);
}
#endif
- _node_latency->at_put_grow(self->_idx, end_latency);
+ set_latency_for_node(self, end_latency);
partial_latency_of_defs(self);
}
@@ -1255,7 +1264,7 @@ void PhaseCFG::schedule_late(VectorSet &visited, Node_List &stack) {
} // end ScheduleLate
//------------------------------GlobalCodeMotion-------------------------------
-void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_list ) {
+void PhaseCFG::global_code_motion() {
ResourceMark rm;
#ifndef PRODUCT
@@ -1265,21 +1274,22 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
#endif
// Initialize the node to block mapping for things on the proj_list
- for (uint i = 0; i < proj_list.size(); i++) {
- unmap_node_from_block(proj_list[i]);
+ for (uint i = 0; i < _matcher.number_of_projections(); i++) {
+ unmap_node_from_block(_matcher.get_projection(i));
}
// Set the basic block for Nodes pinned into blocks
- Arena *a = Thread::current()->resource_area();
- VectorSet visited(a);
- schedule_pinned_nodes( visited );
+ Arena* arena = Thread::current()->resource_area();
+ VectorSet visited(arena);
+ schedule_pinned_nodes(visited);
// Find the earliest Block any instruction can be placed in. Some
// instructions are pinned into Blocks. Unpinned instructions can
// appear in last block in which all their inputs occur.
visited.Clear();
- Node_List stack(a);
- stack.map( (unique >> 1) + 16, NULL); // Pre-grow the list
+ Node_List stack(arena);
+ // Pre-grow the list
+ stack.map((C->unique() >> 1) + 16, NULL);
if (!schedule_early(visited, stack)) {
// Bailout without retry
C->record_method_not_compilable("early schedule failed");
@@ -1287,29 +1297,25 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
}
// Build Def-Use edges.
- proj_list.push(_root); // Add real root as another root
- proj_list.pop();
-
// Compute the latency information (via backwards walk) for all the
// instructions in the graph
_node_latency = new GrowableArray(); // resource_area allocation
- if( C->do_scheduling() )
- ComputeLatenciesBackwards(visited, stack);
+ if (C->do_scheduling()) {
+ compute_latencies_backwards(visited, stack);
+ }
// Now schedule all codes as LATE as possible. This is the LCA in the
// dominator tree of all USES of a value. Pick the block with the least
// loop nesting depth that is lowest in the dominator tree.
// ( visited.Clear() called in schedule_late()->Node_Backward_Iterator() )
schedule_late(visited, stack);
- if( C->failing() ) {
+ if (C->failing()) {
// schedule_late fails only when graph is incorrect.
assert(!VerifyGraphEdges, "verification should have failed");
return;
}
- unique = C->unique();
-
#ifndef PRODUCT
if (trace_opto_pipelining()) {
tty->print("\n---- Detect implicit null checks ----\n");
@@ -1332,10 +1338,11 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
// By reversing the loop direction we get a very minor gain on mpegaudio.
// Feel free to revert to a forward loop for clarity.
// for( int i=0; i < (int)matcher._null_check_tests.size(); i+=2 ) {
- for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) {
- Node *proj = matcher._null_check_tests[i ];
- Node *val = matcher._null_check_tests[i+1];
- get_block_for_node(proj)->implicit_null_check(this, proj, val, allowed_reasons);
+ for (int i = _matcher._null_check_tests.size() - 2; i >= 0; i -= 2) {
+ Node* proj = _matcher._null_check_tests[i];
+ Node* val = _matcher._null_check_tests[i + 1];
+ Block* block = get_block_for_node(proj);
+ block->implicit_null_check(this, proj, val, allowed_reasons);
// The implicit_null_check will only perform the transformation
// if the null branch is truly uncommon, *and* it leads to an
// uncommon trap. Combined with the too_many_traps guards
@@ -1352,11 +1359,11 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
// Schedule locally. Right now a simple topological sort.
// Later, do a real latency aware scheduler.
- uint max_idx = C->unique();
- GrowableArray ready_cnt(max_idx, max_idx, -1);
+ GrowableArray ready_cnt(C->unique(), C->unique(), -1);
visited.Clear();
- for (uint i = 0; i < _num_blocks; i++) {
- if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ if (!block->schedule_local(this, _matcher, ready_cnt, visited)) {
if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
C->record_method_not_compilable("local schedule failed");
}
@@ -1366,15 +1373,17 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
// If we inserted any instructions between a Call and his CatchNode,
// clone the instructions on all paths below the Catch.
- for (uint i = 0; i < _num_blocks; i++) {
- _blocks[i]->call_catch_cleanup(this, C);
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ block->call_catch_cleanup(this, C);
}
#ifndef PRODUCT
if (trace_opto_pipelining()) {
tty->print("\n---- After GlobalCodeMotion ----\n");
- for (uint i = 0; i < _num_blocks; i++) {
- _blocks[i]->dump();
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ block->dump();
}
}
#endif
@@ -1382,10 +1391,29 @@ void PhaseCFG::GlobalCodeMotion( Matcher &matcher, uint unique, Node_List &proj_
_node_latency = (GrowableArray *)0xdeadbeef;
}
+bool PhaseCFG::do_global_code_motion() {
+
+ build_dominator_tree();
+ if (C->failing()) {
+ return false;
+ }
+
+ NOT_PRODUCT( C->verify_graph_edges(); )
+
+ estimate_block_frequency();
+
+ global_code_motion();
+
+ if (C->failing()) {
+ return false;
+ }
+
+ return true;
+}
//------------------------------Estimate_Block_Frequency-----------------------
// Estimate block frequencies based on IfNode probabilities.
-void PhaseCFG::Estimate_Block_Frequency() {
+void PhaseCFG::estimate_block_frequency() {
// Force conditional branches leading to uncommon traps to be unlikely,
// not because we get to the uncommon_trap with less relative frequency,
@@ -1393,7 +1421,7 @@ void PhaseCFG::Estimate_Block_Frequency() {
// there once.
if (C->do_freq_based_layout()) {
Block_List worklist;
- Block* root_blk = _blocks[0];
+ Block* root_blk = get_block(0);
for (uint i = 1; i < root_blk->num_preds(); i++) {
Block *pb = get_block_for_node(root_blk->pred(i));
if (pb->has_uncommon_code()) {
@@ -1402,7 +1430,9 @@ void PhaseCFG::Estimate_Block_Frequency() {
}
while (worklist.size() > 0) {
Block* uct = worklist.pop();
- if (uct == _broot) continue;
+ if (uct == get_root_block()) {
+ continue;
+ }
for (uint i = 1; i < uct->num_preds(); i++) {
Block *pb = get_block_for_node(uct->pred(i));
if (pb->_num_succs == 1) {
@@ -1426,12 +1456,12 @@ void PhaseCFG::Estimate_Block_Frequency() {
_root_loop->scale_freq();
// Save outmost loop frequency for LRG frequency threshold
- _outer_loop_freq = _root_loop->outer_loop_freq();
+ _outer_loop_frequency = _root_loop->outer_loop_freq();
// force paths ending at uncommon traps to be infrequent
if (!C->do_freq_based_layout()) {
Block_List worklist;
- Block* root_blk = _blocks[0];
+ Block* root_blk = get_block(0);
for (uint i = 1; i < root_blk->num_preds(); i++) {
Block *pb = get_block_for_node(root_blk->pred(i));
if (pb->has_uncommon_code()) {
@@ -1451,8 +1481,8 @@ void PhaseCFG::Estimate_Block_Frequency() {
}
#ifdef ASSERT
- for (uint i = 0; i < _num_blocks; i++ ) {
- Block *b = _blocks[i];
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* b = get_block(i);
assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requires meaningful block frequency");
}
#endif
@@ -1476,16 +1506,16 @@ void PhaseCFG::Estimate_Block_Frequency() {
CFGLoop* PhaseCFG::create_loop_tree() {
#ifdef ASSERT
- assert( _blocks[0] == _broot, "" );
- for (uint i = 0; i < _num_blocks; i++ ) {
- Block *b = _blocks[i];
+ assert(get_block(0) == get_root_block(), "first block should be root block");
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
// Check that _loop field are clear...we could clear them if not.
- assert(b->_loop == NULL, "clear _loop expected");
+ assert(block->_loop == NULL, "clear _loop expected");
// Sanity check that the RPO numbering is reflected in the _blocks array.
// It doesn't have to be for the loop tree to be built, but if it is not,
// then the blocks have been reordered since dom graph building...which
// may question the RPO numbering
- assert(b->_rpo == i, "unexpected reverse post order number");
+ assert(block->_rpo == i, "unexpected reverse post order number");
}
#endif
@@ -1495,11 +1525,11 @@ CFGLoop* PhaseCFG::create_loop_tree() {
Block_List worklist;
// Assign blocks to loops
- for(uint i = _num_blocks - 1; i > 0; i-- ) { // skip Root block
- Block *b = _blocks[i];
+ for(uint i = number_of_blocks() - 1; i > 0; i-- ) { // skip Root block
+ Block* block = get_block(i);
- if (b->head()->is_Loop()) {
- Block* loop_head = b;
+ if (block->head()->is_Loop()) {
+ Block* loop_head = block;
assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
Node* tail_n = loop_head->pred(LoopNode::LoopBackControl);
Block* tail = get_block_for_node(tail_n);
@@ -1533,23 +1563,23 @@ CFGLoop* PhaseCFG::create_loop_tree() {
// Create a member list for each loop consisting
// of both blocks and (immediate child) loops.
- for (uint i = 0; i < _num_blocks; i++) {
- Block *b = _blocks[i];
- CFGLoop* lp = b->_loop;
+ for (uint i = 0; i < number_of_blocks(); i++) {
+ Block* block = get_block(i);
+ CFGLoop* lp = block->_loop;
if (lp == NULL) {
// Not assigned to a loop. Add it to the method's pseudo loop.
- b->_loop = root_loop;
+ block->_loop = root_loop;
lp = root_loop;
}
- if (lp == root_loop || b != lp->head()) { // loop heads are already members
- lp->add_member(b);
+ if (lp == root_loop || block != lp->head()) { // loop heads are already members
+ lp->add_member(block);
}
if (lp != root_loop) {
if (lp->parent() == NULL) {
// Not a nested loop. Make it a child of the method's pseudo loop.
root_loop->add_nested_loop(lp);
}
- if (b == lp->head()) {
+ if (block == lp->head()) {
// Add nested loop to member list of parent loop.
lp->parent()->add_member(lp);
}
diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
index 4330643b8b5..06cecaddbdc 100644
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
@@ -416,7 +416,7 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
if (C->cfg() != NULL) {
Block* block = C->cfg()->get_block_for_node(node);
if (block == NULL) {
- print_prop("block", C->cfg()->_blocks[0]->_pre_order);
+ print_prop("block", C->cfg()->get_block(0)->_pre_order);
} else {
print_prop("block", block->_pre_order);
}
@@ -637,10 +637,10 @@ void IdealGraphPrinter::walk_nodes(Node *start, bool edges, VectorSet* temp_set)
if (C->cfg() != NULL) {
// once we have a CFG there are some nodes that aren't really
// reachable but are in the CFG so add them here.
- for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
- Block *b = C->cfg()->_blocks[i];
- for (uint s = 0; s < b->_nodes.size(); s++) {
- nodeStack.push(b->_nodes[s]);
+ for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) {
+ Block* block = C->cfg()->get_block(i);
+ for (uint s = 0; s < block->_nodes.size(); s++) {
+ nodeStack.push(block->_nodes[s]);
}
}
}
@@ -698,24 +698,24 @@ void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, in
tail(EDGES_ELEMENT);
if (C->cfg() != NULL) {
head(CONTROL_FLOW_ELEMENT);
- for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
- Block *b = C->cfg()->_blocks[i];
+ for (uint i = 0; i < C->cfg()->number_of_blocks(); i++) {
+ Block* block = C->cfg()->get_block(i);
begin_head(BLOCK_ELEMENT);
- print_attr(BLOCK_NAME_PROPERTY, b->_pre_order);
+ print_attr(BLOCK_NAME_PROPERTY, block->_pre_order);
end_head();
head(SUCCESSORS_ELEMENT);
- for (uint s = 0; s < b->_num_succs; s++) {
+ for (uint s = 0; s < block->_num_succs; s++) {
begin_elem(SUCCESSOR_ELEMENT);
- print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order);
+ print_attr(BLOCK_NAME_PROPERTY, block->_succs[s]->_pre_order);
end_elem();
}
tail(SUCCESSORS_ELEMENT);
head(NODES_ELEMENT);
- for (uint s = 0; s < b->_nodes.size(); s++) {
+ for (uint s = 0; s < block->_nodes.size(); s++) {
begin_elem(NODE_ELEMENT);
- print_attr(NODE_ID_PROPERTY, get_node_id(b->_nodes[s]));
+ print_attr(NODE_ID_PROPERTY, get_node_id(block->_nodes[s]));
end_elem();
}
tail(NODES_ELEMENT);
diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp
index 82a8ea893e4..4455cd4571f 100644
--- a/hotspot/src/share/vm/opto/ifg.cpp
+++ b/hotspot/src/share/vm/opto/ifg.cpp
@@ -37,12 +37,9 @@
#include "opto/memnode.hpp"
#include "opto/opcodes.hpp"
-//=============================================================================
-//------------------------------IFG--------------------------------------------
PhaseIFG::PhaseIFG( Arena *arena ) : Phase(Interference_Graph), _arena(arena) {
}
-//------------------------------init-------------------------------------------
void PhaseIFG::init( uint maxlrg ) {
_maxlrg = maxlrg;
_yanked = new (_arena) VectorSet(_arena);
@@ -59,7 +56,6 @@ void PhaseIFG::init( uint maxlrg ) {
}
}
-//------------------------------add--------------------------------------------
// Add edge between vertices a & b. These are sorted (triangular matrix),
// then the smaller number is inserted in the larger numbered array.
int PhaseIFG::add_edge( uint a, uint b ) {
@@ -71,7 +67,6 @@ int PhaseIFG::add_edge( uint a, uint b ) {
return _adjs[a].insert( b );
}
-//------------------------------add_vector-------------------------------------
// Add an edge between 'a' and everything in the vector.
void PhaseIFG::add_vector( uint a, IndexSet *vec ) {
// IFG is triangular, so do the inserts where 'a' < 'b'.
@@ -86,7 +81,6 @@ void PhaseIFG::add_vector( uint a, IndexSet *vec ) {
}
}
-//------------------------------test-------------------------------------------
// Is there an edge between a and b?
int PhaseIFG::test_edge( uint a, uint b ) const {
// Sort a and b, so that a is larger
@@ -95,7 +89,6 @@ int PhaseIFG::test_edge( uint a, uint b ) const {
return _adjs[a].member(b);
}
-//------------------------------SquareUp---------------------------------------
// Convert triangular matrix to square matrix
void PhaseIFG::SquareUp() {
assert( !_is_square, "only on triangular" );
@@ -111,7 +104,6 @@ void PhaseIFG::SquareUp() {
_is_square = true;
}
-//------------------------------Compute_Effective_Degree-----------------------
// Compute effective degree in bulk
void PhaseIFG::Compute_Effective_Degree() {
assert( _is_square, "only on square" );
@@ -120,7 +112,6 @@ void PhaseIFG::Compute_Effective_Degree() {
lrgs(i).set_degree(effective_degree(i));
}
-//------------------------------test_edge_sq-----------------------------------
int PhaseIFG::test_edge_sq( uint a, uint b ) const {
assert( _is_square, "only on square" );
// Swap, so that 'a' has the lesser count. Then binary search is on
@@ -130,7 +121,6 @@ int PhaseIFG::test_edge_sq( uint a, uint b ) const {
return _adjs[a].member(b);
}
-//------------------------------Union------------------------------------------
// Union edges of B into A
void PhaseIFG::Union( uint a, uint b ) {
assert( _is_square, "only on square" );
@@ -146,7 +136,6 @@ void PhaseIFG::Union( uint a, uint b ) {
}
}
-//------------------------------remove_node------------------------------------
// Yank a Node and all connected edges from the IFG. Return a
// list of neighbors (edges) yanked.
IndexSet *PhaseIFG::remove_node( uint a ) {
@@ -165,7 +154,6 @@ IndexSet *PhaseIFG::remove_node( uint a ) {
return neighbors(a);
}
-//------------------------------re_insert--------------------------------------
// Re-insert a yanked Node.
void PhaseIFG::re_insert( uint a ) {
assert( _is_square, "only on square" );
@@ -180,7 +168,6 @@ void PhaseIFG::re_insert( uint a ) {
}
}
-//------------------------------compute_degree---------------------------------
// Compute the degree between 2 live ranges. If both live ranges are
// aligned-adjacent powers-of-2 then we use the MAX size. If either is
// mis-aligned (or for Fat-Projections, not-adjacent) then we have to
@@ -196,7 +183,6 @@ int LRG::compute_degree( LRG &l ) const {
return tmp;
}
-//------------------------------effective_degree-------------------------------
// Compute effective degree for this live range. If both live ranges are
// aligned-adjacent powers-of-2 then we use the MAX size. If either is
// mis-aligned (or for Fat-Projections, not-adjacent) then we have to
@@ -221,7 +207,6 @@ int PhaseIFG::effective_degree( uint lidx ) const {
#ifndef PRODUCT
-//------------------------------dump-------------------------------------------
void PhaseIFG::dump() const {
tty->print_cr("-- Interference Graph --%s--",
_is_square ? "square" : "triangular" );
@@ -260,7 +245,6 @@ void PhaseIFG::dump() const {
tty->print("\n");
}
-//------------------------------stats------------------------------------------
void PhaseIFG::stats() const {
ResourceMark rm;
int *h_cnt = NEW_RESOURCE_ARRAY(int,_maxlrg*2);
@@ -276,7 +260,6 @@ void PhaseIFG::stats() const {
tty->print_cr("");
}
-//------------------------------verify-----------------------------------------
void PhaseIFG::verify( const PhaseChaitin *pc ) const {
// IFG is square, sorted and no need for Find
for( uint i = 0; i < _maxlrg; i++ ) {
@@ -298,7 +281,6 @@ void PhaseIFG::verify( const PhaseChaitin *pc ) const {
}
#endif
-//------------------------------interfere_with_live----------------------------
// Interfere this register with everything currently live. Use the RegMasks
// to trim the set of possible interferences. Return a count of register-only
// interferences as an estimate of register pressure.
@@ -315,7 +297,6 @@ void PhaseChaitin::interfere_with_live( uint r, IndexSet *liveout ) {
_ifg->add_edge( r, l );
}
-//------------------------------build_ifg_virtual------------------------------
// Actually build the interference graph. Uses virtual registers only, no
// physical register masks. This allows me to be very aggressive when
// coalescing copies. Some of this aggressiveness will have to be undone
@@ -325,9 +306,9 @@ void PhaseChaitin::interfere_with_live( uint r, IndexSet *liveout ) {
void PhaseChaitin::build_ifg_virtual( ) {
// For all blocks (in any order) do...
- for( uint i=0; i<_cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- IndexSet *liveout = _live->live(b);
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
+ IndexSet* liveout = _live->live(block);
// The IFG is built by a single reverse pass over each basic block.
// Starting with the known live-out set, we remove things that get
@@ -337,8 +318,8 @@ void PhaseChaitin::build_ifg_virtual( ) {
// The defined value interferes with everything currently live. The
// value is then removed from the live-ness set and it's inputs are
// added to the live-ness set.
- for( uint j = b->end_idx() + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j-1];
+ for (uint j = block->end_idx() + 1; j > 1; j--) {
+ Node* n = block->_nodes[j - 1];
// Get value being defined
uint r = _lrg_map.live_range_id(n);
@@ -408,7 +389,6 @@ void PhaseChaitin::build_ifg_virtual( ) {
} // End of forall blocks
}
-//------------------------------count_int_pressure-----------------------------
uint PhaseChaitin::count_int_pressure( IndexSet *liveout ) {
IndexSetIterator elements(liveout);
uint lidx;
@@ -424,7 +404,6 @@ uint PhaseChaitin::count_int_pressure( IndexSet *liveout ) {
return cnt;
}
-//------------------------------count_float_pressure---------------------------
uint PhaseChaitin::count_float_pressure( IndexSet *liveout ) {
IndexSetIterator elements(liveout);
uint lidx;
@@ -438,7 +417,6 @@ uint PhaseChaitin::count_float_pressure( IndexSet *liveout ) {
return cnt;
}
-//------------------------------lower_pressure---------------------------------
// Adjust register pressure down by 1. Capture last hi-to-low transition,
static void lower_pressure( LRG *lrg, uint where, Block *b, uint *pressure, uint *hrp_index ) {
if (lrg->mask().is_UP() && lrg->mask_size()) {
@@ -460,40 +438,41 @@ static void lower_pressure( LRG *lrg, uint where, Block *b, uint *pressure, uint
}
}
-//------------------------------build_ifg_physical-----------------------------
// Build the interference graph using physical registers when available.
// That is, if 2 live ranges are simultaneously alive but in their acceptable
// register sets do not overlap, then they do not interfere.
uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
NOT_PRODUCT( Compile::TracePhase t3("buildIFG", &_t_buildIFGphysical, TimeCompiler); )
- uint spill_reg = LRG::SPILL_REG;
uint must_spill = 0;
// For all blocks (in any order) do...
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
// Clone (rather than smash in place) the liveout info, so it is alive
// for the "collect_gc_info" phase later.
- IndexSet liveout(_live->live(b));
- uint last_inst = b->end_idx();
+ IndexSet liveout(_live->live(block));
+ uint last_inst = block->end_idx();
// Compute first nonphi node index
uint first_inst;
- for( first_inst = 1; first_inst < last_inst; first_inst++ )
- if( !b->_nodes[first_inst]->is_Phi() )
+ for (first_inst = 1; first_inst < last_inst; first_inst++) {
+ if (!block->_nodes[first_inst]->is_Phi()) {
break;
+ }
+ }
// Spills could be inserted before CreateEx node which should be
// first instruction in block after Phis. Move CreateEx up.
- for( uint insidx = first_inst; insidx < last_inst; insidx++ ) {
- Node *ex = b->_nodes[insidx];
- if( ex->is_SpillCopy() ) continue;
- if( insidx > first_inst && ex->is_Mach() &&
- ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+ for (uint insidx = first_inst; insidx < last_inst; insidx++) {
+ Node *ex = block->_nodes[insidx];
+ if (ex->is_SpillCopy()) {
+ continue;
+ }
+ if (insidx > first_inst && ex->is_Mach() && ex->as_Mach()->ideal_Opcode() == Op_CreateEx) {
// If the CreateEx isn't above all the MachSpillCopies
// then move it to the top.
- b->_nodes.remove(insidx);
- b->_nodes.insert(first_inst, ex);
+ block->_nodes.remove(insidx);
+ block->_nodes.insert(first_inst, ex);
}
// Stop once a CreateEx or any other node is found
break;
@@ -503,12 +482,12 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
uint pressure[2], hrp_index[2];
pressure[0] = pressure[1] = 0;
hrp_index[0] = hrp_index[1] = last_inst+1;
- b->_reg_pressure = b->_freg_pressure = 0;
+ block->_reg_pressure = block->_freg_pressure = 0;
// Liveout things are presumed live for the whole block. We accumulate
// 'area' accordingly. If they get killed in the block, we'll subtract
// the unused part of the block from the area.
int inst_count = last_inst - first_inst;
- double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
+ double cost = (inst_count <= 0) ? 0.0 : block->_freq * double(inst_count);
assert(!(cost < 0.0), "negative spill cost" );
IndexSetIterator elements(&liveout);
uint lidx;
@@ -519,13 +498,15 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if (lrg.mask().is_UP() && lrg.mask_size()) {
if (lrg._is_float || lrg._is_vector) { // Count float pressure
pressure[1] += lrg.reg_pressure();
- if( pressure[1] > b->_freg_pressure )
- b->_freg_pressure = pressure[1];
+ if (pressure[1] > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1];
+ }
// Count int pressure, but do not count the SP, flags
- } else if( lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
+ } else if(lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI])) {
pressure[0] += lrg.reg_pressure();
- if( pressure[0] > b->_reg_pressure )
- b->_reg_pressure = pressure[0];
+ if (pressure[0] > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0];
+ }
}
}
}
@@ -541,8 +522,8 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// value is then removed from the live-ness set and it's inputs are added
// to the live-ness set.
uint j;
- for( j = last_inst + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j - 1];
+ for (j = last_inst + 1; j > 1; j--) {
+ Node* n = block->_nodes[j - 1];
// Get value being defined
uint r = _lrg_map.live_range_id(n);
@@ -551,7 +532,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if(r) {
// A DEF normally costs block frequency; rematerialized values are
// removed from the DEF sight, so LOWER costs here.
- lrgs(r)._cost += n->rematerialize() ? 0 : b->_freq;
+ lrgs(r)._cost += n->rematerialize() ? 0 : block->_freq;
// If it is not live, then this instruction is dead. Probably caused
// by spilling and rematerialization. Who cares why, yank this baby.
@@ -560,7 +541,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if( !n->is_Proj() ||
// Could also be a flags-projection of a dead ADD or such.
(_lrg_map.live_range_id(def) && !liveout.member(_lrg_map.live_range_id(def)))) {
- b->_nodes.remove(j - 1);
+ block->_nodes.remove(j - 1);
if (lrgs(r)._def == n) {
lrgs(r)._def = 0;
}
@@ -580,21 +561,21 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
RegMask itmp = lrgs(r).mask();
itmp.AND(*Matcher::idealreg2regmask[Op_RegI]);
int iregs = itmp.Size();
- if( pressure[0]+iregs > b->_reg_pressure )
- b->_reg_pressure = pressure[0]+iregs;
- if( pressure[0] <= (uint)INTPRESSURE &&
- pressure[0]+iregs > (uint)INTPRESSURE ) {
- hrp_index[0] = j-1;
+ if (pressure[0]+iregs > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0] + iregs;
+ }
+ if (pressure[0] <= (uint)INTPRESSURE && pressure[0] + iregs > (uint)INTPRESSURE) {
+ hrp_index[0] = j - 1;
}
// Count the float-only registers
RegMask ftmp = lrgs(r).mask();
ftmp.AND(*Matcher::idealreg2regmask[Op_RegD]);
int fregs = ftmp.Size();
- if( pressure[1]+fregs > b->_freg_pressure )
- b->_freg_pressure = pressure[1]+fregs;
- if( pressure[1] <= (uint)FLOATPRESSURE &&
- pressure[1]+fregs > (uint)FLOATPRESSURE ) {
- hrp_index[1] = j-1;
+ if (pressure[1] + fregs > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1] + fregs;
+ }
+ if(pressure[1] <= (uint)FLOATPRESSURE && pressure[1]+fregs > (uint)FLOATPRESSURE) {
+ hrp_index[1] = j - 1;
}
}
@@ -607,7 +588,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if( n->is_SpillCopy()
&& lrgs(r).is_singledef() // MultiDef live range can still split
&& n->outcnt() == 1 // and use must be in this block
- && _cfg.get_block_for_node(n->unique_out()) == b ) {
+ && _cfg.get_block_for_node(n->unique_out()) == block) {
// All single-use MachSpillCopy(s) that immediately precede their
// use must color early. If a longer live range steals their
// color, the spill copy will split and may push another spill copy
@@ -617,14 +598,16 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
//
Node *single_use = n->unique_out();
- assert( b->find_node(single_use) >= j, "Use must be later in block");
+ assert(block->find_node(single_use) >= j, "Use must be later in block");
// Use can be earlier in block if it is a Phi, but then I should be a MultiDef
// Find first non SpillCopy 'm' that follows the current instruction
// (j - 1) is index for current instruction 'n'
Node *m = n;
- for( uint i = j; i <= last_inst && m->is_SpillCopy(); ++i ) { m = b->_nodes[i]; }
- if( m == single_use ) {
+ for (uint i = j; i <= last_inst && m->is_SpillCopy(); ++i) {
+ m = block->_nodes[i];
+ }
+ if (m == single_use) {
lrgs(r)._area = 0.0;
}
}
@@ -633,7 +616,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if( liveout.remove(r) ) {
// Adjust register pressure.
// Capture last hi-to-lo pressure transition
- lower_pressure( &lrgs(r), j-1, b, pressure, hrp_index );
+ lower_pressure(&lrgs(r), j - 1, block, pressure, hrp_index);
assert( pressure[0] == count_int_pressure (&liveout), "" );
assert( pressure[1] == count_float_pressure(&liveout), "" );
}
@@ -646,7 +629,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if (liveout.remove(x)) {
lrgs(x)._area -= cost;
// Adjust register pressure.
- lower_pressure(&lrgs(x), j-1, b, pressure, hrp_index);
+ lower_pressure(&lrgs(x), j - 1, block, pressure, hrp_index);
assert( pressure[0] == count_int_pressure (&liveout), "" );
assert( pressure[1] == count_float_pressure(&liveout), "" );
}
@@ -718,7 +701,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// Area remaining in the block
inst_count--;
- cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
+ cost = (inst_count <= 0) ? 0.0 : block->_freq * double(inst_count);
// Make all inputs live
if( !n->is_Phi() ) { // Phi function uses come from prior block
@@ -743,7 +726,7 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if (k < debug_start) {
// A USE costs twice block frequency (once for the Load, once
// for a Load-delay). Rematerialized uses only cost once.
- lrg._cost += (def->rematerialize() ? b->_freq : (b->_freq + b->_freq));
+ lrg._cost += (def->rematerialize() ? block->_freq : (block->_freq + block->_freq));
}
// It is live now
if (liveout.insert(x)) {
@@ -753,12 +736,14 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
if (lrg.mask().is_UP() && lrg.mask_size()) {
if (lrg._is_float || lrg._is_vector) {
pressure[1] += lrg.reg_pressure();
- if( pressure[1] > b->_freg_pressure )
- b->_freg_pressure = pressure[1];
+ if (pressure[1] > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1];
+ }
} else if( lrg.mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) ) {
pressure[0] += lrg.reg_pressure();
- if( pressure[0] > b->_reg_pressure )
- b->_reg_pressure = pressure[0];
+ if (pressure[0] > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0];
+ }
}
}
assert( pressure[0] == count_int_pressure (&liveout), "" );
@@ -772,44 +757,47 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
// If we run off the top of the block with high pressure and
// never see a hi-to-low pressure transition, just record that
// the whole block is high pressure.
- if( pressure[0] > (uint)INTPRESSURE ) {
+ if (pressure[0] > (uint)INTPRESSURE) {
hrp_index[0] = 0;
- if( pressure[0] > b->_reg_pressure )
- b->_reg_pressure = pressure[0];
+ if (pressure[0] > block->_reg_pressure) {
+ block->_reg_pressure = pressure[0];
+ }
}
- if( pressure[1] > (uint)FLOATPRESSURE ) {
+ if (pressure[1] > (uint)FLOATPRESSURE) {
hrp_index[1] = 0;
- if( pressure[1] > b->_freg_pressure )
- b->_freg_pressure = pressure[1];
+ if (pressure[1] > block->_freg_pressure) {
+ block->_freg_pressure = pressure[1];
+ }
}
// Compute high pressure indice; avoid landing in the middle of projnodes
j = hrp_index[0];
- if( j < b->_nodes.size() && j < b->end_idx()+1 ) {
- Node *cur = b->_nodes[j];
- while( cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch() ) {
+ if (j < block->_nodes.size() && j < block->end_idx() + 1) {
+ Node* cur = block->_nodes[j];
+ while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) {
j--;
- cur = b->_nodes[j];
+ cur = block->_nodes[j];
}
}
- b->_ihrp_index = j;
+ block->_ihrp_index = j;
j = hrp_index[1];
- if( j < b->_nodes.size() && j < b->end_idx()+1 ) {
- Node *cur = b->_nodes[j];
- while( cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch() ) {
+ if (j < block->_nodes.size() && j < block->end_idx() + 1) {
+ Node* cur = block->_nodes[j];
+ while (cur->is_Proj() || (cur->is_MachNullCheck()) || cur->is_Catch()) {
j--;
- cur = b->_nodes[j];
+ cur = block->_nodes[j];
}
}
- b->_fhrp_index = j;
+ block->_fhrp_index = j;
#ifndef PRODUCT
// Gather Register Pressure Statistics
if( PrintOptoStatistics ) {
- if( b->_reg_pressure > (uint)INTPRESSURE || b->_freg_pressure > (uint)FLOATPRESSURE )
+ if (block->_reg_pressure > (uint)INTPRESSURE || block->_freg_pressure > (uint)FLOATPRESSURE) {
_high_pressure++;
- else
+ } else {
_low_pressure++;
+ }
}
#endif
} // End of for all blocks
diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp
index fc05a79b416..8d9daa54b86 100644
--- a/hotspot/src/share/vm/opto/lcm.cpp
+++ b/hotspot/src/share/vm/opto/lcm.cpp
@@ -501,7 +501,7 @@ Node *Block::select(PhaseCFG *cfg, Node_List &worklist, GrowableArray &read
n_choice = 1;
}
- uint n_latency = cfg->_node_latency->at_grow(n->_idx);
+ uint n_latency = cfg->get_latency_for_node(n);
uint n_score = n->req(); // Many inputs get high score to break ties
// Keep best latency found
@@ -797,7 +797,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray &
Node *n = _nodes[j];
int idx = n->_idx;
tty->print("# ready cnt:%3d ", ready_cnt.at(idx));
- tty->print("latency:%3d ", cfg->_node_latency->at_grow(idx));
+ tty->print("latency:%3d ", cfg->get_latency_for_node(n));
tty->print("%4d: %s\n", idx, n->Name());
}
}
@@ -825,7 +825,7 @@ bool Block::schedule_local(PhaseCFG *cfg, Matcher &matcher, GrowableArray &
#ifndef PRODUCT
if (cfg->trace_opto_pipelining()) {
tty->print("# select %d: %s", n->_idx, n->Name());
- tty->print(", latency:%d", cfg->_node_latency->at_grow(n->_idx));
+ tty->print(", latency:%d", cfg->get_latency_for_node(n));
n->dump();
if (Verbose) {
tty->print("# ready list:");
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index df84634832a..22deebb5a83 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -213,6 +213,7 @@ class LibraryCallKit : public GraphKit {
void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
+ static bool klass_needs_init_guard(Node* kls);
bool inline_unsafe_allocate();
bool inline_unsafe_copyMemory();
bool inline_native_currentThread();
@@ -2892,8 +2893,21 @@ bool LibraryCallKit::inline_unsafe_fence(vmIntrinsics::ID id) {
}
}
+bool LibraryCallKit::klass_needs_init_guard(Node* kls) {
+ if (!kls->is_Con()) {
+ return true;
+ }
+ const TypeKlassPtr* klsptr = kls->bottom_type()->isa_klassptr();
+ if (klsptr == NULL) {
+ return true;
+ }
+ ciInstanceKlass* ik = klsptr->klass()->as_instance_klass();
+ // don't need a guard for a klass that is already initialized
+ return !ik->is_initialized();
+}
+
//----------------------------inline_unsafe_allocate---------------------------
-// public native Object sun.mics.Unsafe.allocateInstance(Class> cls);
+// public native Object sun.misc.Unsafe.allocateInstance(Class> cls);
bool LibraryCallKit::inline_unsafe_allocate() {
if (callee()->is_static()) return false; // caller must have the capability!
@@ -2905,16 +2919,19 @@ bool LibraryCallKit::inline_unsafe_allocate() {
kls = null_check(kls);
if (stopped()) return true; // argument was like int.class
- // Note: The argument might still be an illegal value like
- // Serializable.class or Object[].class. The runtime will handle it.
- // But we must make an explicit check for initialization.
- Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
- // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
- // can generate code to load it as unsigned byte.
- Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
- Node* bits = intcon(InstanceKlass::fully_initialized);
- Node* test = _gvn.transform(new (C) SubINode(inst, bits));
- // The 'test' is non-zero if we need to take a slow path.
+ Node* test = NULL;
+ if (LibraryCallKit::klass_needs_init_guard(kls)) {
+ // Note: The argument might still be an illegal value like
+ // Serializable.class or Object[].class. The runtime will handle it.
+ // But we must make an explicit check for initialization.
+ Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
+ // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
+ // can generate code to load it as unsigned byte.
+ Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
+ Node* bits = intcon(InstanceKlass::fully_initialized);
+ test = _gvn.transform(new (C) SubINode(inst, bits));
+ // The 'test' is non-zero if we need to take a slow path.
+ }
Node* obj = new_instance(kls, test);
set_result(obj);
diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp
index 846609e8a49..ab7381b639d 100644
--- a/hotspot/src/share/vm/opto/live.cpp
+++ b/hotspot/src/share/vm/opto/live.cpp
@@ -30,9 +30,6 @@
#include "opto/machnode.hpp"
-
-//=============================================================================
-//------------------------------PhaseLive--------------------------------------
// Compute live-in/live-out. We use a totally incremental algorithm. The LIVE
// problem is monotonic. The steady-state solution looks like this: pull a
// block from the worklist. It has a set of delta's - values which are newly
@@ -53,9 +50,9 @@ void PhaseLive::compute(uint maxlrg) {
// Init the sparse live arrays. This data is live on exit from here!
// The _live info is the live-out info.
- _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet)*_cfg._num_blocks);
+ _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks());
uint i;
- for( i=0; i<_cfg._num_blocks; i++ ) {
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
_live[i].initialize(_maxlrg);
}
@@ -65,14 +62,14 @@ void PhaseLive::compute(uint maxlrg) {
// Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT
// Array of values defined locally in blocks
- _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg._num_blocks);
- for( i=0; i<_cfg._num_blocks; i++ ) {
+ _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg.number_of_blocks());
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
_defs[i].initialize(_maxlrg);
}
// Array of delta-set pointers, indexed by block pre_order-1.
- _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg._num_blocks);
- memset( _deltas, 0, sizeof(IndexSet*)* _cfg._num_blocks);
+ _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks());
+ memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
_free_IndexSet = NULL;
@@ -80,31 +77,32 @@ void PhaseLive::compute(uint maxlrg) {
VectorSet first_pass(Thread::current()->resource_area());
// Outer loop: must compute local live-in sets and push into predecessors.
- uint iters = _cfg._num_blocks; // stat counters
- for( uint j=_cfg._num_blocks; j>0; j-- ) {
- Block *b = _cfg._blocks[j-1];
+ for (uint j = _cfg.number_of_blocks(); j > 0; j--) {
+ Block* block = _cfg.get_block(j - 1);
// Compute the local live-in set. Start with any new live-out bits.
- IndexSet *use = getset( b );
- IndexSet *def = &_defs[b->_pre_order-1];
+ IndexSet* use = getset(block);
+ IndexSet* def = &_defs[block->_pre_order-1];
DEBUG_ONLY(IndexSet *def_outside = getfreeset();)
uint i;
- for( i=b->_nodes.size(); i>1; i-- ) {
- Node *n = b->_nodes[i-1];
- if( n->is_Phi() ) break;
+ for (i = block->_nodes.size(); i > 1; i--) {
+ Node* n = block->_nodes[i-1];
+ if (n->is_Phi()) {
+ break;
+ }
uint r = _names[n->_idx];
assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
def->insert( r );
use->remove( r );
uint cnt = n->req();
- for( uint k=1; kin(k);
uint nkidx = nk->_idx;
- if (_cfg.get_block_for_node(nk) != b) {
+ if (_cfg.get_block_for_node(nk) != block) {
uint u = _names[nkidx];
- use->insert( u );
- DEBUG_ONLY(def_outside->insert( u );)
+ use->insert(u);
+ DEBUG_ONLY(def_outside->insert(u);)
}
}
}
@@ -113,41 +111,38 @@ void PhaseLive::compute(uint maxlrg) {
_free_IndexSet = def_outside; // Drop onto free list
#endif
// Remove anything defined by Phis and the block start instruction
- for( uint k=i; k>0; k-- ) {
- uint r = _names[b->_nodes[k-1]->_idx];
- def->insert( r );
- use->remove( r );
+ for (uint k = i; k > 0; k--) {
+ uint r = _names[block->_nodes[k - 1]->_idx];
+ def->insert(r);
+ use->remove(r);
}
// Push these live-in things to predecessors
- for( uint l=1; lnum_preds(); l++ ) {
- Block *p = _cfg.get_block_for_node(b->pred(l));
- add_liveout( p, use, first_pass );
+ for (uint l = 1; l < block->num_preds(); l++) {
+ Block* p = _cfg.get_block_for_node(block->pred(l));
+ add_liveout(p, use, first_pass);
// PhiNode uses go in the live-out set of prior blocks.
- for( uint k=i; k>0; k-- )
- add_liveout( p, _names[b->_nodes[k-1]->in(l)->_idx], first_pass );
+ for (uint k = i; k > 0; k--) {
+ add_liveout(p, _names[block->_nodes[k-1]->in(l)->_idx], first_pass);
+ }
}
- freeset( b );
- first_pass.set(b->_pre_order);
+ freeset(block);
+ first_pass.set(block->_pre_order);
// Inner loop: blocks that picked up new live-out values to be propagated
- while( _worklist->size() ) {
- // !!!!!
-// #ifdef ASSERT
- iters++;
-// #endif
- Block *b = _worklist->pop();
- IndexSet *delta = getset(b);
+ while (_worklist->size()) {
+ Block* block = _worklist->pop();
+ IndexSet *delta = getset(block);
assert( delta->count(), "missing delta set" );
// Add new-live-in to predecessors live-out sets
- for (uint l = 1; l < b->num_preds(); l++) {
- Block* block = _cfg.get_block_for_node(b->pred(l));
- add_liveout(block, delta, first_pass);
+ for (uint l = 1; l < block->num_preds(); l++) {
+ Block* predecessor = _cfg.get_block_for_node(block->pred(l));
+ add_liveout(predecessor, delta, first_pass);
}
- freeset(b);
+ freeset(block);
} // End of while-worklist-not-empty
} // End of for-all-blocks-outer-loop
@@ -155,7 +150,7 @@ void PhaseLive::compute(uint maxlrg) {
// We explicitly clear all of the IndexSets which we are about to release.
// This allows us to recycle their internal memory into IndexSet's free list.
- for( i=0; i<_cfg._num_blocks; i++ ) {
+ for (i = 0; i < _cfg.number_of_blocks(); i++) {
_defs[i].clear();
if (_deltas[i]) {
// Is this always true?
@@ -171,13 +166,11 @@ void PhaseLive::compute(uint maxlrg) {
}
-//------------------------------stats------------------------------------------
#ifndef PRODUCT
void PhaseLive::stats(uint iters) const {
}
#endif
-//------------------------------getset-----------------------------------------
// Get an IndexSet for a block. Return existing one, if any. Make a new
// empty one if a prior one does not exist.
IndexSet *PhaseLive::getset( Block *p ) {
@@ -188,7 +181,6 @@ IndexSet *PhaseLive::getset( Block *p ) {
return delta; // Return set of new live-out items
}
-//------------------------------getfreeset-------------------------------------
// Pull from free list, or allocate. Internal allocation on the returned set
// is always from thread local storage.
IndexSet *PhaseLive::getfreeset( ) {
@@ -207,7 +199,6 @@ IndexSet *PhaseLive::getfreeset( ) {
return f;
}
-//------------------------------freeset----------------------------------------
// Free an IndexSet from a block.
void PhaseLive::freeset( const Block *p ) {
IndexSet *f = _deltas[p->_pre_order-1];
@@ -216,7 +207,6 @@ void PhaseLive::freeset( const Block *p ) {
_deltas[p->_pre_order-1] = NULL;
}
-//------------------------------add_liveout------------------------------------
// Add a live-out value to a given blocks live-out set. If it is new, then
// also add it to the delta set and stick the block on the worklist.
void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
@@ -233,8 +223,6 @@ void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
}
}
-
-//------------------------------add_liveout------------------------------------
// Add a vector of live-out values to a given blocks live-out set.
void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
IndexSet *live = &_live[p->_pre_order-1];
@@ -262,7 +250,6 @@ void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
}
#ifndef PRODUCT
-//------------------------------dump-------------------------------------------
// Dump the live-out set for a block
void PhaseLive::dump( const Block *b ) const {
tty->print("Block %d: ",b->_pre_order);
@@ -275,18 +262,19 @@ void PhaseLive::dump( const Block *b ) const {
tty->print("\n");
}
-//------------------------------verify_base_ptrs-------------------------------
// Verify that base pointers and derived pointers are still sane.
void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
#ifdef ASSERT
Unique_Node_List worklist(a);
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
- Block *b = _cfg._blocks[i];
- for( uint j = b->end_idx() + 1; j > 1; j-- ) {
- Node *n = b->_nodes[j-1];
- if( n->is_Phi() ) break;
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
+ Block* block = _cfg.get_block(i);
+ for (uint j = block->end_idx() + 1; j > 1; j--) {
+ Node* n = block->_nodes[j-1];
+ if (n->is_Phi()) {
+ break;
+ }
// Found a safepoint?
- if( n->is_MachSafePoint() ) {
+ if (n->is_MachSafePoint()) {
MachSafePointNode *sfpt = n->as_MachSafePoint();
JVMState* jvms = sfpt->jvms();
if (jvms != NULL) {
@@ -358,7 +346,6 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
#endif
}
-//------------------------------verify-------------------------------------
// Verify that graphs and base pointers are still sane.
void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
#ifdef ASSERT
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index 962c3c12894..ae27f6ffa21 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -67,8 +67,8 @@ const uint Matcher::_begin_rematerialize = _BEGIN_REMATERIALIZE;
const uint Matcher::_end_rematerialize = _END_REMATERIALIZE;
//---------------------------Matcher-------------------------------------------
-Matcher::Matcher( Node_List &proj_list ) :
- PhaseTransform( Phase::Ins_Select ),
+Matcher::Matcher()
+: PhaseTransform( Phase::Ins_Select ),
#ifdef ASSERT
_old2new_map(C->comp_arena()),
_new2old_map(C->comp_arena()),
@@ -78,7 +78,7 @@ Matcher::Matcher( Node_List &proj_list ) :
_swallowed(swallowed),
_begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE),
_end_inst_chain_rule(_END_INST_CHAIN_RULE),
- _must_clone(must_clone), _proj_list(proj_list),
+ _must_clone(must_clone),
_register_save_policy(register_save_policy),
_c_reg_save_policy(c_reg_save_policy),
_register_save_type(register_save_type),
@@ -1304,8 +1304,9 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
proj->_rout.Insert(OptoReg::Name(i));
}
- if( proj->_rout.is_NotEmpty() )
- _proj_list.push(proj);
+ if (proj->_rout.is_NotEmpty()) {
+ push_projection(proj);
+ }
}
// Transfer the safepoint information from the call to the mcall
// Move the JVMState list
@@ -1685,14 +1686,15 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
}
// If the _leaf is an AddP, insert the base edge
- if( leaf->is_AddP() )
+ if (leaf->is_AddP()) {
mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base));
+ }
- uint num_proj = _proj_list.size();
+ uint number_of_projections_prior = number_of_projections();
// Perform any 1-to-many expansions required
- MachNode *ex = mach->Expand(s,_proj_list, mem);
- if( ex != mach ) {
+ MachNode *ex = mach->Expand(s, _projection_list, mem);
+ if (ex != mach) {
assert(ex->ideal_reg() == mach->ideal_reg(), "ideal types should match");
if( ex->in(1)->is_Con() )
ex->in(1)->set_req(0, C->root());
@@ -1713,7 +1715,7 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
// generated belatedly during spill code generation.
if (_allocation_started) {
guarantee(ex == mach, "no expand rules during spill generation");
- guarantee(_proj_list.size() == num_proj, "no allocation during spill generation");
+ guarantee(number_of_projections_prior == number_of_projections(), "no allocation during spill generation");
}
if (leaf->is_Con() || leaf->is_DecodeNarrowPtr()) {
diff --git a/hotspot/src/share/vm/opto/matcher.hpp b/hotspot/src/share/vm/opto/matcher.hpp
index 280b8ad8865..8435b0f997b 100644
--- a/hotspot/src/share/vm/opto/matcher.hpp
+++ b/hotspot/src/share/vm/opto/matcher.hpp
@@ -88,7 +88,7 @@ class Matcher : public PhaseTransform {
Node *transform( Node *dummy );
- Node_List &_proj_list; // For Machine nodes killing many values
+ Node_List _projection_list; // For Machine nodes killing many values
Node_Array _shared_nodes;
@@ -183,10 +183,30 @@ public:
void collect_null_checks( Node *proj, Node *orig_proj );
void validate_null_checks( );
- Matcher( Node_List &proj_list );
+ Matcher();
+
+ // Get a projection node at position pos
+ Node* get_projection(uint pos) {
+ return _projection_list[pos];
+ }
+
+ // Push a projection node onto the projection list
+ void push_projection(Node* node) {
+ _projection_list.push(node);
+ }
+
+ Node* pop_projection() {
+ return _projection_list.pop();
+ }
+
+ // Number of nodes in the projection list
+ uint number_of_projections() const {
+ return _projection_list.size();
+ }
// Select instructions for entire method
- void match( );
+ void match();
+
// Helper for match
OptoReg::Name warp_incoming_stk_arg( VMReg reg );
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index 24a4497c680..8a06acdc983 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -54,11 +54,10 @@ extern uint size_deopt_handler();
extern int emit_exception_handler(CodeBuffer &cbuf);
extern int emit_deopt_handler(CodeBuffer &cbuf);
-//------------------------------Output-----------------------------------------
// Convert Nodes to instruction bits and pass off to the VM
void Compile::Output() {
// RootNode goes
- assert( _cfg->_broot->_nodes.size() == 0, "" );
+ assert( _cfg->get_root_block()->_nodes.size() == 0, "" );
// The number of new nodes (mostly MachNop) is proportional to
// the number of java calls and inner loops which are aligned.
@@ -68,8 +67,8 @@ void Compile::Output() {
return;
}
// Make sure I can find the Start Node
- Block *entry = _cfg->_blocks[1];
- Block *broot = _cfg->_broot;
+ Block *entry = _cfg->get_block(1);
+ Block *broot = _cfg->get_root_block();
const StartNode *start = entry->_nodes[0]->as_Start();
@@ -109,40 +108,44 @@ void Compile::Output() {
}
// Insert epilogs before every return
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- Block *b = _cfg->_blocks[i];
- if( !b->is_connector() && b->non_connector_successor(0) == _cfg->_broot ) { // Found a program exit point?
- Node *m = b->end();
- if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) {
- MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return);
- b->add_inst( epilog );
- _cfg->map_node_to_block(epilog, b);
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ Block* block = _cfg->get_block(i);
+ if (!block->is_connector() && block->non_connector_successor(0) == _cfg->get_root_block()) { // Found a program exit point?
+ Node* m = block->end();
+ if (m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt) {
+ MachEpilogNode* epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return);
+ block->add_inst(epilog);
+ _cfg->map_node_to_block(epilog, block);
}
}
}
# ifdef ENABLE_ZAP_DEAD_LOCALS
- if ( ZapDeadCompiledLocals ) Insert_zap_nodes();
+ if (ZapDeadCompiledLocals) {
+ Insert_zap_nodes();
+ }
# endif
- uint* blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
- blk_starts[0] = 0;
+ uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1);
+ blk_starts[0] = 0;
// Initialize code buffer and process short branches.
CodeBuffer* cb = init_buffer(blk_starts);
- if (cb == NULL || failing()) return;
+ if (cb == NULL || failing()) {
+ return;
+ }
ScheduleAndBundle();
#ifndef PRODUCT
if (trace_opto_output()) {
tty->print("\n---- After ScheduleAndBundle ----\n");
- for (uint i = 0; i < _cfg->_num_blocks; i++) {
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
tty->print("\nBB#%03d:\n", i);
- Block *bb = _cfg->_blocks[i];
- for (uint j = 0; j < bb->_nodes.size(); j++) {
- Node *n = bb->_nodes[j];
+ Block* block = _cfg->get_block(i);
+ for (uint j = 0; j < block->_nodes.size(); j++) {
+ Node* n = block->_nodes[j];
OptoReg::Name reg = _regalloc->get_reg_first(n);
tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : "");
n->dump();
@@ -151,11 +154,15 @@ void Compile::Output() {
}
#endif
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
BuildOopMaps();
- if (failing()) return;
+ if (failing()) {
+ return;
+ }
fill_buffer(cb, blk_starts);
}
@@ -217,8 +224,8 @@ void Compile::Insert_zap_nodes() {
return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care
// Insert call to zap runtime stub before every node with an oop map
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- Block *b = _cfg->_blocks[i];
+ for( uint i=0; i<_cfg->number_of_blocks(); i++ ) {
+ Block *b = _cfg->get_block(i);
for ( uint j = 0; j < b->_nodes.size(); ++j ) {
Node *n = b->_nodes[j];
@@ -275,7 +282,6 @@ Node* Compile::call_zap_node(MachSafePointNode* node_to_check, int block_no) {
return _matcher->match_sfpt(ideal_node);
}
-//------------------------------is_node_getting_a_safepoint--------------------
bool Compile::is_node_getting_a_safepoint( Node* n) {
// This code duplicates the logic prior to the call of add_safepoint
// below in this file.
@@ -285,7 +291,6 @@ bool Compile::is_node_getting_a_safepoint( Node* n) {
# endif // ENABLE_ZAP_DEAD_LOCALS
-//------------------------------compute_loop_first_inst_sizes------------------
// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
// of a loop. When aligning a loop we need to provide enough instructions
// in cpu's fetch buffer to feed decoders. The loop alignment could be
@@ -302,42 +307,39 @@ void Compile::compute_loop_first_inst_sizes() {
// or alignment padding is larger then MaxLoopPad. By default, MaxLoopPad
// is equal to OptoLoopAlignment-1 except on new Intel cpus, where it is
// equal to 11 bytes which is the largest address NOP instruction.
- if( MaxLoopPad < OptoLoopAlignment-1 ) {
- uint last_block = _cfg->_num_blocks-1;
- for( uint i=1; i <= last_block; i++ ) {
- Block *b = _cfg->_blocks[i];
+ if (MaxLoopPad < OptoLoopAlignment - 1) {
+ uint last_block = _cfg->number_of_blocks() - 1;
+ for (uint i = 1; i <= last_block; i++) {
+ Block* block = _cfg->get_block(i);
// Check the first loop's block which requires an alignment.
- if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) {
+ if (block->loop_alignment() > (uint)relocInfo::addr_unit()) {
uint sum_size = 0;
uint inst_cnt = NumberOfLoopInstrToAlign;
- inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+ inst_cnt = block->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
// Check subsequent fallthrough blocks if the loop's first
// block(s) does not have enough instructions.
- Block *nb = b;
- while( inst_cnt > 0 &&
- i < last_block &&
- !_cfg->_blocks[i+1]->has_loop_alignment() &&
- !nb->has_successor(b) ) {
+ Block *nb = block;
+ while(inst_cnt > 0 &&
+ i < last_block &&
+ !_cfg->get_block(i + 1)->has_loop_alignment() &&
+ !nb->has_successor(block)) {
i++;
- nb = _cfg->_blocks[i];
+ nb = _cfg->get_block(i);
inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
} // while( inst_cnt > 0 && i < last_block )
- b->set_first_inst_size(sum_size);
+ block->set_first_inst_size(sum_size);
} // f( b->head()->is_Loop() )
} // for( i <= last_block )
} // if( MaxLoopPad < OptoLoopAlignment-1 )
}
-//----------------------shorten_branches---------------------------------------
// The architecture description provides short branch variants for some long
// branch instructions. Replace eligible long branches with short branches.
void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size) {
-
- // ------------------
// Compute size of each block, method size, and relocation information size
- uint nblocks = _cfg->_num_blocks;
+ uint nblocks = _cfg->number_of_blocks();
uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks);
uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks);
@@ -364,7 +366,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
uint last_avoid_back_to_back_adr = max_uint;
uint nop_size = (new (this) MachNopNode())->size(_regalloc);
for (uint i = 0; i < nblocks; i++) { // For all blocks
- Block *b = _cfg->_blocks[i];
+ Block* block = _cfg->get_block(i);
// During short branch replacement, we store the relative (to blk_starts)
// offset of jump in jmp_offset, rather than the absolute offset of jump.
@@ -377,10 +379,10 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
DEBUG_ONLY( jmp_rule[i] = 0; )
// Sum all instruction sizes to compute block size
- uint last_inst = b->_nodes.size();
+ uint last_inst = block->_nodes.size();
uint blk_size = 0;
for (uint j = 0; j < last_inst; j++) {
- Node* nj = b->_nodes[j];
+ Node* nj = block->_nodes[j];
// Handle machine instruction nodes
if (nj->is_Mach()) {
MachNode *mach = nj->as_Mach();
@@ -441,8 +443,8 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
// When the next block starts a loop, we may insert pad NOP
// instructions. Since we cannot know our future alignment,
// assume the worst.
- if (i< nblocks-1) {
- Block *nb = _cfg->_blocks[i+1];
+ if (i < nblocks - 1) {
+ Block* nb = _cfg->get_block(i + 1);
int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit();
if (max_loop_pad > 0) {
assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), "");
@@ -473,26 +475,26 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
has_short_branch_candidate = false;
int adjust_block_start = 0;
for (uint i = 0; i < nblocks; i++) {
- Block *b = _cfg->_blocks[i];
+ Block* block = _cfg->get_block(i);
int idx = jmp_nidx[i];
- MachNode* mach = (idx == -1) ? NULL: b->_nodes[idx]->as_Mach();
+ MachNode* mach = (idx == -1) ? NULL: block->_nodes[idx]->as_Mach();
if (mach != NULL && mach->may_be_short_branch()) {
#ifdef ASSERT
assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity");
int j;
// Find the branch; ignore trailing NOPs.
- for (j = b->_nodes.size()-1; j>=0; j--) {
- Node* n = b->_nodes[j];
+ for (j = block->_nodes.size()-1; j>=0; j--) {
+ Node* n = block->_nodes[j];
if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con)
break;
}
- assert(j >= 0 && j == idx && b->_nodes[j] == (Node*)mach, "sanity");
+ assert(j >= 0 && j == idx && block->_nodes[j] == (Node*)mach, "sanity");
#endif
int br_size = jmp_size[i];
int br_offs = blk_starts[i] + jmp_offset[i];
// This requires the TRUE branch target be in succs[0]
- uint bnum = b->non_connector_successor(0)->_pre_order;
+ uint bnum = block->non_connector_successor(0)->_pre_order;
int offset = blk_starts[bnum] - br_offs;
if (bnum > i) { // adjust following block's offset
offset -= adjust_block_start;
@@ -520,7 +522,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
diff -= nop_size;
}
adjust_block_start += diff;
- b->_nodes.map(idx, replacement);
+ block->_nodes.map(idx, replacement);
mach->subsume_by(replacement, C);
mach = replacement;
progress = true;
@@ -1083,8 +1085,8 @@ CodeBuffer* Compile::init_buffer(uint* blk_starts) {
if (has_mach_constant_base_node()) {
// Fill the constant table.
// Note: This must happen before shorten_branches.
- for (uint i = 0; i < _cfg->_num_blocks; i++) {
- Block* b = _cfg->_blocks[i];
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ Block* b = _cfg->get_block(i);
for (uint j = 0; j < b->_nodes.size(); j++) {
Node* n = b->_nodes[j];
@@ -1170,7 +1172,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// !!!!! This preserves old handling of oopmaps for now
debug_info()->set_oopmaps(_oop_map_set);
- uint nblocks = _cfg->_num_blocks;
+ uint nblocks = _cfg->number_of_blocks();
// Count and start of implicit null check instructions
uint inct_cnt = 0;
uint *inct_starts = NEW_RESOURCE_ARRAY(uint, nblocks+1);
@@ -1218,21 +1220,21 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// Now fill in the code buffer
Node *delay_slot = NULL;
- for (uint i=0; i < nblocks; i++) {
- Block *b = _cfg->_blocks[i];
-
- Node *head = b->head();
+ for (uint i = 0; i < nblocks; i++) {
+ Block* block = _cfg->get_block(i);
+ Node* head = block->head();
// If this block needs to start aligned (i.e, can be reached other
// than by falling-thru from the previous block), then force the
// start of a new bundle.
- if (Pipeline::requires_bundling() && starts_bundle(head))
+ if (Pipeline::requires_bundling() && starts_bundle(head)) {
cb->flush_bundle(true);
+ }
#ifdef ASSERT
- if (!b->is_connector()) {
+ if (!block->is_connector()) {
stringStream st;
- b->dump_head(_cfg, &st);
+ block->dump_head(_cfg, &st);
MacroAssembler(cb).block_comment(st.as_string());
}
jmp_target[i] = 0;
@@ -1243,16 +1245,16 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
int blk_offset = current_offset;
// Define the label at the beginning of the basic block
- MacroAssembler(cb).bind(blk_labels[b->_pre_order]);
+ MacroAssembler(cb).bind(blk_labels[block->_pre_order]);
- uint last_inst = b->_nodes.size();
+ uint last_inst = block->_nodes.size();
// Emit block normally, except for last instruction.
// Emit means "dump code bits into code buffer".
for (uint j = 0; j_nodes[j];
+ Node* n = block->_nodes[j];
// See if delay slots are supported
if (valid_bundle_info(n) &&
@@ -1306,9 +1308,9 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
assert((padding % nop_size) == 0, "padding is not a multiple of NOP size");
int nops_cnt = padding / nop_size;
MachNode *nop = new (this) MachNopNode(nops_cnt);
- b->_nodes.insert(j++, nop);
+ block->_nodes.insert(j++, nop);
last_inst++;
- _cfg->map_node_to_block(nop, b);
+ _cfg->map_node_to_block(nop, block);
nop->emit(*cb, _regalloc);
cb->flush_bundle(true);
current_offset = cb->insts_size();
@@ -1322,7 +1324,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
mcall->method_set((intptr_t)mcall->entry_point());
// Save the return address
- call_returns[b->_pre_order] = current_offset + mcall->ret_addr_offset();
+ call_returns[block->_pre_order] = current_offset + mcall->ret_addr_offset();
if (mcall->is_MachCallLeaf()) {
is_mcall = false;
@@ -1359,7 +1361,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// If this is a branch, then fill in the label with the target BB's label
else if (mach->is_MachBranch()) {
// This requires the TRUE branch target be in succs[0]
- uint block_num = b->non_connector_successor(0)->_pre_order;
+ uint block_num = block->non_connector_successor(0)->_pre_order;
// Try to replace long branch if delay slot is not used,
// it is mostly for back branches since forward branch's
@@ -1392,8 +1394,8 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// Insert padding between avoid_back_to_back branches.
if (needs_padding && replacement->avoid_back_to_back()) {
MachNode *nop = new (this) MachNopNode();
- b->_nodes.insert(j++, nop);
- _cfg->map_node_to_block(nop, b);
+ block->_nodes.insert(j++, nop);
+ _cfg->map_node_to_block(nop, block);
last_inst++;
nop->emit(*cb, _regalloc);
cb->flush_bundle(true);
@@ -1405,7 +1407,7 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
jmp_size[i] = new_size;
jmp_rule[i] = mach->rule();
#endif
- b->_nodes.map(j, replacement);
+ block->_nodes.map(j, replacement);
mach->subsume_by(replacement, C);
n = replacement;
mach = replacement;
@@ -1413,8 +1415,8 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
}
mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num );
} else if (mach->ideal_Opcode() == Op_Jump) {
- for (uint h = 0; h < b->_num_succs; h++) {
- Block* succs_block = b->_succs[h];
+ for (uint h = 0; h < block->_num_succs; h++) {
+ Block* succs_block = block->_succs[h];
for (uint j = 1; j < succs_block->num_preds(); j++) {
Node* jpn = succs_block->pred(j);
if (jpn->is_JumpProj() && jpn->in(0) == mach) {
@@ -1425,7 +1427,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
}
}
}
-
#ifdef ASSERT
// Check that oop-store precedes the card-mark
else if (mach->ideal_Opcode() == Op_StoreCM) {
@@ -1436,17 +1437,18 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
if (oop_store == NULL) continue;
count++;
uint i4;
- for( i4 = 0; i4 < last_inst; ++i4 ) {
- if( b->_nodes[i4] == oop_store ) break;
+ for (i4 = 0; i4 < last_inst; ++i4) {
+ if (block->_nodes[i4] == oop_store) {
+ break;
+ }
}
// Note: This test can provide a false failure if other precedence
// edges have been added to the storeCMNode.
- assert( i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store");
+ assert(i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store");
}
assert(count > 0, "storeCM expects at least one precedence edge");
}
#endif
-
else if (!n->is_Proj()) {
// Remember the beginning of the previous instruction, in case
// it's followed by a flag-kill and a null-check. Happens on
@@ -1542,12 +1544,12 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
// If the next block is the top of a loop, pad this block out to align
// the loop top a little. Helps prevent pipe stalls at loop back branches.
if (i < nblocks-1) {
- Block *nb = _cfg->_blocks[i+1];
+ Block *nb = _cfg->get_block(i + 1);
int padding = nb->alignment_padding(current_offset);
if( padding > 0 ) {
MachNode *nop = new (this) MachNopNode(padding / nop_size);
- b->_nodes.insert( b->_nodes.size(), nop );
- _cfg->map_node_to_block(nop, b);
+ block->_nodes.insert(block->_nodes.size(), nop);
+ _cfg->map_node_to_block(nop, block);
nop->emit(*cb, _regalloc);
current_offset = cb->insts_size();
}
@@ -1587,8 +1589,6 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
}
#endif
- // ------------------
-
#ifndef PRODUCT
// Information on the size of the method, without the extraneous code
Scheduling::increment_method_size(cb->insts_size());
@@ -1649,52 +1649,55 @@ void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_start
_inc_table.set_size(cnt);
uint inct_cnt = 0;
- for( uint i=0; i<_cfg->_num_blocks; i++ ) {
- Block *b = _cfg->_blocks[i];
+ for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+ Block* block = _cfg->get_block(i);
Node *n = NULL;
int j;
// Find the branch; ignore trailing NOPs.
- for( j = b->_nodes.size()-1; j>=0; j-- ) {
- n = b->_nodes[j];
- if( !n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con )
+ for (j = block->_nodes.size() - 1; j >= 0; j--) {
+ n = block->_nodes[j];
+ if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) {
break;
+ }
}
// If we didn't find anything, continue
- if( j < 0 ) continue;
+ if (j < 0) {
+ continue;
+ }
// Compute ExceptionHandlerTable subtable entry and add it
// (skip empty blocks)
- if( n->is_Catch() ) {
+ if (n->is_Catch()) {
// Get the offset of the return from the call
- uint call_return = call_returns[b->_pre_order];
+ uint call_return = call_returns[block->_pre_order];
#ifdef ASSERT
assert( call_return > 0, "no call seen for this basic block" );
- while( b->_nodes[--j]->is_MachProj() ) ;
- assert( b->_nodes[j]->is_MachCall(), "CatchProj must follow call" );
+ while (block->_nodes[--j]->is_MachProj()) ;
+ assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call");
#endif
// last instruction is a CatchNode, find it's CatchProjNodes
- int nof_succs = b->_num_succs;
+ int nof_succs = block->_num_succs;
// allocate space
GrowableArray handler_bcis(nof_succs);
GrowableArray handler_pcos(nof_succs);
// iterate through all successors
for (int j = 0; j < nof_succs; j++) {
- Block* s = b->_succs[j];
+ Block* s = block->_succs[j];
bool found_p = false;
- for( uint k = 1; k < s->num_preds(); k++ ) {
- Node *pk = s->pred(k);
- if( pk->is_CatchProj() && pk->in(0) == n ) {
+ for (uint k = 1; k < s->num_preds(); k++) {
+ Node* pk = s->pred(k);
+ if (pk->is_CatchProj() && pk->in(0) == n) {
const CatchProjNode* p = pk->as_CatchProj();
found_p = true;
// add the corresponding handler bci & pco information
- if( p->_con != CatchProjNode::fall_through_index ) {
+ if (p->_con != CatchProjNode::fall_through_index) {
// p leads to an exception handler (and is not fall through)
- assert(s == _cfg->_blocks[s->_pre_order],"bad numbering");
+ assert(s == _cfg->get_block(s->_pre_order), "bad numbering");
// no duplicates, please
- if( !handler_bcis.contains(p->handler_bci()) ) {
+ if (!handler_bcis.contains(p->handler_bci())) {
uint block_num = s->non_connector()->_pre_order;
handler_bcis.append(p->handler_bci());
handler_pcos.append(blk_labels[block_num].loc_pos());
@@ -1713,9 +1716,9 @@ void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_start
}
// Handle implicit null exception table updates
- if( n->is_MachNullCheck() ) {
- uint block_num = b->non_connector_successor(0)->_pre_order;
- _inc_table.append( inct_starts[inct_cnt++], blk_labels[block_num].loc_pos() );
+ if (n->is_MachNullCheck()) {
+ uint block_num = block->non_connector_successor(0)->_pre_order;
+ _inc_table.append(inct_starts[inct_cnt++], blk_labels[block_num].loc_pos());
continue;
}
} // End of for all blocks fill in exception table entries
@@ -1774,14 +1777,12 @@ Scheduling::Scheduling(Arena *arena, Compile &compile)
memset(_current_latency, 0, node_max * sizeof(unsigned short));
// Clear the bundling information
- memcpy(_bundle_use_elements,
- Pipeline_Use::elaborated_elements,
- sizeof(Pipeline_Use::elaborated_elements));
+ memcpy(_bundle_use_elements, Pipeline_Use::elaborated_elements, sizeof(Pipeline_Use::elaborated_elements));
// Get the last node
- Block *bb = _cfg->_blocks[_cfg->_blocks.size()-1];
+ Block* block = _cfg->get_block(_cfg->number_of_blocks() - 1);
- _next_node = bb->_nodes[bb->_nodes.size()-1];
+ _next_node = block->_nodes[block->_nodes.size() - 1];
}
#ifndef PRODUCT
@@ -1831,7 +1832,6 @@ void Scheduling::step_and_clear() {
sizeof(Pipeline_Use::elaborated_elements));
}
-//------------------------------ScheduleAndBundle------------------------------
// Perform instruction scheduling and bundling over the sequence of
// instructions in backwards order.
void Compile::ScheduleAndBundle() {
@@ -1858,7 +1858,6 @@ void Compile::ScheduleAndBundle() {
scheduling.DoScheduling();
}
-//------------------------------ComputeLocalLatenciesForward-------------------
// Compute the latency of all the instructions. This is fairly simple,
// because we already have a legal ordering. Walk over the instructions
// from first to last, and compute the latency of the instruction based
@@ -2028,7 +2027,6 @@ Node * Scheduling::ChooseNodeToBundle() {
return _available[0];
}
-//------------------------------AddNodeToAvailableList-------------------------
void Scheduling::AddNodeToAvailableList(Node *n) {
assert( !n->is_Proj(), "projections never directly made available" );
#ifndef PRODUCT
@@ -2074,7 +2072,6 @@ void Scheduling::AddNodeToAvailableList(Node *n) {
#endif
}
-//------------------------------DecrementUseCounts-----------------------------
void Scheduling::DecrementUseCounts(Node *n, const Block *bb) {
for ( uint i=0; i < n->len(); i++ ) {
Node *def = n->in(i);
@@ -2097,7 +2094,6 @@ void Scheduling::DecrementUseCounts(Node *n, const Block *bb) {
}
}
-//------------------------------AddNodeToBundle--------------------------------
void Scheduling::AddNodeToBundle(Node *n, const Block *bb) {
#ifndef PRODUCT
if (_cfg->C->trace_opto_output()) {
@@ -2312,7 +2308,6 @@ void Scheduling::AddNodeToBundle(Node *n, const Block *bb) {
DecrementUseCounts(n,bb);
}
-//------------------------------ComputeUseCount--------------------------------
// This method sets the use count within a basic block. We will ignore all
// uses outside the current basic block. As we are doing a backwards walk,
// any node we reach that has a use count of 0 may be scheduled. This also
@@ -2397,20 +2392,22 @@ void Scheduling::DoScheduling() {
Block *bb;
// Walk over all the basic blocks in reverse order
- for( int i=_cfg->_num_blocks-1; i >= 0; succ_bb = bb, i-- ) {
- bb = _cfg->_blocks[i];
+ for (int i = _cfg->number_of_blocks() - 1; i >= 0; succ_bb = bb, i--) {
+ bb = _cfg->get_block(i);
#ifndef PRODUCT
if (_cfg->C->trace_opto_output()) {
tty->print("# Schedule BB#%03d (initial)\n", i);
- for (uint j = 0; j < bb->_nodes.size(); j++)
+ for (uint j = 0; j < bb->_nodes.size(); j++) {
bb->_nodes[j]->dump();
+ }
}
#endif
// On the head node, skip processing
- if( bb == _cfg->_broot )
+ if (bb == _cfg->get_root_block()) {
continue;
+ }
// Skip empty, connector blocks
if (bb->is_connector())
@@ -2547,7 +2544,6 @@ void Scheduling::DoScheduling() {
} // end DoScheduling
-//------------------------------verify_good_schedule---------------------------
// Verify that no live-range used in the block is killed in the block by a
// wrong DEF. This doesn't verify live-ranges that span blocks.
@@ -2560,7 +2556,6 @@ static bool edge_from_to( Node *from, Node *to ) {
}
#ifdef ASSERT
-//------------------------------verify_do_def----------------------------------
void Scheduling::verify_do_def( Node *n, OptoReg::Name def, const char *msg ) {
// Check for bad kills
if( OptoReg::is_valid(def) ) { // Ignore stores & control flow
@@ -2576,7 +2571,6 @@ void Scheduling::verify_do_def( Node *n, OptoReg::Name def, const char *msg ) {
}
}
-//------------------------------verify_good_schedule---------------------------
void Scheduling::verify_good_schedule( Block *b, const char *msg ) {
// Zap to something reasonable for the verify code
@@ -2636,7 +2630,6 @@ static void add_prec_edge_from_to( Node *from, Node *to ) {
from->add_prec(to);
}
-//------------------------------anti_do_def------------------------------------
void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is_def ) {
if( !OptoReg::is_valid(def_reg) ) // Ignore stores & control flow
return;
@@ -2706,7 +2699,6 @@ void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is
add_prec_edge_from_to(kill,pinch);
}
-//------------------------------anti_do_use------------------------------------
void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) {
if( !OptoReg::is_valid(use_reg) ) // Ignore stores & control flow
return;
@@ -2727,7 +2719,6 @@ void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) {
}
}
-//------------------------------ComputeRegisterAntidependences-----------------
// We insert antidependences between the reads and following write of
// allocated registers to prevent illegal code motion. Hopefully, the
// number of added references should be fairly small, especially as we
@@ -2861,8 +2852,6 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) {
}
}
-//------------------------------garbage_collect_pinch_nodes-------------------------------
-
// Garbage collect pinch nodes for reuse by other blocks.
//
// The block scheduler's insertion of anti-dependence
@@ -2937,7 +2926,6 @@ void Scheduling::cleanup_pinch( Node *pinch ) {
pinch->set_req(0, NULL);
}
-//------------------------------print_statistics-------------------------------
#ifndef PRODUCT
void Scheduling::dump_available() const {
diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp
index 654c6f724b9..a1d1527127e 100644
--- a/hotspot/src/share/vm/opto/phaseX.cpp
+++ b/hotspot/src/share/vm/opto/phaseX.cpp
@@ -1643,8 +1643,8 @@ void PhasePeephole::do_transform() {
bool method_name_not_printed = true;
// Examine each basic block
- for( uint block_number = 1; block_number < _cfg._num_blocks; ++block_number ) {
- Block *block = _cfg._blocks[block_number];
+ for (uint block_number = 1; block_number < _cfg.number_of_blocks(); ++block_number) {
+ Block* block = _cfg.get_block(block_number);
bool block_not_printed = true;
// and each instruction within a block
diff --git a/hotspot/src/share/vm/opto/postaloc.cpp b/hotspot/src/share/vm/opto/postaloc.cpp
index 76c3def2d40..fdb72dd42c6 100644
--- a/hotspot/src/share/vm/opto/postaloc.cpp
+++ b/hotspot/src/share/vm/opto/postaloc.cpp
@@ -405,28 +405,29 @@ void PhaseChaitin::post_allocate_copy_removal() {
// Need a mapping from basic block Node_Lists. We need a Node_List to
// map from register number to value-producing Node.
- Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1);
- memset( blk2value, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) );
+ Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
+ memset(blk2value, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
// Need a mapping from basic block Node_Lists. We need a Node_List to
// map from register number to register-defining Node.
- Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1);
- memset( blk2regnd, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) );
+ Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1);
+ memset(blk2regnd, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1));
// We keep unused Node_Lists on a free_list to avoid wasting
// memory.
GrowableArray free_list = GrowableArray(16);
// For all blocks
- for( uint i = 0; i < _cfg._num_blocks; i++ ) {
+ for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
uint j;
- Block *b = _cfg._blocks[i];
+ Block* block = _cfg.get_block(i);
// Count of Phis in block
uint phi_dex;
- for( phi_dex = 1; phi_dex < b->_nodes.size(); phi_dex++ ) {
- Node *phi = b->_nodes[phi_dex];
- if( !phi->is_Phi() )
+ for (phi_dex = 1; phi_dex < block->_nodes.size(); phi_dex++) {
+ Node* phi = block->_nodes[phi_dex];
+ if (!phi->is_Phi()) {
break;
+ }
}
// If any predecessor has not been visited, we do not know the state
@@ -434,21 +435,23 @@ void PhaseChaitin::post_allocate_copy_removal() {
// along Phi input edges
bool missing_some_inputs = false;
Block *freed = NULL;
- for( j = 1; j < b->num_preds(); j++ ) {
- Block *pb = _cfg.get_block_for_node(b->pred(j));
+ for (j = 1; j < block->num_preds(); j++) {
+ Block* pb = _cfg.get_block_for_node(block->pred(j));
// Remove copies along phi edges
- for( uint k=1; k_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false );
- if( blk2value[pb->_pre_order] ) { // Have a mapping on this edge?
+ for (uint k = 1; k < phi_dex; k++) {
+ elide_copy(block->_nodes[k], j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false);
+ }
+ if (blk2value[pb->_pre_order]) { // Have a mapping on this edge?
// See if this predecessor's mappings have been used by everybody
// who wants them. If so, free 'em.
uint k;
- for( k=0; k_num_succs; k++ ) {
- Block *pbsucc = pb->_succs[k];
- if( !blk2value[pbsucc->_pre_order] && pbsucc != b )
+ for (k = 0; k < pb->_num_succs; k++) {
+ Block* pbsucc = pb->_succs[k];
+ if (!blk2value[pbsucc->_pre_order] && pbsucc != block) {
break; // Found a future user
+ }
}
- if( k >= pb->_num_succs ) { // No more uses, free!
+ if (k >= pb->_num_succs) { // No more uses, free!
freed = pb; // Record last block freed
free_list.push(blk2value[pb->_pre_order]);
free_list.push(blk2regnd[pb->_pre_order]);
@@ -467,20 +470,20 @@ void PhaseChaitin::post_allocate_copy_removal() {
value.map(_max_reg,NULL);
regnd.map(_max_reg,NULL);
// Set mappings as OUR mappings
- blk2value[b->_pre_order] = &value;
- blk2regnd[b->_pre_order] = ®nd;
+ blk2value[block->_pre_order] = &value;
+ blk2regnd[block->_pre_order] = ®nd;
// Initialize value & regnd for this block
- if( missing_some_inputs ) {
+ if (missing_some_inputs) {
// Some predecessor has not yet been visited; zap map to empty
- for( uint k = 0; k < (uint)_max_reg; k++ ) {
+ for (uint k = 0; k < (uint)_max_reg; k++) {
value.map(k,NULL);
regnd.map(k,NULL);
}
} else {
if( !freed ) { // Didn't get a freebie prior block
// Must clone some data
- freed = _cfg.get_block_for_node(b->pred(1));
+ freed = _cfg.get_block_for_node(block->pred(1));
Node_List &f_value = *blk2value[freed->_pre_order];
Node_List &f_regnd = *blk2regnd[freed->_pre_order];
for( uint k = 0; k < (uint)_max_reg; k++ ) {
@@ -489,9 +492,11 @@ void PhaseChaitin::post_allocate_copy_removal() {
}
}
// Merge all inputs together, setting to NULL any conflicts.
- for( j = 1; j < b->num_preds(); j++ ) {
- Block *pb = _cfg.get_block_for_node(b->pred(j));
- if( pb == freed ) continue; // Did self already via freelist
+ for (j = 1; j < block->num_preds(); j++) {
+ Block* pb = _cfg.get_block_for_node(block->pred(j));
+ if (pb == freed) {
+ continue; // Did self already via freelist
+ }
Node_List &p_regnd = *blk2regnd[pb->_pre_order];
for( uint k = 0; k < (uint)_max_reg; k++ ) {
if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs?
@@ -503,9 +508,9 @@ void PhaseChaitin::post_allocate_copy_removal() {
}
// For all Phi's
- for( j = 1; j < phi_dex; j++ ) {
+ for (j = 1; j < phi_dex; j++) {
uint k;
- Node *phi = b->_nodes[j];
+ Node *phi = block->_nodes[j];
uint pidx = _lrg_map.live_range_id(phi);
OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg();
@@ -516,8 +521,8 @@ void PhaseChaitin::post_allocate_copy_removal() {
if( phi != x && u != x ) // Found a different input
u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
}
- if( u != NodeSentinel ) { // Junk Phi. Remove
- b->_nodes.remove(j--);
+ if (u != NodeSentinel) { // Junk Phi. Remove
+ block->_nodes.remove(j--);
phi_dex--;
_cfg.unmap_node_from_block(phi);
phi->replace_by(u);
@@ -547,13 +552,13 @@ void PhaseChaitin::post_allocate_copy_removal() {
}
// For all remaining instructions
- for( j = phi_dex; j < b->_nodes.size(); j++ ) {
- Node *n = b->_nodes[j];
+ for (j = phi_dex; j < block->_nodes.size(); j++) {
+ Node* n = block->_nodes[j];
- if( n->outcnt() == 0 && // Dead?
- n != C->top() && // (ignore TOP, it has no du info)
- !n->is_Proj() ) { // fat-proj kills
- j -= yank_if_dead(n,b,&value,®nd);
+ if(n->outcnt() == 0 && // Dead?
+ n != C->top() && // (ignore TOP, it has no du info)
+ !n->is_Proj() ) { // fat-proj kills
+ j -= yank_if_dead(n, block, &value, ®nd);
continue;
}
@@ -598,8 +603,9 @@ void PhaseChaitin::post_allocate_copy_removal() {
const uint two_adr = n->is_Mach() ? n->as_Mach()->two_adr() : 0;
// Remove copies along input edges
- for( k = 1; k < n->req(); k++ )
- j -= elide_copy( n, k, b, value, regnd, two_adr!=k );
+ for (k = 1; k < n->req(); k++) {
+ j -= elide_copy(n, k, block, value, regnd, two_adr != k);
+ }
// Unallocated Nodes define no registers
uint lidx = _lrg_map.live_range_id(n);
@@ -630,8 +636,8 @@ void PhaseChaitin::post_allocate_copy_removal() {
// then 'n' is a useless copy. Do not update the register->node
// mapping so 'n' will go dead.
if( value[nreg] != val ) {
- if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) {
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ if (eliminate_copy_of_constant(val, n, block, value, regnd, nreg, OptoReg::Bad)) {
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
} else {
// Update the mapping: record new Node defined by the register
regnd.map(nreg,n);
@@ -640,8 +646,8 @@ void PhaseChaitin::post_allocate_copy_removal() {
value.map(nreg,val);
}
} else if( !may_be_copy_of_callee(n) ) {
- assert( n->is_Copy(), "" );
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ assert(n->is_Copy(), "");
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
}
} else if (RegMask::is_vector(n_ideal_reg)) {
// If Node 'n' does not change the value mapped by the register,
@@ -660,7 +666,7 @@ void PhaseChaitin::post_allocate_copy_removal() {
}
} else if (n->is_Copy()) {
// Note: vector can't be constant and can't be copy of calee.
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
}
} else {
// If the value occupies a register pair, record same info
@@ -674,18 +680,18 @@ void PhaseChaitin::post_allocate_copy_removal() {
tmp.Remove(nreg);
nreg_lo = tmp.find_first_elem();
}
- if( value[nreg] != val || value[nreg_lo] != val ) {
- if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) {
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ if (value[nreg] != val || value[nreg_lo] != val) {
+ if (eliminate_copy_of_constant(val, n, block, value, regnd, nreg, nreg_lo)) {
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
} else {
regnd.map(nreg , n );
regnd.map(nreg_lo, n );
value.map(nreg ,val);
value.map(nreg_lo,val);
}
- } else if( !may_be_copy_of_callee(n) ) {
- assert( n->is_Copy(), "" );
- j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+ } else if (!may_be_copy_of_callee(n)) {
+ assert(n->is_Copy(), "");
+ j -= replace_and_yank_if_dead(n, nreg, block, value, regnd);
}
}
diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp
index 6e4323b406e..ac4f8e35824 100644
--- a/hotspot/src/share/vm/opto/reg_split.cpp
+++ b/hotspot/src/share/vm/opto/reg_split.cpp
@@ -397,10 +397,15 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint
#endif
// See if the cloned def kills any flags, and copy those kills as well
uint i = insidx+1;
- if( clone_projs( b, i, def, spill, maxlrg) ) {
+ int found_projs = clone_projs( b, i, def, spill, maxlrg);
+ if (found_projs > 0) {
// Adjust the point where we go hi-pressure
- if( i <= b->_ihrp_index ) b->_ihrp_index++;
- if( i <= b->_fhrp_index ) b->_fhrp_index++;
+ if (i <= b->_ihrp_index) {
+ b->_ihrp_index += found_projs;
+ }
+ if (i <= b->_fhrp_index) {
+ b->_fhrp_index += found_projs;
+ }
}
return spill;
@@ -529,13 +534,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
// a Def is UP or DOWN. UP means that it should get a register (ie -
// it is always in LRP regions), and DOWN means that it is probably
// on the stack (ie - it crosses HRP regions).
- Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
- bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
+ Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg.number_of_blocks() + 1);
+ bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg.number_of_blocks() + 1);
Node **debug_defs = NEW_SPLIT_ARRAY( Node*, spill_cnt );
VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
// Initialize Reaches & UP
- for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
+ for (bidx = 0; bidx < _cfg.number_of_blocks() + 1; bidx++) {
Reaches[bidx] = NEW_SPLIT_ARRAY( Node*, spill_cnt );
UP[bidx] = NEW_SPLIT_ARRAY( bool, spill_cnt );
Node **Reachblock = Reaches[bidx];
@@ -555,13 +560,13 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
//----------PASS 1----------
//----------Propagation & Node Insertion Code----------
// Walk the Blocks in RPO for DEF & USE info
- for( bidx = 0; bidx < _cfg._num_blocks; bidx++ ) {
+ for( bidx = 0; bidx < _cfg.number_of_blocks(); bidx++ ) {
if (C->check_node_count(spill_cnt, out_of_nodes)) {
return 0;
}
- b = _cfg._blocks[bidx];
+ b = _cfg.get_block(bidx);
// Reaches & UP arrays for this block
Reachblock = Reaches[b->_pre_order];
UPblock = UP[b->_pre_order];
@@ -1394,8 +1399,8 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
// DEBUG
#ifdef ASSERT
// Validate all live range index assignments
- for (bidx = 0; bidx < _cfg._num_blocks; bidx++) {
- b = _cfg._blocks[bidx];
+ for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) {
+ b = _cfg.get_block(bidx);
for (insidx = 0; insidx <= b->end_idx(); insidx++) {
Node *n = b->_nodes[insidx];
uint defidx = _lrg_map.find(n);
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index 188cf4a6e60..ea44e2c6679 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -3234,19 +3234,22 @@ JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
env, string, (uintptr_t *) isCopy);
#endif /* USDT2 */
- //%note jni_5
- if (isCopy != NULL) {
- *isCopy = JNI_TRUE;
- }
oop s = JNIHandles::resolve_non_null(string);
int s_len = java_lang_String::length(s);
typeArrayOop s_value = java_lang_String::value(s);
int s_offset = java_lang_String::offset(s);
- jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1, mtInternal); // add one for zero termination
- if (s_len > 0) {
- memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
+ jchar* buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
+ /* JNI Specification states return NULL on OOM */
+ if (buf != NULL) {
+ if (s_len > 0) {
+ memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
+ }
+ buf[s_len] = 0;
+ //%note jni_5
+ if (isCopy != NULL) {
+ *isCopy = JNI_TRUE;
+ }
}
- buf[s_len] = 0;
#ifndef USDT2
DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
#else /* USDT2 */
@@ -3335,9 +3338,14 @@ JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboole
#endif /* USDT2 */
oop java_string = JNIHandles::resolve_non_null(string);
size_t length = java_lang_String::utf8_length(java_string);
- char* result = AllocateHeap(length + 1, mtInternal);
- java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
- if (isCopy != NULL) *isCopy = JNI_TRUE;
+ /* JNI Specification states return NULL on OOM */
+ char* result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
+ if (result != NULL) {
+ java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
+ if (isCopy != NULL) {
+ *isCopy = JNI_TRUE;
+ }
+ }
#ifndef USDT2
DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
#else /* USDT2 */
@@ -3591,11 +3599,16 @@ JNI_QUICK_ENTRY(ElementType*, \
* Avoid asserts in typeArrayOop. */ \
result = (ElementType*)get_bad_address(); \
} else { \
- result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \
- /* copy the array to the c chunk */ \
- memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
+ /* JNI Specification states return NULL on OOM */ \
+ result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
+ if (result != NULL) { \
+ /* copy the array to the c chunk */ \
+ memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
+ if (isCopy) { \
+ *isCopy = JNI_TRUE; \
+ } \
+ } \
} \
- if (isCopy) *isCopy = JNI_TRUE; \
DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\
return result; \
JNI_END
@@ -3628,11 +3641,16 @@ JNI_QUICK_ENTRY(ElementType*, \
* Avoid asserts in typeArrayOop. */ \
result = (ElementType*)get_bad_address(); \
} else { \
- result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \
- /* copy the array to the c chunk */ \
- memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
+ /* JNI Specification states return NULL on OOM */ \
+ result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
+ if (result != NULL) { \
+ /* copy the array to the c chunk */ \
+ memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
+ if (isCopy) { \
+ *isCopy = JNI_TRUE; \
+ } \
+ } \
} \
- if (isCopy) *isCopy = JNI_TRUE; \
ReturnProbe; \
return result; \
JNI_END
@@ -5027,9 +5045,15 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
tty->print_cr("Running test: " #unit_test_function_call); \
unit_test_function_call
+// Forward declaration
+void TestReservedSpace_test();
+void TestReserveMemorySpecial_test();
+
void execute_internal_vm_tests() {
if (ExecuteInternalVMTests) {
tty->print_cr("Running internal VM tests");
+ run_unit_test(TestReservedSpace_test());
+ run_unit_test(TestReserveMemorySpecial_test());
run_unit_test(GlobalDefinitions::test_globals());
run_unit_test(GCTimerAllTest::all());
run_unit_test(arrayOopDesc::test_max_array_length());
diff --git a/hotspot/src/share/vm/prims/jvmti.xml b/hotspot/src/share/vm/prims/jvmti.xml
index c23a7b5e1c3..87a28ae0cfc 100644
--- a/hotspot/src/share/vm/prims/jvmti.xml
+++ b/hotspot/src/share/vm/prims/jvmti.xml
@@ -1,7 +1,7 @@
KO!!! "+obj.getClass().getSimpleName()+".hashCode got NPE with a null "+param);
+ failed++;
+ }
+
+ try {
+ obj.toString();
+ System.out.println("OK: "+obj.getClass().getSimpleName()+".toString worked with a null "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO!!! "+obj.getClass().getSimpleName()+".toString got NPE.");
+ failed++;
+ }
+ }
+}
diff --git a/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java
new file mode 100644
index 00000000000..452e940b0fd
--- /dev/null
+++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
+import javax.management.openmbean.OpenMBeanConstructorInfo;
+import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
+import javax.management.openmbean.OpenMBeanInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenMBeanOperationInfo;
+import javax.management.openmbean.OpenMBeanOperationInfoSupport;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.SimpleType;
+
+/*
+ * @test
+ * @bug 8023529
+ * @summary Test that OpenMBean*Info.equals do not throw NPE
+ * @author Shanliang JIANG
+ * @run clean OpenMBeanInfoEqualsNPETest
+ * @run build OpenMBeanInfoEqualsNPETest
+ * @run main OpenMBeanInfoEqualsNPETest
+ */
+public class OpenMBeanInfoEqualsNPETest {
+ private static int failed = 0;
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("---OpenMBeanInfoEqualsNPETest-main ...");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanAttributeInfoSupport...");
+ OpenMBeanAttributeInfo openMBeanAttributeInfo0 = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, 1, new Integer[]{1, 2, 3});
+ OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3});
+ test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "defaultValue");
+
+ openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, 1, null);
+ test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "legalValues");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport...");
+ OpenMBeanConstructorInfo openMBeanConstructorInfo0 = new OpenMBeanConstructorInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, new DescriptorSupport());
+ OpenMBeanConstructorInfo openMBeanConstructorInfo;
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", null, new DescriptorSupport());
+ test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "sigs");
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, null);
+ test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanOperationInfoSupport...");
+ OpenMBeanOperationInfo openMBeanOperationInfo0 = new OpenMBeanOperationInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, new DescriptorSupport());
+ OpenMBeanOperationInfo openMBeanOperationInfo;
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport());
+ test(openMBeanOperationInfo0, openMBeanOperationInfo, "sigs");
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, MBeanOperationInfo.UNKNOWN, null);
+ test(openMBeanOperationInfo0, openMBeanOperationInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1...");
+ OpenMBeanParameterInfo openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, -1, 1);
+ OpenMBeanParameterInfo openMBeanParameterInfo;
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, -1, 1);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, null, 1);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "min value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, -1, null);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "max value");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2...");
+ openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2});
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2});
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, null);
+ test(openMBeanParameterInfo0, openMBeanParameterInfo, "legal values");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanInfoSupport...");
+ String className = "toto";
+ String description = "titi";
+ OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{};
+ OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{};
+ OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{};
+ MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{};
+
+ OpenMBeanInfo ominfo0 = new OpenMBeanInfoSupport("toto", description, attrInfos, constrInfos, operaInfos, notifInfos);
+ OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "class name");
+
+ ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "description");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "attrInfos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos);
+ test(ominfo0, ominfo, "constructor infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos);
+ test(ominfo0, ominfo, "operation infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null);
+ test(ominfo0, ominfo, "notif infos");
+
+ if (failed > 0) {
+ throw new RuntimeException("Test failed: "+failed);
+ } else {
+ System.out.println("---Test: PASSED");
+ }
+ }
+
+ private static void test(Object obj1, Object obj2, String param) {
+ try {
+ obj1.equals(obj2);
+ System.out.println("OK-1: "+obj1.getClass().getSimpleName()+
+ ".equals worked with a null field: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+
+ ".equals got NPE with a null field: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+
+ try {
+ obj2.equals(obj1);
+ System.out.println("OK-2: "+obj2.getClass().getSimpleName()+
+ ".equals worked with a null field: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+
+ ".equals got NPE with a null field: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+
+ try {
+ obj1.equals(null);
+ obj2.equals(null);
+
+ System.out.println("OK-3: "+obj1.getClass().getSimpleName()+
+ ".equals worked with a null object.");
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+
+ ".equals got NPE with a null object.");
+ npe.printStackTrace();
+ failed++;
+ }
+ }
+}
diff --git a/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java
new file mode 100644
index 00000000000..3c829434193
--- /dev/null
+++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.management.MBeanNotificationInfo;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.openmbean.OpenMBeanAttributeInfo;
+import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
+import javax.management.openmbean.OpenMBeanConstructorInfo;
+import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
+import javax.management.openmbean.OpenMBeanInfo;
+import javax.management.openmbean.OpenMBeanInfoSupport;
+import javax.management.openmbean.OpenMBeanOperationInfo;
+import javax.management.openmbean.OpenMBeanOperationInfoSupport;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.SimpleType;
+
+/*
+ * @test
+ * @bug 8023529
+ * @summary Test that OpenMBean*Info.hashCode do not throw NPE
+ * @author Shanliang JIANG
+ * @run clean OpenMBeanInfoHashCodeNPETest
+ * @run build OpenMBeanInfoHashCodeNPETest
+ * @run main OpenMBeanInfoHashCodeNPETest
+ */
+public class OpenMBeanInfoHashCodeNPETest {
+ private static int failed = 0;
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("---OpenMBeanInfoHashCodeNPETest-main ...");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanInfohashCodeTest...");
+ OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3});
+ test(openMBeanAttributeInfo, "defaultValue");
+
+ openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport(
+ "name", "description", SimpleType.INTEGER, true, true, false, 1, null);
+ test(openMBeanAttributeInfo, "legalValues");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport...");
+ OpenMBeanConstructorInfo openMBeanConstructorInfo;
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", null, new DescriptorSupport());
+ test(openMBeanConstructorInfo, "sigs");
+
+ openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, null);
+ test(openMBeanConstructorInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanOperationInfoSupport...");
+ OpenMBeanOperationInfo openMBeanOperationInfo;
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport());
+ test(openMBeanOperationInfo, "sigs");
+
+ openMBeanOperationInfo = new OpenMBeanOperationInfoSupport(
+ "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, null);
+ test(openMBeanOperationInfo, "Descriptor");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1...");
+ OpenMBeanParameterInfo openMBeanParameterInfo;
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, -1, 1);
+ test(openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, null, 1);
+ test(openMBeanParameterInfo, "min value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 0, -1, null);
+ test(openMBeanParameterInfo, "max value");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2...");
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2});
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2});
+ test(openMBeanParameterInfo, "default value");
+
+ openMBeanParameterInfo = new OpenMBeanParameterInfoSupport(
+ "name", "description", SimpleType.INTEGER, 1, null);
+ test(openMBeanParameterInfo, "legal values");
+
+ // ----
+ System.out.println("\n---Testing on OpenMBeanInfoSupport...");
+ String className = "toto";
+ String description = "titi";
+ OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{};
+ OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{};
+ OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{};
+ MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{};
+
+ OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo, "class name");
+
+ ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos);
+ test(ominfo, "description");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos);
+ test(ominfo, "attrInfos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos);
+ test(ominfo, "constructor infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos);
+ test(ominfo, "operation infos");
+
+ ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null);
+ test(ominfo, "notif infos");
+
+ if (failed > 0) {
+ throw new RuntimeException("Test failed: "+failed);
+ } else {
+ System.out.println("---Test: PASSED");
+ }
+ }
+
+ private static void test(Object obj, String param) {
+ try {
+ obj.hashCode();
+ System.out.println("OK-1: "+obj.getClass().getSimpleName()+
+ ".hashCode worked with a null paramer: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+
+ ".hashCode got NPE with null paramer: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+
+ try {
+ obj.toString();
+ System.out.println("OK-1: "+obj.getClass().getSimpleName()+
+ ".toString worked with a null paramer: "+param);
+ } catch (NullPointerException npe) {
+ System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+
+ ".toString got NPE with null paramer: "+param);
+ npe.printStackTrace();
+ failed++;
+ }
+ }
+}
diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java
new file mode 100644
index 00000000000..86efed134f3
--- /dev/null
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Map;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXPrincipal;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnector;
+import javax.security.auth.Subject;
+
+/*
+ * @test
+ * @bug 6566891
+ * @summary Check no memory leak on RMIConnector's rmbscMap
+ * @author Shanliang JIANG
+ * @run clean RMIConnectorInternalMapTest
+ * @run build RMIConnectorInternalMapTest
+ * @run main RMIConnectorInternalMapTest
+ */
+
+public class RMIConnectorInternalMapTest {
+ public static void main(String[] args) throws Exception {
+ System.out.println("---RMIConnectorInternalMapTest starting...");
+
+ JMXConnectorServer connectorServer = null;
+ JMXConnector connectorClient = null;
+
+ try {
+ MBeanServer mserver = ManagementFactory.getPlatformMBeanServer();
+ JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0);
+ connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver);
+ connectorServer.start();
+
+ JMXServiceURL serverAddr = connectorServer.getAddress();
+ connectorClient = JMXConnectorFactory.connect(serverAddr, null);
+ connectorClient.connect();
+
+ Field rmbscMapField = RMIConnector.class.getDeclaredField("rmbscMap");
+ rmbscMapField.setAccessible(true);
+ Map> map =
+ (Map>) rmbscMapField.get(connectorClient);
+ if (map != null && !map.isEmpty()) { // failed
+ throw new RuntimeException("RMIConnector's rmbscMap must be empty at the initial time.");
+ }
+
+ Subject delegationSubject =
+ new Subject(true,
+ Collections.singleton(new JMXPrincipal("delegate")),
+ Collections.EMPTY_SET,
+ Collections.EMPTY_SET);
+ MBeanServerConnection mbsc1 =
+ connectorClient.getMBeanServerConnection(delegationSubject);
+ MBeanServerConnection mbsc2 =
+ connectorClient.getMBeanServerConnection(delegationSubject);
+
+ if (mbsc1 == null) {
+ throw new RuntimeException("Got null connection.");
+ }
+ if (mbsc1 != mbsc2) {
+ throw new RuntimeException("Not got same connection with a same subject.");
+ }
+
+ map = (Map>) rmbscMapField.get(connectorClient);
+ if (map == null || map.isEmpty()) { // failed
+ throw new RuntimeException("RMIConnector's rmbscMap has wrong size "
+ + "after creating a delegated connection.");
+ }
+
+ delegationSubject = null;
+ mbsc1 = null;
+ mbsc2 = null;
+
+ int i = 0;
+ while (!map.isEmpty() && i++ < 60) {
+ System.gc();
+ Thread.sleep(100);
+ }
+ System.out.println("---GC times: " + i);
+
+ if (!map.isEmpty()) {
+ throw new RuntimeException("Failed to clean RMIConnector's rmbscMap");
+ } else {
+ System.out.println("---RMIConnectorInternalMapTest: PASSED!");
+ }
+ } finally {
+ try {
+ connectorClient.close();
+ connectorServer.stop();
+ } catch (Exception e) {
+ }
+ }
+ }
+}
diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java
new file mode 100644
index 00000000000..7b5224e9b92
--- /dev/null
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnector;
+
+/*
+ * @test
+ * @bug 6566891
+ * @summary Check no memory leak on RMIConnector's nullSubjectConn
+ * @author Shanliang JIANG
+ * @run clean RMIConnectorNullSubjectConnTest
+ * @run build RMIConnectorNullSubjectConnTest
+ * @run main RMIConnectorNullSubjectConnTest
+ */
+
+public class RMIConnectorNullSubjectConnTest {
+ public static void main(String[] args) throws Exception {
+ System.out.println("---RMIConnectorNullSubjectConnTest starting...");
+
+ JMXConnectorServer connectorServer = null;
+ JMXConnector connectorClient = null;
+
+ try {
+ MBeanServer mserver = ManagementFactory.getPlatformMBeanServer();
+ JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0);
+ connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver);
+ connectorServer.start();
+
+ JMXServiceURL serverAddr = connectorServer.getAddress();
+ connectorClient = JMXConnectorFactory.connect(serverAddr, null);
+ connectorClient.connect();
+
+ Field nullSubjectConnField = RMIConnector.class.getDeclaredField("nullSubjectConnRef");
+ nullSubjectConnField.setAccessible(true);
+
+ WeakReference weak =
+ (WeakReference)nullSubjectConnField.get(connectorClient);
+
+ if (weak != null && weak.get() != null) {
+ throw new RuntimeException("nullSubjectConnRef must be null at initial time.");
+ }
+
+ MBeanServerConnection conn1 = connectorClient.getMBeanServerConnection(null);
+ MBeanServerConnection conn2 = connectorClient.getMBeanServerConnection(null);
+ if (conn1 == null) {
+ throw new RuntimeException("A connection with null subject should not be null.");
+ } else if (conn1 != conn2) {
+ throw new RuntimeException("The 2 connections with null subject are not equal.");
+ }
+
+ conn1 = null;
+ conn2 = null;
+ int i = 1;
+ do {
+ System.gc();
+ Thread.sleep(100);
+ weak = (WeakReference)nullSubjectConnField.get(connectorClient);
+ } while ((weak != null && weak.get() != null) && i++ < 60);
+
+ System.out.println("---GC times: " + i);
+
+ if (weak != null && weak.get() != null) {
+ throw new RuntimeException("Failed to clean RMIConnector's nullSubjectConn");
+ } else {
+ System.out.println("---RMIConnectorNullSubjectConnTest: PASSED!");
+ }
+ } finally {
+ try {
+ connectorClient.close();
+ connectorServer.stop();
+ } catch (Exception e) {
+ }
+ }
+ }
+}
diff --git a/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java
new file mode 100644
index 00000000000..805a6a203cb
--- /dev/null
+++ b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Field;
+import java.util.function.Function;
+
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestCallerSensitive {
+
+ private static void getF(T arg) {
+ Function,Field[]> firstFunction = Class::getFields;
+ }
+
+ public void testConstructorReferenceVarArgs() {
+ getF("Hello World");
+ }
+
+}
diff --git a/jdk/test/sun/security/krb5/runNameEquals.sh b/jdk/test/sun/security/krb5/runNameEquals.sh
index 6db90c35315..b9cfb08d8b5 100644
--- a/jdk/test/sun/security/krb5/runNameEquals.sh
+++ b/jdk/test/sun/security/krb5/runNameEquals.sh
@@ -22,7 +22,7 @@
#
# @test
-# @bug 6317711 6944847
+# @bug 6317711 6944847 8024046
# @summary Ensure the GSSName has the correct impl which respects
# the contract for equals and hashCode across different configurations.
@@ -56,6 +56,15 @@ case "$OS" in
PATHSEP=":"
FILESEP="/"
NATIVE=true
+ # Not all *nix has native GSS libs installed
+ krb5-config --libs gssapi 2> /dev/null
+ if [ $? != 0 ]; then
+ # Fedora has a different path
+ /usr/kerberos/bin/krb5-config --libs gssapi 2> /dev/null
+ if [ $? != 0 ]; then
+ NATIVE=false
+ fi
+ fi
;;
CYGWIN* )
PATHSEP=";"
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java
index c6dd8ce9720..b64d424fe88 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java
@@ -21,17 +21,24 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4969799
* @summary javax.net.ssl.SSLSocket.SSLSocket(InetAddress,int) shouldn't
* throw exception
- *
- * This is making sure that starting a new handshake throws the right
- * exception. There is a similar test for SSLSocket.
- *
+ * @run main/othervm CloseEngineException
*/
+//
+// This is making sure that starting a new handshake throws the right
+// exception. There is a similar test for SSLSocket.
+//
+
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java
index 7d9274af36e..1c6103bb353 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java
@@ -21,11 +21,17 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4931274
* @summary closeInbound does not signal when a close_notify has not
* been received.
+ * @run main/othervm CloseInboundException
* @author Brad Wetmore
*/
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java
index 57224816b71..3c3e2e22b3d 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java
@@ -21,15 +21,22 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 5019096
* @summary Add scatter/gather APIs for SSLEngine
- *
- * Check to see if the args are being parsed properly.
- *
+ * @run main/othervm CloseStart
*/
+//
+// Check to see if the args are being parsed properly.
+//
+
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java
index f9548d60be5..e912ff69b95 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java
@@ -21,11 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4969459
* @summary Delegated tasks are not reflecting the subclasses of SSLException
- *
+ * @run main/othervm DelegatedTaskWrongException
*/
import javax.net.ssl.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java
index f77938869f3..49387e3589b 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java
@@ -21,10 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 6728126
* @summary Parsing Extensions in Client Hello message is done in a wrong way
+ * @run main/othervm EmptyExtensionData
*/
import javax.net.ssl.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java
index ed1f84caeef..b7a1a9c509a 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java
@@ -21,11 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4980882
* @summary SSLEngine should enforce setUseClientMode
- *
+ * @run main/othervm EngineEnforceUseClientMode
* @author Brad R. Wetmore
*/
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
index da8e591d922..fbe2f2e7854 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
@@ -21,16 +21,21 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 6207322
* @summary SSLEngine is returning a premature FINISHED message when doing
- * an abbreviated handshake.
+ * an abbreviated handshake.
* @run main/othervm RehandshakeFinished
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
- *
+ * @author Brad Wetmore
+ */
+
+/*
* This test may need some updating if the messages change order.
* Currently I'm expecting that there is a simple renegotiation, with
* each message being contained in a single SSL packet.
@@ -41,8 +46,6 @@
* FINISHED
* CCS
* FINISHED
- *
- * @author Brad Wetmore
*/
/**
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
new file mode 100644
index 00000000000..c25d74c7d2c
--- /dev/null
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 7188657
+ * @summary There should be a way to reorder the JSSE ciphers
+ * @run main/othervm UseCipherSuitesOrder
+ * TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+import java.util.Arrays;
+
+public class UseCipherSuitesOrder {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+ // use local cipher suites preference
+ SSLParameters params = sslServerSocket.getSSLParameters();
+ params.setUseCipherSuitesOrder(true);
+ params.setCipherSuites(srvEnabledCipherSuites);
+ sslServerSocket.setSSLParameters(params);
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ SSLSession session = sslSocket.getSession();
+ if (!srvEnabledCipherSuites[0].equals(session.getCipherSuite())) {
+ throw new Exception(
+ "Expected to negotiate " + srvEnabledCipherSuites[0] +
+ " , but not " + session.getCipherSuite());
+ }
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+ sslSocket.setEnabledCipherSuites(cliEnabledCipherSuites);
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ // client enabled cipher suites
+ private static String[] cliEnabledCipherSuites;
+
+ // server enabled cipher suites
+ private static String[] srvEnabledCipherSuites;
+
+ private static void parseArguments(String[] args) throws Exception {
+ if (args.length != 1) {
+ System.out.println("Usage: java UseCipherSuitesOrder ciphersuites");
+ System.out.println("\tciphersuites: " +
+ "a list of enabled cipher suites, separated with comma");
+ throw new Exception("Incorrect usage");
+ }
+
+ cliEnabledCipherSuites = args[0].split(",");
+
+ if (cliEnabledCipherSuites.length < 2) {
+ throw new Exception("Need to enable at least two cipher suites");
+ }
+
+ // Only need to use 2 cipher suites in server side.
+ srvEnabledCipherSuites = Arrays.copyOf(
+ cliEnabledCipherSuites, 2);
+
+ // Reverse the cipher suite preference in server side.
+ srvEnabledCipherSuites[0] = cliEnabledCipherSuites[1];
+ srvEnabledCipherSuites[1] = cliEnabledCipherSuites[0];
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+ // parse the arguments
+ parseArguments(args);
+
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Start the tests.
+ */
+ new UseCipherSuitesOrder();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ UseCipherSuitesOrder() throws Exception {
+ Exception startException = null;
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ startException = e;
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ if (serverThread != null) {
+ serverThread.join();
+ }
+ } else {
+ if (clientThread != null) {
+ clientThread.join();
+ }
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
+ */
+ if ((local != null) && (remote != null)) {
+ // If both failed, return the curthread's exception.
+ local.initCause(remote);
+ exception = local;
+ } else if (local != null) {
+ exception = local;
+ } else if (remote != null) {
+ exception = remote;
+ } else if (startException != null) {
+ exception = startException;
+ }
+
+ /*
+ * If there was an exception *AND* a startException,
+ * output it.
+ */
+ if (exception != null) {
+ if (exception != startException && startException != null) {
+ exception.addSuppressed(startException);
+ }
+ throw exception;
+ }
+
+ // Fall-through: no exception to throw!
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java
index 4d5460739cd..a6a6912c0aa 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java
@@ -34,7 +34,7 @@ public class IllegalSNIName {
public static void main(String[] args) throws Exception {
String[] illegalNames = {
- "example\u3003\u3002com",
+ "example\u3002\u3002com",
"example..com",
"com\u3002",
"com.",
diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java
deleted file mode 100644
index 082776667a4..00000000000
--- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- *
- *
- * This isn't the test case: ImmutableResourceTest.sh is.
- * Refer to ImmutableResourceTest.sh when running this test.
- *
- * @bug 6287579
- * @summary SubClasses of ListResourceBundle should fix getContents()
- */
-import java.util.ResourceBundle;
-
-public class ImmutableResourceTest {
-
- public static void main(String[] args) throws Exception {
-
- /* Reach under the covers and get the message strings */
- sun.tools.jconsole.resources.JConsoleResources jcr =
- new sun.tools.jconsole.resources.JConsoleResources ();
- Object [][] testData = jcr.getContents();
-
- /* Shred our copy of the message strings */
- for (int ii = 0; ii < testData.length; ii++) {
- testData[ii][0] = "xxx";
- testData[ii][1] = "yyy";
- }
-
- /*
- * Try a lookup for the shredded key.
- * If this is successful we have a problem.
- */
- String ss = sun.tools.jconsole.Resources.getText("xxx");
- if ("yyy".equals(ss)) {
- throw new Exception ("SubClasses of ListResourceBundle should fix getContents()");
- }
- System.out.println("...Finished.");
- }
-}
diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh
deleted file mode 100644
index dedf21271b0..00000000000
--- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6287579
-# @summary SubClasses of ListResourceBundle should fix getContents()
-#
-# @run shell ImmutableResourceTest.sh
-
-# Beginning of subroutines:
-status=1
-
-#Call this from anywhere to fail the test with an error message
-# usage: fail "reason why the test failed"
-fail()
- { echo "The test failed :-("
- echo "$*" 1>&2
- echo "exit status was $status"
- exit $status
- } #end of fail()
-
-#Call this from anywhere to pass the test with a message
-# usage: pass "reason why the test passed if applicable"
-pass()
- { echo "The test passed!!!"
- echo "$*" 1>&2
- exit 0
- } #end of pass()
-
-# end of subroutines
-
-# The beginning of the script proper
-
-OS=`uname -s`
-case "$OS" in
- SunOS | Linux | Darwin )
- PATHSEP=":"
- ;;
-
- Windows* | CYGWIN*)
- PATHSEP=";"
- ;;
-
- # catch all other OSs
- * )
- echo "Unrecognized system! $OS"
- fail "Unrecognized system! $OS"
- ;;
-esac
-
-TARGETCLASS="ImmutableResourceTest"
-if [ -z "${TESTJAVA}" ] ; then
- # TESTJAVA is not set, so the test is running stand-alone.
- # TESTJAVA holds the path to the root directory of the build of the JDK
- # to be tested. That is, any java files run explicitly in this shell
- # should use TESTJAVA in the path to the java interpreter.
- # So, we'll set this to the JDK spec'd on the command line. If none
- # is given on the command line, tell the user that and use a default.
- # THIS IS THE JDK BEING TESTED.
- if [ -n "$1" ] ; then
- TESTJAVA=$1
- else
- TESTJAVA=$JAVA_HOME
- fi
- TESTSRC=.
- TESTCLASSES=.
- #Deal with .class files:
-fi
-#
-echo "JDK under test is: $TESTJAVA"
-#
-CP="-classpath ${TESTCLASSES}${PATHSEP}${TESTJAVA}/lib/jconsole.jar"
-# Compile the test class using the classpath we need:
-#
-env
-#
-set -vx
-#
-#Compile. jconsole.jar is required on the classpath.
-${TESTJAVA}/bin/javac -d "${TESTCLASSES}" ${CP} -g \
- "${TESTSRC}"/"${TARGETCLASS}".java
-#
-#Run the test class, again with the classpath we need:
-${TESTJAVA}/bin/java ${CP} ${TARGETCLASS}
-status=$?
-echo "test status was: $status"
-if [ $status -eq "0" ];
- then pass ""
-
- else fail "unspecified test failure"
-fi
diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java
index 6d4e27be860..1ed5bb642c7 100644
--- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java
+++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,377 +27,134 @@
* This isn't the test case: ResourceCheckTest.sh is.
* Refer to ResourceCheckTest.sh when running this test.
*
- * @bug 5008856 5023573 5024917 5062569
+ * @bug 5008856 5023573 5024917 5062569 7172176
* @summary 'missing resource key' error for key = "Operating system"
*/
-import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import sun.tools.jconsole.Messages;
import sun.tools.jconsole.Resources;
+/*
+ * Ensures that there is a one-to-one mapping between constants in the
+ * Message class and the keys in the sun.tools.jconsole.resources.messages
+ * bundle.
+ *
+ * An error will be thrown if there is a:
+ *
+ * - key in the resource bundle that doesn't have a public static field with
+ * the same name in the Message class.
+ *
+ * - public static field in the Message class that doesn't have a key with
+ * the same name in the resource bundle.
+ *
+ * - message with a mnemonic identifier(&) for which a mnemonic can't
+ * be looked up using Resources#getMnemonicInt().
+ *
+ */
public class ResourceCheckTest {
+ private static final String MISSING_RESOURCE_KEY_PREFIX = "missing message for";
+ private static final String RESOURCE_BUNDLE = "sun.tools.jconsole.resources.messages";
+ private static final String NEW_LINE = String.format("%n");
- public static void main(String[] args){
- Object [][] testData = {
- {"<", "", "", "", ""},
- {"<<", "", "", "", ""},
- {">", "", "", "", ""},
- {" 1 day", "", "", "", ""},
- {" 1 hour", "", "", "", ""},
- {" 1 min", "", "", "", ""},
- {" 1 month", "", "", "", ""},
- {" 1 year", "", "", "", ""},
- {" 2 hours", "", "", "", ""},
- {" 3 hours", "", "", "", ""},
- {" 3 months", "", "", "", ""},
- {" 5 min", "", "", "", ""},
- {" 6 hours", "", "", "", ""},
- {" 6 months", "", "", "", ""},
- {" 7 days", "", "", "", ""},
- {"10 min", "", "", "", ""},
- {"12 hours", "", "", "", ""},
- {"30 min", "", "", "", ""},
- {"ACTION", "", "", "", ""},
- {"ACTION_INFO", "", "", "", ""},
- {"All", "", "", "", ""},
- {"Architecture", "", "", "", ""},
- {"Attribute", "", "", "", ""},
- {"Attribute value", "", "", "", ""},
- {"Attribute values", "", "", "", ""},
- {"Attributes", "", "", "", ""},
- {"Blank", "", "", "", ""},
- {"BlockedCount WaitedCount", "BlockedCount", "WaitedCount", "", ""},
- {"Boot class path", "", "", "", ""},
- {"BorderedComponent.moreOrLessButton.toolTip", "", "", "", ""},
- {"Close", "", "", "", ""},
- {"CPU Usage", "", "", "", ""},
- {"CPUUsageFormat","PhonyPercentage", "", "", ""},
- {"Cancel", "", "", "", ""},
- {"Cascade", "", "", "", ""},
- {"Cascade.mnemonic", "", "", "", ""},
- {"Chart:", "", "", "", ""},
- {"Chart:.mnemonic", "", "", "", ""},
- {"ClassTab.infoLabelFormat", "LoadedCount", "UnloadedCount", "TotalCount", ""},
- {"ClassTab.loadedClassesPlotter.accessibleName", "", "", "", ""},
- {"Class path", "", "", "", ""},
- {"Classes", "", "", "", ""},
- {"ClassName", "", "", "", ""},
- {"Column.Name", "", "", "", ""},
- {"Column.PID", "", "", "", ""},
- {"Committed", "", "", "", ""},
- {"Committed memory", "", "", "", ""},
- {"Committed virtual memory", "", "", "", ""},
- {"Compiler", "", "", "", ""},
- {"Connect...", "", "", "", ""},
- {"Connect", "", "", "", ""},
- {"Connect.mnemonic", "", "", "", ""},
- {"ConnectDialog.connectButton.toolTip", "", "", "", ""},
- {"ConnectDialog.accessibleDescription", "", "", "", ""},
- {"ConnectDialog.masthead.accessibleName", "", "", "", ""},
- {"ConnectDialog.masthead.title", "", "", "", ""},
- {"ConnectDialog.statusBar.accessibleName", "", "", "", ""},
- {"ConnectDialog.title", "", "", "", ""},
- {"Connected. Click to disconnect.", "", "", "", ""},
- {"connectingTo1", "PhonyConnectionName", "", "", ""},
- {"connectingTo2", "PhonyConnectionName", "", "", ""},
- {"connectionFailed1", "", "", "", ""},
- {"connectionFailed2", "PhonyConnectionName", "", "", ""},
- {"connectionLost1", "", "", "", ""},
- {"connectionLost2", "PhonyConnectionName", "", "", ""},
- {"Connection failed", "", "", "", ""},
- {"Connection", "", "", "", ""},
- {"Connection.mnemonic", "", "", "", ""},
- {"Connection name", "", "", "", ""},
- {"ConnectionName (disconnected)", "Phony", "Phony", "", ""},
- {"Constructor", "", "", "", ""},
- {"Create", "Phony", "Phony", "", ""},
- {"Current classes loaded", "", "", "", ""},
- {"Current heap size", "", "", "", ""},
- {"Current value", "PhonyValue", "", "", ""},
- {"Daemon threads", "", "", "", ""},
- {"deadlockAllTab", "", "", "", ""},
- {"deadlockTab", "", "", "", ""},
- {"deadlockTabN", "PhonyInt", "", "", ""},
- {"Description", "", "", "", ""},
- {"Descriptor", "", "", "", ""},
- {"Details", "", "", "", ""},
- {"Detect Deadlock", "", "", "", ""},
- {"Detect Deadlock.mnemonic", "", "", "", ""},
- {"Detect Deadlock.toolTip", "", "", "", ""},
- {"Dimension is not supported:", "", "", "", ""},
- {"Discard chart", "", "", "", ""},
- {"Disconnected. Click to connect.", "", "", "", ""},
- {"Double click to expand/collapse", "", "", "", ""},
- {"Double click to visualize", "", "", "", ""},
- {"DurationDaysHoursMinutes", 0, 13, 54, ""},
- {"DurationDaysHoursMinutes", 1, 13, 54, ""},
- {"DurationDaysHoursMinutes", 2, 13, 54, ""},
- {"DurationDaysHoursMinutes", 1024, 13, 45, ""},
- {"DurationHoursMinutes", 0, 13, "", ""},
- {"DurationHoursMinutes", 1, 0, "", ""},
- {"DurationHoursMinutes", 1, 1, "", ""},
- {"DurationHoursMinutes", 2, 42, "", ""},
- {"DurationMinutes", 0, "", "", ""},
- {"DurationMinutes", 1, "", "", ""},
- {"DurationMinutes", 2, "", "", ""},
- {"DurationSeconds", 0, "", "", ""},
- {"DurationSeconds", 1, "", "", ""},
- {"DurationSeconds", 2, "", "", ""},
- {"Empty array", "", "", "", ""},
- {"Error", "", "", "", ""},
- {"Error: MBeans already exist", "", "", "", ""},
- {"Error: MBeans do not exist", "", "", "", ""},
- {"Event", "", "", "", ""},
- {"Exit", "", "", "", ""},
- {"Exit.mnemonic", "", "", "", ""},
- {"expand", "", "", "", ""},
- {"Fail to load plugin", "", "", "", ""},
- {"FileChooser.fileExists.cancelOption", "", "", "", ""},
- {"FileChooser.fileExists.message", "PhonyFileName", "", "", ""},
- {"FileChooser.fileExists.okOption", "", "", "", ""},
- {"FileChooser.fileExists.title", "", "", "", ""},
- {"FileChooser.savedFile", "PhonyFilePath", "PhonyFileSize", "", ""},
- {"FileChooser.saveFailed.message", "PhonyFilePath", "PhonyMessage", "", ""},
- {"FileChooser.saveFailed.title", "", "", "", ""},
- {"Free physical memory", "", "", "", ""},
- {"Free swap space", "", "", "", ""},
- {"Garbage collector", "", "", "", ""},
- {"GC time", "", "", "", ""},
- {"GC time details", 54, "Phony", 11, ""},
- {"GcInfo", "Phony", -1, 768, ""},
- {"GcInfo", "Phony", 0, 768, ""},
- {"GcInfo", "Phony", 1, 768, ""},
- {"Heap", "", "", "", ""},
- {"Heap Memory Usage", "", "", "", ""},
- {"Help.AboutDialog.accessibleDescription", "", "", "", ""},
- {"Help.AboutDialog.jConsoleVersion", "DummyVersion", "", "", ""},
- {"Help.AboutDialog.javaVersion", "DummyVersion", "", "", ""},
- {"Help.AboutDialog.masthead.accessibleName", "", "", "", ""},
- {"Help.AboutDialog.masthead.title", "", "", "", ""},
- {"Help.AboutDialog.title", "", "", "", ""},
- {"Help.AboutDialog.userGuideLink", "DummyMessage", "", "", ""},
- {"Help.AboutDialog.userGuideLink.mnemonic", "", "", "", ""},
- {"Help.AboutDialog.userGuideLink.url", "DummyURL", "", "", ""},
- {"HelpMenu.About.title", "", "", "", ""},
- {"HelpMenu.About.title.mnemonic", "", "", "", ""},
- {"HelpMenu.UserGuide.title", "", "", "", ""},
- {"HelpMenu.UserGuide.title.mnemonic", "", "", "", ""},
- {"HelpMenu.title", "", "", "", ""},
- {"HelpMenu.title.mnemonic", "", "", "", ""},
- {"Hotspot MBeans...", "", "", "", ""},
- {"Hotspot MBeans....mnemonic", "", "", "", ""},
- {"Hotspot MBeans.dialog.accessibleDescription", "", "", "", ""},
- {"Impact", "", "", "", ""},
- {"Info", "", "", "", ""},
- {"INFO", "", "", "", ""},
- {"Invalid plugin path", "", "", "", ""},
- {"Invalid URL", "", "", "", ""},
- {"Is", "", "", "", ""},
- {"Java Monitoring & Management Console", "", "", "", ""},
- {"Java Virtual Machine", "", "", "", ""},
- {"JConsole: ", "", "", "", ""},
- {"JConsole.accessibleDescription", "", "", "", ""},
- {"JConsole version", "PhonyVersion", "", "", ""},
- {"JIT compiler", "", "", "", ""},
- {"Library path", "", "", "", ""},
- {"Live Threads", "", "", "", ""},
- {"Loaded", "", "", "", ""},
- {"Local Process:", "", "", "", ""},
- {"Local Process:.mnemonic", "", "", "", ""},
- {"Manage Hotspot MBeans in: ", "", "", "", ""},
- {"Management Not Enabled", "", "", "", ""},
- {"Management Will Be Enabled", "", "", "", ""},
- {"Masthead.font", "", "", "", ""},
- {"Max", "", "", "", ""},
- {"Max", "", "", "", ""},
- {"Maximum heap size", "", "", "", ""},
- {"MBeanAttributeInfo", "", "", "", ""},
- {"MBeanInfo", "", "", "", ""},
- {"MBeanNotificationInfo", "", "", "", ""},
- {"MBeanOperationInfo", "", "", "", ""},
- {"MBeans", "", "", "", ""},
- {"MBeansTab.clearNotificationsButton", "", "", "", ""},
- {"MBeansTab.clearNotificationsButton.mnemonic", "", "", "", ""},
- {"MBeansTab.clearNotificationsButton.toolTip", "", "", "", ""},
- {"MBeansTab.compositeNavigationMultiple", 0, 0, "", ""},
- {"MBeansTab.compositeNavigationSingle", "", "", "", ""},
- {"MBeansTab.refreshAttributesButton", "", "", "", ""},
- {"MBeansTab.refreshAttributesButton.mnemonic", "", "", "", ""},
- {"MBeansTab.refreshAttributesButton.toolTip", "", "", "", ""},
- {"MBeansTab.subscribeNotificationsButton", "", "", "", ""},
- {"MBeansTab.subscribeNotificationsButton.mnemonic", "", "", "", ""},
- {"MBeansTab.subscribeNotificationsButton.toolTip", "", "", "", ""},
- {"MBeansTab.tabularNavigationMultiple", 0, 0, "", ""},
- {"MBeansTab.tabularNavigationSingle", "", "", "", ""},
- {"MBeansTab.unsubscribeNotificationsButton", "", "", "", ""},
- {"MBeansTab.unsubscribeNotificationsButton.mnemonic", "", "", "", ""},
- {"MBeansTab.unsubscribeNotificationsButton.toolTip", "", "", "", ""},
- {"Memory", "", "", "", ""},
- {"MemoryPoolLabel", "PhonyMemoryPool", "", "", ""},
- {"MemoryTab.heapPlotter.accessibleName", "", "", "", ""},
- {"MemoryTab.infoLabelFormat", "UsedCount", "CommittedCount", "MaxCount", ""},
- {"MemoryTab.nonHeapPlotter.accessibleName", "", "", "", ""},
- {"MemoryTab.poolChart.aboveThreshold", "Threshold", "", "", ""},
- {"MemoryTab.poolChart.accessibleName", "", "", "", ""},
- {"MemoryTab.poolChart.belowThreshold", "Threshold", "", "", ""},
- {"MemoryTab.poolPlotter.accessibleName", "PhonyMemoryPool", "", "", ""},
- {"Message", "", "", "", ""},
- {"Method successfully invoked", "", "", "", ""},
- {"Monitor locked", "", "", "", ""},
- {"Minimize All", "", "", "", ""},
- {"Minimize All.mnemonic", "", "", "", ""},
- {"Name", "", "", "", ""},
- {"Name and Build", "PhonyName", "PhonyBuild", "", ""},
- {"Name Build and Mode", "PhonyName", "PhonyBuild", "PhonyMode", ""},
- {"Name State", "PhonyName", "PhonyState", "", ""},
- {"Name State LockName", "PhonyName", "PhonyState", "PhonyLock", ""},
- {"Name State LockName LockOwner", "PhonyName", "PhonyState", "PhonyLock", "PhonyOwner"},
- {"New Connection...", "", "", "", ""},
- {"New Connection....mnemonic", "", "", "", ""},
- {"No deadlock detected", "", "", "", ""},
- {"Non-Heap", "", "", "", ""},
- {"Non-Heap Memory Usage", "", "", "", ""},
- {"Notification", "", "", "", ""},
- {"Notification buffer", "", "", "", ""},
- {"Notifications", "", "", "", ""},
- {"NotifTypes", "", "", "", ""},
- {"Number of Loaded Classes", "", "", "", ""},
- {"Number of processors", "", "", "", ""},
- {"Number of Threads", "", "", "", ""},
- {"ObjectName", "", "", "", ""},
- {"Operating System", "", "", "", ""},
- {"Operation", "", "", "", ""},
- {"Operation invocation", "", "", "", ""},
- {"Operation return value", "", "", "", ""},
- {"Operations", "", "", "", ""},
- {"Overview", "", "", "", ""},
- {"OverviewPanel.plotter.accessibleName", "PhonyPlotter", "", "", ""},
- {"Parameter", "", "", "", ""},
- {"Password: ", "", "", "", ""},
- {"Password: .mnemonic", "", "", "", ""},
- {"Password.accessibleName", "", "", "", ""},
- {"Peak", "", "", "", ""},
- {"Perform GC", "", "", "", ""},
- {"Perform GC.mnemonic", "", "", "", ""},
- {"Perform GC.toolTip", "", "", "", ""},
- {"Plotter.accessibleName", "", "", "", ""},
- {"Plotter.accessibleName.keyAndValue", "Key", "Value", "", ""},
- {"Plotter.accessibleName.noData", "", "", "", ""},
- {"Plotter.saveAsMenuItem", "", "", "", ""},
- {"Plotter.saveAsMenuItem.mnemonic", "", "", "", ""},
- {"Plotter.timeRangeMenu", "", "", "", ""},
- {"Plotter.timeRangeMenu.mnemonic", "", "", "", ""},
- {"plot", "", "", "", ""},
- {"Problem adding listener", "", "", "", ""},
- {"Problem displaying MBean", "", "", "", ""},
- {"Problem invoking", "", "", "", ""},
- {"Problem removing listener", "", "", "", ""},
- {"Problem setting attribute", "", "", "", ""},
- {"Process CPU time", "", "", "", ""},
- {"Readable", "", "", "", ""},
- {"Reconnect", "", "", "", ""},
- {"Remote Process:", "", "", "", ""},
- {"Remote Process:.mnemonic", "", "", "", ""},
- {"Remote Process.textField.accessibleName", "", "", "", ""},
- {"remoteTF.usage", "", "", "", ""},
- {"Restore All", "", "", "", ""},
- {"Restore All.mnemonic", "", "", "", ""},
- {"ReturnType", "", "", "", ""},
- {"SeqNum", "", "", "", ""},
- {"Size Bytes", 512, "", "", ""},
- {"Size Gb", 512, "", "", ""},
- {"Size Kb", 512, "", "", ""},
- {"Size Mb", 512, "", "", ""},
- {"Source", "", "", "", ""},
- {"Stack trace", "", "", "", ""},
- {"SummaryTab.headerDateTimeFormat", "", "", "", ""},
- {"SummaryTab.pendingFinalization.label", "", "", "", ""},
- {"SummaryTab.pendingFinalization.value", "ObjectCount", "", "", ""},
- {"SummaryTab.tabName", "", "", "", ""},
- {"SummaryTab.vmVersion", "VMName", "VMVersion", "", ""},
- {"ThreadTab.infoLabelFormat", "LiveCount", "PeakCount", "TotalCount", ""},
- {"ThreadTab.threadInfo.accessibleName", "", "", "", ""},
- {"ThreadTab.threadPlotter.accessibleName", "", "", "", ""},
- {"Threads", "", "", "", ""},
- {"Threshold", "", "", "", ""},
- {"Tile", "", "", "", ""},
- {"Tile.mnemonic", "", "", "", ""},
- {"Time", "", "", "", ""},
- {"Time Range:", "", "", "", ""},
- {"Time Range:.mnemonic", "", "", "", ""},
- {"TimeStamp", "", "", "", ""},
- {"Total classes loaded", "", "", "", ""},
- {"Total classes unloaded", "", "", "", ""},
- {"Total compile time", "", "", "", ""},
- {"Total Loaded", "", "", "", ""},
- {"Total physical memory", "", "", "", ""},
- {"Total swap space", "", "", "", ""},
- {"Total threads started", "", "", "", ""},
- {"Type", "", "", "", ""},
- {"Unavailable", "", "", "", ""},
- {"UNKNOWN", "", "", "", ""},
- {"Unregister", "", "", "", ""},
- {"Uptime", "", "", "", ""},
- {"Usage Threshold", "", "", "", ""},
- {"Used", "", "", "", ""},
- {"Username: ", "", "", "", ""},
- {"Username: .mnemonic", "", "", "", ""},
- {"Username.accessibleName", "", "", "", ""},
- {"UserData", "", "", "", ""},
- {"Value", "", "", "", ""},
- {"Vendor", "", "", "", ""},
- {"Verbose Output", "", "", "", ""},
- {"Verbose Output.toolTip", "", "", "", ""},
- {"visualize", "", "", "", ""},
- {"VM", "", "", "", ""},
- {"VMInternalFrame.accessibleDescription", "", "", "", ""},
- {"VM arguments", "", "", "", ""},
- {"Virtual Machine", "", "", "", ""},
- {"Window", "", "", "", ""},
- {"Window.mnemonic", "", "", "", ""},
- {"Writable", "", "", "", ""},
- {"zz usage text", "PhonyName", "", "", ""},
- };
- //boolean verbose = false;
- boolean verbose = true;
-
- long badLookups = 0;
- System.out.println("Start...");
- for (int ii = 0; ii < testData.length; ii++) {
- String key = (String)testData[ii][0];
-
- if (key.endsWith(".mnemonic")) {
- String baseKey = key.substring(0, key.length() - ".mnemonic".length());
- int mnemonic = Resources.getMnemonicInt(baseKey);
- if (mnemonic == 0) {
- badLookups++;
- System.out.println("****lookup failed for key = " + key);
+ public static void main(String... args) {
+ List errors = new ArrayList<>();
+ // Ensure that all Message fields have a corresponding key/value
+ // in the resource bundle and that mnemonics can be looked
+ // up where applicable.
+ ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+ for (Field field : Messages.class.getFields()) {
+ if (isResourceKeyField(field)) {
+ String resourceKey = field.getName();
+ String message = readField(field);
+ if (message.startsWith(MISSING_RESOURCE_KEY_PREFIX)) {
+ errors.add("Can't find message (and perhaps mnemonic) for "
+ + Messages.class.getSimpleName() + "."
+ + resourceKey + " in resource bundle.");
} else {
- if (verbose) {
- System.out.println(" mnemonic: " + KeyEvent.getKeyText(mnemonic));
+ String resourceMessage = rb.getString(resourceKey);
+ if (hasMnemonicIdentifier(resourceMessage)) {
+ int mi = Resources.getMnemonicInt(message);
+ if (mi == 0) {
+ errors.add("Could not look up mnemonic for message '"
+ + message + "'.");
+ }
}
}
- continue;
}
+ }
- String ss = Resources.getText(key,
- testData[ii][1],
- testData[ii][2],
- testData[ii][3],
- testData[ii][4]);
- if (ss.startsWith("missing resource key")) {
- badLookups++;
- System.out.println("****lookup failed for key = " + key);
- } else {
- if (verbose) {
- System.out.println(" " + ss);
+ // Ensure that there is Message class field for every resource key.
+ for (String key : Collections.list(rb.getKeys())) {
+ try {
+ Messages.class.getField(key);
+ } catch (NoSuchFieldException nfe) {
+ errors.add("Can't find static field ("
+ + Messages.class.getSimpleName() + "." + key
+ + ") matching '" + key
+ + "' in resource bundle. Unused message?");
+ }
+ }
+
+ if (errors.size() > 0) {
+ throwError(errors);
+ }
+ }
+
+ private static String readField(Field field) {
+ try {
+ return (String) field.get(null);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new Error("Could not access field " + field.getName()
+ + " when trying to read resource message.");
+ }
+ }
+
+ private static boolean isResourceKeyField(Field field) {
+ int modifiers = field.getModifiers();
+ return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
+ }
+
+ private static boolean hasMnemonicIdentifier(String s) {
+ for (int i = 0; i < s.length() - 1; i++) {
+ if (s.charAt(i) == '&') {
+ if (s.charAt(i + 1) != '&') {
+ return true;
+ } else {
+ i++;
}
}
}
- if (badLookups > 0) {
- throw new Error ("Resource lookup failed " + badLookups +
- " time(s); Test failed");
+ return false;
+ }
+
+ private static void throwError(List errors) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Found ");
+ buffer.append(errors.size());
+ buffer.append(" error(s) when checking one-to-one mapping ");
+ buffer.append("between Message and resource bundle keys in ");
+ buffer.append(RESOURCE_BUNDLE);
+ buffer.append(" with ");
+ buffer.append(Locale.getDefault());
+ buffer.append(" locale.");
+ buffer.append(NEW_LINE);
+ int errorIndex = 1;
+ for (String error : errors) {
+ buffer.append("Error ");
+ buffer.append(errorIndex);
+ buffer.append(": ");
+ buffer.append(error);
+ buffer.append(NEW_LINE);
+ errorIndex++;
}
- System.out.println("...Finished.");
+ throw new Error(buffer.toString());
}
}
diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh
index bec63a7992f..01c2e4b6f01 100644
--- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh
+++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@ pass()
OS=`uname -s`
case "$OS" in
- SunOS | Linux )
+ SunOS | Linux | Darwin)
PATHSEP=":"
;;
diff --git a/jdk/test/sun/util/locale/provider/Bug8024141.java b/jdk/test/sun/util/locale/provider/Bug8024141.java
new file mode 100644
index 00000000000..24bd0f3024a
--- /dev/null
+++ b/jdk/test/sun/util/locale/provider/Bug8024141.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8024141
+ * @summary Test for cache support of sun.util.locale.provider.LocaleResources.getTimeZoneNames
+ */
+
+import java.time.ZoneId;
+import static java.util.Locale.ENGLISH;
+import static java.time.format.TextStyle.FULL;
+import static java.time.format.TextStyle.SHORT;
+
+public class Bug8024141 {
+ // This test assumes that the two time zones are in GMT. If
+ // they become different zones, need to pick up another zones.
+ private static final String[] ZONES = {
+ "Africa/Abidjan",
+ "Africa/Bamako"
+ };
+
+ public static void main(String[] args) {
+ ZoneId gmt = ZoneId.of("GMT");
+ String gmtName = gmt.getDisplayName(FULL, ENGLISH);
+ String gmtAbbr = gmt.getDisplayName(SHORT, ENGLISH);
+
+ for (String zone : ZONES) {
+ ZoneId id = ZoneId.of(zone);
+ String name = id.getDisplayName(FULL, ENGLISH);
+ String abbr = id.getDisplayName(SHORT, ENGLISH);
+
+ if (!name.equals(gmtName) || !abbr.equals(gmtAbbr)) {
+ throw new RuntimeException("inconsistent name/abbr for " + zone + ":\n"
+ + "name=" + name + ", abbr=" + abbr);
+ }
+ }
+ }
+}
diff --git a/langtools/.hgtags b/langtools/.hgtags
index 42ea6c743db..221777df498 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -225,3 +225,5 @@ ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98
0324dbf07b0f1cc51ad9fa18976489d02d23b60d jdk8-b101
453a305e116507847cc6577b80b4d9794bcb08bf jdk8-b102
76cfe7c61f2575ea5400845b8e80dab6f4b1d7d0 jdk8-b103
+dd4a00c220c6e14d9b2ce93a2bd436a1d04f0d03 jdk8-b104
+375834b5cf086dd7ce9e49f602d81bb51d3e0fa9 jdk8-b105
diff --git a/langtools/src/share/classes/com/sun/source/tree/MethodTree.java b/langtools/src/share/classes/com/sun/source/tree/MethodTree.java
index 8d9820ba5fe..987c3742767 100644
--- a/langtools/src/share/classes/com/sun/source/tree/MethodTree.java
+++ b/langtools/src/share/classes/com/sun/source/tree/MethodTree.java
@@ -53,7 +53,15 @@ public interface MethodTree extends Tree {
Tree getReturnType();
List extends TypeParameterTree> getTypeParameters();
List extends VariableTree> getParameters();
+
+ /**
+ * Return an explicit receiver parameter ("this" parameter).
+ *
+ * @return an explicit receiver parameter ("this" parameter)
+ * @since 1.8
+ */
VariableTree getReceiverParameter();
+
List extends ExpressionTree> getThrows();
BlockTree getBody();
Tree getDefaultValue(); // for annotation types
diff --git a/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java b/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java
index b9f1bddf487..3cd2f6283bf 100644
--- a/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java
+++ b/langtools/src/share/classes/com/sun/source/tree/NewArrayTree.java
@@ -25,7 +25,7 @@
package com.sun.source.tree;
-import java.util.List;
+import com.sun.tools.javac.util.List;
/**
* A tree node for an expression to create a new instance of an array.
@@ -48,4 +48,6 @@ public interface NewArrayTree extends ExpressionTree {
Tree getType();
List extends ExpressionTree> getDimensions();
List extends ExpressionTree> getInitializers();
+ List extends AnnotationTree> getAnnotations();
+ List extends List extends AnnotationTree>> getDimAnnotations();
}
diff --git a/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java b/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java
index 293a38b35a5..6dd469a7601 100644
--- a/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java
+++ b/langtools/src/share/classes/com/sun/source/tree/TypeParameterTree.java
@@ -36,6 +36,8 @@ import javax.lang.model.element.Name;
* name
*
* name extends bounds
+ *
+ * annotations name
*
*
* @jls section 4.4
@@ -48,5 +50,17 @@ import javax.lang.model.element.Name;
public interface TypeParameterTree extends Tree {
Name getName();
List extends Tree> getBounds();
+
+ /**
+ * Return annotations on the type parameter declaration.
+ *
+ * Annotations need Target meta-annotations of
+ * {@link java.lang.annotation.ElementType#TYPE_PARAMETER} or
+ * {@link java.lang.annotation.ElementType#TYPE_USE}
+ * to appear in this position.
+ *
+ * @return annotations on the type parameter declaration
+ * @since 1.8
+ */
List extends AnnotationTree> getAnnotations();
}
diff --git a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
index a6d0466a729..38ba501d190 100644
--- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
+++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java
@@ -285,6 +285,10 @@ public class TreeScanner implements TreeVisitor {
R r = scan(node.getType(), p);
r = scanAndReduce(node.getDimensions(), p, r);
r = scanAndReduce(node.getInitializers(), p, r);
+ r = scanAndReduce(node.getAnnotations(), p, r);
+ for (Iterable< ? extends Tree> dimAnno : node.getDimAnnotations()) {
+ r = scanAndReduce(dimAnno, p, r);
+ }
return r;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
index 95cd4a44d08..bd84d2caf2d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractPackageIndexWriter.java
@@ -159,10 +159,7 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
body.addContent(div);
if (configuration.showProfiles) {
Content profileSummary = configuration.getResource("doclet.Profiles");
- Content profilesTableSummary = configuration.getResource("doclet.Member_Table_Summary",
- configuration.getResource("doclet.Profile_Summary"),
- configuration.getResource("doclet.profiles"));
- addProfilesList(profileSummary, profilesTableSummary, body);
+ addProfilesList(profileSummary, body);
}
addPackagesList(packages, text, tableSummary, body);
}
@@ -214,10 +211,8 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
* Do nothing. This will be overridden.
*
* @param profileSummary the profile summary heading
- * @param profilesTableSummary the profiles table summary information
* @param body the content tree to which the profiles list will be added
*/
- protected void addProfilesList(Content profileSummary, Content profilesTableSummary,
- Content body) {
+ protected void addProfilesList(Content profileSummary, Content body) {
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
index 0d6846ae387..b4e6d8dcd38 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java
@@ -102,7 +102,7 @@ public class AllClassesFrameWriter extends HtmlDocletWriter {
configuration.standardmessage.
error("doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
index 88e1441b7ed..869bc75f89c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java
@@ -304,7 +304,7 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
subDiv.addContent(div);
} catch (Exception e) {
e.printStackTrace();
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
index 90da398c685..2c48f823b1f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java
@@ -25,8 +25,16 @@
package com.sun.tools.doclets.formats.html;
-import java.io.*;
-import java.util.*;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
@@ -95,7 +103,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
super(configuration, filename);
this.classdoc = classdoc;
if (mapper.classToPackageAnnotations.containsKey(classdoc.qualifiedName()))
- pkgToPackageAnnotations = new HashSet(mapper.classToPackageAnnotations.get(classdoc.qualifiedName()));
+ pkgToPackageAnnotations = new TreeSet(mapper.classToPackageAnnotations.get(classdoc.qualifiedName()));
configuration.currentcd = classdoc;
this.pkgSet = new TreeSet();
this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam);
@@ -210,7 +218,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
configuration.standardmessage.
error("doclet.exception_encountered",
exc.toString(), path.getPath());
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
index b98739c9390..25f0f618af9 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java
@@ -610,7 +610,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter
subDiv.addContent(div);
} catch (Exception e) {
e.printStackTrace();
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java
index bb989452b85..00135fc6cec 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/DeprecatedListWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,7 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
index 3d483cdff0c..a324fa02867 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FrameOutputWriter.java
@@ -87,7 +87,7 @@ public class FrameOutputWriter extends HtmlDocletWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
index d5e0bf0c71f..5e477dcc8d2 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HelpWriter.java
@@ -72,7 +72,7 @@ public class HelpWriter extends HtmlDocletWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java
index 739550345b7..24c95876e6f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java
@@ -196,7 +196,7 @@ public class HtmlDoclet extends AbstractDoclet {
}
} catch (Exception e) {
e.printStackTrace();
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
}
@@ -332,7 +332,7 @@ public class HtmlDoclet extends AbstractDoclet {
configuration.message.error((SourcePosition) null,
"doclet.perform_copy_exception_encountered",
exc.toString());
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
index 63aa42be9b1..8dcf113e3f3 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java
@@ -411,7 +411,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
head.addContent(headComment);
}
if (configuration.charset.length() > 0) {
- Content meta = HtmlTree.META("Content-Type", "text/html",
+ Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
configuration.charset);
head.addContent(meta);
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
index abad36dbf99..890635e3df0 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java
@@ -109,7 +109,7 @@ public class LinkFactoryImpl extends LinkFactory {
}
}
// Can't link so just write label.
- link.addContent(label.toString());
+ link.addContent(label);
if (noLabel && !classLinkInfo.excludeTypeParameterLinks) {
link.addContent(getTypeParameterLinks(linkInfo));
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
index 26d3a8f0b4c..3268a446062 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java
@@ -109,7 +109,7 @@ public class PackageFrameWriter extends HtmlDocletWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), DocPaths.PACKAGE_FRAME.getPath());
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
index fad1bd39c04..9499745ed78 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexFrameWriter.java
@@ -71,7 +71,7 @@ public class PackageIndexFrameWriter extends AbstractPackageIndexWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
index e11ed98b527..7a67b38d102 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java
@@ -98,7 +98,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
@@ -123,15 +123,20 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
/**
* {@inheritDoc}
*/
- protected void addProfilesList(Content profileSummary, String profilesTableSummary,
- Content body) {
- Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0, profilesTableSummary,
- getTableCaption(profileSummary));
- table.addContent(getSummaryTableHeader(profileTableHeader, "col"));
- Content tbody = new HtmlTree(HtmlTag.TBODY);
- addProfilesList(tbody);
- table.addContent(tbody);
- Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table);
+ protected void addProfilesList(Content profileSummary, Content body) {
+ Content h2 = HtmlTree.HEADING(HtmlTag.H2, profileSummary);
+ Content profilesDiv = HtmlTree.DIV(h2);
+ Content ul = new HtmlTree(HtmlTag.UL);
+ String profileName;
+ for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
+ profileName = Profile.lookup(i).name;
+ Content profileLinkContent = getTargetProfileLink("classFrame",
+ new StringContent(profileName), profileName);
+ Content li = HtmlTree.LI(profileLinkContent);
+ ul.addContent(li);
+ }
+ profilesDiv.addContent(ul);
+ Content div = HtmlTree.DIV(HtmlStyle.contentContainer, profilesDiv);
body.addContent(div);
}
@@ -150,31 +155,6 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
body.addContent(div);
}
- /**
- * Adds list of profiles in the index table. Generate link to each profile.
- *
- * @param tbody the documentation tree to which the list will be added
- */
- protected void addProfilesList(Content tbody) {
- for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
- String profileName = Profile.lookup(i).name;
- Content profileLinkContent = getTargetProfileLink("classFrame",
- new StringContent(profileName), profileName);
- Content tdProfile = HtmlTree.TD(HtmlStyle.colFirst, profileLinkContent);
- HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
- tdSummary.addStyle(HtmlStyle.colLast);
- tdSummary.addContent(getSpace());
- HtmlTree tr = HtmlTree.TR(tdProfile);
- tr.addContent(tdSummary);
- if (i % 2 == 0) {
- tr.addStyle(HtmlStyle.altColor);
- } else {
- tr.addStyle(HtmlStyle.rowColor);
- }
- tbody.addContent(tr);
- }
- }
-
/**
* Adds list of packages in the index table. Generate link to each package.
*
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
index d9510f224f9..655af8e4c03 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageTreeWriter.java
@@ -105,7 +105,7 @@ public class PackageTreeWriter extends AbstractTreeWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), path.getPath());
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
index 3e2668fe0ac..5814c377f16 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java
@@ -106,7 +106,7 @@ public class PackageUseWriter extends SubWriterHolderWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
index 4689ecadc49..c7217cd5037 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfileIndexFrameWriter.java
@@ -74,7 +74,7 @@ public class ProfileIndexFrameWriter extends AbstractProfileIndexWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
index 38b7b1cee32..c61b7f869c5 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageFrameWriter.java
@@ -115,7 +115,7 @@ public class ProfilePackageFrameWriter extends HtmlDocletWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), DocPaths.PACKAGE_FRAME.getPath());
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
index 6764f5fdf27..a56f33624df 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ProfilePackageIndexFrameWriter.java
@@ -75,7 +75,7 @@ public class ProfilePackageIndexFrameWriter extends AbstractProfileIndexWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java
index 924557c95df..43718e4699c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SingleIndexWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@ public class SingleIndexWriter extends AbstractIndexWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java
index 69f273e7f69..76f750013be 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SplitIndexWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,7 @@ public class SplitIndexWriter extends AbstractIndexWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename.getPath());
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java
index f51a834db81..988facacb58 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TreeWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -93,7 +93,7 @@ public class TreeWriter extends AbstractTreeWriter {
configuration.standardmessage.error(
"doclet.exception_encountered",
exc.toString(), filename);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/Comment.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/Comment.java
index 533c9b7a48c..7d68b3f8bfe 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/Comment.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/Comment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,7 +63,7 @@ public class Comment extends Content {
* is not supported.
*/
public void addContent(Content content) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
@@ -75,7 +75,7 @@ public class Comment extends Content {
* is not supported.
*/
public void addContent(String stringContent) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/DocType.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/DocType.java
index 0e586b4a4e0..fed89db837b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/DocType.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/DocType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -70,7 +70,7 @@ public class DocType extends Content {
* is not supported.
*/
public void addContent(Content content) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
@@ -82,7 +82,7 @@ public class DocType extends Content {
* is not supported.
*/
public void addContent(String stringContent) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java
index 62b0f600283..4478ccf3e97 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlAttr.java
@@ -40,7 +40,6 @@ public enum HtmlAttr {
BORDER,
CELLPADDING,
CELLSPACING,
- CHARSET,
CLASS,
CLEAR,
COLS,
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
index c0048f99940..0eb40080295 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java
@@ -53,6 +53,8 @@ import com.sun.tools.doclets.internal.toolkit.util.DocPath;
*/
public abstract class HtmlDocWriter extends HtmlWriter {
+ public static final String CONTENT_TYPE = "text/html";
+
/**
* Constructor. Initializes the destination file name through the super
* class HtmlWriter.
@@ -194,7 +196,7 @@ public abstract class HtmlDocWriter extends HtmlWriter {
head.addContent(headComment);
}
if (configuration.charset.length() > 0) {
- Content meta = HtmlTree.META("Content-Type", "text/html",
+ Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE,
configuration.charset);
head.addContent(meta);
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocument.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocument.java
index b62fe754309..0e74220839f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocument.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocument.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@ public class HtmlDocument extends Content {
* is not supported.
*/
public void addContent(String stringContent) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
index fe9f5545937..60895e00e97 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTag.java
@@ -25,6 +25,8 @@
package com.sun.tools.doclets.formats.html.markup;
+import java.util.Locale;
+
/**
* Enum representing HTML tags.
*
@@ -115,7 +117,7 @@ public enum HtmlTag {
HtmlTag(BlockType blockType, EndTag endTag ) {
this.blockType = blockType;
this.endTag = endTag;
- this.value = name().toLowerCase();
+ this.value = name().toLowerCase(Locale.US);
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
index e0343f21d94..dc59eb0f4a0 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java
@@ -456,9 +456,9 @@ public class HtmlTree extends Content {
*/
public static HtmlTree META(String httpEquiv, String content, String charSet) {
HtmlTree htmltree = new HtmlTree(HtmlTag.META);
+ String contentCharset = content + "; charset=" + charSet;
htmltree.addAttr(HtmlAttr.HTTP_EQUIV, nullCheck(httpEquiv));
- htmltree.addAttr(HtmlAttr.CONTENT, nullCheck(content));
- htmltree.addAttr(HtmlAttr.CHARSET, nullCheck(charSet));
+ htmltree.addAttr(HtmlAttr.CONTENT, contentCharset);
return htmltree;
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
index 6b4fc6edfc5..f45e3af4196 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/RawHtml.java
@@ -65,7 +65,7 @@ public class RawHtml extends Content {
* is not supported.
*/
public void addContent(Content content) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
@@ -77,7 +77,7 @@ public class RawHtml extends Content {
* is not supported.
*/
public void addContent(String stringContent) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
index 21d67c00cfa..03bd4035c6a 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/StringContent.java
@@ -70,8 +70,9 @@ public class StringContent extends Content {
* DocletAbortException because it
* is not supported.
*/
+ @Override
public void addContent(Content content) {
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
/**
@@ -80,6 +81,7 @@ public class StringContent extends Content {
*
* @param strContent string content to be added
*/
+ @Override
public void addContent(String strContent) {
appendChars(strContent);
}
@@ -87,10 +89,12 @@ public class StringContent extends Content {
/**
* {@inheritDoc}
*/
+ @Override
public boolean isEmpty() {
return (stringContent.length() == 0);
}
+ @Override
public int charCount() {
return RawHtml.charCount(stringContent.toString());
}
@@ -98,6 +102,7 @@ public class StringContent extends Content {
/**
* {@inheritDoc}
*/
+ @Override
public String toString() {
return stringContent.toString();
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
index 633e941041a..32b7648e34b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
@@ -539,7 +539,7 @@ public abstract class Configuration {
initProfiles();
initProfilePackages();
} catch (Exception e) {
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
setSpecificDocletOptions(root.options());
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
index fff01955c6a..2135760c5d1 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Content.java
@@ -55,7 +55,7 @@ public abstract class Content {
write(out, true);
} catch (IOException e) {
// cannot happen from StringWriter
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
return out.toString();
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java
index 56676ec86b8..74b4f04e716 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -138,7 +138,7 @@ public abstract class AbstractBuilder {
} catch (NoSuchMethodException e) {
e.printStackTrace();
configuration.root.printError("Unknown element: " + component);
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
} catch (InvocationTargetException e) {
e.getCause().printStackTrace();
} catch (Exception e) {
@@ -146,7 +146,7 @@ public abstract class AbstractBuilder {
configuration.root.printError("Exception " +
e.getClass().getName() +
" thrown while processing element: " + component);
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java
index 5313f4f80b5..590f3d47d8f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@ public abstract class AbstractMemberBuilder extends AbstractBuilder {
*/
public void build() throws DocletAbortException {
//You may not call the build method in a subbuilder.
- throw new DocletAbortException();
+ throw new DocletAbortException("not supported");
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java
index 6c9b3067846..4172fb04770 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -93,7 +93,7 @@ public class LayoutParser extends DefaultHandler {
return xmlElementsMap.get(root);
} catch (Throwable t) {
t.printStackTrace();
- throw new DocletAbortException();
+ throw new DocletAbortException(t);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java
index da424f66036..66917109dd8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,7 @@ public class SerializedFormBuilder extends AbstractBuilder {
return;
}
} catch (Exception e) {
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
build(layoutParser.parseXML(NAME), contentTree);
writer.close();
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
index a663d386d68..54dff68e55b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
@@ -176,25 +176,32 @@ doclet.Value=Value
doclet.0_and_1={0} and {1}
#Documentation for Enums
-doclet.enum_values_doc=\n\
+doclet.enum_values_doc.main=\n\
Returns an array containing the constants of this enum type, in\n\
the order they are declared. This method may be used to iterate\n\
over the constants as follows:\n\
\n\
for ({0} c : {0}.values())\n\
System.out.println(c);\n\
- \n\
- @return an array containing the constants of this enum type, in\n\
- the order they are declared
+
-doclet.enum_valueof_doc=\n\
+doclet.enum_values_doc.return=\n\
+ an array containing the constants of this enum type, in the order they are declared
+
+doclet.enum_valueof_doc.main=\n\
Returns the enum constant of this type with the specified name.\n\
The string must match exactly an identifier used to declare an\n\
enum constant in this type. (Extraneous whitespace characters are \n\
- not permitted.)\n\
- \n\
- @param name the name of the enum constant to be returned.\n\
- @return the enum constant with the specified name\n\
- @throws IllegalArgumentException if this enum type has no constant\n\
- with the specified name\n\
- @throws NullPointerException if the argument is null
+ not permitted.)
+
+doclet.enum_valueof_doc.param_name=\
+ the name of the enum constant to be returned.
+
+doclet.enum_valueof_doc.return=\
+ the enum constant with the specified name
+
+doclet.enum_valueof_doc.throws_ila=\
+ if this enum type has no constant with the specified name
+
+doclet.enum_valueof_doc.throws_npe=\
+ if the argument is null
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
index f4d58c8cc68..4d7dd74da2c 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java
@@ -126,7 +126,7 @@ public class ValueTaglet extends BaseInlineTaglet {
return (FieldDoc) tag.holder();
} else {
//This should never ever happen.
- throw new DocletAbortException();
+ throw new DocletAbortException("should not happen");
}
}
StringTokenizer st = new StringTokenizer(name, "#");
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java
index a7eb4f660f6..5a579773e75 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -452,7 +452,7 @@ public class ClassUseMapper {
} else if (doc instanceof Parameter) {
annotations = ((Parameter) doc).annotations();
} else {
- throw new DocletAbortException();
+ throw new DocletAbortException("should not happen");
}
for (int i = 0; i < annotations.length; i++) {
AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java
index f55d99a999d..17f9f0b1375 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -197,7 +197,7 @@ public abstract class DocFile {
}
} catch (IOException e) {
e.printStackTrace(System.err);
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletAbortException.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletAbortException.java
index 6261caec4ed..d1b23a579ac 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletAbortException.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocletAbortException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,11 @@ package com.sun.tools.doclets.internal.toolkit.util;
public class DocletAbortException extends RuntimeException {
private static final long serialVersionUID = -9131058909576418984L;
- public DocletAbortException() {
+ public DocletAbortException(String message) {
+ super(message);
+ }
+
+ public DocletAbortException(Throwable cause) {
+ super(cause);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java
index 0d1b63e5679..b5d604081f4 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PackageListWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,7 @@ public class PackageListWriter extends PrintWriter {
} catch (IOException exc) {
configuration.message.error("doclet.exception_encountered",
exc.toString(), DocPaths.PACKAGE_LIST);
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java
index d2ee2d639ed..7990a347c18 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@ class PathDocFileFactory extends DocFileFactory {
Path dir = fileManager.getDefaultFileSystem().getPath(dirName);
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
} catch (IOException e) {
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java
index e9711f5c316..935948420fe 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -269,7 +269,7 @@ class SimpleDocFileFactory extends DocFileFactory {
configuration.message.error(
"doclet.Unable_to_create_directory_0", dir.getPath());
- throw new DocletAbortException();
+ throw new DocletAbortException("can't create directory");
}
/** Return a string to identify the contents of this object,
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java
index 1f7d20c1126..1c209c29a31 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@ class StandardDocFileFactory extends DocFileFactory {
File dir = new File(dirName);
fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
} catch (IOException e) {
- throw new DocletAbortException();
+ throw new DocletAbortException(e);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
index 289f34804e1..b3081f421fe 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
@@ -241,9 +241,9 @@ public class Util {
first = false;
}
} catch (SecurityException exc) {
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
} catch (IOException exc) {
- throw new DocletAbortException();
+ throw new DocletAbortException(exc);
}
}
@@ -667,16 +667,28 @@ public class Util {
for (int j = 0; j < methods.length; j++) {
MethodDoc currentMethod = methods[j];
if (currentMethod.name().equals("values") &&
- currentMethod.parameters().length == 0) {
- currentMethod.setRawCommentText(
- configuration.getText("doclet.enum_values_doc", classDoc.name()));
+ currentMethod.parameters().length == 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(configuration.getText("doclet.enum_values_doc.main", classDoc.name()));
+ sb.append("\n@return ");
+ sb.append(configuration.getText("doclet.enum_values_doc.return"));
+ currentMethod.setRawCommentText(sb.toString());
} else if (currentMethod.name().equals("valueOf") &&
- currentMethod.parameters().length == 1) {
+ currentMethod.parameters().length == 1) {
Type paramType = currentMethod.parameters()[0].type();
if (paramType != null &&
- paramType.qualifiedTypeName().equals(String.class.getName())) {
- currentMethod.setRawCommentText(
- configuration.getText("doclet.enum_valueof_doc"));
+ paramType.qualifiedTypeName().equals(String.class.getName())) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(configuration.getText("doclet.enum_valueof_doc.main", classDoc.name()));
+ sb.append("\n@param name ");
+ sb.append(configuration.getText("doclet.enum_valueof_doc.param_name"));
+ sb.append("\n@return ");
+ sb.append(configuration.getText("doclet.enum_valueof_doc.return"));
+ sb.append("\n@throws IllegalArgumentException ");
+ sb.append(configuration.getText("doclet.enum_valueof_doc.throws_ila"));
+ sb.append("\n@throws NullPointerException ");
+ sb.append(configuration.getText("doclet.enum_valueof_doc.throws_npe"));
+ currentMethod.setRawCommentText(sb.toString());
}
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java
index 04753149340..3b8f8599e09 100644
--- a/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java
+++ b/langtools/src/share/classes/com/sun/tools/doclint/HtmlTag.java
@@ -30,6 +30,7 @@ import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import javax.lang.model.element.Name;
@@ -41,12 +42,14 @@ import static com.sun.tools.doclint.HtmlTag.Attr.*;
*
* The intent of this class is to embody the semantics of W3C HTML 4.01
* to the extent supported/used by javadoc.
+ * In time, we may wish to transition javadoc and doclint to using HTML 5.
*
* This is derivative of com.sun.tools.doclets.formats.html.markup.HtmlTag.
* Eventually, these two should be merged back together, and possibly made
* public.
*
* @see HTML 4.01 Specification
+ * @see HTML 5 Specification
* @author Bhavesh Patel
* @author Jonathan Gibbons (revised)
*/
@@ -118,7 +121,8 @@ public enum HtmlTag {
HEAD(BlockType.OTHER, EndKind.REQUIRED),
- HR(BlockType.BLOCK, EndKind.NONE),
+ HR(BlockType.BLOCK, EndKind.NONE,
+ attrs(AttrKind.OK, WIDTH)), // OK in 4.01; not allowed in 5
HTML(BlockType.OTHER, EndKind.REQUIRED),
@@ -151,7 +155,7 @@ public enum HtmlTag {
OL(BlockType.BLOCK, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT),
- attrs(AttrKind.USE_CSS, START, TYPE)){
+ attrs(AttrKind.OK, START, TYPE)) {
@Override
public boolean accepts(HtmlTag t) {
return (t == LI);
@@ -195,8 +199,8 @@ public enum HtmlTag {
TABLE(BlockType.BLOCK, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT),
attrs(AttrKind.OK, SUMMARY, Attr.FRAME, RULES, BORDER,
- CELLPADDING, CELLSPACING),
- attrs(AttrKind.USE_CSS, ALIGN, WIDTH, BGCOLOR)) {
+ CELLPADDING, CELLSPACING, WIDTH), // width OK in 4.01; not allowed in 5
+ attrs(AttrKind.USE_CSS, ALIGN, BGCOLOR)) {
@Override
public boolean accepts(HtmlTag t) {
switch (t) {
@@ -266,7 +270,7 @@ public enum HtmlTag {
UL(BlockType.BLOCK, EndKind.REQUIRED,
EnumSet.of(Flag.EXPECT_CONTENT),
- attrs(AttrKind.USE_CSS, COMPACT, TYPE)){
+ attrs(AttrKind.OK, COMPACT, TYPE)) { // OK in 4.01; not allowed in 5
@Override
public boolean accepts(HtmlTag t) {
return (t == LI);
@@ -345,7 +349,7 @@ public enum HtmlTag {
WIDTH;
public String getText() {
- return name().toLowerCase();
+ return toLowerCase(name());
}
static final Map index = new HashMap();
@@ -424,11 +428,11 @@ public enum HtmlTag {
}
public String getText() {
- return name().toLowerCase();
+ return toLowerCase(name());
}
public Attr getAttr(Name attrName) {
- return Attr.index.get(attrName.toString().toLowerCase());
+ return Attr.index.get(toLowerCase(attrName.toString()));
}
public AttrKind getAttrKind(Name attrName) {
@@ -450,6 +454,10 @@ public enum HtmlTag {
}
static HtmlTag get(Name tagName) {
- return index.get(tagName.toString().toLowerCase());
+ return index.get(toLowerCase(tagName.toString()));
+ }
+
+ private static String toLowerCase(String s) {
+ return s.toLowerCase(Locale.US);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
index bb29eeaa530..990ea0d06e0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
@@ -340,6 +340,14 @@ public abstract class Attribute implements AnnotationValue {
}
}
+ public static class UnresolvedClass extends Error {
+ public Type classType;
+ public UnresolvedClass(Type type, Type classType) {
+ super(type);
+ this.classType = classType;
+ }
+ }
+
/** A visitor type for dynamic dispatch on the kind of attribute value. */
public static interface Visitor {
void visitConstant(Attribute.Constant value);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
index be0b5038018..aa05cc29204 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java
@@ -27,8 +27,6 @@ package com.sun.tools.javac.code;
import java.util.Locale;
-import javax.lang.model.type.TypeKind;
-
import com.sun.tools.javac.api.Messages;
import com.sun.tools.javac.code.Type.AnnotatedType;
import com.sun.tools.javac.code.Type.ArrayType;
@@ -191,7 +189,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
void printBaseElementType(Type t, StringBuilder sb, Locale locale) {
Type arrel = t;
- while (arrel.getKind() == TypeKind.ARRAY) {
+ while (arrel.hasTag(TypeTag.ARRAY)) {
arrel = arrel.unannotatedType();
arrel = ((ArrayType) arrel).elemtype;
}
@@ -200,7 +198,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
void printBrackets(Type t, StringBuilder sb, Locale locale) {
Type arrel = t;
- while (arrel.getKind() == TypeKind.ARRAY) {
+ while (arrel.hasTag(TypeTag.ARRAY)) {
if (arrel.isAnnotated()) {
sb.append(' ');
sb.append(arrel.getAnnotationMirrors());
@@ -264,12 +262,12 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
public String visitAnnotatedType(AnnotatedType t, Locale locale) {
if (t.typeAnnotations != null &&
t.typeAnnotations.nonEmpty()) {
- if (t.underlyingType.getKind() == TypeKind.ARRAY) {
+ if (t.underlyingType.hasTag(TypeTag.ARRAY)) {
StringBuilder res = new StringBuilder();
printBaseElementType(t, res, locale);
printBrackets(t, res, locale);
return res.toString();
- } else if (t.underlyingType.getKind() == TypeKind.DECLARED &&
+ } else if (t.underlyingType.hasTag(TypeTag.CLASS) &&
t.underlyingType.getEnclosingType() != Type.noType) {
return visit(t.underlyingType.getEnclosingType(), locale) +
". " +
@@ -348,7 +346,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi
args = args.tail;
buf.append(',');
}
- if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) {
+ if (args.head.unannotatedType().hasTag(TypeTag.ARRAY)) {
buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
if (args.head.getAnnotationMirrors().nonEmpty()) {
buf.append(' ');
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
index 3697e05dead..dee7c42ff9a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
@@ -199,7 +199,7 @@ public class Scope {
}
public void enter(Symbol sym, Scope s) {
- enter(sym, s, s);
+ enter(sym, s, s, false);
}
/**
@@ -207,7 +207,7 @@ public class Scope {
* given scope `s' accessed through `origin'. The last two
* arguments are only used in import scopes.
*/
- public void enter(Symbol sym, Scope s, Scope origin) {
+ public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
Assert.check(shared == 0);
if (nelems * 3 >= hashMask * 2)
dble();
@@ -217,7 +217,7 @@ public class Scope {
old = sentinel;
nelems++;
}
- Entry e = makeEntry(sym, old, elems, s, origin);
+ Entry e = makeEntry(sym, old, elems, s, origin, staticallyImported);
table[hash] = e;
elems = e;
@@ -227,7 +227,7 @@ public class Scope {
}
}
- Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
+ Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin, boolean staticallyImported) {
return new Entry(sym, shadowed, sibling, scope);
}
@@ -499,6 +499,10 @@ public class Scope {
else return shadowed.next(sf);
}
+ public boolean isStaticallyImported() {
+ return false;
+ }
+
public Scope getOrigin() {
// The origin is only recorded for import scopes. For all
// other scope entries, the "enclosing" type is available
@@ -517,20 +521,19 @@ public class Scope {
}
@Override
- Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
- return new ImportEntry(sym, shadowed, sibling, scope, origin);
- }
+ Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope,
+ final Scope origin, final boolean staticallyImported) {
+ return new Entry(sym, shadowed, sibling, scope) {
+ @Override
+ public Scope getOrigin() {
+ return origin;
+ }
- static class ImportEntry extends Entry {
- private Scope origin;
-
- ImportEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
- super(sym, shadowed, sibling, scope);
- this.origin = origin;
- }
-
- @Override
- public Scope getOrigin() { return origin; }
+ @Override
+ public boolean isStaticallyImported() {
+ return staticallyImported;
+ }
+ };
}
}
@@ -724,7 +727,7 @@ public class Scope {
}
@Override
- public void enter(Symbol sym, Scope s, Scope origin) {
+ public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
throw new UnsupportedOperationException();
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
index f8b18d18b8e..64c117cb2bc 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -463,26 +463,34 @@ public abstract class Symbol implements Element {
return false;
}
- /** Check for hiding. Note that this doesn't handle multiple
- * (interface) inheritance. */
private boolean hiddenIn(ClassSymbol clazz, Types types) {
- if (kind == MTH && (flags() & STATIC) == 0) return false;
- while (true) {
- if (owner == clazz) return false;
- Scope.Entry e = clazz.members().lookup(name);
- while (e.scope != null) {
- if (e.sym == this) return false;
- if (e.sym.kind == kind &&
+ Symbol sym = hiddenInInternal(clazz, types);
+ return sym != null && sym != this;
+ }
+
+ private Symbol hiddenInInternal(ClassSymbol c, Types types) {
+ Scope.Entry e = c.members().lookup(name);
+ while (e.scope != null) {
+ if (e.sym.kind == kind &&
(kind != MTH ||
- (e.sym.flags() & STATIC) != 0 &&
- types.isSubSignature(e.sym.type, type)))
- return true;
- e = e.next();
+ (e.sym.flags() & STATIC) != 0 &&
+ types.isSubSignature(e.sym.type, type))) {
+ return e.sym;
}
- Type superType = types.supertype(clazz.type);
- if (!superType.hasTag(CLASS)) return false;
- clazz = (ClassSymbol)superType.tsym;
+ e = e.next();
}
+ List hiddenSyms = List.nil();
+ for (Type st : types.interfaces(c.type).prepend(types.supertype(c.type))) {
+ if (st != null && (st.hasTag(CLASS))) {
+ Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
+ if (sym != null) {
+ hiddenSyms = hiddenSyms.prepend(hiddenInInternal((ClassSymbol)st.tsym, types));
+ }
+ }
+ }
+ return hiddenSyms.contains(this) ?
+ this :
+ (hiddenSyms.isEmpty() ? null : hiddenSyms.head);
}
/** Is this symbol inherited into a given class?
@@ -1171,7 +1179,7 @@ public abstract class Symbol implements Element {
/**
* The variable's constant value, if this is a constant.
* Before the constant value is evaluated, it points to an
- * initalizer environment. If this is not a constant, it can
+ * initializer environment. If this is not a constant, it can
* be used for other stuff.
*/
private Object data;
@@ -1223,6 +1231,9 @@ public abstract class Symbol implements Element {
/** The extra (synthetic/mandated) parameters of the method. */
public List extraParams = List.nil();
+ /** The captured local variables in an anonymous class */
+ public List capturedLocals = List.nil();
+
/** The parameters of the method. */
public List params = null;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
index 2764900d054..fb6308ba9bd 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java
@@ -1161,7 +1161,7 @@ public abstract class Type implements TypeMirror {
}
public boolean contains(Type elem) {
- return elem == this || contains(argtypes, elem) || restype.contains(elem);
+ return elem == this || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
}
public MethodType asMethodType() { return this; }
@@ -1525,7 +1525,7 @@ public abstract class Type implements TypeMirror {
}
protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
- Type bound2 = toTypeVarMap.apply(bound);
+ Type bound2 = toTypeVarMap.apply(bound).baseType();
List prevBounds = bounds.get(ib);
for (Type b : prevBounds) {
//check for redundancy - use strict version of isSameType on tvars
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
index 260715dff64..642de5d4c4a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
@@ -29,6 +29,8 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.type.TypeKind;
+import javax.tools.JavaFileObject;
+
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Flags;
@@ -52,12 +54,16 @@ import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Annotate.Annotator;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
@@ -90,11 +96,17 @@ public class TypeAnnotations {
* later processing.
*/
public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
- final Log log, final JCClassDecl tree, Annotate annotate) {
+ final Log log, final Env env, final JCClassDecl tree, final Annotate annotate) {
annotate.afterRepeated( new Annotator() {
@Override
public void enterAnnotation() {
- new TypeAnnotationPositions(syms, names, log, true).scan(tree);
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+
+ try {
+ new TypeAnnotationPositions(syms, names, log, true).scan(tree);
+ } finally {
+ log.useSource(oldSource);
+ }
}
} );
}
@@ -906,7 +918,14 @@ public class TypeAnnotations {
if (!invocation.typeargs.contains(tree)) {
Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
}
- p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
+ MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect());
+ if (exsym == null) {
+ Assert.error("could not determine symbol for {" + invocation + "}");
+ } else if (exsym.isConstructor()) {
+ p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
+ } else {
+ p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
+ }
p.pos = invocation.pos;
p.type_index = invocation.typeargs.indexOf(tree);
return;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
index e1887b5f4a6..06744bf6d06 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -505,12 +505,27 @@ public class Types {
//merge thrown types - form the intersection of all the thrown types in
//all the signatures in the list
+ boolean toErase = !bestSoFar.type.hasTag(FORALL);
List thrown = null;
- for (Symbol msym1 : methodSyms) {
- Type mt1 = memberType(origin.type, msym1);
+ Type mt1 = memberType(origin.type, bestSoFar);
+ for (Symbol msym2 : methodSyms) {
+ Type mt2 = memberType(origin.type, msym2);
+ List thrown_mt2 = mt2.getThrownTypes();
+ if (toErase) {
+ thrown_mt2 = erasure(thrown_mt2);
+ } else {
+ /* If bestSoFar is generic then all the methods are generic.
+ * The opposite is not true: a non generic method can override
+ * a generic method (raw override) so it's safe to cast mt1 and
+ * mt2 to ForAll.
+ */
+ ForAll fa1 = (ForAll)mt1;
+ ForAll fa2 = (ForAll)mt2;
+ thrown_mt2 = subst(thrown_mt2, fa2.tvars, fa1.tvars);
+ }
thrown = (thrown == null) ?
- mt1.getThrownTypes() :
- chk.intersect(mt1.getThrownTypes(), thrown);
+ thrown_mt2 :
+ chk.intersect(thrown_mt2, thrown);
}
final List thrown1 = thrown;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
index 39587558a46..3a0997bef55 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
@@ -332,8 +332,20 @@ public class Annotate {
}
if (expected.tsym == syms.classType.tsym) {
Type result = attr.attribExpr(tree, env, expected);
- if (result.isErroneous())
- return new Attribute.Error(expected);
+ if (result.isErroneous()) {
+ // Does it look like a class literal?
+ if (TreeInfo.name(tree) == names._class) {
+ Name n = (((JCFieldAccess) tree).selected).type.tsym.flatName();
+ return new Attribute.UnresolvedClass(expected,
+ types.createErrorType(n,
+ syms.unknownSymbol, syms.classType));
+ } else {
+ return new Attribute.Error(expected);
+ }
+ }
+
+ // Class literals look like field accesses of a field named class
+ // at the tree level
if (TreeInfo.name(tree) != names._class) {
log.error(tree.pos(), "annotation.value.must.be.class.literal");
return new Attribute.Error(expected);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 335c3249267..6ef409d9339 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -398,7 +398,7 @@ public class Attr extends JCTree.Visitor {
@Override
public Symbol visitMemberSelect(MemberSelectTree node, Env env) {
Symbol site = visit(node.getExpression(), env);
- if (site.kind == ERR)
+ if (site.kind == ERR || site.kind == ABSENT_TYP)
return site;
Name name = (Name)node.getIdentifier();
if (site.kind == PCK) {
@@ -1063,9 +1063,7 @@ public class Attr extends JCTree.Visitor {
if (tree.init != null) {
if ((v.flags_field & FINAL) != 0 &&
- !tree.init.hasTag(NEWCLASS) &&
- !tree.init.hasTag(LAMBDA) &&
- !tree.init.hasTag(REFERENCE)) {
+ memberEnter.needsLazyConstValue(tree.init)) {
// In this case, `v' is final. Ensure that it's initializer is
// evaluated.
v.getConstValue(); // ensure initializer is evaluated
@@ -2395,7 +2393,7 @@ public class Attr extends JCTree.Visitor {
ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ?
recoveryInfo :
- new LambdaResultInfo(lambdaType.getReturnType(), funcContext);
+ new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo;
Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
@@ -2602,35 +2600,12 @@ public class Attr extends JCTree.Visitor {
}
}
- class LambdaResultInfo extends ResultInfo {
-
- LambdaResultInfo(Type pt, CheckContext checkContext) {
- super(VAL, pt, checkContext);
- }
-
- @Override
- protected Type check(DiagnosticPosition pos, Type found) {
- return super.check(pos, found.baseType());
- }
-
- @Override
- protected ResultInfo dup(CheckContext newContext) {
- return new LambdaResultInfo(pt, newContext);
- }
-
- @Override
- protected ResultInfo dup(Type newPt) {
- return new LambdaResultInfo(newPt, checkContext);
- }
- }
-
/**
* Lambda compatibility. Check that given return types, thrown types, parameter types
* are compatible with the expected functional interface descriptor. This means that:
* (i) parameter types must be identical to those of the target descriptor; (ii) return
* types must be compatible with the return type of the expected descriptor;
- * (iii) thrown types must be 'included' in the thrown types list of the expected
- * descriptor.
+ * (iii) finish inference of thrown types if required.
*/
private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) {
Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
@@ -2652,9 +2627,7 @@ public class Attr extends JCTree.Visitor {
if (!speculativeAttr) {
List thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
- if (chk.unhandled(tree.inferredThrownTypes == null ? List.nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) {
- log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes);
- }
+ chk.unhandled(tree.inferredThrownTypes == null ? List.nil() : tree.inferredThrownTypes, thrownTypes);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index 71f191b0092..1bb051b1461 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -875,19 +875,23 @@ public class Check {
}
Type owntype = mtype;
List formals = owntype.getParameterTypes();
+ List nonInferred = sym.type.getParameterTypes();
+ if (nonInferred.length() != formals.length()) nonInferred = formals;
Type last = useVarargs ? formals.last() : null;
- if (sym.name == names.init &&
- sym.owner == syms.enumSym)
- formals = formals.tail.tail;
+ if (sym.name == names.init && sym.owner == syms.enumSym) {
+ formals = formals.tail.tail;
+ nonInferred = nonInferred.tail.tail;
+ }
List args = argtrees;
if (args != null) {
//this is null when type-checking a method reference
while (formals.head != last) {
JCTree arg = args.head;
- Warner warn = convertWarner(arg.pos(), arg.type, formals.head);
+ Warner warn = convertWarner(arg.pos(), arg.type, nonInferred.head);
assertConvertible(arg, arg.type, formals.head, warn);
args = args.tail;
formals = formals.tail;
+ nonInferred = nonInferred.tail;
}
if (useVarargs) {
Type varArg = types.elemtype(last);
@@ -903,17 +907,17 @@ public class Check {
Type varParam = owntype.getParameterTypes().last();
Type lastArg = argtypes.last();
if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
- !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
+ !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
- types.elemtype(varParam), varParam);
+ types.elemtype(varParam), varParam);
}
}
if (useVarargs) {
Type argtype = owntype.getParameterTypes().last();
if (!types.isReifiable(argtype) &&
- (!allowSimplifiedVarargs ||
- sym.attribute(syms.trustMeType.tsym) == null ||
- !isTrustMeAllowedOnMethod(sym))) {
+ (!allowSimplifiedVarargs ||
+ sym.attribute(syms.trustMeType.tsym) == null ||
+ !isTrustMeAllowedOnMethod(sym))) {
warnUnchecked(env.tree.pos(),
"unchecked.generic.array.creation",
argtype);
@@ -929,15 +933,15 @@ public class Check {
return owntype;
}
//where
- private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
- if (types.isConvertible(actual, formal, warn))
- return;
+ private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
+ if (types.isConvertible(actual, formal, warn))
+ return;
- if (formal.isCompound()
- && types.isSubtype(actual, types.supertype(formal))
- && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
- return;
- }
+ if (formal.isCompound()
+ && types.isSubtype(actual, types.supertype(formal))
+ && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
+ return;
+ }
/**
* Check that type 't' is a valid instantiation of a generic class
@@ -1747,7 +1751,7 @@ public class Check {
if (!sup.hasTag(CLASS)) return;
for (Type t1 = sup;
- t1.tsym.type.isParameterized();
+ t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
t1 = types.supertype(t1)) {
for (Scope.Entry e1 = t1.tsym.members().elems;
e1 != null;
@@ -2212,11 +2216,11 @@ public class Check {
if (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
return;
if (seen.contains(t)) {
- tv = (TypeVar)t;
+ tv = (TypeVar)t.unannotatedType();
tv.bound = types.createErrorType(t);
log.error(pos, "cyclic.inheritance", t);
} else if (t.hasTag(TYPEVAR)) {
- tv = (TypeVar)t;
+ tv = (TypeVar)t.unannotatedType();
seen = seen.prepend(tv);
for (Type b : types.getBounds(tv))
checkNonCyclic1(pos, b, seen);
@@ -3329,14 +3333,15 @@ public class Check {
boolean isClassDecl = e.scope == s;
if ((isClassDecl || sym != e.sym) &&
sym.kind == e.sym.kind &&
- sym.name != names.error) {
+ sym.name != names.error &&
+ (!staticImport || !e.isStaticallyImported())) {
if (!e.sym.type.isErroneous()) {
String what = e.sym.toString();
if (!isClassDecl) {
if (staticImport)
log.error(pos, "already.defined.static.single.import", what);
else
- log.error(pos, "already.defined.single.import", what);
+ log.error(pos, "already.defined.single.import", what);
}
else if (sym != e.sym)
log.error(pos, "already.defined.this.unit", what);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java
index e1094b6f9d1..41c0792acf2 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java
@@ -291,7 +291,7 @@ public class Enter extends JCTree.Visitor {
if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
if (isPkgInfo) {
addEnv = true;
- } else {
+ } else if (tree.packageAnnotations.nonEmpty()){
log.error(tree.packageAnnotations.head.pos(),
"pkg.annotations.sb.in.package-info.java");
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
index 10ff59c4f74..e488d45b0c0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
@@ -224,7 +224,7 @@ public class Flow {
}
try {
new AliveAnalyzer().analyzeTree(env, that, make);
- new FlowAnalyzer().analyzeTree(env, that, make);
+ new LambdaFlowAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -1259,12 +1259,24 @@ public class Flow {
ListBuffer prevPending = pendingExits;
try {
pendingExits = ListBuffer.lb();
- caught = List.of(syms.throwableType); //inhibit exception checking
+ caught = tree.getDescriptorType(types).getThrownTypes();
thrown = List.nil();
scan(tree.body);
- tree.inferredThrownTypes = thrown;
- }
- finally {
+ List exits = pendingExits.toList();
+ pendingExits = new ListBuffer();
+ while (exits.nonEmpty()) {
+ FlowPendingExit exit = exits.head;
+ exits = exits.tail;
+ if (exit.thrown == null) {
+ Assert.check(exit.tree.hasTag(RETURN));
+ } else {
+ // uncaught throws will be reported later
+ pendingExits.append(exit);
+ }
+ }
+
+ errorUncaught();
+ } finally {
pendingExits = prevPending;
caught = prevCaught;
thrown = prevThrown;
@@ -1302,6 +1314,33 @@ public class Flow {
}
}
+ /**
+ * Specialized pass that performs inference of thrown types for lambdas.
+ */
+ class LambdaFlowAnalyzer extends FlowAnalyzer {
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (tree.type != null &&
+ tree.type.isErroneous()) {
+ return;
+ }
+ List prevCaught = caught;
+ List prevThrown = thrown;
+ ListBuffer prevPending = pendingExits;
+ try {
+ pendingExits = ListBuffer.lb();
+ caught = List.of(syms.throwableType);
+ thrown = List.nil();
+ scan(tree.body);
+ tree.inferredThrownTypes = thrown;
+ } finally {
+ pendingExits = prevPending;
+ caught = prevCaught;
+ thrown = prevThrown;
+ }
+ }
+ }
+
/**
* This pass implements (i) definite assignment analysis, which ensures that
* each variable is assigned when used and (ii) definite unassignment analysis,
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
index 21b6791bb7d..7633f96d1df 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
@@ -249,7 +249,7 @@ public class LambdaToMethod extends TreeTranslator {
MethodType lambdaType = (MethodType) sym.type;
{
- MethodSymbol owner = (MethodSymbol) localContext.owner;
+ Symbol owner = localContext.owner;
ListBuffer ownerTypeAnnos = new ListBuffer();
ListBuffer lambdaTypeAnnos = new ListBuffer();
@@ -473,7 +473,7 @@ public class LambdaToMethod extends TreeTranslator {
//non-void to non-void conversion:
// return (TYPE)BODY;
JCExpression retExpr = transTypes.coerce(attrEnv, expr, restype);
- return make.Block(0, List.of(make.Return(retExpr)));
+ return make.at(retExpr).Block(0, List.of(make.Return(retExpr)));
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 4ee5e63fc28..75e1d388666 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -356,22 +356,44 @@ public class Lower extends TreeTranslator {
}
}
+ ClassSymbol ownerToCopyFreeVarsFrom(ClassSymbol c) {
+ if (!c.isLocal()) {
+ return null;
+ }
+ Symbol currentOwner = c.owner;
+ while ((currentOwner.owner.kind & TYP) != 0 && currentOwner.isLocal()) {
+ currentOwner = currentOwner.owner;
+ }
+ if ((currentOwner.owner.kind & (VAR | MTH)) != 0 && c.isSubClass(currentOwner, types)) {
+ return (ClassSymbol)currentOwner;
+ }
+ return null;
+ }
+
/** Return the variables accessed from within a local class, which
* are declared in the local class' owner.
* (in reverse order of first access).
*/
List freevars(ClassSymbol c) {
+ List fvs = freevarCache.get(c);
+ if (fvs != null) {
+ return fvs;
+ }
if ((c.owner.kind & (VAR | MTH)) != 0) {
- List fvs = freevarCache.get(c);
- if (fvs == null) {
- FreeVarCollector collector = new FreeVarCollector(c);
- collector.scan(classDef(c));
- fvs = collector.fvs;
- freevarCache.put(c, fvs);
- }
+ FreeVarCollector collector = new FreeVarCollector(c);
+ collector.scan(classDef(c));
+ fvs = collector.fvs;
+ freevarCache.put(c, fvs);
return fvs;
} else {
- return List.nil();
+ ClassSymbol owner = ownerToCopyFreeVarsFrom(c);
+ if (owner != null) {
+ fvs = freevarCache.get(owner);
+ freevarCache.put(c, fvs);
+ return fvs;
+ } else {
+ return List.nil();
+ }
}
}
@@ -1046,7 +1068,7 @@ public class Lower extends TreeTranslator {
boolean needsPrivateAccess(Symbol sym) {
if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
return false;
- } else if (sym.name == names.init && (sym.owner.owner.kind & (VAR | MTH)) != 0) {
+ } else if (sym.name == names.init && sym.owner.isLocal()) {
// private constructor in local class: relax protection
sym.flags_field &= ~PRIVATE;
return false;
@@ -2448,6 +2470,7 @@ public class Lower extends TreeTranslator {
tree.name = Convert.shortName(currentClass.flatName());
// Add this$n and free variables proxy definitions to class.
+
for (List l = fvdefs; l.nonEmpty(); l = l.tail) {
tree.defs = tree.defs.prepend(l.head);
enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
@@ -2670,8 +2693,7 @@ public class Lower extends TreeTranslator {
//where
private void visitMethodDefInternal(JCMethodDecl tree) {
if (tree.name == names.init &&
- (currentClass.isInner() ||
- (currentClass.owner.kind & (VAR | MTH)) != 0)) {
+ (currentClass.isInner() || currentClass.isLocal())) {
// We are seeing a constructor of an inner class.
MethodSymbol m = tree.sym;
@@ -2713,9 +2735,9 @@ public class Lower extends TreeTranslator {
for (List l = fvs; l.nonEmpty(); l = l.tail) {
if (TreeInfo.isInitialConstructor(tree)) {
final Name pName = proxyName(l.head.name);
- m.extraParams =
- m.extraParams.append((VarSymbol)
- (proxies.lookup(pName).sym));
+ m.capturedLocals =
+ m.capturedLocals.append((VarSymbol)
+ (proxies.lookup(pName).sym));
added = added.prepend(
initField(tree.body.pos, pName));
}
@@ -2818,7 +2840,7 @@ public class Lower extends TreeTranslator {
// If created class is local, add free variables after
// explicit constructor arguments.
- if ((c.owner.kind & (VAR | MTH)) != 0) {
+ if (c.isLocal()) {
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
}
@@ -2837,7 +2859,7 @@ public class Lower extends TreeTranslator {
if (tree.encl != null) {
thisArg = attr.makeNullCheck(translate(tree.encl));
thisArg.type = tree.encl.type;
- } else if ((c.owner.kind & (MTH | VAR)) != 0) {
+ } else if (c.isLocal()) {
// local class
thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym);
} else {
@@ -2966,7 +2988,7 @@ public class Lower extends TreeTranslator {
// If we are calling a constructor of a local class, add
// free variables after explicit constructor arguments.
ClassSymbol c = (ClassSymbol)constructor.owner;
- if ((c.owner.kind & (VAR | MTH)) != 0) {
+ if (c.isLocal()) {
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
}
@@ -2994,7 +3016,7 @@ public class Lower extends TreeTranslator {
makeNullCheck(translate(((JCFieldAccess) tree.meth).selected));
tree.meth = make.Ident(constructor);
((JCIdent) tree.meth).name = methName;
- } else if ((c.owner.kind & (MTH | VAR)) != 0 || methName == names._this){
+ } else if (c.isLocal() || methName == names._this){
// local class or this() call
thisArg = makeThis(tree.meth.pos(), c.type.getEnclosingType().tsym);
} else {
@@ -3436,7 +3458,7 @@ public class Lower extends TreeTranslator {
eType,
List.nil());
VarSymbol itvar = new VarSymbol(0, names.fromString("i" + target.syntheticNameChar()),
- types.erasure(iterator.type.getReturnType()),
+ types.erasure(types.asSuper(iterator.type.getReturnType(), syms.iteratorType.tsym)),
currentMethodSym);
JCStatement init = make.
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
index 24a69f09e96..9f9dd4fb874 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
@@ -189,7 +189,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types) &&
!toScope.includes(sym))
- toScope.enter(sym, fromScope, origin.members());
+ toScope.enter(sym, fromScope, origin.members(), true);
}
}
}.importFrom(tsym);
@@ -217,7 +217,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
staticImportAccessible(sym, packge) &&
!toScope.includes(sym) &&
sym.isMemberOf(origin, types)) {
- toScope.enter(sym, fromScope, origin.members());
+ toScope.enter(sym, fromScope, origin.members(), true);
}
}
}
@@ -283,7 +283,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types) &&
chk.checkUniqueStaticImport(pos, sym, toScope))
- toScope.enter(sym, sym.owner.members(), origin.members());
+ toScope.enter(sym, sym.owner.members(), origin.members(), true);
}
}
}.importFrom(tsym);
@@ -313,9 +313,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types)) {
found = true;
- if (sym.kind == MTH ||
- sym.kind != TYP && chk.checkUniqueStaticImport(pos, sym, toScope))
- toScope.enter(sym, sym.owner.members(), origin.members());
+ if (sym.kind != TYP) {
+ toScope.enter(sym, sym.owner.members(), origin.members(), true);
+ }
}
}
}
@@ -677,8 +677,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
if (tree.init != null) {
v.flags_field |= HASINIT;
if ((v.flags_field & FINAL) != 0 &&
- !tree.init.hasTag(NEWCLASS) &&
- !tree.init.hasTag(LAMBDA)) {
+ needsLazyConstValue(tree.init)) {
Env initEnv = getInitEnv(tree, env);
initEnv.info.enclVar = v;
v.setLazyConstValue(initEnv(tree, initEnv), attr, tree.init);
@@ -700,6 +699,59 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
}
}
+ public boolean needsLazyConstValue(JCTree tree) {
+ InitTreeVisitor initTreeVisitor = new InitTreeVisitor();
+ tree.accept(initTreeVisitor);
+ return initTreeVisitor.result;
+ }
+
+ /** Visitor class for expressions which might be constant expressions.
+ */
+ static class InitTreeVisitor extends JCTree.Visitor {
+
+ private boolean result = true;
+
+ @Override
+ public void visitTree(JCTree tree) {}
+
+ @Override
+ public void visitNewClass(JCNewClass that) {
+ result = false;
+ }
+
+ @Override
+ public void visitLambda(JCLambda that) {
+ result = false;
+ }
+
+ @Override
+ public void visitReference(JCMemberReference that) {
+ result = false;
+ }
+
+ @Override
+ public void visitSelect(JCFieldAccess tree) {
+ tree.selected.accept(this);
+ }
+
+ @Override
+ public void visitConditional(JCConditional tree) {
+ tree.cond.accept(this);
+ tree.truepart.accept(this);
+ tree.falsepart.accept(this);
+ }
+
+ @Override
+ public void visitParens(JCParens tree) {
+ tree.expr.accept(this);
+ }
+
+ @Override
+ public void visitTypeCast(JCTypeCast tree) {
+ tree.expr.accept(this);
+ }
+ }
+
/** Create a fresh environment for a variable's initializer.
* If the variable is a field, the owner of the environment's scope
* is be the variable itself, otherwise the owner is the method
@@ -1089,7 +1141,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
}
}
if (allowTypeAnnos) {
- TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
+ TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, env, tree, annotate);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 897cf210140..0439e0d6132 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -1344,32 +1344,23 @@ public class Resolve {
if (bestSoFar.exists())
return bestSoFar;
- Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
- for (; e.scope != null; e = e.next()) {
- sym = e.sym;
- Type origin = e.getOrigin().owner.type;
- if (sym.kind == VAR) {
- if (e.sym.owner.type != origin)
- sym = sym.clone(e.getOrigin().owner);
- return isAccessible(env, origin, sym)
- ? sym : new AccessError(env, origin, sym);
- }
- }
-
Symbol origin = null;
- e = env.toplevel.starImportScope.lookup(name);
- for (; e.scope != null; e = e.next()) {
- sym = e.sym;
- if (sym.kind != VAR)
- continue;
- // invariant: sym.kind == VAR
- if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
- return new AmbiguityError(bestSoFar, sym);
- else if (bestSoFar.kind >= VAR) {
- origin = e.getOrigin().owner;
- bestSoFar = isAccessible(env, origin.type, sym)
- ? sym : new AccessError(env, origin.type, sym);
+ for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
+ Scope.Entry e = sc.lookup(name);
+ for (; e.scope != null; e = e.next()) {
+ sym = e.sym;
+ if (sym.kind != VAR)
+ continue;
+ // invariant: sym.kind == VAR
+ if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
+ return new AmbiguityError(bestSoFar, sym);
+ else if (bestSoFar.kind >= VAR) {
+ origin = e.getOrigin().owner;
+ bestSoFar = isAccessible(env, origin.type, sym)
+ ? sym : new AccessError(env, origin.type, sym);
+ }
}
+ if (bestSoFar.exists()) break;
}
if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
return bestSoFar.clone(origin);
@@ -1868,7 +1859,10 @@ public class Resolve {
}
}
- /** Find qualified member type.
+
+ /**
+ * Find a type declared in a scope (not inherited). Return null
+ * if none is found.
* @param env The current environment.
* @param site The original type from where the selection takes
* place.
@@ -1877,12 +1871,10 @@ public class Resolve {
* always a superclass or implemented interface of
* site's class.
*/
- Symbol findMemberType(Env env,
- Type site,
- Name name,
- TypeSymbol c) {
- Symbol bestSoFar = typeNotFound;
- Symbol sym;
+ Symbol findImmediateMemberType(Env env,
+ Type site,
+ Name name,
+ TypeSymbol c) {
Scope.Entry e = c.members().lookup(name);
while (e.scope != null) {
if (e.sym.kind == TYP) {
@@ -1892,6 +1884,24 @@ public class Resolve {
}
e = e.next();
}
+ return typeNotFound;
+ }
+
+ /** Find a member type inherited from a superclass or interface.
+ * @param env The current environment.
+ * @param site The original type from where the selection takes
+ * place.
+ * @param name The type's name.
+ * @param c The class to search for the member type. This is
+ * always a superclass or implemented interface of
+ * site's class.
+ */
+ Symbol findInheritedMemberType(Env env,
+ Type site,
+ Name name,
+ TypeSymbol c) {
+ Symbol bestSoFar = typeNotFound;
+ Symbol sym;
Type st = types.supertype(c.type);
if (st != null && st.hasTag(CLASS)) {
sym = findMemberType(env, site, name, st.tsym);
@@ -1910,6 +1920,28 @@ public class Resolve {
return bestSoFar;
}
+ /** Find qualified member type.
+ * @param env The current environment.
+ * @param site The original type from where the selection takes
+ * place.
+ * @param name The type's name.
+ * @param c The class to search for the member type. This is
+ * always a superclass or implemented interface of
+ * site's class.
+ */
+ Symbol findMemberType(Env env,
+ Type site,
+ Name name,
+ TypeSymbol c) {
+ Symbol sym = findImmediateMemberType(env, site, name, c);
+
+ if (sym != typeNotFound)
+ return sym;
+
+ return findInheritedMemberType(env, site, name, c);
+
+ }
+
/** Find a global type in given scope and load corresponding class.
* @param env The current environment.
* @param scope The scope in which to look for the type.
@@ -1928,6 +1960,21 @@ public class Resolve {
return bestSoFar;
}
+ Symbol findTypeVar(Env env, Name name, boolean staticOnly) {
+ for (Scope.Entry e = env.info.scope.lookup(name);
+ e.scope != null;
+ e = e.next()) {
+ if (e.sym.kind == TYP) {
+ if (staticOnly &&
+ e.sym.type.hasTag(TYPEVAR) &&
+ e.sym.owner.kind == TYP)
+ return new StaticError(e.sym);
+ return e.sym;
+ }
+ }
+ return typeNotFound;
+ }
+
/** Find an unqualified type symbol.
* @param env The current environment.
* @param name The type's name.
@@ -1938,19 +1985,26 @@ public class Resolve {
boolean staticOnly = false;
for (Env env1 = env; env1.outer != null; env1 = env1.outer) {
if (isStatic(env1)) staticOnly = true;
- for (Scope.Entry e = env1.info.scope.lookup(name);
- e.scope != null;
- e = e.next()) {
- if (e.sym.kind == TYP) {
- if (staticOnly &&
- e.sym.type.hasTag(TYPEVAR) &&
- e.sym.owner.kind == TYP) return new StaticError(e.sym);
- return e.sym;
- }
+ // First, look for a type variable and the first member type
+ final Symbol tyvar = findTypeVar(env1, name, staticOnly);
+ sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
+ name, env1.enclClass.sym);
+
+ // Return the type variable if we have it, and have no
+ // immediate member, OR the type variable is for a method.
+ if (tyvar != typeNotFound) {
+ if (sym == typeNotFound ||
+ (tyvar.kind == TYP && tyvar.exists() &&
+ tyvar.owner.kind == MTH))
+ return tyvar;
}
- sym = findMemberType(env1, env1.enclClass.sym.type, name,
- env1.enclClass.sym);
+ // If the environment is a class def, finish up,
+ // otherwise, do the entire findMemberType
+ if (sym == typeNotFound)
+ sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
+ name, env1.enclClass.sym);
+
if (staticOnly && sym.kind == TYP &&
sym.type.hasTag(CLASS) &&
sym.type.getEnclosingType().hasTag(CLASS) &&
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index ac8b94a8310..73eb2d34acf 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -657,6 +657,14 @@ public class ClassWriter extends ClassFile {
databuf.appendChar(pool.put(s.name));
databuf.appendChar(flags);
}
+ // Now write the captured locals
+ for (VarSymbol s : m.capturedLocals) {
+ final int flags =
+ ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+ ((int) m.flags() & SYNTHETIC);
+ databuf.appendChar(pool.put(s.name));
+ databuf.appendChar(flags);
+ }
endAttr(attrIndex);
return 1;
} else
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
index 0c20e771cd9..73d3b020bc1 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
@@ -363,6 +363,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
throw new Abort();
}
source = Source.instance(context);
+ Target target = Target.instance(context);
attr = Attr.instance(context);
chk = Check.instance(context);
gen = Gen.instance(context);
@@ -403,6 +404,8 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
}
}
+ checkForObsoleteOptions(target);
+
verboseCompilePolicy = options.isSet("verboseCompilePolicy");
if (attrParseOnly)
@@ -432,6 +435,26 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context));
}
+ private void checkForObsoleteOptions(Target target) {
+ // Unless lint checking on options is disabled, check for
+ // obsolete source and target options.
+ boolean obsoleteOptionFound = false;
+ if (options.isUnset(XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option)) {
+ if (source.compareTo(Source.JDK1_5) <= 0) {
+ log.warning(LintCategory.OPTIONS, "option.obsolete.source", source.name);
+ obsoleteOptionFound = true;
+ }
+
+ if (target.compareTo(Target.JDK1_5) <= 0) {
+ log.warning(LintCategory.OPTIONS, "option.obsolete.target", target.name);
+ obsoleteOptionFound = true;
+ }
+
+ if (obsoleteOptionFound)
+ log.warning(LintCategory.OPTIONS, "option.obsolete.suppression");
+ }
+ }
+
/* Switches:
*/
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
index 72a279d7173..2842487b4a7 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
@@ -262,6 +262,11 @@ public class Main {
}
}
+ if (options.get(PROFILE) != null && options.get(BOOTCLASSPATH) != null) {
+ error("err.profile.bootclasspath.conflict");
+ return null;
+ }
+
if (this.classnames != null && classNames != null) {
this.classnames.addAll(Arrays.asList(classNames));
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
index dd3bbe80c6b..d21e7d4acb1 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java
@@ -389,6 +389,7 @@ public enum Option {
XPREFER("-Xprefer:", "opt.prefer", EXTENDED, BASIC, ONEOF, "source", "newer"),
+ // see enum PkgInfo
XPKGINFO("-Xpkginfo:", "opt.pkginfo", EXTENDED, BASIC, ONEOF, "always", "legacy", "nonempty"),
/* -O is a no-op, accepted for backward compatibility. */
@@ -686,7 +687,28 @@ public enum Option {
// For -XpkgInfo:value
public enum PkgInfo {
- ALWAYS, LEGACY, NONEMPTY;
+ /**
+ * Always generate package-info.class for every package-info.java file.
+ * The file may be empty if there annotations with a RetentionPolicy
+ * of CLASS or RUNTIME. This option may be useful in conjunction with
+ * build systems (such as Ant) that expect javac to generate at least
+ * one .class file for every .java file.
+ */
+ ALWAYS,
+ /**
+ * Generate a package-info.class file if package-info.java contains
+ * annotations. The file may be empty if all the annotations have
+ * a RetentionPolicy of SOURCE.
+ * This value is just for backwards compatibility with earlier behavior.
+ * Either of the other two values are to be preferred to using this one.
+ */
+ LEGACY,
+ /**
+ * Generate a package-info.class file if and only if there are annotations
+ * in package-info.java to be written into it.
+ */
+ NONEMPTY;
+
public static PkgInfo get(Options options) {
String v = options.get(XPKGINFO);
return (v == null
diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java
index e44f6734b28..d58c73fa46f 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java
@@ -244,7 +244,10 @@ public class AnnotationProxyMaker {
}
public void visitError(Attribute.Error e) {
- value = null; // indicates a type mismatch
+ if (e instanceof Attribute.UnresolvedClass)
+ value = new MirroredTypeExceptionProxy(((Attribute.UnresolvedClass)e).classType);
+ else
+ value = null; // indicates a type mismatch
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
index 4e966f9b716..7aca9f55726 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java
@@ -89,7 +89,7 @@ import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
* deletion without notice.
*/
public class JavacProcessingEnvironment implements ProcessingEnvironment, Closeable {
- Options options;
+ private final Options options;
private final boolean printProcessorInfo;
private final boolean printRounds;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index 908b0aff112..5d1a22b84a1 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -732,10 +732,6 @@ compiler.misc.incompatible.ret.type.in.mref=\
bad return type in method reference\n\
{0}
-# 0: list of type
-compiler.err.incompatible.thrown.types.in.lambda=\
- incompatible thrown types {0} in lambda expression
-
# 0: list of type
compiler.err.incompatible.thrown.types.in.mref=\
incompatible thrown types {0} in method reference
@@ -1444,6 +1440,17 @@ compiler.warn.static.not.qualified.by.type=\
compiler.warn.source.no.bootclasspath=\
bootstrap class path not set in conjunction with -source {0}
+# 0: string
+compiler.warn.option.obsolete.source=\
+ source value {0} is obsolete and will be removed in a future release
+
+# 0: string
+compiler.warn.option.obsolete.target=\
+ target value {0} is obsolete and will be removed in a future release
+
+compiler.warn.option.obsolete.suppression=\
+ To suppress warnings about obsolete options, use -Xlint:-options.
+
# 0: name, 1: number, 2: number, 3: number, 4: number
compiler.warn.future.attr=\
{0} attribute introduced in version {1}.{2} class files is ignored in version {3}.{4} class files
@@ -2241,7 +2248,7 @@ compiler.err.cant.annotate.static.class=\
# TODO 308: make a better error message
# 0: unused
compiler.err.cant.annotate.nested.type=\
- nested type cannot be annotated
+ scoping construct for static nested type cannot be annotated
# 0: type, 1: type
compiler.err.incorrect.receiver.name=\
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
index f32c2291748..328d9fbf76b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties
@@ -185,6 +185,8 @@ javac.err.invalid.A.key=\
key in annotation processor option ''{0}'' is not a dot-separated sequence of identifiers
javac.err.invalid.flag=\
invalid flag: {0}
+javac.err.profile.bootclasspath.conflict=\
+ profile and bootclasspath options cannot be used together
javac.err.invalid.profile=\
invalid profile: {0}
javac.err.invalid.target=\
diff --git a/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java b/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java
index 8cae1dd3696..1ebea23192d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/Profiles.java
@@ -148,7 +148,7 @@ public abstract class Profiles {
}
}
- final static Map packages = new TreeMap();
+ final Map packages = new TreeMap();
final int maxProfile = 4; // Three compact profiles plus full JRE
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
index 846a4a2e2aa..d2e9b67324b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
@@ -645,7 +645,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public List targets;
public Type getDescriptorType(Types types) {
- return types.findDescriptorType(targets.head);
+ return targets.nonEmpty() ? types.findDescriptorType(targets.head) : types.createErrorType(null);
}
}
@@ -1571,6 +1571,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public Tag getTag() {
return NEWARRAY;
}
+
+ @Override
+ public List getAnnotations() {
+ return annotations;
+ }
+
+ @Override
+ public List> getDimAnnotations() {
+ return dimAnnotations;
+ }
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
index e7c1e12b1cf..653d9e54eff 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
@@ -944,10 +944,17 @@ public class Pretty extends JCTree.Visitor {
try {
if (tree.elemtype != null) {
print("new ");
- printTypeAnnotations(tree.annotations);
JCTree elem = tree.elemtype;
printBaseElementType(elem);
- boolean isElemAnnoType = elem instanceof JCAnnotatedType;
+
+ if (!tree.annotations.isEmpty()) {
+ print(' ');
+ printTypeAnnotations(tree.annotations);
+ }
+ if (tree.elems != null) {
+ print("[]");
+ }
+
int i = 0;
List> da = tree.dimAnnotations;
for (List l = tree.dims; l.nonEmpty(); l = l.tail) {
@@ -960,17 +967,7 @@ public class Pretty extends JCTree.Visitor {
printExpr(l.head);
print("]");
}
- if (tree.elems != null) {
- if (isElemAnnoType) {
- print(' ');
- printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
- }
- print("[]");
- }
- if (isElemAnnoType)
- elem = ((JCAnnotatedType)elem).underlyingType;
- if (elem instanceof JCArrayTypeTree)
- printBrackets((JCArrayTypeTree) elem);
+ printBrackets(elem);
}
if (tree.elems != null) {
print("{");
@@ -1260,20 +1257,24 @@ public class Pretty extends JCTree.Visitor {
}
// prints the brackets of a nested array in reverse order
- private void printBrackets(JCArrayTypeTree tree) throws IOException {
- JCTree elem;
+ // tree is either JCArrayTypeTree or JCAnnotatedTypeTree
+ private void printBrackets(JCTree tree) throws IOException {
+ JCTree elem = tree;
while (true) {
- elem = tree.elemtype;
if (elem.hasTag(ANNOTATED_TYPE)) {
JCAnnotatedType atype = (JCAnnotatedType) elem;
elem = atype.underlyingType;
- if (!elem.hasTag(TYPEARRAY)) break;
- print(' ');
- printTypeAnnotations(atype.annotations);
+ if (elem.hasTag(TYPEARRAY)) {
+ print(' ');
+ printTypeAnnotations(atype.annotations);
+ }
+ }
+ if (elem.hasTag(TYPEARRAY)) {
+ print("[]");
+ elem = ((JCArrayTypeTree)elem).elemtype;
+ } else {
+ break;
}
- print("[]");
- if (!elem.hasTag(TYPEARRAY)) break;
- tree = (JCArrayTypeTree) elem;
}
}
@@ -1378,22 +1379,15 @@ public class Pretty extends JCTree.Visitor {
public void visitAnnotatedType(JCAnnotatedType tree) {
try {
- if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) {
+ if (tree.underlyingType.hasTag(SELECT)) {
JCFieldAccess access = (JCFieldAccess) tree.underlyingType;
printExpr(access.selected, TreeInfo.postfixPrec);
print(".");
printTypeAnnotations(tree.annotations);
print(access.name);
- } else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
- JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
+ } else if (tree.underlyingType.hasTag(TYPEARRAY)) {
printBaseElementType(tree);
- print(' ');
- printTypeAnnotations(tree.annotations);
- print("[]");
- JCExpression elem = array.elemtype;
- if (elem.hasTag(TYPEARRAY)) {
- printBrackets((JCArrayTypeTree) elem);
- }
+ printBrackets(tree);
} else {
printTypeAnnotations(tree.annotations);
printExpr(tree.underlyingType);
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java
index ba1908f218f..79580f60fb5 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java
@@ -128,7 +128,14 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
try {
return clazz.flags();
} catch (CompletionFailure ex) {
- // quietly ignore completion failures
+ /* Quietly ignore completion failures.
+ * Note that a CompletionFailure can only
+ * occur as a result of calling complete(),
+ * which will always remove the current
+ * completer, leaving it to be null or
+ * follow-up completer. Thus the loop
+ * is guaranteed to eventually terminate.
+ */
}
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java
index 058d173ebe7..842a7bf4374 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java
@@ -30,9 +30,12 @@ import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.MemberEnter;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.Context;
+import static com.sun.tools.javac.code.Flags.*;
+
/**
* Javadoc's own memberEnter phase does a few things above and beyond that
* done by javac.
@@ -86,6 +89,17 @@ public class JavadocMemberEnter extends MemberEnter {
@Override
public void visitVarDef(JCVariableDecl tree) {
+ if (tree.init != null) {
+ boolean isFinal = (tree.mods.flags & FINAL) != 0
+ || (env.enclClass.mods.flags & INTERFACE) != 0;
+ if (!isFinal || containsNonConstantExpression(tree.init)) {
+ // Avoid unnecessary analysis and release resources.
+ // In particular, remove non-constant expressions
+ // which may trigger Attr.attribClass, since
+ // method bodies are also removed, in visitMethodDef.
+ tree.init = null;
+ }
+ }
super.visitVarDef(tree);
if (tree.sym != null &&
tree.sym.kind == Kinds.VAR &&
@@ -101,4 +115,95 @@ public class JavadocMemberEnter extends MemberEnter {
private static boolean isParameter(VarSymbol var) {
return (var.flags() & Flags.PARAMETER) != 0;
}
+
+ /**
+ * Simple analysis of an expression tree to see if it contains tree nodes
+ * for any non-constant expression. This does not include checking references
+ * to other fields which may or may not be constant.
+ */
+ private static boolean containsNonConstantExpression(JCExpression tree) {
+ return new MaybeConstantExpressionScanner().containsNonConstantExpression(tree);
+ }
+
+ /**
+ * See JLS 15.18, Constant Expression
+ */
+ private static class MaybeConstantExpressionScanner extends JCTree.Visitor {
+ boolean maybeConstantExpr = true;
+
+ public boolean containsNonConstantExpression(JCExpression tree) {
+ scan(tree);
+ return !maybeConstantExpr;
+ }
+
+ public void scan(JCTree tree) {
+ // short circuit scan when end result is definitely false
+ if (maybeConstantExpr && tree != null)
+ tree.accept(this);
+ }
+
+ @Override
+ /** default for any non-overridden visit method. */
+ public void visitTree(JCTree tree) {
+ maybeConstantExpr = false;
+ }
+
+ @Override
+ public void visitBinary(JCBinary tree) {
+ switch (tree.getTag()) {
+ case MUL: case DIV: case MOD:
+ case PLUS: case MINUS:
+ case SL: case SR: case USR:
+ case LT: case LE: case GT: case GE:
+ case EQ: case NE:
+ case BITAND: case BITXOR: case BITOR:
+ case AND: case OR:
+ break;
+ default:
+ maybeConstantExpr = false;
+ }
+ }
+
+ @Override
+ public void visitConditional(JCConditional tree) {
+ scan(tree.cond);
+ scan(tree.truepart);
+ scan(tree.falsepart);
+ }
+
+ @Override
+ public void visitIdent(JCIdent tree) { }
+
+ @Override
+ public void visitLiteral(JCLiteral tree) { }
+
+ @Override
+ public void visitParens(JCParens tree) {
+ scan(tree.expr);
+ }
+
+ @Override
+ public void visitSelect(JCTree.JCFieldAccess tree) {
+ scan(tree.selected);
+ }
+
+ @Override
+ public void visitTypeCast(JCTypeCast tree) {
+ scan(tree.clazz);
+ scan(tree.expr);
+ }
+
+ @Override
+ public void visitTypeIdent(JCPrimitiveTypeTree tree) { }
+
+ @Override
+ public void visitUnary(JCUnary tree) {
+ switch (tree.getTag()) {
+ case POS: case NEG: case COMPL: case NOT:
+ break;
+ default:
+ maybeConstantExpr = false;
+ }
+ }
+ }
}
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java
index 7cee9aa26e3..ab1e75e591e 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java
@@ -269,6 +269,8 @@ public class Start extends ToolOption.Helper {
setDocletInvoker(docletClass, fileManager, argv);
compOpts = Options.instance(context);
+ // Make sure no obsolete source/target messages are reported
+ compOpts.put("-Xlint:-options", "-Xlint:-options");
// Parse arguments
for (int i = 0 ; i < argv.length ; i++) {
diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java
index 7e1af207eab..3d09c2d63c1 100644
--- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java
@@ -808,7 +808,10 @@ public class JavacState
// Create a set of filenames with full paths.
for (Source s : now.sources().values()) {
- calculatedSources.add(s.file().getPath());
+ // Don't include link only sources when comparing sources to compile
+ if (!s.isLinkedOnly()) {
+ calculatedSources.add(s.file().getPath());
+ }
}
// Read in the file and create another set of filenames with full paths.
try {
diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java
index 14c65f376ae..f0ed51432ee 100644
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java
@@ -249,16 +249,19 @@ public class Main {
return -1;
}
- // Find all source files allowable for linking.
+ // Create a map of all source files that are available for linking. Both -src and
+ // -sourcepath point to such files. It is possible to specify multiple
+ // -sourcepath options to enable different filtering rules. If the
+ // filters are the same for multiple sourcepaths, they may be concatenated
+ // using :(;). Before sending the list of sourcepaths to javac, they are
+ // all concatenated. The list created here is used by the SmartFileWrapper to
+ // make sure only the correct sources are actually available.
// We might find more modules here as well.
Map sources_to_link_to = new HashMap();
- // Always reuse -src for linking as well! This means that we might
- // get two -sourcepath on the commandline after the rewrite, which is
- // fine. We can have as many as we like. You need to have separate -src/-sourcepath/-classpath
- // if you need different filtering rules for different roots. If you have the same filtering
- // rules for all sourcepath roots, you can concatenate them using :(;) as before.
- rewriteOptions(args, "-src", "-sourcepath");
+ findFiles(args, "-src", Util.set(".java"), sources_to_link_to, modules, current_module, true);
findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true);
+ // Rewrite the -src option to make it through to the javac instances.
+ rewriteOptions(args, "-src", "-sourcepath");
// Find all class files allowable for linking.
// And pickup knowledge of all modules found here.
diff --git a/langtools/src/share/classes/javax/tools/JavaCompiler.java b/langtools/src/share/classes/javax/tools/JavaCompiler.java
index 5588c80d428..09c70bae48e 100644
--- a/langtools/src/share/classes/javax/tools/JavaCompiler.java
+++ b/langtools/src/share/classes/javax/tools/JavaCompiler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -251,8 +251,8 @@ public interface JavaCompiler extends Tool, OptionChecker {
* occurred in a user supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error in
* user code.
- * @throws IllegalArgumentException if any of the given
- * compilation units are of other kind than
+ * @throws IllegalArgumentException if any of the options are invalid,
+ * or if any of the given compilation units are of other kind than
* {@linkplain JavaFileObject.Kind#SOURCE source}
*/
CompilationTask getTask(Writer out,
diff --git a/langtools/test/com/sun/javadoc/testCharset/TestCharset.java b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java
new file mode 100644
index 00000000000..c4055eaf4f8
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testCharset/TestCharset.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7052170
+ * @summary Run a test on -charset to make sure the charset gets generated as a
+ * part of the meta tag.
+ * @author Bhavesh Patel
+ * @library ../lib/
+ * @build JavadocTester TestCharset
+ * @run main TestCharset
+ */
+
+public class TestCharset extends JavadocTester {
+
+ //Test information.
+ private static final String BUG_ID = "7052170";
+
+ //Javadoc arguments.
+ private static final String[] ARGS = new String[] {
+ "-d", BUG_ID, "-charset", "UTF-8", "-sourcepath", SRC_DIR, "pkg"
+ };
+
+ private static final String[][] TEST = {
+ {BUG_ID + FS + "index.html",
+ " "},
+ {BUG_ID + FS + "pkg" + FS + "Foo.html",
+ " "}
+ };
+
+ private static final String[][] NEGATED_TEST = {
+ {BUG_ID + FS + "index.html",
+ " "},
+ {BUG_ID + FS + "pkg" + FS + "Foo.html",
+ " "}
+ };
+
+ /**
+ * The entry point of the test.
+ * @param args the array of command line arguments.
+ */
+ public static void main(String[] args) {
+ TestCharset tester = new TestCharset();
+ run(tester, ARGS, TEST, NEGATED_TEST);
+ tester.printSummary();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugId() {
+ return BUG_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugName() {
+ return getClass().getName();
+ }
+}
diff --git a/langtools/test/com/sun/javadoc/testCharset/pkg/Foo.java b/langtools/test/com/sun/javadoc/testCharset/pkg/Foo.java
new file mode 100644
index 00000000000..62d07e54bf7
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testCharset/pkg/Foo.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+public class Foo {}
diff --git a/langtools/test/com/sun/javadoc/testNavagation/TestNavagation.java b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java
similarity index 93%
rename from langtools/test/com/sun/javadoc/testNavagation/TestNavagation.java
rename to langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java
index 5299365284f..9fefe1b7869 100644
--- a/langtools/test/com/sun/javadoc/testNavagation/TestNavagation.java
+++ b/langtools/test/com/sun/javadoc/testNavigation/TestNavigation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,11 +29,11 @@
* @author jamieh
* @library ../lib/
* @build JavadocTester
- * @build TestNavagation
- * @run main TestNavagation
+ * @build TestNavigation
+ * @run main TestNavigation
*/
-public class TestNavagation extends JavadocTester {
+public class TestNavigation extends JavadocTester {
//Test information.
private static final String BUG_ID = "4131628-4664607";
@@ -71,7 +71,7 @@ public class TestNavagation extends JavadocTester {
* @param args the array of command line arguments.
*/
public static void main(String[] args) {
- TestNavagation tester = new TestNavagation();
+ TestNavigation tester = new TestNavigation();
run(tester, ARGS, TEST, NEGATED_TEST);
tester.printSummary();
}
diff --git a/langtools/test/com/sun/javadoc/testNavagation/pkg/A.java b/langtools/test/com/sun/javadoc/testNavigation/pkg/A.java
similarity index 100%
rename from langtools/test/com/sun/javadoc/testNavagation/pkg/A.java
rename to langtools/test/com/sun/javadoc/testNavigation/pkg/A.java
diff --git a/langtools/test/com/sun/javadoc/testNavagation/pkg/C.java b/langtools/test/com/sun/javadoc/testNavigation/pkg/C.java
similarity index 100%
rename from langtools/test/com/sun/javadoc/testNavagation/pkg/C.java
rename to langtools/test/com/sun/javadoc/testNavigation/pkg/C.java
diff --git a/langtools/test/com/sun/javadoc/testNavagation/pkg/E.java b/langtools/test/com/sun/javadoc/testNavigation/pkg/E.java
similarity index 100%
rename from langtools/test/com/sun/javadoc/testNavagation/pkg/E.java
rename to langtools/test/com/sun/javadoc/testNavigation/pkg/E.java
diff --git a/langtools/test/com/sun/javadoc/testNavagation/pkg/I.java b/langtools/test/com/sun/javadoc/testNavigation/pkg/I.java
similarity index 100%
rename from langtools/test/com/sun/javadoc/testNavagation/pkg/I.java
rename to langtools/test/com/sun/javadoc/testNavigation/pkg/I.java
diff --git a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
index a52d3ccd5ac..7d878d7ecd3 100644
--- a/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
+++ b/langtools/test/com/sun/javadoc/testProfiles/TestProfiles.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8006124 8009684
+ * @bug 8006124 8009684 8016921
* @summary Test javadoc support for profiles.
* @author Bhavesh Patel
* @library ../lib/
@@ -33,7 +33,7 @@
public class TestProfiles extends JavadocTester {
//Test information.
- private static final String BUG_ID = "8006124-8009684";
+ private static final String BUG_ID = "8006124-8009684-8016921";
private static final String PROFILE_BUG_ID = BUG_ID + "-1";
private static final String PACKAGE_BUG_ID = BUG_ID + "-2";
//Javadoc arguments.
@@ -105,6 +105,14 @@ public class TestProfiles extends JavadocTester {
{PROFILE_BUG_ID + FS + "index.html",
" "
+ },
+ //Test for "overview-summary.html" showing the profile list.
+ {PROFILE_BUG_ID + FS + "overview-summary.html",
+ ""
}
};
private static final String[][] PROFILES_NEGATED_TEST = {
@@ -159,6 +167,13 @@ public class TestProfiles extends JavadocTester {
},
{PACKAGE_BUG_ID + FS + "pkg2" + FS + "Class1Pkg2.html",
"compact1, compact2, compact3
"
+ },
+ {PACKAGE_BUG_ID + FS + "overview-summary.html",
+ ""
}
};
diff --git a/langtools/test/com/sun/javadoc/testSeeTag/TestSeeTag.java b/langtools/test/com/sun/javadoc/testSeeTag/TestSeeTag.java
new file mode 100644
index 00000000000..2d2f64e6295
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSeeTag/TestSeeTag.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8017191
+ * @summary Javadoc is confused by at-link to imported classes outside of the set of generated packages
+ * @author jjg
+ * @library ../lib/
+ * @build JavadocTester TestSeeTag
+ * @run main TestSeeTag
+ */
+
+public class TestSeeTag extends JavadocTester {
+
+ //Test information.
+ private static final String BUG_ID = "8017191";
+ private static final String OUTPUT_DIR = BUG_ID;
+
+ //Javadoc arguments.
+ private static final String[] ARGS = new String[] {
+ "-d", OUTPUT_DIR, "-sourcepath", SRC_DIR, "pkg"
+ };
+
+ //Input for string search tests.
+ private static final String[][] TEST = {
+ { OUTPUT_DIR + FS + "pkg" + FS + "Test.html",
+ "List"
+ }
+ };
+ private static final String[][] NEGATED_TEST = {
+ { OUTPUT_DIR + FS + "pkg" + FS + "Test.html",
+ "<code>List</code>"
+ }
+ };
+
+ /**
+ * The entry point of the test.
+ * @param args the array of command line arguments.
+ */
+ public static void main(String[] args) {
+ TestSeeTag tester = new TestSeeTag();
+ run(tester, ARGS, TEST, NEGATED_TEST);
+ tester.printSummary();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugId() {
+ return BUG_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugName() {
+ return getClass().getName();
+ }
+}
diff --git a/langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInLambda.java b/langtools/test/com/sun/javadoc/testSeeTag/pkg/Test.java
similarity index 79%
rename from langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInLambda.java
rename to langtools/test/com/sun/javadoc/testSeeTag/pkg/Test.java
index 53845226a4b..ee997767132 100644
--- a/langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInLambda.java
+++ b/langtools/test/com/sun/javadoc/testSeeTag/pkg/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,12 +21,9 @@
* questions.
*/
-// key: compiler.err.incompatible.thrown.types.in.lambda
+package pkg;
+import java.util.List;
-class IncompatibleThrownTypesInLambda {
- interface SAM {
- void m();
- }
+/** @see List */
+public class Test { }
- SAM s = ()-> { throw new Exception(); };
-}
diff --git a/langtools/test/tools/doclint/html/ListTagsTest.java b/langtools/test/tools/doclint/html/ListTagsTest.java
index 571c8f9e6f6..1d55bfd2cbf 100644
--- a/langtools/test/tools/doclint/html/ListTagsTest.java
+++ b/langtools/test/tools/doclint/html/ListTagsTest.java
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 8006251 8013405
+ * @bug 8006251 8013405 8022173
* @summary test list tags
* @library ..
* @build DocLintTester
@@ -15,6 +15,7 @@ public class ListTagsTest {
* abc
* bad
* bad
+ * bad
*
*/
public void supportedTags() { }
diff --git a/langtools/test/tools/doclint/html/OtherTagsTest.java b/langtools/test/tools/doclint/html/OtherTagsTest.java
index ce6af8246c7..df72dac05fd 100644
--- a/langtools/test/tools/doclint/html/OtherTagsTest.java
+++ b/langtools/test/tools/doclint/html/OtherTagsTest.java
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 8006251
+ * @bug 8006251 8022173
* @summary test other tags
* @library ..
* @build DocLintTester
@@ -14,6 +14,7 @@ public class OtherTagsTest {
*
*
*
+ *
*
*
*
diff --git a/langtools/test/tools/doclint/html/OtherTagsTest.out b/langtools/test/tools/doclint/html/OtherTagsTest.out
index 0ead88e77a5..3fbcb15781c 100644
--- a/langtools/test/tools/doclint/html/OtherTagsTest.out
+++ b/langtools/test/tools/doclint/html/OtherTagsTest.out
@@ -10,19 +10,19 @@ OtherTagsTest.java:15: error: element not allowed in documentation comments:
*
^
-OtherTagsTest.java:17: error: element not allowed in documentation comments:
+OtherTagsTest.java:18: error: element not allowed in documentation comments:
*
^
-OtherTagsTest.java:18: error: element not allowed in documentation comments:
+OtherTagsTest.java:19: error: element not allowed in documentation comments:
*
^
-OtherTagsTest.java:19: error: element not allowed in documentation comments:
+OtherTagsTest.java:20: error: element not allowed in documentation comments:
*
^
-OtherTagsTest.java:20: error: element not allowed in documentation comments:
^
-OtherTagsTest.java:21: error: element not allowed in documentation comments:
+OtherTagsTest.java:22: error: element not allowed in documentation comments:
*
^
9 errors
diff --git a/langtools/test/tools/doclint/html/TableTagsTest.java b/langtools/test/tools/doclint/html/TableTagsTest.java
index 7cea1b35f9d..c5cb2e54290 100644
--- a/langtools/test/tools/doclint/html/TableTagsTest.java
+++ b/langtools/test/tools/doclint/html/TableTagsTest.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8006251
+ * @bug 8006251 8022173
* @summary test table tags
* @library ..
* @build DocLintTester
@@ -39,6 +39,7 @@ public class TableTagsTest {
*
*
*
+ *
*/
public void supportedTags() { }
}
diff --git a/langtools/test/tools/javac/4980495/static/Test.out b/langtools/test/tools/javac/4980495/static/Test.out
index 84e289271e5..3cf0c35ba0e 100644
--- a/langtools/test/tools/javac/4980495/static/Test.out
+++ b/langtools/test/tools/javac/4980495/static/Test.out
@@ -1,2 +1,2 @@
-Test.java:9:1: compiler.err.already.defined.static.single.import: f
+Test.java:15:9: compiler.err.ref.ambiguous: f, kindname.variable, f, p1.A1, kindname.variable, f, p2.A2
1 error
diff --git a/langtools/test/tools/javac/6758789/T6758789b.out b/langtools/test/tools/javac/6758789/T6758789b.out
index 5bdb51c22cd..89a63fdb2b0 100644
--- a/langtools/test/tools/javac/6758789/T6758789b.out
+++ b/langtools/test/tools/javac/6758789/T6758789b.out
@@ -1,5 +1,5 @@
T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo, T6758789a.Foo, kindname.class, T6758789a
-T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo
+T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo
- compiler.err.warnings.and.werror
1 error
2 warnings
diff --git a/langtools/test/tools/javac/7118412/ShadowingTest.java b/langtools/test/tools/javac/7118412/ShadowingTest.java
new file mode 100644
index 00000000000..4bbcfc636c6
--- /dev/null
+++ b/langtools/test/tools/javac/7118412/ShadowingTest.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7118412
+ * @summary Shadowing of type-variables vs. member types
+ */
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public class ShadowingTest {
+
+ // We generate a method "test" that tries to call T.. This controls whether
+ // "test" is static or not.
+ private enum MethodContext {
+ STATIC("static "),
+ INSTANCE("");
+
+ public final String methodcontext;
+
+ MethodContext(final String methodcontext) {
+ this.methodcontext = methodcontext;
+ }
+ }
+
+ // These control whether or not a type parameter, method type
+ // parameter, or inner class get declared (and in the case of
+ // inner classes, whether it's static or not.
+
+ private enum MethodTypeParameterDecl {
+ NO(""),
+ YES(" ");
+
+ public final String tyvar;
+
+ MethodTypeParameterDecl(final String tyvar) {
+ this.tyvar = tyvar;
+ }
+ }
+
+ private enum InsideDef {
+ NONE(""),
+ STATIC("static class T { public void inner() {} }\n"),
+ INSTANCE("class T { public void inner() {} }\n");
+
+ public final String instancedef;
+
+ InsideDef(final String instancedef) {
+ this.instancedef = instancedef;
+ }
+ }
+
+ private enum TypeParameterDecl {
+ NO(""),
+ YES("");
+
+ public final String tyvar;
+
+ TypeParameterDecl(final String tyvar) {
+ this.tyvar = tyvar;
+ }
+ }
+
+ // Represents what method we try to call. This is a way of
+ // checking which T we're seeing.
+ private enum MethodCall {
+ // Method type variables extend Number, so we have intValue
+ METHOD_TYPEVAR("intValue"),
+ // The inner class declaration has a method called "inner"
+ INNER_CLASS("inner"),
+ // The class type variables extend Collection, so we call iterator
+ TYPEVAR("iterator"),
+ // The outer class declaration has a method called "outer"
+ OUTER_CLASS("outer");
+
+ public final String methodcall;
+
+ MethodCall(final String methodcall) {
+ this.methodcall = methodcall;
+ }
+
+ }
+
+ public boolean succeeds(final MethodCall call,
+ final MethodTypeParameterDecl mtyvar,
+ final MethodContext ctx,
+ final InsideDef inside,
+ final TypeParameterDecl tyvar) {
+ switch(call) {
+ // We want to resolve to the method type variable
+ case METHOD_TYPEVAR: switch(mtyvar) {
+ // If the method type variable exists, then T will
+ // resolve to it, and we'll have intValue.
+ case YES: return true;
+ // Otherwise, this cannot succeed.
+ default: return false;
+ }
+ // We want to resolve to the inner class
+ case INNER_CLASS: switch(mtyvar) {
+ // The method type parameter will shadow the inner
+ // class, so there can't be one.
+ case NO: switch(ctx) {
+ // If we're not static, then either one should succeed.
+ case INSTANCE: switch(inside) {
+ case INSTANCE:
+ case STATIC:
+ return true;
+ default: return false;
+ }
+ case STATIC: switch(inside) {
+ // If we are static, and the inner class is
+ // static, then we also succeed, because we
+ // can't see the type variable.
+ case STATIC: return true;
+ case INSTANCE: switch(tyvar) {
+ // If we're calling from a non-static
+ // context, there can't be a class type
+ // variable, because that will shadow the
+ // static inner class definition.
+ case NO: return true;
+ default: return false;
+ }
+ // If the inner class isn't declared, we can't
+ // see it.
+ default: return false;
+ }
+ // Can't get here.
+ default: return false;
+ }
+ default: return false;
+ }
+ // We want to resolve to the class type parameter
+ case TYPEVAR: switch(mtyvar) {
+ // We can't have a method type parameter, as that would
+ // shadow the class type parameter
+ case NO: switch(ctx) {
+ case INSTANCE: switch(inside) {
+ // We have to be in an instance context. If
+ // we're static, we can't see the type
+ // variable.
+ case NONE: switch(tyvar) {
+ // Obviously, the type parameter has to be declared.
+ case YES: return true;
+ default: return false;
+ }
+ default: return false;
+ }
+ default: return false;
+ }
+ default: return false;
+ }
+ // We want to resolve to the outer class
+ case OUTER_CLASS: switch(mtyvar) {
+ case NO: switch(inside) {
+ case NONE: switch(tyvar) {
+ // Basically, nothing else can be declared, or
+ // else we can't see it. Even if our context
+ // is static, the compiler will complain if
+ // non-static T's exist, because they will
+ // shadow the outer class.
+ case NO: return true;
+ default: return false;
+ }
+ default: return false;
+ }
+ default: return false;
+ }
+ }
+ return false;
+ }
+
+ private static final File classesdir = new File("7118412");
+
+ private int errors = 0;
+
+ private int dirnum = 0;
+
+ private void doTest(final MethodTypeParameterDecl mtyvar,
+ final TypeParameterDecl tyvar,
+ final InsideDef insidedef, final MethodContext ctx,
+ final MethodCall call)
+ throws IOException {
+ final String content = "import java.util.Collection;\n" +
+ "class Test" + tyvar.tyvar + " {\n" +
+ " " + insidedef.instancedef +
+ " " + ctx.methodcontext + mtyvar.tyvar + "void test(T t) { t." +
+ call.methodcall + "(); }\n" +
+ "}\n" +
+ "class T { void outer() {} }\n";
+ final File dir = new File(classesdir, "" + dirnum);
+ final File Test_java = writeFile(dir, "Test.java", content);
+ dirnum++;
+ if(succeeds(call, mtyvar, ctx, insidedef, tyvar)) {
+ if(!assert_compile_succeed(Test_java))
+ System.err.println("Failed file:\n" + content);
+ }
+ else {
+ if(!assert_compile_fail(Test_java))
+ System.err.println("Failed file:\n" + content);
+ }
+ }
+
+ private void run() throws Exception {
+ classesdir.mkdir();
+ for(MethodTypeParameterDecl mtyvar : MethodTypeParameterDecl.values())
+ for(TypeParameterDecl tyvar : TypeParameterDecl.values())
+ for(InsideDef insidedef : InsideDef.values())
+ for(MethodContext ctx : MethodContext.values())
+ for(MethodCall methodcall : MethodCall.values())
+ doTest(mtyvar, tyvar, insidedef, ctx, methodcall);
+ if (errors != 0)
+ throw new Exception("ShadowingTest test failed with " +
+ errors + " errors.");
+ }
+
+ private boolean assert_compile_fail(final File file) {
+ final String filename = file.getPath();
+ final String[] args = { filename };
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ final int rc = com.sun.tools.javac.Main.compile(args, pw);
+ pw.close();
+ if (rc == 0) {
+ System.err.println("Compilation of " + file.getName() +
+ " didn't fail as expected.");
+ errors++;
+ return false;
+ } else return true;
+ }
+
+ private boolean assert_compile_succeed(final File file) {
+ final String filename = file.getPath();
+ final String[] args = { filename };
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ final int rc = com.sun.tools.javac.Main.compile(args, pw);
+ pw.close();
+ if (rc != 0) {
+ System.err.println("Compilation of " + file.getName() +
+ " didn't succeed as expected. Output:");
+ System.err.println(sw.toString());
+ errors++;
+ return false;
+ } else return true;
+ }
+
+ private File writeFile(final File dir,
+ final String path,
+ final String body) throws IOException {
+ final File f = new File(dir, path);
+ f.getParentFile().mkdirs();
+ final FileWriter out = new FileWriter(f);
+ out.write(body);
+ out.close();
+ return f;
+ }
+
+ public static void main(String... args) throws Exception {
+ new ShadowingTest().run();
+ }
+
+}
diff --git a/langtools/test/tools/javac/7182350/T7182350.java b/langtools/test/tools/javac/7182350/T7182350.java
new file mode 100644
index 00000000000..7470794f4e5
--- /dev/null
+++ b/langtools/test/tools/javac/7182350/T7182350.java
@@ -0,0 +1,14 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 7182350
+ * @summary verify correct output of -Xlint:unchecked on methods with unchecked conversations in parameters
+ * @compile/ref=T7182350.out -XDrawDiagnostics -Xlint:unchecked T7182350.java
+ */
+
+import java.util.*;
+
+class T7182350 {
+ public static void quicksort(Vector vector, Comparator compare) {
+ Collections.sort(vector,compare);
+ }
+}
diff --git a/langtools/test/tools/javac/7182350/T7182350.out b/langtools/test/tools/javac/7182350/T7182350.out
new file mode 100644
index 00000000000..e88378348c2
--- /dev/null
+++ b/langtools/test/tools/javac/7182350/T7182350.out
@@ -0,0 +1,4 @@
+T7182350.java:12:25: compiler.warn.unchecked.meth.invocation.applied: kindname.method, sort, java.util.List,java.util.Comparator super T>, java.util.Vector,java.util.Comparator, kindname.class, java.util.Collections
+T7182350.java:12:26: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.Vector, java.util.List
+T7182350.java:12:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.Comparator, java.util.Comparator super T>
+3 warnings
diff --git a/langtools/test/tools/javac/8015701/AnonymousParameters.java b/langtools/test/tools/javac/8015701/AnonymousParameters.java
deleted file mode 100644
index 746b2b9696a..00000000000
--- a/langtools/test/tools/javac/8015701/AnonymousParameters.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8015701
- * @summary javac should generate method parameters correctly.
- * @compile -parameters AnonymousParameters.java
- * @run main AnonymousParameters
- */
-import java.lang.Class;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Parameter;
-import java.util.concurrent.Callable;
-
-public class AnonymousParameters {
-
- String[] names = {
- "this$0",
- "val$message"
- };
-
- public static void main(String... args) throws Exception {
- new AnonymousParameters().run();
- }
-
- void run() throws Exception {
- Class> cls = new ParameterNames().makeInner("hello").getClass();
- Constructor> ctor = cls.getDeclaredConstructors()[0];
- Parameter[] params = ctor.getParameters();
-
- if(params.length == 2) {
- for(int i = 0; i < 2; i++) {
- System.err.println("Testing parameter " + params[i].getName());
- if(!params[i].getName().equals(names[i]))
- error("Expected parameter name " + names[i] +
- " got " + params[i].getName());
- }
- } else
- error("Expected 2 parameters");
-
- if(0 != errors)
- throw new Exception("MethodParameters test failed with " +
- errors + " errors");
- }
-
- void error(String msg) {
- System.err.println("Error: " + msg);
- errors++;
- }
-
- int errors;
-}
-
-class ParameterNames {
-
- public Callable makeInner(final String message) {
- return new Callable() {
- public String call() throws Exception {
- return message;
- }
- };
- }
-
- public static void main(String... args) throws Exception {
- ParameterNames test = new ParameterNames();
- System.out.println(test.makeInner("Hello").call());
- }
-}
diff --git a/langtools/test/tools/javac/MethodParameters/CaptureTest.java b/langtools/test/tools/javac/MethodParameters/CaptureTest.java
new file mode 100644
index 00000000000..ed865faecd4
--- /dev/null
+++ b/langtools/test/tools/javac/MethodParameters/CaptureTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8015701
+ * @summary Test method parameter attribute generation with captured locals.
+ * @compile -parameters CaptureTest.java
+ * @run main CaptureTest
+ */
+import java.lang.Class;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.ArrayList;
+
+public class CaptureTest {
+
+ private static final int SYNTHETIC = 0x1000;
+ private static final int MANDATED = 0x8000;
+
+ public static void main(String... args) throws Exception {
+ new CaptureTest().run();
+ }
+
+
+ private void run() throws Exception {
+ final Encloser pn = new Encloser();
+
+ /* Cases covered here:
+ *
+ * - Local class
+ * - Inner class
+ * - Anonymous class
+ * - Anonymous class extending a local
+ * - Anonymous class extending an inner
+ */
+ pn.makeLocal("hello").check();
+ pn.makeInner("hello").check();
+ pn.makeAnon("hello").check();
+ pn.makeAnonExtendsLocal("hello").check();
+ pn.makeAnonExtendsInner("hello").check();
+
+ if (0 != errors)
+ throw new Exception("MethodParameters test failed with " +
+ errors + " errors");
+ }
+
+ private void error(final String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+
+ abstract class Tester {
+
+ public Tester(final int param) {}
+
+ protected abstract String[] names();
+ protected abstract int[] modifiers();
+ protected abstract Class[] types();
+
+ public void check() {
+ final Class> cls = this.getClass();
+ final Constructor> ctor = cls.getDeclaredConstructors()[0];
+ final Parameter[] params = ctor.getParameters();
+ final String[] names = names();
+ final int[] modifiers = modifiers();
+ final Class[] types = types();
+
+ System.err.println("Testing class " + cls);
+
+ if (params.length == names.length) {
+ for (int i = 0; i < names.length; i++) {
+ System.err.println("Testing parameter " + params[i].getName());
+ if (!params[i].getName().equals(names[i]))
+ error("Expected parameter name " + names[i] +
+ " got " + params[i].getName());
+ if (params[i].getModifiers() != modifiers[i])
+ error("Expected parameter modifiers " +
+ modifiers[i] + " got " +
+ params[i].getModifiers());
+ if (!params[i].getType().equals(types[i]))
+ error("Expected parameter type " + types[i] +
+ " got " + params[i].getType());
+ }
+ } else
+ error("Expected " + names.length + " parameters");
+
+ }
+
+ }
+
+ class Encloser {
+ private class InnerTester extends Tester {
+ public InnerTester(final int innerparam) {
+ super(innerparam);
+ }
+
+ protected String[] names() {
+ return new String[] {
+ "this$1",
+ "innerparam"
+ };
+ }
+
+ protected int[] modifiers() {
+ return new int[] {
+ Modifier.FINAL | SYNTHETIC,
+ Modifier.FINAL
+ };
+ }
+
+ protected Class[] types() {
+ return new Class[] {
+ Encloser.class,
+ int.class
+ };
+ }
+ }
+
+ public Tester makeInner(final String message) {
+ return new InnerTester(2);
+ }
+
+ public Tester makeLocal(final String message) {
+ class LocalTester extends Tester {
+ public LocalTester(final int localparam) {
+ super(localparam);
+ }
+
+ protected String[] names() {
+ return new String[] {
+ "this$1",
+ "localparam",
+ "val$message"
+ };
+ }
+
+ protected int[] modifiers() {
+ return new int[] {
+ Modifier.FINAL | MANDATED,
+ Modifier.FINAL,
+ Modifier.FINAL | SYNTHETIC
+ };
+ }
+
+ protected Class[] types() {
+ return new Class[] {
+ Encloser.class,
+ int.class,
+ String.class
+ };
+ }
+
+ public String message() {
+ return message;
+ }
+ }
+
+ return new LocalTester(2);
+ }
+
+ public Tester makeAnonExtendsLocal(final String message) {
+ abstract class LocalTester extends Tester {
+ public LocalTester(final int localparam) {
+ super(localparam);
+ }
+
+ protected String[] names() {
+ return new String[] {
+ "this$1",
+ "localparam",
+ "val$message"
+ };
+ }
+
+ protected int[] modifiers() {
+ return new int[] {
+ Modifier.FINAL | MANDATED,
+ Modifier.FINAL,
+ Modifier.FINAL | SYNTHETIC
+ };
+ }
+
+ protected Class[] types() {
+ return new Class[] {
+ Encloser.class,
+ int.class,
+ String.class
+ };
+ }
+
+ }
+
+ return new LocalTester(2) {
+ public String message() {
+ return message;
+ }
+ };
+ }
+
+ public Tester makeAnonExtendsInner(final String message) {
+ return new InnerTester(2) {
+ protected String[] names() {
+ return new String[] {
+ "this$1",
+ "innerparam",
+ "val$message"
+ };
+ }
+
+ protected int[] modifiers() {
+ return new int[] {
+ Modifier.FINAL | MANDATED,
+ Modifier.FINAL,
+ Modifier.FINAL | SYNTHETIC
+ };
+ }
+
+ protected Class[] types() {
+ return new Class[] {
+ Encloser.class,
+ int.class,
+ String.class
+ };
+ }
+
+ public String message() {
+ return message;
+ }
+ };
+ }
+
+ public Tester makeAnon(final String message) {
+ return new Tester(2) {
+ protected String[] names() {
+ return new String[] {
+ "this$1",
+ "param",
+ "val$message"
+ };
+ }
+
+ protected int[] modifiers() {
+ return new int[] {
+ Modifier.FINAL | MANDATED,
+ Modifier.FINAL,
+ Modifier.FINAL | SYNTHETIC
+ };
+ }
+
+ protected Class[] types() {
+ return new Class[] {
+ Encloser.class,
+ int.class,
+ String.class
+ };
+ }
+
+ public String message() {
+ return message;
+ }
+ };
+ }
+ }
+}
diff --git a/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java b/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java
new file mode 100644
index 00000000000..186774a63be
--- /dev/null
+++ b/langtools/test/tools/javac/T8009640/CheckRejectProfileBCPOptionsIfUsedTogetherTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8009640
+ * @summary -profile does not work when -bootclasspath specified
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main CheckRejectProfileBCPOptionsIfUsedTogetherTest
+ */
+
+import com.sun.tools.javac.util.Assert;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CheckRejectProfileBCPOptionsIfUsedTogetherTest {
+
+ private static final String TestSrc =
+ "public class Test {\n" +
+ " javax.swing.JButton b;\n" +
+ "}";
+
+ public static void main(String args[]) throws Exception {
+ List errOutput = new ArrayList<>();
+ String testJDK = ToolBox.jdkUnderTest;
+ ToolBox.createJavaFileFromSource(TestSrc);
+
+ ToolBox.AnyToolArgs javacParams =
+ new ToolBox.AnyToolArgs(ToolBox.Expect.FAIL)
+ .appendArgs(ToolBox.javacBinary)
+ .appendArgs(ToolBox.testToolVMOpts)
+ .appendArgs("-profile", "compact1", "-bootclasspath",
+ testJDK + "/jre/lib/rt.jar", "Test.java")
+ .setErrOutput(errOutput);
+
+ ToolBox.executeCommand(javacParams);
+
+ Assert.check(errOutput.get(0).startsWith(
+ "javac: profile and bootclasspath options cannot be used together"),
+ "Incorrect javac error output");
+ }
+
+}
diff --git a/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java b/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java
new file mode 100644
index 00000000000..78d97cad28d
--- /dev/null
+++ b/langtools/test/tools/javac/T8013394/CompileErrorWithIteratorTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8013394
+ * @summary compile of iterator use fails with error "defined in an inaccessible class or interface"
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main CompileErrorWithIteratorTest
+ */
+
+public class CompileErrorWithIteratorTest {
+
+ private static final String TestCollectionSrc =
+ "package pkg;\n" +
+
+ "import java.util.Iterator;\n" +
+ "import java.util.NoSuchElementException;\n" +
+
+ "public class TestCollection implements Iterable {\n" +
+ " public testCollectionIterator iterator() {\n" +
+ " return new testCollectionIterator();\n" +
+ " }\n" +
+ " class testCollectionIterator implements Iterator {\n" +
+ " public boolean hasNext() { return true; }\n" +
+ " public E next() throws NoSuchElementException\n" +
+ " {\n" +
+ " return null;\n" +
+ " }\n" +
+ " public void remove() {}\n" +
+ " }\n" +
+ "}";
+
+ private static final String TestSrc =
+ "import pkg.TestCollection;\n" +
+ "\n" +
+ "public class Test {\n" +
+ "\n" +
+ " public static void main(String[] args) {\n" +
+ " TestCollection tc1 = new TestCollection();\n" +
+ " for (String s : tc1) {\n" +
+ " System.out.println(s);\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+
+ public static void main(String args[]) throws Exception {
+ new CompileErrorWithIteratorTest().run();
+ }
+
+ void run() throws Exception {
+ compile();
+ }
+
+ void compile() throws Exception {
+ ToolBox.JavaToolArgs javacParams =
+ new ToolBox.JavaToolArgs()
+ .setSources(TestCollectionSrc, TestSrc);
+ ToolBox.javac(javacParams);
+ }
+
+}
diff --git a/langtools/test/tools/javac/T8019486/WrongLVTForLambdaTest.java b/langtools/test/tools/javac/T8019486/WrongLVTForLambdaTest.java
new file mode 100644
index 00000000000..9d7d32abb3b
--- /dev/null
+++ b/langtools/test/tools/javac/T8019486/WrongLVTForLambdaTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8019486
+ * @summary javac, generates erroneous LVT for a test case with lambda code
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main WrongLVTForLambdaTest
+ */
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.util.Assert;
+
+public class WrongLVTForLambdaTest {
+
+ static final String testSource =
+ /* 01 */ "import java.util.List;\n" +
+ /* 02 */ "import java.util.Arrays;\n" +
+ /* 03 */ "import java.util.stream.Collectors;\n" +
+ /* 04 */ "\n" +
+ /* 05 */ "public class Foo {\n" +
+ /* 06 */ " void bar(int value) {\n" +
+ /* 07 */ " final List numbers = Arrays.asList(1, 2, 3);\n" +
+ /* 08 */ " final List numbersPlusOne = \n" +
+ /* 09 */ " numbers.stream().map(number -> number / 1).collect(Collectors.toList());\n" +
+ /* 10 */ " }\n" +
+ /* 11 */ "}";
+
+ static final int[][] expectedLNT = {
+ // {line-number, start-pc},
+ {9, 0}, //number -> number / 1
+ };
+
+ static final String methodToLookFor = "lambda$0";
+
+ public static void main(String[] args) throws Exception {
+ new WrongLVTForLambdaTest().run();
+ }
+
+ void run() throws Exception {
+ compileTestClass();
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Foo.class").toUri()), methodToLookFor);
+ }
+
+ void compileTestClass() throws Exception {
+ ToolBox.JavaToolArgs javacSuccessArgs =
+ new ToolBox.JavaToolArgs().setSources(testSource);
+ ToolBox.javac(javacSuccessArgs);
+ }
+
+ void checkClassFile(final File cfile, String methodToFind) throws Exception {
+ ClassFile classFile = ClassFile.read(cfile);
+ boolean methodFound = false;
+ for (Method method : classFile.methods) {
+ if (method.getName(classFile.constant_pool).equals(methodToFind)) {
+ methodFound = true;
+ Code_attribute code = (Code_attribute) method.attributes.get("Code");
+ LineNumberTable_attribute lnt =
+ (LineNumberTable_attribute) code.attributes.get("LineNumberTable");
+ Assert.check(lnt.line_number_table_length == expectedLNT.length,
+ "The LineNumberTable found has a length different to the expected one");
+ int i = 0;
+ for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) {
+ Assert.check(entry.line_number == expectedLNT[i][0] &&
+ entry.start_pc == expectedLNT[i][1],
+ "LNT entry at pos " + i + " differ from expected." +
+ "Found " + entry.line_number + ":" + entry.start_pc +
+ ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
+ i++;
+ }
+ }
+ }
+ Assert.check(methodFound, "The seek method was not found");
+ }
+
+ void error(String msg) {
+ throw new AssertionError(msg);
+ }
+
+}
diff --git a/langtools/test/tools/javac/T8022053/UnverifiableInitForNestedLocalClassTest.java b/langtools/test/tools/javac/T8022053/UnverifiableInitForNestedLocalClassTest.java
new file mode 100644
index 00000000000..bdf40dbcb1f
--- /dev/null
+++ b/langtools/test/tools/javac/T8022053/UnverifiableInitForNestedLocalClassTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8022053
+ * @summary 8022053: javac generates unverifiable initializer for nested subclass of local class
+ * @run main UnverifiableInitForNestedLocalClassTest
+ */
+
+public class UnverifiableInitForNestedLocalClassTest {
+
+ public static void main(final String[] args) {
+ test("test");
+ }
+
+ static void test(final String arg) {
+ final String inlined = " inlined ";
+ class LocalClass {
+ String m() {
+ return "LocalClass " + arg + inlined;
+ }
+
+ class SubClass extends LocalClass {
+ @Override
+ String m() {
+ return "SubClass " + arg + inlined;
+ }
+ }
+
+ class SubSubClass extends SubClass {
+ @Override
+ String m() {
+ return "SubSubClass " + arg + inlined;
+ }
+ }
+
+ class AnotherLocal {
+ class AnotherSub extends LocalClass {
+ @Override
+ String m() {
+ return "AnotherSub " + arg + inlined;
+ }
+ }
+ }
+ }
+ System.out.println(new LocalClass().m());
+ System.out.println(new LocalClass().new SubClass().m());
+ System.out.println(new LocalClass().new SubSubClass().m());
+ System.out.println(new LocalClass().new AnotherLocal().new AnotherSub().m());
+ }
+
+}
diff --git a/langtools/test/tools/javac/T8022316/CompilerErrorGenericThrowPlusMethodRefTest.java b/langtools/test/tools/javac/T8022316/CompilerErrorGenericThrowPlusMethodRefTest.java
new file mode 100644
index 00000000000..f7d0391649e
--- /dev/null
+++ b/langtools/test/tools/javac/T8022316/CompilerErrorGenericThrowPlusMethodRefTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8022316
+ * @summary Generic throws, overriding and method reference
+ * @compile/fail/ref=CompilerErrorGenericThrowPlusMethodRefTest.out -XDrawDiagnostics CompilerErrorGenericThrowPlusMethodRefTest.java
+ */
+
+@SuppressWarnings("unchecked")
+public class CompilerErrorGenericThrowPlusMethodRefTest {
+ interface SAM11 {
+ public void foo() throws E ;
+ }
+
+ interface SAM12 extends SAM11{
+ @Override
+ public void foo() throws Throwable;
+ }
+
+ public void boo() throws RuntimeException {}
+
+ static void test1() {
+ try {
+ SAM12 s2 = new CompilerErrorGenericThrowPlusMethodRefTest()::boo;
+ s2.foo();
+ } catch(Throwable ex) {}
+ }
+
+ static void test2() {
+ SAM11 s1 = null;
+ s1.foo();
+ s1.foo();
+ }
+
+ interface SAM21 {
+ void m(E arg) throws E;
+ }
+
+ interface SAM22 {
+ void m(F arg) throws F;
+ }
+
+ interface SAM23 extends SAM21, SAM22 {}
+
+ public void bar(E e) throws E {}
+
+ static void test3(E e) {
+ try {
+ SAM23 s2 = new CompilerErrorGenericThrowPlusMethodRefTest()::bar;
+ s2.m(e);
+ } catch(Exception ex) {}
+ }
+
+}
diff --git a/langtools/test/tools/javac/T8022316/CompilerErrorGenericThrowPlusMethodRefTest.out b/langtools/test/tools/javac/T8022316/CompilerErrorGenericThrowPlusMethodRefTest.out
new file mode 100644
index 00000000000..58015ae026e
--- /dev/null
+++ b/langtools/test/tools/javac/T8022316/CompilerErrorGenericThrowPlusMethodRefTest.out
@@ -0,0 +1,2 @@
+CompilerErrorGenericThrowPlusMethodRefTest.java:55:26: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+1 error
diff --git a/langtools/test/tools/javac/T8023112/SkipLazyConstantCreationForMethodRefTest.java b/langtools/test/tools/javac/T8023112/SkipLazyConstantCreationForMethodRefTest.java
new file mode 100644
index 00000000000..e0c530c5c47
--- /dev/null
+++ b/langtools/test/tools/javac/T8023112/SkipLazyConstantCreationForMethodRefTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8023112
+ * @summary Mixing up the method type argument with the class type for method
+ * reference ClassType::new
+ * @compile SkipLazyConstantCreationForMethodRefTest.java
+ */
+
+public class SkipLazyConstantCreationForMethodRefTest {
+ SkipLazyConstantCreationForMethodRefTest(int a, boolean b) {}
+ SkipLazyConstantCreationForMethodRefTest() {}
+}
+
+class SubClass extends SkipLazyConstantCreationForMethodRefTest {
+ SubClass(int a, boolean b) {}
+}
+
+interface SAM {
+ SubClass m(int a, boolean b);
+}
+
+interface Tester1 {
+ SAM s11 = SubClass::new;
+ SAM s12 = (SubClass::new);
+ SAM s13 = (SAM)SubClass::new;
+ SAM s14 = true ? s11 : s12;
+ SAM s15 = true ? s11 : (SAM)SubClass::new;
+ SAM s16 = true ? (SAM)SubClass::new : s12;
+}
+
+interface Tester2 {
+ SAM s21 = Tester1.s11;
+}
diff --git a/langtools/test/tools/javac/TestPkgInfo.java b/langtools/test/tools/javac/TestPkgInfo.java
index 15adff341d9..7c12ecedc6c 100644
--- a/langtools/test/tools/javac/TestPkgInfo.java
+++ b/langtools/test/tools/javac/TestPkgInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,10 @@
/*
* @test
- * @bug 6960424
- * @summary new option -Xpkginfo for better control of when package-info.class is generated
+ * @bug 6960424 8022161
+ * @summary new option -Xpkginfo for better control of when package-info.class
+ * is generated, also ensures no failures if package-info.java is
+ * not available.
*/
import java.io.*;
@@ -43,8 +45,11 @@ public class TestPkgInfo {
public static void main(String... args) throws Exception {
new TestPkgInfo().run(args);
}
-
public void run(String... args) throws Exception {
+ testPositive();
+ testNoExceptions();
+ }
+ public void testPositive(String... args) throws Exception {
boolean[] booleanValues = { false, true };
for (OptKind ok: OptKind.values()) {
for (boolean sr: booleanValues) {
@@ -65,6 +70,32 @@ public class TestPkgInfo {
throw new Exception(errors + " errors occurred");
}
+ /** this should throw no exceptions **/
+ void testNoExceptions() throws Exception {
+ count++;
+ System.err.println("Test " + count + ": ALWAYS nofile");
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("package test; class Hello{}");
+
+ // test specific tmp directory
+ File tmpDir = new File("tmp.test" + count);
+ File classesDir = new File(tmpDir, "classes");
+ classesDir.mkdirs();
+ File javafile = new File(new File(tmpDir, "src"), "Hello.java");
+ writeFile(javafile, sb.toString());
+ // build up list of options and files to be compiled
+ List opts = new ArrayList<>();
+ List files = new ArrayList<>();
+
+ opts.add("-d");
+ opts.add(classesDir.getPath());
+ opts.add("-Xpkginfo:always");
+ files.add(javafile);
+
+ compile(opts, files);
+ }
+
void test(OptKind ok, boolean sr, boolean cr, boolean rr) throws Exception {
count++;
System.err.println("Test " + count + ": ok:" + ok + " sr:" + sr + " cr:" + cr + " rr:" + rr);
@@ -91,15 +122,15 @@ public class TestPkgInfo {
writeFile(pkginfo_java, sb.toString());
// build up list of options and files to be compiled
- List opts = new ArrayList();
- List files = new ArrayList();
+ List opts = new ArrayList<>();
+ List files = new ArrayList<>();
opts.add("-d");
opts.add(classesDir.getPath());
if (ok.opt != null)
opts.add(ok.opt);
//opts.add("-verbose");
- files.add(pkginfo_java);
+ files.add(pkginfo_java);
compile(opts, files);
@@ -134,7 +165,7 @@ public class TestPkgInfo {
/** Compile files with options provided. */
void compile(List opts, List files) throws Exception {
System.err.println("javac: " + opts + " " + files);
- List args = new ArrayList();
+ List args = new ArrayList<>();
args.addAll(opts);
for (File f: files)
args.add(f.getPath());
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java
index b660855a5b0..644b68471a2 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java
@@ -35,13 +35,16 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
// Test count helps identify test case in event of failure.
int testcount = 0;
- // Base test case template descriptions
+ // Base test case template descriptions;true==annotations in code attribute.
enum srce {
src1("(repeating) type annotations on on field in method body",true),
src2("(repeating) type annotations on type parameters, bounds and type arguments", true),
src3("(repeating) type annotations on type parameters of class, method return value in method", true),
src4("(repeating) type annotations on field in anonymous class", false),
- src5("(repeating) type annotations on field in anonymous class", false);
+ src5("(repeating) type annotations on field in anonymous class", false),
+ src6("(repeating) type annotations on void method declaration", false),
+ src7("(repeating) type annotations in use of instanceof", true),
+ src8("(repeating) type annotations in use of instanceof in method", true);
String description;
Boolean local;
@@ -84,6 +87,12 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
test( 0, 8, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src1);
test( 2, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src5);
test( 0, 2, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src5);
+ test( 0, 0, 2, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src6);
+ test( 0, 0, 0, 2, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src6);
+ test( 2, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src7);
+ test( 0, 2, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src7);
+ test( 4, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src8);
+ test( 0, 4, 0, 0, As, BDs, ABMix, "RUNTIME", et, ++testrun, srce.src8);
break;
case "FIELD":
test( 8, 0, 0, 0, As, BDs, ABMix, "CLASS", et, ++testrun, srce.src1);
@@ -121,18 +130,6 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " +
et2 + ", src=" + source + "\n " + source.description;
- if(
-// 8005681 - src1,2,3 - skip cases with repeated annotations on new, array, cast.
- (( source.equals(srce.src1) || source.equals(srce.src2) ||
- source.equals(srce.src3)) && (ABmix || (Arepeats && BDrepeats)))
- // 8008928 - src4,5 - this change cause crash with t-a on anon class)
- || (source.equals(srce.src4) || source.equals(srce.src5))
- ) {
- System.out.println(testDef +
- "\n 8005681-skip repeated annotations on new,array,cast");
- return;
- }
-
println(testDef);
// Create test source and File.
String sourceString = sourceString(tname, rtn, et2, Arepeats,
@@ -178,9 +175,7 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
println("Pass");
}
- //
// Source for test cases
- //
String sourceString(String testname, String retentn, String annot2,
Boolean Arepeats, Boolean BDrepeats, Boolean ABmix,
srce src) {
@@ -359,6 +354,63 @@ public class CombinationsTargetTest2 extends ClassfileTestHelper {
hasInnerClass=true;
innerClassname="$1";
break;
+ case src6: // (repeating)annotations on void method declaration
+ /*
+ * class Test95{
+ * @A @A @B @B public void test() { };
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " _As_ _Bs_ public void test() { }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ hasInnerClass=false;
+ break;
+ case src7: // (repeating) type annotations in use of instanceof
+ /*
+ * class Test10{
+ * String data = "test";
+ * boolean dataIsString = ( data instanceof @A @B @A @B String);
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " String data = \"test\";\n" +
+ " boolean dataIsString = ( data instanceof _As_ _Bs_ String);\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ hasInnerClass=false;
+ break;
+ case src8: // (repeating) type annotations in use of instanceof
+ /*
+ * class Test20{
+ * String data = "test";
+ * Boolean isString() {
+ * if( data instanceof @A @B @A @B String )
+ * return true;
+ * else
+ * return( data instanceof @A @B @A @B String );
+ * }
+ * }
+ */
+ source = new String( source +
+ "// " + src.description + "\n" +
+ "class "+ testname + "{\n" +
+ " String data = \"test\";\n" +
+ " Boolean isString() { \n" +
+ " if( data instanceof _As_ _Bs_ String )\n" +
+ " return true;\n" +
+ " else\n" +
+ " return( data instanceof _As_ _Bs_ String );\n" +
+ " }\n" +
+ "}\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) +
+ "\n\n";
+ hasInnerClass=false;
+ break;
+
}
return imports + source;
}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java
new file mode 100644
index 00000000000..26bd4d288b3
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/DummyProcessor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+
+import java.util.Set;
+
+/* A simple annotation processor. */
+@SupportedAnnotationTypes("*")
+public class DummyProcessor extends AbstractProcessor {
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public final boolean process(Set extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+ return false;
+ }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8020715.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8020715.java
new file mode 100644
index 00000000000..89670f3edf4
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/T8020715.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Regression: compiling program with lambda crashed compiler
+ * @bug 8020715
+ * @compile T8020715.java
+ */
+class T8020715 {
+ // This crashed.
+ private static void makeTask1() {
+ class LocalClass {
+ private Runnable r = () -> {};
+ }
+ }
+
+ // This crashed, too.
+ private void makeTask2() {
+ class LocalClass {
+ private Runnable r = () -> {};
+ }
+ }
+
+ // This is fine.
+ private class InnerClass {
+ private Runnable r = () -> {};
+ }
+}
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java
new file mode 100644
index 00000000000..5485e53af19
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeVariableCycleTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8023768
+ * @summary Type annotations on a type variable, where the bound of
+ * the type variable is an annotated type variable,
+ * need to be processed correctly.
+ * @author Werner Dietl
+ * @compile TypeVariableCycleTest.java
+ */
+
+import java.lang.annotation.*;
+
+class TypeVariableCycleTest {
+ MTV cast(CTV p) {
+ return (@TA MTV) p;
+ }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA {}
+
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java
index 38e46159cea..a8d1311eb47 100644
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java
@@ -85,4 +85,24 @@ public class Constructors {
" } } }";
}
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
+ typeIndex = 0, offset = 4),
+ @TADescription(annotation = "TB", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
+ typeIndex = 0, offset = 0)
+ })
+ public String generic1() {
+ return "class Test { Test(int i) { new <@TA T>Test(); }" +
+ " Test() { <@TB String>this(0); } }";
+ }
+
+ @TADescriptions({
+ @TADescription(annotation = "TA", type = CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
+ typeIndex = 0, offset = 0)
+ })
+ public String generic2() {
+ return "class Super { Super(int i) { } } " +
+ "class Test extends Super { Test() { <@TA String>super(0); } }";
+ }
+
}
diff --git a/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java b/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java
deleted file mode 100644
index 566780d16a3..00000000000
--- a/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @ignore 8007517: DefaultMethodRegressionTests.java fail in TL
- * @bug 8003639
- * @summary convert lambda testng tests to jtreg and add them
- * @run testng DefaultMethodRegressionTests
- */
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.*;
-
-/**
- * This set of classes/interfaces (K/I/C) is specially designed to expose a
- * bug in the JVM where it did not find some overloaded methods in some
- * specific situations. (fixed by hotspot changeset ffb9316fd9ed)
- */
-interface K {
- int bbb(Long l);
-}
-
-interface I extends K {
- default void aaa() {}
- default void aab() {}
- default void aac() {}
-
- default int bbb(Integer i) { return 22; }
- default int bbb(Float f) { return 33; }
- default int bbb(Long l) { return 44; }
- default int bbb(Double d) { return 55; }
- default int bbb(String s) { return 66; }
-
- default void caa() {}
- default void cab() {}
- default void cac() {}
-}
-
-class C implements I {}
-
-public class DefaultMethodRegressionTests {
-
- @Test(groups = "vm")
- public void testLostOverloadedMethod() {
- C c = new C();
- assertEquals(c.bbb(new Integer(1)), 22);
- assertEquals(c.bbb(new Float(1.1)), 33);
- assertEquals(c.bbb(new Long(1L)), 44);
- assertEquals(c.bbb(new Double(0.01)), 55);
- assertEquals(c.bbb(new String("")), 66);
- }
-
- // Test to ensure that the inference verifier accepts older classfiles
- // with classes that implement interfaces with defaults.
- @Test(groups = "vm")
- public void testInferenceVerifier() {
- // interface I { int m() default { return 99; } }
- byte I_bytes[] = {
- (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x33,
- 0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
- 0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
- 0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
- 0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
- 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
- 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
- 0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
- 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
- 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00
- };
- // public class C implements I {} /* -target 1.5 */
- byte C_bytes[] = {
- (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
- 0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
- 0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
- 0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
- 0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
- 0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
- 0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
- 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
- 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
- 0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
- 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
- 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
- 0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- ClassLoader cl = new ClassLoader() {
- protected Class> findClass(String name) {
- if (name.equals("I")) {
- return defineClass("I", I_bytes, 0, I_bytes.length);
- } else if (name.equals("C")) {
- return defineClass("C", C_bytes, 0, C_bytes.length);
- } else {
- return null;
- }
- }
- };
- try {
- Class.forName("C", true, cl);
- } catch (Exception e) {
- // unmodified verifier will throw VerifyError
- fail("No exception should be thrown");
- }
- }
-}
diff --git a/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java b/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java
index 83445676920..2b4ea9f6b51 100644
--- a/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java
+++ b/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/AlreadDefinedStaticImport.java
@@ -23,5 +23,5 @@
// key: compiler.err.already.defined.static.single.import
-import static p.E1.A;
+import p.E1.A;
import static p.E2.A;
diff --git a/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java b/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java
index b9c09c0703b..034b731a949 100644
--- a/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java
+++ b/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E1.java
@@ -23,4 +23,6 @@
package p;
-public enum E1 { A, B, C}
+public class E1 {
+ public static class A { }
+}
diff --git a/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java b/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java
index 8341d3e372c..960c25d81e6 100644
--- a/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java
+++ b/langtools/test/tools/javac/diags/examples/AlreadyDefinedStaticImport/p/E2.java
@@ -23,4 +23,6 @@
package p;
-public enum E2 { A, B, C }
+public class E2 {
+ public static class A { }
+}
diff --git a/langtools/test/tools/javac/diags/examples/ObsoleteSourceAndTarget.java b/langtools/test/tools/javac/diags/examples/ObsoleteSourceAndTarget.java
new file mode 100644
index 00000000000..10416fd6aab
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/ObsoleteSourceAndTarget.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.option.obsolete.source
+// key: compiler.warn.option.obsolete.target
+// key: compiler.warn.option.obsolete.suppression
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 1.5 -target 1.5
+
+class ObsoleteSourceAndTarget {
+ public static void foo() {;}
+}
diff --git a/langtools/test/tools/javac/generics/7015430/T7015430_1.out b/langtools/test/tools/javac/generics/7015430/T7015430_1.out
index 3bee4e5da71..fb1fb0bf9c8 100644
--- a/langtools/test/tools/javac/generics/7015430/T7015430_1.out
+++ b/langtools/test/tools/javac/generics/7015430/T7015430_1.out
@@ -1,13 +1,13 @@
T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:51:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:51:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
T7015430.java:69:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:78:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:78:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:105:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:105:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
T7015430.java:114:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:42:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
diff --git a/langtools/test/tools/javac/generics/7015430/T7015430_2.out b/langtools/test/tools/javac/generics/7015430/T7015430_2.out
index da5be706917..2d24234c786 100644
--- a/langtools/test/tools/javac/generics/7015430/T7015430_2.out
+++ b/langtools/test/tools/javac/generics/7015430/T7015430_2.out
@@ -1,15 +1,15 @@
T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable