--- a/.hgtags-top-repo Thu Aug 29 16:18:31 2013 -0700
+++ b/.hgtags-top-repo Wed Jul 05 19:10:19 2017 +0200
@@ -226,3 +226,4 @@
5eb3c1dc348f72a7f84f7d9d07834e8bbe09a799 jdk8-b102
b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103
96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104
+5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105
--- a/NewMakefile.gmk Thu Aug 29 16:18:31 2013 -0700
+++ b/NewMakefile.gmk Wed Jul 05 19:10:19 2017 +0200
@@ -69,11 +69,11 @@
# 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 @@
$(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 @@
$(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 <component> # Build <component> and everything it depends on. )
$(info . make <component>-only # Build <component> only, without dependencies. This)
$(info . # is faster but can result in incorrect build results!)
--- a/README-builds.html Thu Aug 29 16:18:31 2013 -0700
+++ b/README-builds.html Wed Jul 05 19:10:19 2017 +0200
@@ -1210,19 +1210,18 @@
<blockquote>
<p>
- <b>Q:</b> The <code>configure</code> file looks horrible!
+ <b>Q:</b> The <code>generated-configure.sh</code> file looks horrible!
How are you going to edit it?
<br>
- <b>A:</b> The <code>configure</code> file is generated (think
+ <b>A:</b> The <code>generated-configure.sh</code> file is generated (think
"compiled") by the autoconf tools. The source code is
- in <code>configure.ac</code> various .m4 files in common/autoconf,
- which are
- much more readable.
+ in <code>configure.ac</code> and various .m4 files in common/autoconf,
+ which are much more readable.
</p>
<p>
<b>Q:</b>
- Why is the <code>configure</code> file checked in,
+ Why is the <code>generated-configure.sh</code> file checked in,
if it is generated?
<br>
<b>A:</b>
@@ -1237,13 +1236,29 @@
<p>
<b>Q:</b>
Do you require a specific version of autoconf for regenerating
- <code>configure</code>?
+ <code>generated-configure.sh</code>?
<br>
<b>A:</b>
- 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 <code>configure</code>
- in commits that made small changes to <code>configure.ac</code>).
+ 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 <code>generated-configure.sh</code>.
+ </p>
+
+ <p>
+ <b>Q:</b>
+ How do you regenerate <code>generated-configure.sh</code>
+ after making changes to the input files?
+ <br>
+ <b>A:</b>
+ Regnerating <code>generated-configure.sh</code>
+ should always be done using the
+ script <code>common/autoconf/autogen.sh</code> to
+ ensure that the correct files get updated. This
+ script should also be run after mercurial tries to
+ merge <code>generated-configure.sh</code> as a
+ merge of the generated file is not guaranteed to
+ be correct.
</p>
<p>
--- a/common/autoconf/autogen.sh Thu Aug 29 16:18:31 2013 -0700
+++ b/common/autoconf/autogen.sh Wed Jul 05 19:10:19 2017 +0200
@@ -44,10 +44,8 @@
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 @@
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
--- a/common/autoconf/configure.ac Thu Aug 29 16:18:31 2013 -0700
+++ b/common/autoconf/configure.ac Wed Jul 05 19:10:19 2017 +0200
@@ -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])
--- a/common/autoconf/generated-configure.sh Thu Aug 29 16:18:31 2013 -0700
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 19:10:19 2017 +0200
@@ -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 <build-dev@openjdk.java.net>.
#
#
-# 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 @@
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 @@
# 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 @@
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 @@
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_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 @@
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 @@
# ... 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'
- fi
-else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
+ fi
+else
+ 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 @@
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 @@
$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 @@
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 @@
if $ac_init_version; then
cat <<\_ACEOF
OpenJDK configure jdk8
-generated by GNU Autoconf 2.67
-
-Copyright (C) 2010 Free Software Foundation, Inc.
+generated by GNU Autoconf 2.69
+
+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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ $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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
# 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 @@
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 @@
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 @@
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 @@
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 @@
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:${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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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:${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 @@
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:${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 @@
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:${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 @@
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:${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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ $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 @@
$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 @@
{ $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 @@
$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 @@
{ $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 @@
$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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ { $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 @@
{ { $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 "$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 @@
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 @@
{ { $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 @@
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_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 @@
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 @@
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ $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_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 @@
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 @@
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 @@
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 @@
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 @@
{ $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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ { $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 @@
{ $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 @@
{ { $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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ $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 @@
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 @@
# 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 @@
{ { $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 "$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
@@ -30075,8 +30105,8 @@
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 @@
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 @@
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 @@
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 @@
# 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 @@
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 @@
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 @@
# 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 @@
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 @@
# 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 @@
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 @@
# 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 @@
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 @@
# 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 @@
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 @@
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 <X11/Xlib.h>
@@ -30869,7 +30899,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{ $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 @@
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 @@
{ $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 @@
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 @@
{ $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 @@
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 @@
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 @@
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 @@
See the pkg-config man page for more details.
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
-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 @@
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 @@
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 @@
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 @@
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 @@
: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 @@
-: ${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 @@
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 @@
# ... 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'
- fi
-else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
+ fi
+else
+ 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 @@
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 @@
# 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 @@
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 @@
_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 @@
"$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 @@
# 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 @@
{
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 @@
ac_cs_awk_cr=$ac_cr
fi
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF
@@ -34351,7 +34383,7 @@
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 @@
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 @@
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 @@
# 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 @@
# 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 @@
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 @@
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 @@
[\\/$]*) 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 @@
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_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 @@
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
;;
--- a/common/autoconf/help.m4 Thu Aug 29 16:18:31 2013 -0700
+++ b/common/autoconf/help.m4 Wed Jul 05 19:10:19 2017 +0200
@@ -83,7 +83,7 @@
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 @@
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" ;;
* )
--- a/common/autoconf/libraries.m4 Thu Aug 29 16:18:31 2013 -0700
+++ b/common/autoconf/libraries.m4 Wed Jul 05 19:10:19 2017 +0200
@@ -185,7 +185,7 @@
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 <X11/Xlib.h>
@@ -197,7 +197,7 @@
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)
--- a/common/makefiles/Main.gmk Thu Aug 29 16:18:31 2013 -0700
+++ b/common/makefiles/Main.gmk Wed Jul 05 19:10:19 2017 +0200
@@ -183,7 +183,7 @@
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 @@
.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
--- a/corba/.hgtags Thu Aug 29 16:18:31 2013 -0700
+++ b/corba/.hgtags Wed Jul 05 19:10:19 2017 +0200
@@ -226,3 +226,4 @@
528c7e76eaeee022817ee085668459bc97cf5665 jdk8-b102
49c4a777fdfd648d4c3fffc940fdb97a23108ca8 jdk8-b103
d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104
+4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105
--- a/hotspot/.hgtags Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/.hgtags Wed Jul 05 19:10:19 2017 +0200
@@ -371,3 +371,5 @@
580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46
104743074675359cfbf7f4dcd9ab2a5974a16627 jdk8-b104
c1604d5885a6f2adc0bcea2fa142a8f6bafad2f0 hs25-b47
+acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105
+18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Wed Jul 05 19:10:19 2017 +0200
@@ -35,8 +35,9 @@
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 @@
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 @@
},
__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 @@
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 @@
}
// 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 @@
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 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 @@
// 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 @@
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 @@
// 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) {" +
--- a/hotspot/make/hotspot_version Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/hotspot_version Wed Jul 05 19:10:19 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=47
+HS_BUILD_NUMBER=48
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/amd64.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/linux/makefiles/amd64.make Wed Jul 05 19:10:19 2017 +0200
@@ -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 += -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
--- a/hotspot/make/linux/makefiles/gcc.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make Wed Jul 05 19:10:19 2017 +0200
@@ -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 @@
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
--- a/hotspot/make/windows/build_vm_def.sh Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/windows/build_vm_def.sh Wed Jul 05 19:10:19 2017 +0200
@@ -42,8 +42,6 @@
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 @@
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"
--- a/hotspot/make/windows/makefiles/debug.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/windows/makefiles/debug.make Wed Jul 05 19:10:19 2017 +0200
@@ -49,9 +49,6 @@
# 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)
--- a/hotspot/make/windows/makefiles/fastdebug.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/windows/makefiles/fastdebug.make Wed Jul 05 19:10:19 2017 +0200
@@ -48,9 +48,6 @@
# 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)
--- a/hotspot/make/windows/makefiles/product.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/windows/makefiles/product.make Wed Jul 05 19:10:19 2017 +0200
@@ -51,9 +51,6 @@
# 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)
--- a/hotspot/make/windows/makefiles/projectcreator.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/windows/makefiles/projectcreator.make Wed Jul 05 19:10:19 2017 +0200
@@ -92,6 +92,10 @@
-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 @@
-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 \
--- a/hotspot/make/windows/makefiles/vm.make Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/make/windows/makefiles/vm.make Wed Jul 05 19:10:19 2017 +0200
@@ -393,3 +393,11 @@
_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)
+
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -642,13 +642,14 @@
#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 @@
}
#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 @@
// 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 @@
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 @@
}
-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 @@
// 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 @@
return n;
}
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+ // No tests available for this platform
+}
+#endif
--- a/hotspot/src/os/linux/vm/globals_linux.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -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") \
\
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -2720,36 +2720,7 @@
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_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 @@
// 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 @@
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 @@
}
fclose(fp);
}
- munmap (p, page_size);
- if (result)
- return true;
- }
-
- if (warn) {
+ munmap(p, page_size);
+ }
+
+ if (warn && !result) {
warning("HugeTLBFS is not supported by the operating system.");
}
@@ -3235,82 +3224,114 @@
static size_t _large_page_size = 0;
-void os::large_page_init() {
- if (!UseLargePages) {
- UseHugeTLBFS = false;
- UseSHM = false;
- return;
- }
-
- 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.
+size_t os::Linux::find_large_page_size() {
+ size_t large_page_size = 0;
+
+ // 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);
}
- }
-
- // print a warning if any large page related flag is specified on command line
- bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
-
+ fclose(fp);
+ }
+
+ 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;
-
- UseLargePages = UseHugeTLBFS || UseSHM;
+ return;
+ }
+
+ 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 @@
#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 @@
return NULL;
}
- if ((addr != NULL) && 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;
+}
+
+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;
+ }
+
+ 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 @@
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 @@
}
#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
--- a/hotspot/src/os/linux/vm/os_linux.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -32,6 +32,7 @@
class Linux {
friend class os;
+ friend class TestReserveMemorySpecial;
// For signal-chaining
#define MAXSIGNUM 32
@@ -92,8 +93,21 @@
static void rebuild_cpu_to_node_map();
static GrowableArray<int>* 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);
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/posix/vm/os_posix.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -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 @@
return ::fdopen(fd, mode);
}
+void* os::get_default_process_handle() {
+ return (void*)::dlopen(NULL, RTLD_LAZY);
+}
+
+// Builds a platform dependent Agent_OnLoad_<lib_name> 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");
}
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -3385,7 +3385,7 @@
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 @@
return strlen(buffer);
}
+
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+ // No tests available for this platform
+}
+#endif
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -3156,7 +3156,12 @@
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 @@
return true;
}
+void* os::get_default_process_handle() {
+ return (void*)GetModuleHandle(NULL);
+}
+
+// Builds a platform dependent Agent_OnLoad_<lib_name> 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 @@
}
#endif
+
+#ifndef PRODUCT
+void TestReserveMemorySpecial_test() {
+ // No tests available for this platform
+}
+#endif
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -3460,7 +3460,9 @@
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);
}
}
@@ -8696,9 +8698,10 @@
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) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -981,7 +981,8 @@
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;
@@ -1106,7 +1107,8 @@
// 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;
@@ -2006,10 +2008,12 @@
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);
@@ -2026,12 +2030,8 @@
// 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
@@ -3700,14 +3700,15 @@
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();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -776,9 +776,10 @@
// 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
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -313,7 +313,8 @@
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");
}
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -70,9 +70,6 @@
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;
}
--- a/hotspot/src/share/vm/memory/allocation.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/memory/allocation.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -666,7 +666,7 @@
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 @@
(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)
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -193,6 +193,8 @@
alignment = lcm(os::large_page_size(), alignment);
}
+ assert(alignment >= min_alignment(), "Must be");
+
return alignment;
}
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -95,13 +95,13 @@
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 @@
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 @@
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 @@
}
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();
}
--- a/hotspot/src/share/vm/memory/metaspace.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -345,7 +345,7 @@
};
// 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());
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -681,17 +681,23 @@
// 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 is small enough to allow UnscaledNarrowOop then
// just use UnscaledNarrowOop.
@@ -742,6 +748,8 @@
}
}
#endif
+
+ assert(is_ptr_aligned((char*)base, alignment), "Must be");
return (char*)base; // also return NULL (don't care) for 32-bit VM
}
@@ -867,27 +875,33 @@
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;
--- a/hotspot/src/share/vm/memory/universe.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -346,7 +346,7 @@
};
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); }
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -3234,19 +3234,22 @@
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 @@
#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 @@
* 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 @@
* 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 @@
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());
--- a/hotspot/src/share/vm/prims/jvmti.xml Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmti.xml Wed Jul 05 19:10:19 2017 +0200
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
<!--
- Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ 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
@@ -358,7 +358,7 @@
<specification label="JVM(TM) Tool Interface"
majorversion="1"
minorversion="2"
- microversion="2">
+ microversion="3">
<title subtitle="Version">
<tm>JVM</tm> Tool Interface
</title>
@@ -431,12 +431,46 @@
On the <tm>Solaris</tm> Operating Environment, an agent library is a shared
object (<code>.so</code> file).
<p/>
+
An agent may be started at VM startup by specifying the agent library
name using a <internallink id="starting">command line option</internallink>.
Some implementations may support a mechanism to <internallink id="onattach">
start agents</internallink> in the live <functionlink id="GetPhase">phase</functionlink>.
The details of how this is initiated are implementation specific.
</intro>
+
+ <intro id="entry point" label="Statically Linked Agents (since version 1.2.3)">
+
+ A native JVMTI Agent may be <i>statically linked</i> with the VM.
+ The manner in which the library and VM image are combined is
+ implementation-dependent.
+ An agent L whose image has been combined with the VM is defined as
+ <i>statically linked</i> if and only if the agent exports a function
+ called Agent_OnLoad_L.
+<p/>
+ If a <i>statically linked</i> agent L exports a function called
+ Agent_OnLoad_L and a function called Agent_OnLoad, the Agent_OnLoad
+ function will be ignored.
+ If an agent L is <i>statically linked</i>, an Agent_OnLoad_L
+ function will be invoked with the same arguments and expected return
+ value as specified for the Agent_OnLoad function.
+ An agent L that is <i>statically linked</i> will prohibit an agent of
+ the same name from being loaded dynamically.
+<p/>
+ The VM will invoke the Agent_OnUnload_L function of the agent, if such
+ a function is exported, at the same point during startup as it would
+ have called the dynamic entry point Agent_OnUnLoad.
+ If a <i>statically linked</i> agent L exports a function called
+ Agent_OnUnLoad_L and a function called Agent_OnUnLoad, the Agent_OnUnLoad
+ function will be ignored.
+<p/>
+ If an agent L is <i>statically linked</i>, an Agent_OnAttach_L function
+ will be invoked with the same arguments and expected return value as
+ specified for the Agent_OnAttach function.
+ If a <i>statically linked</i> agent L exports a function called
+ Agent_OnAttach_L and a function called Agent_OnAttach, the Agent_OnAttach
+ function will be ignored.
+</intro>
<intro id="starting" label="Agent Command Line Options">
The term "command-line option" is used below to
@@ -455,7 +489,7 @@
<dd>
The name following <code>-agentlib:</code> is the name of the
library to load. Lookup of the library, both its full name and location,
- proceeds in a platform-specific manner.
+ proceeds in a platform-specific manner.
Typically, the <i><agent-lib-name></i> is expanded to an
operating system specific file name.
The <i><options></i> will be passed to the agent on start-up.
@@ -463,7 +497,11 @@
<code>-agentlib:foo=opt1,opt2</code> is specified, the VM will attempt to
load the shared library <code>foo.dll</code> from the system <code>PATH</code>
under <tm>Windows</tm> or <code>libfoo.so</code> from the
- <code>LD_LIBRARY_PATH</code> under the <tm>Solaris</tm> operating environment.
+ <code>LD_LIBRARY_PATH</code> under the <tm>Solaris</tm> operating
+ environment.
+ If the agent library is statically linked into the executable
+ then no actual loading takes place.
+ <p/>
</dd>
<dt><code>-agentpath:</code><i><path-to-agent></i><code>=</code><i><options></i></dt>
<dd>
@@ -473,11 +511,20 @@
The <i><options></i> will be passed to the agent on start-up.
For example, if the option
<code>-agentpath:c:\myLibs\foo.dll=opt1,opt2</code> is specified, the VM will attempt to
- load the shared library <code>c:\myLibs\foo.dll</code>.
+ load the shared library <code>c:\myLibs\foo.dll</code>. If the agent
+ library is statically linked into the executable
+ then no actual loading takes place.
+ <p/>
</dd>
</dl>
- The start-up routine <internallink id="onload"><code>Agent_OnLoad</code></internallink>
- in the library will be invoked.
+ For a dynamic shared library agent, the start-up routine
+ <internallink id="onload"><code>Agent_OnLoad</code></internallink>
+ in the library will be invoked. If the agent library is statically linked
+ into the executable then the system will attempt to invoke the
+ <code>Agent_OnLoad_<agent-lib-name></code> entry point where
+ <agent-lib-name> is the basename of the
+ agent. In the above example <code>-agentpath:c:\myLibs\foo.dll=opt1,opt2</code>,
+ the system will attempt to find and call the <code>Agent_OnLoad_foo</code> start-up routine.
<p/>
Libraries loaded with <code>-agentlib:</code> or <code>-agentpath:</code>
will be searched for JNI native method implementations to facilitate the
@@ -502,11 +549,13 @@
If the agent is started in the <code>OnLoad</code>
<functionlink id="GetPhase">phase</functionlink> the function
<internallink id="onload"><code>Agent_OnLoad</code></internallink>
- will be invoked.
+ or <internallink id="onload"><code>Agent_OnLoad_L</code></internallink>
+ for statically linked agents will be invoked.
If the agent is started in the live
<functionlink id="GetPhase">phase</functionlink> the function
<internallink id="onattach"><code>Agent_OnAttach</code></internallink>
- will be invoked.
+ or <internallink id="onattach"><code>Agent_OnAttach_L</code></internallink>
+ for statically linked agents will be invoked.
Exactly one call to a start-up function is made per agent.
</intro>
@@ -516,6 +565,11 @@
<example>
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)</example>
+ Or for a statically linked agent named 'L':
+ <example>
+JNIEXPORT jint JNICALL
+Agent_OnLoad_L(JavaVM *vm, char *options, void *reserved)</example>
+
The VM will start the agent by calling this function.
It will be called early enough in VM initialization that:
<ul>
@@ -531,7 +585,8 @@
<li>no objects have been created</li>
</ul>
<p/>
- The VM will call the <code>Agent_OnLoad</code> function with
+ The VM will call the <code>Agent_OnLoad</code> or
+ <code>Agent_OnLoad_<agent-lib-name></code> function with
<i><options></i> as the second argument -
that is, using the command-line option examples,
<code>"opt1,opt2"</code> will be passed to the <code>char *options</code>
@@ -540,7 +595,8 @@
<internallink id="mUTF">modified UTF-8</internallink> string.
If <i>=<options></i> is not specified,
a zero length string is passed to <code>options</code>.
- The lifespan of the <code>options</code> string is the <code>Agent_OnLoad</code>
+ The lifespan of the <code>options</code> string is the
+ <code>Agent_OnLoad</code> or <code>Agent_OnLoad_<agent-lib-name></code>
call. If needed beyond this time the string or parts of the string must
be copied.
The period between when <code>Agent_OnLoad</code> is called and when it
@@ -570,7 +626,8 @@
their functionality.
</rationale>
<p/>
- The return value from <code>Agent_OnLoad</code> is used to indicate an error.
+ The return value from <code>Agent_OnLoad</code> or
+ <code>Agent_OnLoad_<agent-lib-name></code> is used to indicate an error.
Any value other than zero indicates an error and causes termination of the VM.
</intro>
@@ -587,6 +644,11 @@
<example>
JNIEXPORT jint JNICALL
Agent_OnAttach(JavaVM* vm, char *options, void *reserved)</example>
+Or for a statically linked agent named 'L':
+ <example>
+JNIEXPORT jint JNICALL
+Agent_OnAttach_L(JavaVM* vm, char *options, void *reserved)</example>
+
<p/>
The VM will start the agent by calling this function.
It will be called in the context of a thread
@@ -596,13 +658,14 @@
</internallink> string.
If startup options were not provided, a zero length string is passed to
<code>options</code>. The lifespan of the <code>options</code> string is the
- <code>Agent_OnAttach</code> call. If needed beyond this time the string or parts of
- the string must be copied.
+ <code>Agent_OnAttach</code> or <code>Agent_OnAttach_<agent-lib-name></code> call.
+ If needed beyond this time the string or parts of the string must be copied.
<p/>
Note that some <internallink id="capability">capabilities</internallink>
may not be available in the live phase.
<p/>
- The <code>Agent_OnAttach</code> function initializes the agent and returns a value
+ The <code>Agent_OnAttach</code> or <code>Agent_OnAttach_<agent-lib-name
+ ></code> function initializes the agent and returns a value
to the VM to indicate if an error occurred. Any value other than zero indicates an error.
An error does not cause the VM to terminate. Instead the VM ignores the error, or takes
some implementation specific action -- for example it might print an error to standard error,
@@ -615,8 +678,14 @@
<example>
JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm)</example>
+ Or for a statically linked agent named 'L':
+ <example>
+JNIEXPORT void JNICALL
+Agent_OnUnload_L(JavaVM *vm)</example>
+
This function will be called by the VM when the library is about to be unloaded.
- The library will be unloaded and this function will be called if some platform specific
+ The library will be unloaded (unless it is statically linked into the
+ executable) and this function will be called if some platform specific
mechanism causes the unload (an unload mechanism is not specified in this document)
or the library is (in effect) unloaded by the termination of the VM whether through
normal termination or VM failure, including start-up failure.
@@ -625,8 +694,9 @@
<eventlink id="VMDeath">VM Death event</eventlink>: for the VM Death event
to be sent, the VM must have run at least to the point of initialization and a valid
<jvmti/> environment must exist which has set a callback for VMDeath
- and enabled the event
- None of these are required for <code>Agent_OnUnload</code> and this function
+ and enabled the event.
+ None of these are required for <code>Agent_OnUnload</code> or
+ <code>Agent_OnUnload_<agent-lib-name></code> and this function
is also called if the library is unloaded for other reasons.
In the case that a VM Death event is sent, it will be sent before this
function is called (assuming this function is called due to VM termination).
@@ -10701,10 +10771,14 @@
<constants id="jvmtiPhase" label="Phases of execution" kind="enum">
<constant id="JVMTI_PHASE_ONLOAD" num="1">
<code>OnLoad</code> phase: while in the
- <internallink id="onload"><code>Agent_OnLoad</code></internallink> function.
+ <internallink id="onload"><code>Agent_OnLoad</code></internallink>
+ or, for statically linked agents, the <internallink id="onload">
+ <code>Agent_OnLoad_<agent-lib-name>
+ </code></internallink> function.
</constant>
<constant id="JVMTI_PHASE_PRIMORDIAL" num="2">
- Primordial phase: between return from <code>Agent_OnLoad</code> and the
+ Primordial phase: between return from <code>Agent_OnLoad</code>
+ or <code>Agent_OnLoad_<agent-lib-name></code> and the
<code>VMStart</code> event.
</constant>
<constant id="JVMTI_PHASE_START" num="6">
@@ -14261,6 +14335,9 @@
<change date="11 October 2012" version="1.2.2">
Fixed the "HTTP" and "Missing Anchor" errors reported by the LinkCheck tool.
</change>
+ <change date="19 June 2013" version="1.2.3">
+ Added support for statically linked agents.
+ </change>
</changehistory>
</specification>
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -2191,6 +2191,8 @@
char buffer[JVM_MAXPATHLEN];
void* library = NULL;
jint result = JNI_ERR;
+ const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
+ size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols);
// get agent name and options
const char* agent = op->arg(0);
@@ -2200,43 +2202,48 @@
// The abs paramter should be "true" or "false"
bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0);
+ // Initially marked as invalid. It will be set to valid if we can find the agent
+ AgentLibrary *agent_lib = new AgentLibrary(agent, options, is_absolute_path, NULL);
- // If the path is absolute we attempt to load the library. Otherwise we try to
- // load it from the standard dll directory.
+ // Check for statically linked in agent. If not found then if the path is
+ // absolute we attempt to load the library. Otherwise we try to load it
+ // from the standard dll directory.
- if (is_absolute_path) {
- library = os::dll_load(agent, ebuf, sizeof ebuf);
- } else {
- // Try to load the agent from the standard dll directory
- if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
- agent)) {
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
- }
- if (library == NULL) {
- // not found - try local path
- char ns[1] = {0};
- if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) {
+ if (!os::find_builtin_agent(agent_lib, on_attach_symbols, num_symbol_entries)) {
+ if (is_absolute_path) {
+ library = os::dll_load(agent, ebuf, sizeof ebuf);
+ } else {
+ // Try to load the agent from the standard dll directory
+ if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+ agent)) {
library = os::dll_load(buffer, ebuf, sizeof ebuf);
}
+ if (library == NULL) {
+ // not found - try local path
+ char ns[1] = {0};
+ if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) {
+ library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ }
+ }
}
+ if (library != NULL) {
+ agent_lib->set_os_lib(library);
+ agent_lib->set_valid();
+ }
}
-
// If the library was loaded then we attempt to invoke the Agent_OnAttach
// function
- if (library != NULL) {
-
+ if (agent_lib->valid()) {
// Lookup the Agent_OnAttach function
OnAttachEntry_t on_attach_entry = NULL;
- const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
- for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_attach_symbols); symbol_index++) {
- on_attach_entry =
- CAST_TO_FN_PTR(OnAttachEntry_t, os::dll_lookup(library, on_attach_symbols[symbol_index]));
- if (on_attach_entry != NULL) break;
- }
-
+ on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t,
+ os::find_agent_function(agent_lib, false, on_attach_symbols, num_symbol_entries));
if (on_attach_entry == NULL) {
// Agent_OnAttach missing - unload library
- os::dll_unload(library);
+ if (!agent_lib->is_static_lib()) {
+ os::dll_unload(library);
+ }
+ delete agent_lib;
} else {
// Invoke the Agent_OnAttach function
JavaThread* THREAD = JavaThread::current();
@@ -2256,7 +2263,9 @@
// If OnAttach returns JNI_OK then we add it to the list of
// agent libraries so that we can call Agent_OnUnload later.
if (result == JNI_OK) {
- Arguments::add_loaded_agent(agent, (char*)options, is_absolute_path, library);
+ Arguments::add_loaded_agent(agent_lib);
+ } else {
+ delete agent_lib;
}
// Agent_OnAttach executed so completion status is JNI_OK
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -1554,18 +1554,22 @@
return false;
}
- // rewrite sourc file name index:
+ // rewrite source file name index:
u2 source_file_name_idx = scratch_class->source_file_name_index();
if (source_file_name_idx != 0) {
u2 new_source_file_name_idx = find_new_index(source_file_name_idx);
- scratch_class->set_source_file_name_index(new_source_file_name_idx);
+ if (new_source_file_name_idx != 0) {
+ scratch_class->set_source_file_name_index(new_source_file_name_idx);
+ }
}
// rewrite class generic signature index:
u2 generic_signature_index = scratch_class->generic_signature_index();
if (generic_signature_index != 0) {
u2 new_generic_signature_index = find_new_index(generic_signature_index);
- scratch_class->set_generic_signature_index(new_generic_signature_index);
+ if (new_generic_signature_index != 0) {
+ scratch_class->set_generic_signature_index(new_generic_signature_index);
+ }
}
return true;
@@ -1737,7 +1741,10 @@
for (int i = 0; i < len; i++) {
const u2 cp_index = elem[i].name_cp_index;
- elem[i].name_cp_index = find_new_index(cp_index);
+ const u2 new_cp_index = find_new_index(cp_index);
+ if (new_cp_index != 0) {
+ elem[i].name_cp_index = new_cp_index;
+ }
}
}
} // end rewrite_cp_refs_in_method()
--- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -128,7 +128,7 @@
WB_END
#endif // INCLUDE_ALL_GCS
-#ifdef INCLUDE_NMT
+#if INCLUDE_NMT
// Alloc memory using the test memory type so that we can use that to see if
// NMT picks it up correctly
WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
@@ -181,6 +181,10 @@
return MemTracker::wbtest_wait_for_data_merge();
WB_END
+WB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env))
+ return MemTracker::tracking_level() == MemTracker::NMT_detail;
+WB_END
+
#endif // INCLUDE_NMT
static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
@@ -439,7 +443,7 @@
{CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
{CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
#endif // INCLUDE_ALL_GCS
-#ifdef INCLUDE_NMT
+#if INCLUDE_NMT
{CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc },
{CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree },
{CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory },
@@ -447,6 +451,7 @@
{CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
{CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
{CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge},
+ {CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported},
#endif // INCLUDE_NMT
{CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
{CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -118,11 +118,21 @@
// For use by -agentlib, -agentpath and -Xrun
class AgentLibrary : public CHeapObj<mtInternal> {
friend class AgentLibraryList;
+public:
+ // Is this library valid or not. Don't rely on os_lib == NULL as statically
+ // linked lib could have handle of RTLD_DEFAULT which == 0 on some platforms
+ enum AgentState {
+ agent_invalid = 0,
+ agent_valid = 1
+ };
+
private:
char* _name;
char* _options;
void* _os_lib;
bool _is_absolute_path;
+ bool _is_static_lib;
+ AgentState _state;
AgentLibrary* _next;
public:
@@ -133,6 +143,11 @@
void* os_lib() const { return _os_lib; }
void set_os_lib(void* os_lib) { _os_lib = os_lib; }
AgentLibrary* next() const { return _next; }
+ bool is_static_lib() const { return _is_static_lib; }
+ void set_static_lib(bool static_lib) { _is_static_lib = static_lib; }
+ bool valid() { return (_state == agent_valid); }
+ void set_valid() { _state = agent_valid; }
+ void set_invalid() { _state = agent_invalid; }
// Constructor
AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
@@ -147,6 +162,8 @@
_is_absolute_path = is_absolute_path;
_os_lib = os_lib;
_next = NULL;
+ _state = agent_invalid;
+ _is_static_lib = false;
}
};
@@ -276,6 +293,8 @@
{ _agentList.add(new AgentLibrary(name, options, absolute_path, NULL)); }
// Late-binding agents not started via arguments
+ static void add_loaded_agent(AgentLibrary *agentLib)
+ { _agentList.add(agentLib); }
static void add_loaded_agent(const char* name, char* options, bool absolute_path, void* os_lib)
{ _agentList.add(new AgentLibrary(name, options, absolute_path, os_lib)); }
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -1933,6 +1933,9 @@
notproduct(bool, ExecuteInternalVMTests, false, \
"Enable execution of internal VM tests.") \
\
+ notproduct(bool, VerboseInternalVMTests, false, \
+ "Turn on logging for internal VM tests.") \
+ \
product_pd(bool, UseTLAB, "Use thread-local object allocation") \
\
product_pd(bool, ResizeTLAB, \
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -124,13 +124,15 @@
Mutex* Management_lock = NULL;
Monitor* Service_lock = NULL;
-Mutex* Stacktrace_lock = NULL;
+Monitor* PeriodicTask_lock = NULL;
-Monitor* JfrQuery_lock = NULL;
+#ifdef INCLUDE_TRACE
+Mutex* JfrStacktrace_lock = NULL;
Monitor* JfrMsg_lock = NULL;
Mutex* JfrBuffer_lock = NULL;
Mutex* JfrStream_lock = NULL;
-Monitor* PeriodicTask_lock = NULL;
+Mutex* JfrThreadGroups_lock = NULL;
+#endif
#define MAX_NUM_MUTEX 128
static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -206,7 +208,6 @@
def(Patching_lock , Mutex , special, true ); // used for safepointing and code patching.
def(ObjAllocPost_lock , Monitor, special, false);
def(Service_lock , Monitor, special, true ); // used for service thread operations
- def(Stacktrace_lock , Mutex, special, true ); // used for JFR stacktrace database
def(JmethodIdCreation_lock , Mutex , leaf, true ); // used for creating jmethodIDs.
def(SystemDictionary_lock , Monitor, leaf, true ); // lookups done by VM thread
@@ -272,11 +273,16 @@
def(Debug3_lock , Mutex , nonleaf+4, true );
def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread
def(CompileThread_lock , Monitor, nonleaf+5, false );
+ def(PeriodicTask_lock , Monitor, nonleaf+5, true);
+#ifdef INCLUDE_TRACE
def(JfrMsg_lock , Monitor, leaf, true);
def(JfrBuffer_lock , Mutex, nonleaf+1, true);
+ def(JfrThreadGroups_lock , Mutex, nonleaf+1, true);
def(JfrStream_lock , Mutex, nonleaf+2, true);
- def(PeriodicTask_lock , Monitor, nonleaf+5, true);
+ def(JfrStacktrace_lock , Mutex, special, true );
+#endif
+
}
GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -137,13 +137,15 @@
extern Mutex* Management_lock; // a lock used to serialize JVM management
extern Monitor* Service_lock; // a lock used for service thread operation
-extern Mutex* Stacktrace_lock; // used to guard access to the stacktrace table
+extern Monitor* PeriodicTask_lock; // protects the periodic task structure
-extern Monitor* JfrQuery_lock; // protects JFR use
+#ifdef INCLUDE_TRACE
+extern Mutex* JfrStacktrace_lock; // used to guard access to the JFR stacktrace table
extern Monitor* JfrMsg_lock; // protects JFR messaging
extern Mutex* JfrBuffer_lock; // protects JFR buffer operations
extern Mutex* JfrStream_lock; // protects JFR stream access
-extern Monitor* PeriodicTask_lock; // protects the periodic task structure
+extern Mutex* JfrThreadGroups_lock; // protects JFR access to Thread Groups
+#endif
// A MutexLocker provides mutual exclusion with respect to a given mutex
// for the scope which contains the locker. The lock is an OS lock, not
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -443,6 +443,67 @@
return _native_java_library;
}
+/*
+ * Support for finding Agent_On(Un)Load/Attach<_lib_name> if it exists.
+ * If check_lib == true then we are looking for an
+ * Agent_OnLoad_lib_name or Agent_OnAttach_lib_name function to determine if
+ * this library is statically linked into the image.
+ * If check_lib == false then we will look for the appropriate symbol in the
+ * executable if agent_lib->is_static_lib() == true or in the shared library
+ * referenced by 'handle'.
+ */
+void* os::find_agent_function(AgentLibrary *agent_lib, bool check_lib,
+ const char *syms[], size_t syms_len) {
+ const char *lib_name;
+ void *handle = agent_lib->os_lib();
+ void *entryName = NULL;
+ char *agent_function_name;
+ size_t i;
+
+ // If checking then use the agent name otherwise test is_static_lib() to
+ // see how to process this lookup
+ lib_name = ((check_lib || agent_lib->is_static_lib()) ? agent_lib->name() : NULL);
+ for (i = 0; i < syms_len; i++) {
+ agent_function_name = build_agent_function_name(syms[i], lib_name, agent_lib->is_absolute_path());
+ if (agent_function_name == NULL) {
+ break;
+ }
+ entryName = dll_lookup(handle, agent_function_name);
+ FREE_C_HEAP_ARRAY(char, agent_function_name, mtThread);
+ if (entryName != NULL) {
+ break;
+ }
+ }
+ return entryName;
+}
+
+// See if the passed in agent is statically linked into the VM image.
+bool os::find_builtin_agent(AgentLibrary *agent_lib, const char *syms[],
+ size_t syms_len) {
+ void *ret;
+ void *proc_handle;
+ void *save_handle;
+
+ if (agent_lib->name() == NULL) {
+ return false;
+ }
+ proc_handle = get_default_process_handle();
+ // Check for Agent_OnLoad/Attach_lib_name function
+ save_handle = agent_lib->os_lib();
+ // We want to look in this process' symbol table.
+ agent_lib->set_os_lib(proc_handle);
+ ret = find_agent_function(agent_lib, true, syms, syms_len);
+ agent_lib->set_os_lib(save_handle);
+ if (ret != NULL) {
+ // Found an entry point like Agent_OnLoad_lib_name so we have a static agent
+ agent_lib->set_os_lib(proc_handle);
+ agent_lib->set_valid();
+ agent_lib->set_static_lib(true);
+ return true;
+ }
+ return false;
+}
+
// --------------------- heap allocation utilities ---------------------
char *os::strdup(const char *str, MEMFLAGS flags) {
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -46,6 +46,8 @@
# include <setjmp.h>
#endif
+class AgentLibrary;
+
// os defines the interface to operating system; this includes traditional
// OS services (time, I/O) as well as other functionality with system-
// dependent code.
@@ -328,8 +330,8 @@
static char* non_memory_address_word();
// reserve, commit and pin the entire memory region
- static char* reserve_memory_special(size_t size, char* addr = NULL,
- bool executable = false);
+ static char* reserve_memory_special(size_t size, size_t alignment,
+ char* addr, bool executable);
static bool release_memory_special(char* addr, size_t bytes);
static void large_page_init();
static size_t large_page_size();
@@ -537,6 +539,17 @@
// Unload library
static void dll_unload(void *lib);
+ // Return the handle of this process
+ static void* get_default_process_handle();
+
+ // Check for static linked agent library
+ static bool find_builtin_agent(AgentLibrary *agent_lib, const char *syms[],
+ size_t syms_len);
+
+ // Find agent entry point
+ static void *find_agent_function(AgentLibrary *agent_lib, bool check_lib,
+ const char *syms[], size_t syms_len);
+
// Print out system information; they are called by fatal error handler.
// Output format may be different on different platforms.
static void print_os_info(outputStream* st);
@@ -806,6 +819,11 @@
// ResumeThread call)
static void pause();
+ // Builds a platform dependent Agent_OnLoad_<libname> function name
+ // which is used to find statically linked in agents.
+ static char* build_agent_function_name(const char *sym, const char *cname,
+ bool is_absolute_path);
+
class SuspendedThreadTaskContext {
public:
SuspendedThreadTaskContext(Thread* thread, void *ucontext) : _thread(thread), _ucontext(ucontext) {}
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -3696,15 +3696,18 @@
// num_symbol_entries must be passed-in since only the caller knows the number of symbols in the array.
static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_symbols[], size_t num_symbol_entries) {
OnLoadEntry_t on_load_entry = NULL;
- void *library = agent->os_lib(); // check if we have looked it up before
-
- if (library == NULL) {
+ void *library = NULL;
+
+ if (!agent->valid()) {
char buffer[JVM_MAXPATHLEN];
char ebuf[1024];
const char *name = agent->name();
const char *msg = "Could not find agent library ";
- if (agent->is_absolute_path()) {
+ // First check to see if agent is statcally linked into executable
+ if (os::find_builtin_agent(agent, on_load_symbols, num_symbol_entries)) {
+ library = agent->os_lib();
+ } else if (agent->is_absolute_path()) {
library = os::dll_load(name, ebuf, sizeof ebuf);
if (library == NULL) {
const char *sub_msg = " in absolute path, with error: ";
@@ -3738,13 +3741,15 @@
}
}
agent->set_os_lib(library);
+ agent->set_valid();
}
// Find the OnLoad function.
- for (size_t symbol_index = 0; symbol_index < num_symbol_entries; symbol_index++) {
- on_load_entry = CAST_TO_FN_PTR(OnLoadEntry_t, os::dll_lookup(library, on_load_symbols[symbol_index]));
- if (on_load_entry != NULL) break;
- }
+ on_load_entry =
+ CAST_TO_FN_PTR(OnLoadEntry_t, os::find_agent_function(agent,
+ false,
+ on_load_symbols,
+ num_symbol_entries));
return on_load_entry;
}
@@ -3819,22 +3824,23 @@
void Threads::shutdown_vm_agents() {
// Send any Agent_OnUnload notifications
const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
+ size_t num_symbol_entries = ARRAY_SIZE(on_unload_symbols);
extern struct JavaVM_ main_vm;
for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
// Find the Agent_OnUnload function.
- for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) {
- Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
- os::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index]));
-
- // Invoke the Agent_OnUnload function
- if (unload_entry != NULL) {
- JavaThread* thread = JavaThread::current();
- ThreadToNativeFromVM ttn(thread);
- HandleMark hm(thread);
- (*unload_entry)(&main_vm);
- break;
- }
+ Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
+ os::find_agent_function(agent,
+ false,
+ on_unload_symbols,
+ num_symbol_entries));
+
+ // Invoke the Agent_OnUnload function
+ if (unload_entry != NULL) {
+ JavaThread* thread = JavaThread::current();
+ ThreadToNativeFromVM ttn(thread);
+ HandleMark hm(thread);
+ (*unload_entry)(&main_vm);
}
}
}
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -42,8 +42,19 @@
// ReservedSpace
+
+// Dummy constructor
+ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
+ _alignment(0), _special(false), _executable(false) {
+}
+
ReservedSpace::ReservedSpace(size_t size) {
- initialize(size, 0, false, NULL, 0, false);
+ size_t page_size = os::page_size_for_region(size, size, 1);
+ bool large_pages = page_size != (size_t)os::vm_page_size();
+ // Don't force the alignment to be large page aligned,
+ // since that will waste memory.
+ size_t alignment = os::vm_allocation_granularity();
+ initialize(size, alignment, large_pages, NULL, 0, false);
}
ReservedSpace::ReservedSpace(size_t size, size_t alignment,
@@ -129,16 +140,18 @@
if (special) {
- base = os::reserve_memory_special(size, requested_address, executable);
+ base = os::reserve_memory_special(size, alignment, requested_address, executable);
if (base != NULL) {
if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
// OS ignored requested address. Try different address.
return;
}
- // Check alignment constraints
+ // Check alignment constraints.
assert((uintptr_t) base % alignment == 0,
- "Large pages returned a non-aligned address");
+ err_msg("Large pages returned a non-aligned address, base: "
+ PTR_FORMAT " alignment: " PTR_FORMAT,
+ base, (void*)(uintptr_t)alignment));
_special = true;
} else {
// failed; try to reserve regular memory below
@@ -715,4 +728,188 @@
tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary());
}
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+#define test_log(...) \
+ do {\
+ if (VerboseInternalVMTests) { \
+ tty->print_cr(__VA_ARGS__); \
+ tty->flush(); \
+ }\
+ } while (false)
+
+class TestReservedSpace : 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 release_memory_for_test(ReservedSpace rs) {
+ if (rs.special()) {
+ guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail");
+ } else {
+ guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail");
+ }
+ }
+
+ static void test_reserved_space1(size_t size, size_t alignment) {
+ test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size);
+
+ assert(is_size_aligned(size, alignment), "Incorrect input parameters");
+
+ ReservedSpace rs(size, // size
+ alignment, // alignment
+ UseLargePages, // large
+ NULL, // requested_address
+ 0); // noacces_prefix
+
+ test_log(" rs.special() == %d", rs.special());
+
+ assert(rs.base() != NULL, "Must be");
+ assert(rs.size() == size, "Must be");
+
+ assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses");
+ assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses");
+
+ if (rs.special()) {
+ small_page_write(rs.base(), size);
+ }
+
+ release_memory_for_test(rs);
+ }
+
+ static void test_reserved_space2(size_t size) {
+ test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size);
+
+ assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
+
+ ReservedSpace rs(size);
+
+ test_log(" rs.special() == %d", rs.special());
+
+ assert(rs.base() != NULL, "Must be");
+ assert(rs.size() == size, "Must be");
+
+ if (rs.special()) {
+ small_page_write(rs.base(), size);
+ }
+
+ release_memory_for_test(rs);
+ }
+
+ static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {
+ test_log("test_reserved_space3(%p, %p, %d)",
+ (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large);
+
+ assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
+ assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment");
+
+ bool large = maybe_large && UseLargePages && size >= os::large_page_size();
+
+ ReservedSpace rs(size, alignment, large, false);
+
+ test_log(" rs.special() == %d", rs.special());
+
+ assert(rs.base() != NULL, "Must be");
+ assert(rs.size() == size, "Must be");
+
+ if (rs.special()) {
+ small_page_write(rs.base(), size);
+ }
+
+ release_memory_for_test(rs);
+ }
+
+
+ static void test_reserved_space1() {
+ size_t size = 2 * 1024 * 1024;
+ size_t ag = os::vm_allocation_granularity();
+
+ test_reserved_space1(size, ag);
+ test_reserved_space1(size * 2, ag);
+ test_reserved_space1(size * 10, ag);
+ }
+
+ static void test_reserved_space2() {
+ size_t size = 2 * 1024 * 1024;
+ size_t ag = os::vm_allocation_granularity();
+
+ test_reserved_space2(size * 1);
+ test_reserved_space2(size * 2);
+ test_reserved_space2(size * 10);
+ test_reserved_space2(ag);
+ test_reserved_space2(size - ag);
+ test_reserved_space2(size);
+ test_reserved_space2(size + ag);
+ test_reserved_space2(size * 2);
+ test_reserved_space2(size * 2 - ag);
+ test_reserved_space2(size * 2 + ag);
+ test_reserved_space2(size * 3);
+ test_reserved_space2(size * 3 - ag);
+ test_reserved_space2(size * 3 + ag);
+ test_reserved_space2(size * 10);
+ test_reserved_space2(size * 10 + size / 2);
+ }
+
+ static void test_reserved_space3() {
+ size_t ag = os::vm_allocation_granularity();
+
+ test_reserved_space3(ag, ag , false);
+ test_reserved_space3(ag * 2, ag , false);
+ test_reserved_space3(ag * 3, ag , false);
+ test_reserved_space3(ag * 2, ag * 2, false);
+ test_reserved_space3(ag * 4, ag * 2, false);
+ test_reserved_space3(ag * 8, ag * 2, false);
+ test_reserved_space3(ag * 4, ag * 4, false);
+ test_reserved_space3(ag * 8, ag * 4, false);
+ test_reserved_space3(ag * 16, ag * 4, false);
+
+ if (UseLargePages) {
+ size_t lp = os::large_page_size();
+
+ // Without large pages
+ test_reserved_space3(lp, ag * 4, false);
+ test_reserved_space3(lp * 2, ag * 4, false);
+ test_reserved_space3(lp * 4, ag * 4, false);
+ test_reserved_space3(lp, lp , false);
+ test_reserved_space3(lp * 2, lp , false);
+ test_reserved_space3(lp * 3, lp , false);
+ test_reserved_space3(lp * 2, lp * 2, false);
+ test_reserved_space3(lp * 4, lp * 2, false);
+ test_reserved_space3(lp * 8, lp * 2, false);
+
+ // With large pages
+ test_reserved_space3(lp, ag * 4 , true);
+ test_reserved_space3(lp * 2, ag * 4, true);
+ test_reserved_space3(lp * 4, ag * 4, true);
+ test_reserved_space3(lp, lp , true);
+ test_reserved_space3(lp * 2, lp , true);
+ test_reserved_space3(lp * 3, lp , true);
+ test_reserved_space3(lp * 2, lp * 2, true);
+ test_reserved_space3(lp * 4, lp * 2, true);
+ test_reserved_space3(lp * 8, lp * 2, true);
+ }
+ }
+
+ static void test_reserved_space() {
+ test_reserved_space1();
+ test_reserved_space2();
+ test_reserved_space3();
+ }
+};
+
+void TestReservedSpace_test() {
+ TestReservedSpace::test_reserved_space();
+}
+
+#endif // PRODUCT
+
#endif
--- a/hotspot/src/share/vm/runtime/virtualspace.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/runtime/virtualspace.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -53,6 +53,7 @@
public:
// Constructor
+ ReservedSpace();
ReservedSpace(size_t size);
ReservedSpace(size_t size, size_t alignment, bool large,
char* requested_address = NULL,
--- a/hotspot/src/share/vm/services/management.cpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/services/management.cpp Wed Jul 05 19:10:19 2017 +0200
@@ -876,8 +876,6 @@
total_used += u.used();
total_committed += u.committed();
- // if any one of the memory pool has undefined init_size or max_size,
- // set it to -1
if (u.init_size() == (size_t)-1) {
has_undefined_init_size = true;
}
@@ -894,6 +892,15 @@
}
}
+ // if any one of the memory pool has undefined init_size or max_size,
+ // set it to -1
+ if (has_undefined_init_size) {
+ total_init = (size_t)-1;
+ }
+ if (has_undefined_max_size) {
+ total_max = (size_t)-1;
+ }
+
MemoryUsage usage((heap ? InitialHeapSize : total_init),
total_used,
total_committed,
--- a/hotspot/src/share/vm/services/memTracker.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/services/memTracker.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -87,6 +87,8 @@
MEMFLAGS flags, address pc = 0, Thread* thread = NULL) { }
static inline void record_virtual_memory_commit(address addr, size_t size,
address pc = 0, Thread* thread = NULL) { }
+ static inline void record_virtual_memory_release(address addr, size_t size,
+ Thread* thread = NULL) { }
static inline void record_virtual_memory_type(address base, MEMFLAGS flags,
Thread* thread = NULL) { }
static inline Tracker get_realloc_tracker() { return _tkr; }
@@ -372,6 +374,13 @@
tkr.record(addr, size, flags, pc);
}
+ static inline void record_virtual_memory_release(address addr, size_t size,
+ Thread* thread = NULL) {
+ if (is_on()) {
+ Tracker tkr(Tracker::Release, thread);
+ tkr.record(addr, size);
+ }
+ }
// record memory type on virtual memory base address
static inline void record_virtual_memory_type(address base, MEMFLAGS flags,
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 19:10:19 2017 +0200
@@ -402,6 +402,14 @@
#define align_size_up_(size, alignment) (((size) + ((alignment) - 1)) & ~((alignment) - 1))
+inline bool is_size_aligned(size_t size, size_t alignment) {
+ return align_size_up_(size, alignment) == size;
+}
+
+inline bool is_ptr_aligned(void* ptr, size_t alignment) {
+ return align_size_up_((intptr_t)ptr, (intptr_t)alignment) == (intptr_t)ptr;
+}
+
inline intptr_t align_size_up(intptr_t size, intptr_t alignment) {
return align_size_up_(size, alignment);
}
@@ -414,6 +422,14 @@
#define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment)))
+inline void* align_ptr_up(void* ptr, size_t alignment) {
+ return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment);
+}
+
+inline void* align_ptr_down(void* ptr, size_t alignment) {
+ return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment);
+}
+
// Align objects by rounding up their size, in HeapWord units.
#define align_object_size_(size) align_size_up_(size, MinObjAlignment)
--- a/hotspot/test/TEST.ROOT Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/test/TEST.ROOT Wed Jul 05 19:10:19 2017 +0200
@@ -25,7 +25,8 @@
# This file identifies the root of the test-suite hierarchy.
# It also contains test-suite configuration information.
-# DO NOT EDIT without first contacting hotspot-regtest@sun.com
# The list of keywords supported in this test suite
keys=cte_test jcmd nmt regression gc
+
+groups=TEST.groups [closed/TEST.groups]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/TEST.groups Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,192 @@
+#
+# 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.
+#
+
+# Profile-based Test Group Definitions
+#
+# These groups define the tests that cover the different possible runtimes:
+# - compact1, compact2, compact3, full JRE, JDK
+#
+# In addition they support testing of the minimal VM on compact1 and compact2.
+# Essentially this defines groups based around the specified API's and VM
+# services available in the runtime.
+#
+# The groups are defined hierarchically in two forms:
+# - The need_xxx groups list all the tests that have a dependency on
+# a specific profile. This is either because it tests a feature in
+# that profile, or the test infrastructure uses a feature in that
+# profile.
+# - The primary groups are defined in terms of the other primary groups
+# combined with the needs_xxx groups (including and excluding them as
+# appropriate). For example the jre can run all tests from compact3, plus
+# those from needs_jre, but excluding those from need_jdk.
+#
+# The bottom group defines all the actual tests to be considered, simply
+# by listing the top-level test directories.
+#
+# To use a group simply list it on the jtreg command line eg:
+# jtreg :jdk
+# runs all tests. While
+# jtreg :compact2
+# runs those tests that only require compact1 and compact2 API's.
+#
+
+# Full JDK can run all tests
+#
+jdk = \
+ :jre \
+ :needs_jdk
+
+# Tests that require a full JDK to execute. Either they test a feature
+# only in the JDK or they use tools that are only in the JDK. The latter
+# can be resolved in some cases by using tools from the compile-jdk.
+#
+needs_jdk = \
+ gc/TestG1ZeroPGCTJcmdThreadPrint.java \
+ gc/metaspace/ClassMetaspaceSizeInJmapHeap.java \
+ gc/metaspace/TestMetaspacePerfCounters.java \
+ runtime/6819213/TestBootNativeLibraryPath.java \
+ runtime/6878713/Test6878713.sh \
+ runtime/6925573/SortMethodsTest.java \
+ runtime/7107135/Test7107135.sh \
+ runtime/7158988/FieldMonitor.java \
+ runtime/7194254/Test7194254.java \
+ runtime/jsig/Test8017498.sh \
+ runtime/Metaspace/FragmentMetaspace.java \
+ runtime/NMT/BaselineWithParameter.java \
+ runtime/NMT/JcmdScale.java \
+ runtime/NMT/JcmdWithNMTDisabled.java \
+ runtime/NMT/MallocTestType.java \
+ runtime/NMT/ReleaseCommittedMemory.java \
+ runtime/NMT/ShutdownTwice.java \
+ runtime/NMT/SummaryAfterShutdown.java \
+ runtime/NMT/SummarySanityCheck.java \
+ runtime/NMT/ThreadedMallocTestType.java \
+ runtime/NMT/ThreadedVirtualAllocTestType.java \
+ runtime/NMT/VirtualAllocTestType.java \
+ runtime/RedefineObject/TestRedefineObject.java \
+ serviceability/attach/AttachWithStalePidFile.java
+
+# JRE adds further tests to compact3
+#
+jre = \
+ :compact3 \
+ :needs_jre \
+ -:needs_jdk
+
+# Tests that require the full JRE
+#
+needs_jre = \
+ compiler/6852078/Test6852078.java \
+ compiler/7047069/Test7047069.java \
+ runtime/6294277/SourceDebugExtension.java
+
+# Compact 3 adds further tests to compact2
+#
+compact3 = \
+ :compact2 \
+ :needs_compact3 \
+ -:needs_jre \
+ -:needs_jdk
+
+
+# Tests that require compact3 API's
+#
+needs_compact3 = \
+ compiler/whitebox/DeoptimizeMethodTest.java \
+ compiler/whitebox/SetForceInlineMethodTest.java \
+ compiler/whitebox/SetDontInlineMethodTest.java \
+ compiler/whitebox/DeoptimizeAllTest.java \
+ compiler/whitebox/MakeMethodNotCompilableTest.java \
+ compiler/whitebox/ClearMethodStateTest.java \
+ compiler/whitebox/EnqueueMethodForCompilationTest.java \
+ compiler/whitebox/IsMethodCompilableTest.java \
+ gc/6581734/Test6581734.java \
+ gc/7072527/TestFullGCCount.java \
+ gc/7168848/HumongousAlloc.java \
+ gc/arguments/TestG1HeapRegionSize.java \
+ gc/metaspace/TestMetaspaceMemoryPool.java \
+ runtime/InternalApi/ThreadCpuTimesDeadlock.java \
+ serviceability/threads/TestFalseDeadLock.java
+
+# Compact 2 adds full VM tests
+compact2 = \
+ :compact2_minimal \
+ :compact1 \
+ :needs_full_vm_compact2 \
+ -:needs_compact3 \
+ -:needs_jre \
+ -:needs_jdk
+
+# Tests that require compact2 API's and a full VM
+#
+needs_full_vm_compact2 =
+
+# Compact 1 adds full VM tests
+#
+compact1 = \
+ :compact1_minimal \
+ :needs_full_vm_compact1 \
+ -:needs_compact2 \
+ -:needs_full_vm_compact2 \
+ -:needs_compact3 \
+ -:needs_jre \
+ -:needs_jdk
+
+# Tests that require compact1 API's and a full VM
+#
+needs_full_vm_compact1 = \
+ runtime/NMT \
+ gc/g1/TestRegionAlignment.java \
+ gc/g1/TestShrinkToOneRegion.java \
+ gc/metaspace/G1AddMetaspaceDependency.java \
+ runtime/6929067/Test6929067.sh
+
+# Minimal VM on Compact 2 adds in some compact2 tests
+#
+compact2_minimal = \
+ :compact1_minimal \
+ :needs_compact2 \
+ -:needs_full_vm_compact2 \
+ -:needs_compact3 \
+ -:needs_jre \
+ -:needs_jdk
+
+# Tests that require compact2 API's
+#
+needs_compact2 = \
+ compiler/6589834/Test_ia32.java
+
+# All tests that run on the most minimal configuration: Minimal VM on Compact 1
+compact1_minimal = \
+ serviceability/ \
+ compiler/ \
+ testlibrary/ \
+ sanity/ \
+ runtime/ \
+ gc/ \
+ -:needs_full_vm_compact1 \
+ -:needs_full_vm_compact2 \
+ -:needs_compact2 \
+ -:needs_compact3 \
+ -:needs_jre \
+ -:needs_jdk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8004051/Test8004051.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * 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 8004051
+ * @bug 8005722
+ * @summary assert(_oprs_len[mode] < maxNumberOfOperands) failed: array overflow
+ *
+ * @run main/othervm -Xcomp -client Test8004051
+ */
+
+public class Test8004051 {
+ public static void main(String[] argv) {
+ Object o = new Object();
+ fillPrimRect(1.1f, 1.2f, 1.3f, 1.4f,
+ o, o,
+ 1.5f, 1.6f, 1.7f, 1.8f,
+ 2.0f, 2.1f, 2.2f, 2.3f,
+ 2.4f, 2.5f, 2.6f, 2.7f,
+ 100, 101);
+ System.out.println("Test passed, test did not assert");
+ }
+
+ static boolean fillPrimRect(float x, float y, float w, float h,
+ Object rectTex, Object wrapTex,
+ float bx, float by, float bw, float bh,
+ float f1, float f2, float f3, float f4,
+ float f5, float f6, float f7, float f8,
+ int i1, int i2 ) {
+ System.out.println(x + " " + y + " " + w + " " + h + " " +
+ bx + " " + by + " " + bw + " " + bh);
+ return true;
+ }
+}
--- a/hotspot/test/runtime/7051189/Xchecksig.sh Thu Aug 29 16:18:31 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-#
-# Copyright (c) 2011, 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 Xchecksig.sh
-# @bug 7051189
-# @summary Need to suppress info message if -xcheck:jni used with libjsig.so
-# @run shell Xchecksig.sh
-#
-
-if [ "${TESTSRC}" = "" ]
-then
- TESTSRC=${PWD}
- echo "TESTSRC not set. Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../test_env.sh
-
-OS=`uname -s`
-case "$OS" in
- Windows_* | CYGWIN_* )
- printf "Not testing libjsig.so on Windows. PASSED.\n "
- exit 0
- ;;
-esac
-
-JAVA=${TESTJAVA}${FS}bin${FS}java
-
-# LD_PRELOAD arch needs to match the binary we run, so run the java
-# 64-bit binary directly if we are testing 64-bit (bin/ARCH/java).
-# Check if TESTVMOPS contains -d64, but cannot use
-# java ${TESTVMOPS} to run "java -d64" with LD_PRELOAD.
-
-if [ ${OS} -eq "SunOS" ]
-then
- printf "SunOS test TESTVMOPTS = ${TESTVMOPTS}"
- printf ${TESTVMOPTS} | grep d64 > /dev/null
- if [ $? -eq 0 ]
- then
- printf "SunOS 64-bit test\n"
- BIT_FLAG=-d64
- fi
-fi
-
-ARCH=`uname -p`
-case $ARCH in
- i386)
- if [ X${BIT_FLAG} != "X" ]
- then
- ARCH=amd64
- JAVA=${TESTJAVA}${FS}bin${FS}${ARCH}${FS}java
- fi
- ;;
- sparc)
- if [ X${BIT_FLAG} != "X" ]
- then
- ARCH=sparcv9
- JAVA=${TESTJAVA}${FS}bin${FS}${ARCH}${FS}java
- fi
- ;;
- * )
- printf "Not testing architecture $ARCH, skipping test.\n"
- exit 0
- ;;
-esac
-
-LIBJSIG=${COMPILEJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so
-
-# If libjsig and binary do not match, skip test.
-
-A=`file ${LIBJSIG} | awk '{ print $3 }'`
-B=`file ${JAVA} | awk '{ print $3 }'`
-
-if [ $A -ne $B ]
-then
- printf "Mismatching binary and library to preload, skipping test.\n"
- exit 0
-fi
-
-if [ ! -f ${LIBJSIG} ]
-then
- printf "Skipping test: libjsig missing for given architecture: ${LIBJSIG}\n"
- exit 0
-fi
-# Use java -version to test, java version info appears on stderr,
-# the libjsig message we are removing appears on stdout.
-
-# grep returns zero meaning found, non-zero means not found:
-
-LD_PRELOAD=${LIBJSIG} ${JAVA} ${TESTVMOPTS} -Xcheck:jni -version 2>&1 | grep "libjsig is activated"
-if [ $? -eq 0 ]; then
- printf "Failed: -Xcheck:jni prints message when libjsig.so is loaded.\n"
- exit 1
-fi
-
-
-LD_PRELOAD=${LIBJSIG} ${JAVA} ${TESTVMOPTS} -Xcheck:jni -verbose:jni -version 2>&1 | grep "libjsig is activated"
-if [ $? != 0 ]; then
- printf "Failed: -Xcheck:jni does not print message when libjsig.so is loaded and -verbose:jni is set.\n"
- exit 1
-fi
-
-printf "PASSED\n"
-exit 0
-
--- a/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java Wed Jul 05 19:10:19 2017 +0200
@@ -45,6 +45,13 @@
String pid = Integer.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
+ boolean has_nmt_detail = wb.NMTIsDetailSupported();
+ if (has_nmt_detail) {
+ System.out.println("NMT detail support detected.");
+ } else {
+ System.out.println("NMT detail support not detected.");
+ }
+
Thread reserveThread = new Thread() {
public void run() {
addr = wb.NMTReserveMemory(reserveSize);
@@ -58,7 +65,9 @@
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=512KB, committed=0KB)");
- output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 512KB for Test");
+ if (has_nmt_detail) {
+ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 512KB for Test");
+ }
Thread commitThread = new Thread() {
public void run() {
@@ -72,7 +81,9 @@
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=512KB, committed=128KB)");
- output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB");
+ if (has_nmt_detail) {
+ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB");
+ }
Thread uncommitThread = new Thread() {
public void run() {
--- a/hotspot/test/runtime/NMT/VirtualAllocTestType.java Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/test/runtime/NMT/VirtualAllocTestType.java Wed Jul 05 19:10:19 2017 +0200
@@ -46,13 +46,22 @@
String pid = Integer.toString(ProcessTools.getProcessId());
ProcessBuilder pb = new ProcessBuilder();
+ boolean has_nmt_detail = wb.NMTIsDetailSupported();
+ if (has_nmt_detail) {
+ System.out.println("NMT detail support detected.");
+ } else {
+ System.out.println("NMT detail support not detected.");
+ }
+
addr = wb.NMTReserveMemory(reserveSize);
mergeData();
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
- pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=0KB)");
- output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 256KB for Test");
+ if (has_nmt_detail) {
+ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + reserveSize) + "\\] reserved 256KB for Test");
+ }
wb.NMTCommitMemory(addr, commitSize);
@@ -60,7 +69,9 @@
output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB, committed=128KB)");
- output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB");
+ if (has_nmt_detail) {
+ output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed 128KB");
+ }
wb.NMTUncommitMemory(addr, commitSize);
@@ -71,7 +82,6 @@
output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" + Long.toHexString(addr + commitSize) + "\\] committed");
wb.NMTReleaseMemory(addr, reserveSize);
-
mergeData();
output = new OutputAnalyzer(pb.start());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/XCheckJniJsig/XCheckJSig.java Wed Jul 05 19:10:19 2017 +0200
@@ -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 7051189 8023393
+ * @summary Need to suppress info message if -Xcheck:jni is used with libjsig.so
+ * @library /testlibrary
+ * @run main XCheckJSig
+ */
+
+import java.util.*;
+import com.oracle.java.testlibrary.*;
+
+public class XCheckJSig {
+ public static void main(String args[]) throws Throwable {
+
+ System.out.println("Regression test for bugs 7051189 and 8023393");
+ if (!Platform.isSolaris() && !Platform.isLinux() && !Platform.isOSX()) {
+ System.out.println("Test only applicable on Solaris, Linux, and Mac OSX, skipping");
+ return;
+ }
+
+ String jdk_path = System.getProperty("test.jdk");
+ String os_arch = Platform.getOsArch();
+ String libjsig;
+ String env_var;
+ if (Platform.isOSX()) {
+ libjsig = jdk_path + "/jre/lib/server/libjsig.dylib";
+ env_var = "DYLD_INSERT_LIBRARIES";
+ } else {
+ libjsig = jdk_path + "/jre/lib/" + os_arch + "/libjsig.so";
+ env_var = "LD_PRELOAD";
+ }
+ String java_program;
+ if (Platform.isSolaris()) {
+ // On Solaris, need to call the 64-bit Java directly in order for
+ // LD_PRELOAD to work because libjsig.so is 64-bit.
+ java_program = jdk_path + "/jre/bin/" + os_arch + "/java";
+ } else {
+ java_program = JDKToolFinder.getJDKTool("java");
+ }
+ // If this test fails, these might be useful to know.
+ System.out.println("libjsig: " + libjsig);
+ System.out.println("osArch: " + os_arch);
+ System.out.println("java_program: " + java_program);
+
+ ProcessBuilder pb = new ProcessBuilder(java_program, "-Xcheck:jni", "-version");
+ Map<String, String> env = pb.environment();
+ env.put(env_var, libjsig);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("libjsig is activated");
+ output.shouldHaveExitValue(0);
+
+ pb = new ProcessBuilder(java_program, "-Xcheck:jni", "-verbose:jni", "-version");
+ env = pb.environment();
+ env.put(env_var, libjsig);
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("libjsig is activated");
+ output.shouldHaveExitValue(0);
+ }
+}
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Thu Aug 29 16:18:31 2013 -0700
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Jul 05 19:10:19 2017 +0200
@@ -90,6 +90,7 @@
public native void NMTUncommitMemory(long addr, long size);
public native void NMTReleaseMemory(long addr, long size);
public native boolean NMTWaitForDataMerge();
+ public native boolean NMTIsDetailSupported();
// Compiler
public native void deoptimizeAll();
--- a/jaxp/.hgtags Thu Aug 29 16:18:31 2013 -0700
+++ b/jaxp/.hgtags Wed Jul 05 19:10:19 2017 +0200
@@ -226,3 +226,4 @@
7cffafa606e9fb865e7b5e6a56e0a681ce5cf617 jdk8-b102
b1ceab582fc6d795b20aaa8a3fde2eba34af9399 jdk8-b103
a22fe9bd01e6c7e7ddc7995dfc9471711692b8d1 jdk8-b104
+09a46ec11f880154886c70be03aff5ab2ddf0ab7 jdk8-b105
--- a/jdk/.hgtags Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/.hgtags Wed Jul 05 19:10:19 2017 +0200
@@ -226,3 +226,4 @@
8ed8e2b4b90e0ac9aa5b3efef51cd576a9db96a9 jdk8-b102
e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103
f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104
+1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105
--- a/jdk/make/com/sun/security/auth/FILES_java.gmk Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/make/com/sun/security/auth/FILES_java.gmk Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,6 @@
com/sun/security/auth/UserPrincipal.java \
com/sun/security/auth/LdapPrincipal.java \
com/sun/security/auth/PolicyFile.java \
- com/sun/security/auth/SubjectCodeSource.java \
- com/sun/security/auth/PolicyParser.java \
com/sun/security/auth/PrincipalComparator.java \
com/sun/security/auth/callback/TextCallbackHandler.java \
com/sun/security/auth/callback/DialogCallbackHandler.java
--- a/jdk/makefiles/Profiles.gmk Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/makefiles/Profiles.gmk Wed Jul 05 19:10:19 2017 +0200
@@ -65,10 +65,6 @@
$(if $(PROFILE_2_JRE_JAR_FILES), $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_2_JRE_JAR_FILES))) \
$(PROFILE_1_JARS)
-ifneq ($(ENABLE_JFR), true)
- PROFILE_3_JRE_JAR_FILES := $(filter-out jfr.jar, $(PROFILE_3_JRE_JAR_FILES))
-endif
-
PROFILE_3_JARS := \
$(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \
$(PROFILE_2_JARS)
@@ -77,6 +73,10 @@
FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES))
endif
+ifneq ($(ENABLE_JFR), true)
+ FULL_JRE_JAR_FILES := $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES))
+endif
+
FULL_JRE_JARS := \
$(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(FULL_JRE_JAR_FILES)) \
$(PROFILE_3_JARS)
--- a/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Wed Jul 05 19:10:19 2017 +0200
@@ -87,6 +87,7 @@
private int incomingInterruptFD;
static {
+ IOUtil.load();
initStructSizes();
String datamodel = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.arch.data.model")
--- a/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -246,9 +246,4 @@
}
return this;
}
-
-
- static {
- Util.load();
- }
}
--- a/jdk/src/share/back/SDE.c Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/back/SDE.c Wed Jul 05 19:10:19 2017 +0200
@@ -28,6 +28,12 @@
#include "util.h"
#include "SDE.h"
+#ifdef __APPLE__
+/* use setjmp/longjmp versions that do not save/restore the signal mask */
+#define setjmp _setjmp
+#define longjmp _longjmp
+#endif
+
/**
* This SourceDebugExtension code does not
* allow concurrent translation - due to caching method.
--- a/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/com/sun/tools/attach/VirtualMachine.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, 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
@@ -59,7 +59,7 @@
* {@link java.lang.instrument} for a detailed description on how these agents
* are loaded and started). The {@link #loadAgentLibrary loadAgentLibrary} and
* {@link #loadAgentPath loadAgentPath} methods are used to load agents that
- * are deployed in a dynamic library and make use of the <a
+ * are deployed either in a dynamic library or statically linked into the VM and make use of the <a
* href="../../../../../../../../technotes/guides/jvmti/index.html">JVM Tools
* Interface</a>. </p>
*
@@ -298,25 +298,29 @@
* <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM
* TI</a> client is called an <i>agent</i>. It is developed in a native language.
* A JVM TI agent is deployed in a platform specific manner but it is typically the
- * platform equivalent of a dynamic library. This method causes the given agent
- * library to be loaded into the target VM (if not already loaded).
+ * platform equivalent of a dynamic library. Alternatively, it may be statically linked into the VM.
+ * This method causes the given agent library to be loaded into the target
+ * VM (if not already loaded or if not statically linked into the VM).
* It then causes the target VM to invoke the <code>Agent_OnAttach</code> function
+ * or, for a statically linked agent named 'L', the <code>Agent_OnAttach_L</code> function
* as specified in the
* <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools
- * Interface</a> specification. Note that the <code>Agent_OnAttach</code>
+ * Interface</a> specification. Note that the <code>Agent_OnAttach[_L]</code>
* function is invoked even if the agent library was loaded prior to invoking
* this method.
*
* <p> The agent library provided is the name of the agent library. It is interpreted
* in the target virtual machine in an implementation-dependent manner. Typically an
* implementation will expand the library name into an operating system specific file
- * name. For example, on UNIX systems, the name <tt>foo</tt> might be expanded to
- * <tt>libfoo.so</tt>, and located using the search path specified by the
- * <tt>LD_LIBRARY_PATH</tt> environment variable.</p>
+ * name. For example, on UNIX systems, the name <tt>L</tt> might be expanded to
+ * <tt>libL.so</tt>, and located using the search path specified by the
+ * <tt>LD_LIBRARY_PATH</tt> environment variable. If the agent named 'L' is
+ * statically linked into the VM then the VM must export a function named
+ * <code>Agent_OnAttach_L</code>.</p>
*
- * <p> If the <code>Agent_OnAttach</code> function in the agent library returns
+ * <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns
* an error then an {@link com.sun.tools.attach.AgentInitializationException} is
- * thrown. The return value from the <code>Agent_OnAttach</code> can then be
+ * thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be
* obtained by invoking the {@link
* com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}
* method on the exception. </p>
@@ -325,15 +329,16 @@
* The name of the agent library.
*
* @param options
- * The options to provide to the <code>Agent_OnAttach</code>
+ * The options to provide to the <code>Agent_OnAttach[_L]</code>
* function (can be <code>null</code>).
*
* @throws AgentLoadException
- * If the agent library does not exist, or cannot be loaded for
- * another reason.
+ * If the agent library does not exist, the agent library is not
+ * statically linked with the VM, or the agent library cannot be
+ * loaded for another reason.
*
* @throws AgentInitializationException
- * If the <code>Agent_OnAttach</code> function returns an error
+ * If the <code>Agent_OnAttach[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
@@ -359,11 +364,12 @@
* The name of the agent library.
*
* @throws AgentLoadException
- * If the agent library does not exist, or cannot be loaded for
- * another reason.
+ * If the agent library does not exist, the agent library is not
+ * statically linked with the VM, or the agent library cannot be
+ * loaded for another reason.
*
* @throws AgentInitializationException
- * If the <code>Agent_OnAttach</code> function returns an error
+ * If the <code>Agent_OnAttach[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
@@ -383,12 +389,23 @@
* <p> A <a href="../../../../../../../../technotes/guides/jvmti/index.html">JVM
* TI</a> client is called an <i>agent</i>. It is developed in a native language.
* A JVM TI agent is deployed in a platform specific manner but it is typically the
- * platform equivalent of a dynamic library. This method causes the given agent
- * library to be loaded into the target VM (if not already loaded).
- * It then causes the target VM to invoke the <code>Agent_OnAttach</code> function
- * as specified in the
+ * platform equivalent of a dynamic library. Alternatively, the native
+ * library specified by the agentPath parameter may be statically
+ * linked with the VM. The parsing of the agentPath parameter into
+ * a statically linked library name is done in a platform
+ * specific manner in the VM. For example, in UNIX, an agentPath parameter
+ * of <code>/a/b/libL.so</code> would name a library 'L'.
+ *
+ * See the JVM TI Specification for more details.
+ *
+ * This method causes the given agent library to be loaded into the target
+ * VM (if not already loaded or if not statically linked into the VM).
+ * It then causes the target VM to invoke the <code>Agent_OnAttach</code>
+ * function or, for a statically linked agent named 'L', the
+ * <code>Agent_OnAttach_L</code> function as specified in the
* <a href="../../../../../../../../technotes/guides/jvmti/index.html"> JVM Tools
- * Interface</a> specification. Note that the <code>Agent_OnAttach</code>
+ * Interface</a> specification.
+ * Note that the <code>Agent_OnAttach[_L]</code>
* function is invoked even if the agent library was loaded prior to invoking
* this method.
*
@@ -396,9 +413,9 @@
* agent library. Unlike {@link #loadAgentLibrary loadAgentLibrary}, the library name
* is not expanded in the target virtual machine. </p>
*
- * <p> If the <code>Agent_OnAttach</code> function in the agent library returns
+ * <p> If the <code>Agent_OnAttach[_L]</code> function in the agent library returns
* an error then an {@link com.sun.tools.attach.AgentInitializationException} is
- * thrown. The return value from the <code>Agent_OnAttach</code> can then be
+ * thrown. The return value from the <code>Agent_OnAttach[_L]</code> can then be
* obtained by invoking the {@link
* com.sun.tools.attach.AgentInitializationException#returnValue() returnValue}
* method on the exception. </p>
@@ -407,15 +424,16 @@
* The full path of the agent library.
*
* @param options
- * The options to provide to the <code>Agent_OnAttach</code>
+ * The options to provide to the <code>Agent_OnAttach[_L]</code>
* function (can be <code>null</code>).
*
* @throws AgentLoadException
- * If the agent library does not exist, or cannot be loaded for
- * another reason.
+ * If the agent library does not exist, the agent library is not
+ * statically linked with the VM, or the agent library cannot be
+ * loaded for another reason.
*
* @throws AgentInitializationException
- * If the <code>Agent_OnAttach</code> function returns an error
+ * If the <code>Agent_OnAttach[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
@@ -441,11 +459,12 @@
* The full path to the agent library.
*
* @throws AgentLoadException
- * If the agent library does not exist, or cannot be loaded for
- * another reason.
+ * If the agent library does not exist, the agent library is not
+ * statically linked with the VM, or the agent library cannot be
+ * loaded for another reason.
*
* @throws AgentInitializationException
- * If the <code>Agent_OnAttach</code> function returns an error
+ * If the <code>Agent_OnAttach[_L]</code> function returns an error.
*
* @throws IOException
* If an I/O error occurs
--- a/jdk/src/share/classes/java/io/BufferedInputStream.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/io/BufferedInputStream.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -50,7 +50,15 @@
public
class BufferedInputStream extends FilterInputStream {
- private static int defaultBufferSize = 8192;
+ private static int DEFAULT_BUFFER_SIZE = 8192;
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/**
* The internal buffer array where the data is stored. When necessary,
@@ -172,7 +180,7 @@
* @param in the underlying input stream.
*/
public BufferedInputStream(InputStream in) {
- this(in, defaultBufferSize);
+ this(in, DEFAULT_BUFFER_SIZE);
}
/**
@@ -215,8 +223,11 @@
} else if (buffer.length >= marklimit) {
markpos = -1; /* buffer got too big, invalidate mark */
pos = 0; /* drop buffer contents */
+ } else if (buffer.length >= MAX_BUFFER_SIZE) {
+ throw new OutOfMemoryError("Required array size too large");
} else { /* grow buffer */
- int nsz = pos * 2;
+ int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
+ pos * 2 : MAX_BUFFER_SIZE;
if (nsz > marklimit)
nsz = marklimit;
byte nbuf[] = new byte[nsz];
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Wed Jul 05 19:10:19 2017 +0200
@@ -1307,7 +1307,7 @@
* specified substring, starting at the specified index. The integer
* returned is the smallest value {@code k} for which:
* <blockquote><pre>
- * k >= Math.min(fromIndex, str.length()) &&
+ * k >= Math.min(fromIndex, this.length()) &&
* this.toString().startsWith(str, k)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then -1 is returned.
@@ -1346,7 +1346,7 @@
* specified substring. The integer returned is the largest value <i>k</i>
* such that:
* <blockquote><pre>
- * k <= Math.min(fromIndex, str.length()) &&
+ * k <= Math.min(fromIndex, this.length()) &&
* this.toString().startsWith(str, k)
* </pre></blockquote>
* If no such value of <i>k</i> exists, then -1 is returned.
--- a/jdk/src/share/classes/java/lang/Class.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/lang/Class.java Wed Jul 05 19:10:19 2017 +0200
@@ -3338,8 +3338,16 @@
* @since 1.8
*/
public AnnotatedType getAnnotatedSuperclass() {
- return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
-}
+ if (this == Object.class ||
+ isInterface() ||
+ isArray() ||
+ isPrimitive() ||
+ this == Void.TYPE) {
+ return null;
+ }
+
+ return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
+ }
/**
* Returns an array of AnnotatedType objects that represent the use of types to
--- a/jdk/src/share/classes/java/lang/Math.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/lang/Math.java Wed Jul 05 19:10:19 2017 +0200
@@ -698,11 +698,8 @@
return 0;
}
- private static Random randomNumberGenerator;
-
- private static synchronized Random initRNG() {
- Random rnd = randomNumberGenerator;
- return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
+ private static final class RandomNumberGeneratorHolder {
+ static final Random randomNumberGenerator = new Random();
}
/**
@@ -729,9 +726,7 @@
* @see Random#nextDouble()
*/
public static double random() {
- Random rnd = randomNumberGenerator;
- if (rnd == null) rnd = initRNG();
- return rnd.nextDouble();
+ return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
/**
--- a/jdk/src/share/classes/java/lang/ProcessBuilder.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java Wed Jul 05 19:10:19 2017 +0200
@@ -29,7 +29,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.security.AccessControlException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
@@ -1033,9 +1032,9 @@
// Can not disclose the fail reason for read-protected files.
try {
security.checkRead(prog);
- } catch (AccessControlException ace) {
+ } catch (SecurityException se) {
exceptionInfo = "";
- cause = ace;
+ cause = se;
}
}
// It's much easier for us to create a high-quality error
--- a/jdk/src/share/classes/java/lang/StrictMath.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/lang/StrictMath.java Wed Jul 05 19:10:19 2017 +0200
@@ -678,11 +678,8 @@
return Math.round(a);
}
- private static Random randomNumberGenerator;
-
- private static synchronized Random initRNG() {
- Random rnd = randomNumberGenerator;
- return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd;
+ private static final class RandomNumberGeneratorHolder {
+ static final Random randomNumberGenerator = new Random();
}
/**
@@ -709,9 +706,7 @@
* @see Random#nextDouble()
*/
public static double random() {
- Random rnd = randomNumberGenerator;
- if (rnd == null) rnd = initRNG();
- return rnd.nextDouble();
+ return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
/**
--- a/jdk/src/share/classes/java/math/BigDecimal.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/math/BigDecimal.java Wed Jul 05 19:10:19 2017 +0200
@@ -2659,28 +2659,32 @@
if (ys == 0)
return 1;
- int sdiff = this.scale - val.scale;
+ long sdiff = (long)this.scale - val.scale;
if (sdiff != 0) {
// Avoid matching scales if the (adjusted) exponents differ
- int xae = this.precision() - this.scale; // [-1]
- int yae = val.precision() - val.scale; // [-1]
+ long xae = (long)this.precision() - this.scale; // [-1]
+ long yae = (long)val.precision() - val.scale; // [-1]
if (xae < yae)
return -1;
if (xae > yae)
return 1;
BigInteger rb = null;
if (sdiff < 0) {
- if ( (xs == INFLATED ||
- (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) &&
+ // The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
+ if ( sdiff > Integer.MIN_VALUE &&
+ (xs == INFLATED ||
+ (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) &&
ys == INFLATED) {
- rb = bigMultiplyPowerTen(-sdiff);
+ rb = bigMultiplyPowerTen((int)-sdiff);
return rb.compareMagnitude(val.intVal);
}
} else { // sdiff > 0
- if ( (ys == INFLATED ||
- (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) &&
+ // The cases sdiff > Integer.MAX_VALUE intentionally fall through.
+ if ( sdiff <= Integer.MAX_VALUE &&
+ (ys == INFLATED ||
+ (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) &&
xs == INFLATED) {
- rb = val.bigMultiplyPowerTen(sdiff);
+ rb = val.bigMultiplyPowerTen((int)sdiff);
return this.intVal.compareMagnitude(rb);
}
}
@@ -4545,7 +4549,7 @@
if(cmp > 0) { // satisfy constraint (b)
yscale -= 1; // [that is, divisor *= 10]
int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
- if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+ if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
// assert newScale >= xscale
int raise = checkScaleNonZero((long) mcp + yscale - xscale);
long scaledXs;
@@ -4626,7 +4630,7 @@
// return BigDecimal object whose scale will be set to 'scl'.
int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
BigDecimal quotient;
- if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+ if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
int raise = checkScaleNonZero((long) mcp + yscale - xscale);
long scaledXs;
if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
@@ -4673,7 +4677,7 @@
// return BigDecimal object whose scale will be set to 'scl'.
BigDecimal quotient;
int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
- if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+ if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
int raise = checkScaleNonZero((long) mcp + yscale - xscale);
BigInteger rb = bigMultiplyPowerTen(xs,raise);
quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
@@ -4714,7 +4718,7 @@
// return BigDecimal object whose scale will be set to 'scl'.
BigDecimal quotient;
int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
- if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+ if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
int raise = checkScaleNonZero((long) mcp + yscale - xscale);
BigInteger rb = bigMultiplyPowerTen(xs,raise);
quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
@@ -4745,7 +4749,7 @@
// return BigDecimal object whose scale will be set to 'scl'.
BigDecimal quotient;
int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
- if (checkScaleNonZero((long) mcp + yscale) > xscale) {
+ if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
int raise = checkScaleNonZero((long) mcp + yscale - xscale);
BigInteger rb = bigMultiplyPowerTen(xs,raise);
quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
--- a/jdk/src/share/classes/java/math/BigInteger.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/math/BigInteger.java Wed Jul 05 19:10:19 2017 +0200
@@ -2109,7 +2109,7 @@
// This is a quick way to approximate the size of the result,
// similar to doing log2[n] * exponent. This will give an upper bound
// of how big the result can be, and which algorithm to use.
- int scaleFactor = remainingBits * exponent;
+ long scaleFactor = (long)remainingBits * exponent;
// Use slightly different algorithms for small and large operands.
// See if the result will safely fit into a long. (Largest 2^63-1)
--- a/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/rmi/server/RMISocketFactory.java Wed Jul 05 19:10:19 2017 +0200
@@ -50,13 +50,13 @@
* @implNote
* <p>You can use the {@code RMISocketFactory} class to create a server socket that
* is bound to a specific address, restricting the origin of requests. For example,
- * the following code implements a socket factory that binds server sockets to the
+ * the following code implements a socket factory that binds server sockets to an IPv4
* loopback address. This restricts RMI to processing requests only from the local host.
*
* <pre>{@code
* class LoopbackSocketFactory extends RMISocketFactory {
* public ServerSocket createServerSocket(int port) throws IOException {
- * return new ServerSocket(port, 5, InetAddress.getLoopbackAddress());
+ * return new ServerSocket(port, 5, InetAddress.getByName("127.0.0.1"));
* }
*
* public Socket createSocket(String host, int port) throws IOException {
@@ -72,8 +72,8 @@
* }</pre>
*
* Set the {@code java.rmi.server.hostname} system property
- * to a host name (typically {@code localhost}) that resolves to the loopback
- * interface to ensure that the generated stubs use the right network interface.
+ * to {@code 127.0.0.1} to ensure that the generated stubs connect to the right
+ * network interface.
*
* @author Ann Wollrath
* @author Peter Jones
--- a/jdk/src/share/classes/java/util/Collections.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/Collections.java Wed Jul 05 19:10:19 2017 +0200
@@ -27,7 +27,6 @@
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.IOException;
-import java.io.InvalidObjectException;
import java.lang.reflect.Array;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -35,6 +34,7 @@
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
+import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@@ -1148,7 +1148,16 @@
public Spliterator<E> spliterator() {
return (Spliterator<E>)c.spliterator();
}
-
+ @SuppressWarnings("unchecked")
+ @Override
+ public Stream<E> stream() {
+ return (Stream<E>)c.stream();
+ }
+ @SuppressWarnings("unchecked")
+ @Override
+ public Stream<E> parallelStream() {
+ return (Stream<E>)c.parallelStream();
+ }
}
/**
@@ -2009,8 +2018,8 @@
* through the returned collection.<p>
*
* It is imperative that the user manually synchronize on the returned
- * collection when traversing it via {@link Iterator} or
- * {@link Spliterator}:
+ * collection when traversing it via {@link Iterator}, {@link Spliterator}
+ * or {@link Stream}:
* <pre>
* Collection c = Collections.synchronizedCollection(myCollection);
* ...
@@ -2120,6 +2129,14 @@
public Spliterator<E> spliterator() {
return c.spliterator(); // Must be manually synched by user!
}
+ @Override
+ public Stream<E> stream() {
+ return c.stream(); // Must be manually synched by user!
+ }
+ @Override
+ public Stream<E> parallelStream() {
+ return c.parallelStream(); // Must be manually synched by user!
+ }
private void writeObject(ObjectOutputStream s) throws IOException {
synchronized (mutex) {s.defaultWriteObject();}
}
@@ -3172,6 +3189,10 @@
}
@Override
public Spliterator<E> spliterator() {return c.spliterator();}
+ @Override
+ public Stream<E> stream() {return c.stream();}
+ @Override
+ public Stream<E> parallelStream() {return c.parallelStream();}
}
/**
@@ -5096,6 +5117,22 @@
") > toIndex(" + toIndex + ")");
return new CopiesList<>(toIndex - fromIndex, element);
}
+
+ // Override default methods in Collection
+ @Override
+ public Stream<E> stream() {
+ return IntStream.range(0, n).mapToObj(i -> element);
+ }
+
+ @Override
+ public Stream<E> parallelStream() {
+ return IntStream.range(0, n).parallel().mapToObj(i -> element);
+ }
+
+ @Override
+ public Spliterator<E> spliterator() {
+ return stream().spliterator();
+ }
}
/**
@@ -5503,6 +5540,10 @@
@Override
public Spliterator<E> spliterator() {return s.spliterator();}
+ @Override
+ public Stream<E> stream() {return s.stream();}
+ @Override
+ public Stream<E> parallelStream() {return s.parallelStream();}
private static final long serialVersionUID = 2454657854757543876L;
@@ -5568,10 +5609,14 @@
@Override
public void forEach(Consumer<? super E> action) {q.forEach(action);}
@Override
- public Spliterator<E> spliterator() {return q.spliterator();}
- @Override
public boolean removeIf(Predicate<? super E> filter) {
return q.removeIf(filter);
}
+ @Override
+ public Spliterator<E> spliterator() {return q.spliterator();}
+ @Override
+ public Stream<E> stream() {return q.stream();}
+ @Override
+ public Stream<E> parallelStream() {return q.parallelStream();}
}
}
--- a/jdk/src/share/classes/java/util/ComparableTimSort.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/ComparableTimSort.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009 Google Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -146,7 +147,7 @@
*/
int stackLen = (len < 120 ? 5 :
len < 1542 ? 10 :
- len < 119151 ? 19 : 40);
+ len < 119151 ? 24 : 40);
runBase = new int[stackLen];
runLen = new int[stackLen];
}
--- a/jdk/src/share/classes/java/util/Comparator.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparator.java Wed Jul 05 19:10:19 2017 +0200
@@ -199,7 +199,7 @@
* composed using following code,
*
* <pre>{@code
- * Comparator<String> cmp = Comparator.comparing(String::length)
+ * Comparator<String> cmp = Comparator.comparingInt(String::length)
* .thenComparing(String.CASE_INSENSITIVE_ORDER);
* }</pre>
*
@@ -270,18 +270,18 @@
* extracts a {@code int} sort key.
*
* @implSpec This default implementation behaves as if {@code
- * thenComparing(comparing(keyExtractor))}.
+ * thenComparing(comparingInt(keyExtractor))}.
*
* @param keyExtractor the function used to extract the integer sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code int} sort key
* @throws NullPointerException if the argument is null.
- * @see #comparing(ToIntFunction)
+ * @see #comparingInt(ToIntFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
- default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
- return thenComparing(comparing(keyExtractor));
+ default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
+ return thenComparing(comparingInt(keyExtractor));
}
/**
@@ -289,18 +289,18 @@
* extracts a {@code long} sort key.
*
* @implSpec This default implementation behaves as if {@code
- * thenComparing(comparing(keyExtractor))}.
+ * thenComparing(comparingLong(keyExtractor))}.
*
* @param keyExtractor the function used to extract the long sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code long} sort key
* @throws NullPointerException if the argument is null.
- * @see #comparing(ToLongFunction)
+ * @see #comparingLong(ToLongFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
- default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
- return thenComparing(comparing(keyExtractor));
+ default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
+ return thenComparing(comparingLong(keyExtractor));
}
/**
@@ -308,18 +308,18 @@
* extracts a {@code double} sort key.
*
* @implSpec This default implementation behaves as if {@code
- * thenComparing(comparing(keyExtractor))}.
+ * thenComparing(comparingDouble(keyExtractor))}.
*
* @param keyExtractor the function used to extract the double sort key
* @return a lexicographic-order comparator composed of this and then the
* {@code double} sort key
* @throws NullPointerException if the argument is null.
- * @see #comparing(ToDoubleFunction)
+ * @see #comparingDouble(ToDoubleFunction)
* @see #thenComparing(Comparator)
* @since 1.8
*/
- default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
- return thenComparing(comparing(keyExtractor));
+ default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
+ return thenComparing(comparingDouble(keyExtractor));
}
/**
@@ -484,7 +484,7 @@
* @throws NullPointerException if the argument is null
* @since 1.8
*/
- public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
+ public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
@@ -505,7 +505,7 @@
* @throws NullPointerException if the argument is null
* @since 1.8
*/
- public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
+ public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
@@ -526,7 +526,7 @@
* @throws NullPointerException if the argument is null
* @since 1.8
*/
- public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
+ public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
--- a/jdk/src/share/classes/java/util/Random.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/Random.java Wed Jul 05 19:10:19 2017 +0200
@@ -26,9 +26,13 @@
package java.util;
import java.io.*;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
+import java.util.stream.StreamSupport;
import sun.misc.Unsafe;
@@ -85,6 +89,13 @@
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
+ private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+
+ // IllegalArgumentException messages
+ static final String BadBound = "bound must be positive";
+ static final String BadRange = "bound must be greater than origin";
+ static final String BadSize = "size must be non-negative";
+
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
@@ -222,6 +233,82 @@
}
/**
+ * The form of nextLong used by LongStream Spliterators. If
+ * origin is greater than bound, acts as unbounded form of
+ * nextLong, else as bounded form.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final long internalNextLong(long origin, long bound) {
+ long r = nextLong();
+ if (origin < bound) {
+ long n = bound - origin, m = n - 1;
+ if ((n & m) == 0L) // power of two
+ r = (r & m) + origin;
+ else if (n > 0L) { // reject over-represented candidates
+ for (long u = r >>> 1; // ensure nonnegative
+ u + m - (r = u % n) < 0L; // rejection check
+ u = nextLong() >>> 1) // retry
+ ;
+ r += origin;
+ }
+ else { // range not representable as long
+ while (r < origin || r >= bound)
+ r = nextLong();
+ }
+ }
+ return r;
+ }
+
+ /**
+ * The form of nextInt used by IntStream Spliterators.
+ * For the unbounded case: uses nextInt().
+ * For the bounded case with representable range: uses nextInt(int bound)
+ * For the bounded case with unrepresentable range: uses nextInt()
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final int internalNextInt(int origin, int bound) {
+ if (origin < bound) {
+ int n = bound - origin;
+ if (n > 0) {
+ return nextInt(n) + origin;
+ }
+ else { // range not representable as int
+ int r;
+ do {
+ r = nextInt();
+ } while (r < origin || r >= bound);
+ return r;
+ }
+ }
+ else {
+ return nextInt();
+ }
+ }
+
+ /**
+ * The form of nextDouble used by DoubleStream Spliterators.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final double internalNextDouble(double origin, double bound) {
+ double r = nextDouble();
+ if (origin < bound) {
+ r = r * (bound - origin) + origin;
+ if (r >= bound) // correct for rounding
+ r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+ }
+ return r;
+ }
+
+ /**
* Returns the next pseudorandom, uniformly distributed {@code int}
* value from this random number generator's sequence. The general
* contract of {@code nextInt} is that one {@code int} value is
@@ -247,23 +334,23 @@
* between 0 (inclusive) and the specified value (exclusive), drawn from
* this random number generator's sequence. The general contract of
* {@code nextInt} is that one {@code int} value in the specified range
- * is pseudorandomly generated and returned. All {@code n} possible
+ * is pseudorandomly generated and returned. All {@code bound} possible
* {@code int} values are produced with (approximately) equal
- * probability. The method {@code nextInt(int n)} is implemented by
+ * probability. The method {@code nextInt(int bound)} is implemented by
* class {@code Random} as if by:
* <pre> {@code
- * public int nextInt(int n) {
- * if (n <= 0)
- * throw new IllegalArgumentException("n must be positive");
+ * public int nextInt(int bound) {
+ * if (bound <= 0)
+ * throw new IllegalArgumentException("bound must be positive");
*
- * if ((n & -n) == n) // i.e., n is a power of 2
- * return (int)((n * (long)next(31)) >> 31);
+ * if ((bound & -bound) == bound) // i.e., bound is a power of 2
+ * return (int)((bound * (long)next(31)) >> 31);
*
* int bits, val;
* do {
* bits = next(31);
- * val = bits % n;
- * } while (bits - val + (n-1) < 0);
+ * val = bits % bound;
+ * } while (bits - val + (bound-1) < 0);
* return val;
* }}</pre>
*
@@ -289,28 +376,28 @@
* greatly increases the length of the sequence of values returned by
* successive calls to this method if n is a small power of two.
*
- * @param n the bound on the random number to be returned. Must be
- * positive.
+ * @param bound the upper bound (exclusive). Must be positive.
* @return the next pseudorandom, uniformly distributed {@code int}
- * value between {@code 0} (inclusive) and {@code n} (exclusive)
+ * value between zero (inclusive) and {@code bound} (exclusive)
* from this random number generator's sequence
- * @throws IllegalArgumentException if n is not positive
+ * @throws IllegalArgumentException if bound is not positive
* @since 1.2
*/
-
- public int nextInt(int n) {
- if (n <= 0)
- throw new IllegalArgumentException("n must be positive");
+ public int nextInt(int bound) {
+ if (bound <= 0)
+ throw new IllegalArgumentException(BadBound);
- if ((n & -n) == n) // i.e., n is a power of 2
- return (int)((n * (long)next(31)) >> 31);
-
- int bits, val;
- do {
- bits = next(31);
- val = bits % n;
- } while (bits - val + (n-1) < 0);
- return val;
+ int r = next(31);
+ int m = bound - 1;
+ if ((bound & m) == 0) // i.e., bound is a power of 2
+ r = (int)((bound * (long)r) >> 31);
+ else {
+ for (int u = r;
+ u - (r = u % bound) + m < 0;
+ u = next(31))
+ ;
+ }
+ return r;
}
/**
@@ -442,8 +529,7 @@
* @see Math#random
*/
public double nextDouble() {
- return (((long)(next(26)) << 27) + next(27))
- / (double)(1L << 53);
+ return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
private double nextNextGaussian;
@@ -513,57 +599,563 @@
}
}
+ // stream methods, coded in a way intended to better isolate for
+ // maintenance purposes the small differences across forms.
+
/**
- * Returns a stream of pseudorandom, uniformly distributed
- * {@code integer} values from this random number generator's
- * sequence. Values are obtained as needed by calling
- * {@link #nextInt()}.
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code int} values.
+ *
+ * <p>A pseudorandom {@code int} value is generated as if it's the result of
+ * calling the method {@link #nextInt()}.
*
- * @return an infinite stream of {@code integer} values
+ * @param streamSize the number of values to generate
+ * @return a stream of pseudorandom {@code int} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @since 1.8
+ */
+ public IntStream ints(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, streamSize, Integer.MAX_VALUE, 0),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code int}
+ * values.
+ *
+ * <p>A pseudorandom {@code int} value is generated as if it's the result of
+ * calling the method {@link #nextInt()}.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * ints(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code int} values
* @since 1.8
*/
public IntStream ints() {
- return IntStream.generate(this::nextInt);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number
+ * of pseudorandom {@code int} values, each conforming to the given
+ * origin (inclusive) and bound (exclusive).
+ *
+ * <p>A pseudorandom {@code int} value is generated as if it's the result of
+ * calling the following method with the origin and bound:
+ * <pre> {@code
+ * int nextInt(int origin, int bound) {
+ * int n = bound - origin;
+ * if (n > 0) {
+ * return nextInt(n) + origin;
+ * }
+ * else { // range not representable as int
+ * int r;
+ * do {
+ * r = nextInt();
+ * } while (r < origin || r >= bound);
+ * return r;
+ * }
+ * }}</pre>
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code int} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public IntStream ints(long streamSize, int randomNumberOrigin,
+ int randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
}
/**
- * Returns a stream of pseudorandom, uniformly distributed
- * {@code long} values from this random number generator's
- * sequence. Values are obtained as needed by calling
- * {@link #nextLong()}.
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * int} values, each conforming to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * <p>A pseudorandom {@code int} value is generated as if it's the result of
+ * calling the following method with the origin and bound:
+ * <pre> {@code
+ * int nextInt(int origin, int bound) {
+ * int n = bound - origin;
+ * if (n > 0) {
+ * return nextInt(n) + origin;
+ * }
+ * else { // range not representable as int
+ * int r;
+ * do {
+ * r = nextInt();
+ * } while (r < origin || r >= bound);
+ * return r;
+ * }
+ * }}</pre>
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
- * @return an infinite stream of {@code long} values
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code int} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code long} values.
+ *
+ * <p>A pseudorandom {@code long} value is generated as if it's the result
+ * of calling the method {@link #nextLong()}.
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of pseudorandom {@code long} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @since 1.8
+ */
+ public LongStream longs(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, streamSize, Long.MAX_VALUE, 0L),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code long}
+ * values.
+ *
+ * <p>A pseudorandom {@code long} value is generated as if it's the result
+ * of calling the method {@link #nextLong()}.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code long} values
* @since 1.8
*/
public LongStream longs() {
- return LongStream.generate(this::nextLong);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code long}, each conforming to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * <p>A pseudorandom {@code long} value is generated as if it's the result
+ * of calling the following method with the origin and bound:
+ * <pre> {@code
+ * long nextLong(long origin, long bound) {
+ * long r = nextLong();
+ * long n = bound - origin, m = n - 1;
+ * if ((n & m) == 0L) // power of two
+ * r = (r & m) + origin;
+ * else if (n > 0L) { // reject over-represented candidates
+ * for (long u = r >>> 1; // ensure nonnegative
+ * u + m - (r = u % n) < 0L; // rejection check
+ * u = nextLong() >>> 1) // retry
+ * ;
+ * r += origin;
+ * }
+ * else { // range not representable as long
+ * while (r < origin || r >= bound)
+ * r = nextLong();
+ * }
+ * return r;
+ * }}</pre>
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code long} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public LongStream longs(long streamSize, long randomNumberOrigin,
+ long randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
}
/**
- * Returns a stream of pseudorandom, uniformly distributed
- * {@code double} values between {@code 0.0} and {@code 1.0}
- * from this random number generator's sequence. Values are
- * obtained as needed by calling {@link #nextDouble()}.
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * long} values, each conforming to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * <p>A pseudorandom {@code long} value is generated as if it's the result
+ * of calling the following method with the origin and bound:
+ * <pre> {@code
+ * long nextLong(long origin, long bound) {
+ * long r = nextLong();
+ * long n = bound - origin, m = n - 1;
+ * if ((n & m) == 0L) // power of two
+ * r = (r & m) + origin;
+ * else if (n > 0L) { // reject over-represented candidates
+ * for (long u = r >>> 1; // ensure nonnegative
+ * u + m - (r = u % n) < 0L; // rejection check
+ * u = nextLong() >>> 1) // retry
+ * ;
+ * r += origin;
+ * }
+ * else { // range not representable as long
+ * while (r < origin || r >= bound)
+ * r = nextLong();
+ * }
+ * return r;
+ * }}</pre>
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
*
- * @return an infinite stream of {@code double} values
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code long} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code double} values, each between zero
+ * (inclusive) and one (exclusive).
+ *
+ * <p>A pseudorandom {@code double} value is generated as if it's the result
+ * of calling the method {@link #nextDouble()}}.
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of {@code double} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @since 1.8
+ */
+ public DoubleStream doubles(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * double} values, each between zero (inclusive) and one
+ * (exclusive).
+ *
+ * <p>A pseudorandom {@code double} value is generated as if it's the result
+ * of calling the method {@link #nextDouble()}}.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code double} values
* @since 1.8
*/
public DoubleStream doubles() {
- return DoubleStream.generate(this::nextDouble);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code double} values, each conforming to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * <p>A pseudorandom {@code double} value is generated as if it's the result
+ * of calling the following method with the origin and bound:
+ * <pre> {@code
+ * double nextDouble(double origin, double bound) {
+ * double r = nextDouble();
+ * r = r * (bound - origin) + origin;
+ * if (r >= bound) // correct for rounding
+ * r = Math.nextDown(bound);
+ * return r;
+ * }}</pre>
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code double} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+ double randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (!(randomNumberOrigin < randomNumberBound))
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * double} values, each conforming to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * <p>A pseudorandom {@code double} value is generated as if it's the result
+ * of calling the following method with the origin and bound:
+ * <pre> {@code
+ * double nextDouble(double origin, double bound) {
+ * double r = nextDouble();
+ * r = r * (bound - origin) + origin;
+ * if (r >= bound) // correct for rounding
+ * r = Math.nextDown(bound);
+ * return r;
+ * }}</pre>
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code double} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+ if (!(randomNumberOrigin < randomNumberBound))
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
}
/**
- * Returns a stream of pseudorandom, Gaussian ("normally")
- * distributed {@code double} values with mean {@code 0.0}
- * and standard deviation {@code 1.0} from this random number
- * generator's sequence. Values are obtained as needed by
- * calling {@link #nextGaussian()}.
- *
- * @return an infinite stream of {@code double} values
- * @since 1.8
+ * Spliterator for int streams. We multiplex the four int
+ * versions into one class by treating a bound less than origin as
+ * unbounded, and also by treating "infinite" as equivalent to
+ * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+ * approach. The long and double versions of this class are
+ * identical except for types.
+ */
+ static final class RandomIntsSpliterator implements Spliterator.OfInt {
+ final Random rng;
+ long index;
+ final long fence;
+ final int origin;
+ final int bound;
+ RandomIntsSpliterator(Random rng, long index, long fence,
+ int origin, int bound) {
+ this.rng = rng; this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomIntsSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomIntsSpliterator(rng, i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rng.internalNextInt(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ Random r = rng;
+ int o = origin, b = bound;
+ do {
+ consumer.accept(r.internalNextInt(o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for long streams.
*/
- public DoubleStream gaussians() {
- return DoubleStream.generate(this::nextGaussian);
+ static final class RandomLongsSpliterator implements Spliterator.OfLong {
+ final Random rng;
+ long index;
+ final long fence;
+ final long origin;
+ final long bound;
+ RandomLongsSpliterator(Random rng, long index, long fence,
+ long origin, long bound) {
+ this.rng = rng; this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomLongsSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomLongsSpliterator(rng, i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rng.internalNextLong(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ Random r = rng;
+ long o = origin, b = bound;
+ do {
+ consumer.accept(r.internalNextLong(o, b));
+ } while (++i < f);
+ }
+ }
+
+ }
+
+ /**
+ * Spliterator for double streams.
+ */
+ static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+ final Random rng;
+ long index;
+ final long fence;
+ final double origin;
+ final double bound;
+ RandomDoublesSpliterator(Random rng, long index, long fence,
+ double origin, double bound) {
+ this.rng = rng; this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomDoublesSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomDoublesSpliterator(rng, i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rng.internalNextDouble(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ Random r = rng;
+ double o = origin, b = bound;
+ do {
+ consumer.accept(r.internalNextDouble(o, b));
+ } while (++i < f);
+ }
+ }
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/SplittableRandom.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,1002 @@
+/*
+ * 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.
+ */
+
+package java.util;
+
+import java.security.SecureRandom;
+import java.net.InetAddress;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+import java.util.function.DoubleConsumer;
+import java.util.stream.StreamSupport;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.DoubleStream;
+
+/**
+ * A generator of uniform pseudorandom values applicable for use in
+ * (among other contexts) isolated parallel computations that may
+ * generate subtasks. Class {@code SplittableRandom} supports methods for
+ * producing pseudorandom numbers of type {@code int}, {@code long},
+ * and {@code double} with similar usages as for class
+ * {@link java.util.Random} but differs in the following ways:
+ *
+ * <ul>
+ *
+ * <li>Series of generated values pass the DieHarder suite testing
+ * independence and uniformity properties of random number generators.
+ * (Most recently validated with <a
+ * href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> version
+ * 3.31.1</a>.) These tests validate only the methods for certain
+ * types and ranges, but similar properties are expected to hold, at
+ * least approximately, for others as well. The <em>period</em>
+ * (length of any series of generated values before it repeats) is at
+ * least 2<sup>64</sup>. </li>
+ *
+ * <li> Method {@link #split} constructs and returns a new
+ * SplittableRandom instance that shares no mutable state with the
+ * current instance. However, with very high probability, the
+ * values collectively generated by the two objects have the same
+ * statistical properties as if the same quantity of values were
+ * generated by a single thread using a single {@code
+ * SplittableRandom} object. </li>
+ *
+ * <li>Instances of SplittableRandom are <em>not</em> thread-safe.
+ * They are designed to be split, not shared, across threads. For
+ * example, a {@link java.util.concurrent.ForkJoinTask
+ * fork/join-style} computation using random numbers might include a
+ * construction of the form {@code new
+ * Subtask(aSplittableRandom.split()).fork()}.
+ *
+ * <li>This class provides additional methods for generating random
+ * streams, that employ the above techniques when used in {@code
+ * stream.parallel()} mode.</li>
+ *
+ * </ul>
+ *
+ * <p>Instances of {@code SplittableRandom} are not cryptographically
+ * secure. Consider instead using {@link java.security.SecureRandom}
+ * in security-sensitive applications. Additionally,
+ * default-constructed instances do not use a cryptographically random
+ * seed unless the {@linkplain System#getProperty system property}
+ * {@code java.util.secureRandomSeed} is set to {@code true}.
+ *
+ * @author Guy Steele
+ * @author Doug Lea
+ * @since 1.8
+ */
+public final class SplittableRandom {
+
+ /*
+ * Implementation Overview.
+ *
+ * This algorithm was inspired by the "DotMix" algorithm by
+ * Leiserson, Schardl, and Sukha "Deterministic Parallel
+ * Random-Number Generation for Dynamic-Multithreading Platforms",
+ * PPoPP 2012, as well as those in "Parallel random numbers: as
+ * easy as 1, 2, 3" by Salmon, Morae, Dror, and Shaw, SC 2011. It
+ * differs mainly in simplifying and cheapening operations.
+ *
+ * The primary update step (method nextSeed()) is to add a
+ * constant ("gamma") to the current (64 bit) seed, forming a
+ * simple sequence. The seed and the gamma values for any two
+ * SplittableRandom instances are highly likely to be different.
+ *
+ * Methods nextLong, nextInt, and derivatives do not return the
+ * sequence (seed) values, but instead a hash-like bit-mix of
+ * their bits, producing more independently distributed sequences.
+ * For nextLong, the mix64 bit-mixing function computes the same
+ * value as the "64-bit finalizer" function in Austin Appleby's
+ * MurmurHash3 algorithm. See
+ * http://code.google.com/p/smhasher/wiki/MurmurHash3 , which
+ * comments: "The constants for the finalizers were generated by a
+ * simple simulated-annealing algorithm, and both avalanche all
+ * bits of 'h' to within 0.25% bias." The mix32 function is
+ * equivalent to (int)(mix64(seed) >>> 32), but faster because it
+ * omits a step that doesn't contribute to result.
+ *
+ * The split operation uses the current generator to form the seed
+ * and gamma for another SplittableRandom. To conservatively
+ * avoid potential correlations between seed and value generation,
+ * gamma selection (method nextGamma) uses the "Mix13" constants
+ * for MurmurHash3 described by David Stafford
+ * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
+ * To avoid potential weaknesses in bit-mixing transformations, we
+ * restrict gammas to odd values with at least 12 and no more than
+ * 52 bits set. Rather than rejecting candidates with too few or
+ * too many bits set, method nextGamma flips some bits (which has
+ * the effect of mapping at most 4 to any given gamma value).
+ * This reduces the effective set of 64bit odd gamma values by
+ * about 2<sup>14</sup>, a very tiny percentage, and serves as an
+ * automated screening for sequence constant selection that is
+ * left as an empirical decision in some other hashing and crypto
+ * algorithms.
+ *
+ * The resulting generator thus transforms a sequence in which
+ * (typically) many bits change on each step, with an inexpensive
+ * mixer with good (but less than cryptographically secure)
+ * avalanching.
+ *
+ * The default (no-argument) constructor, in essence, invokes
+ * split() for a common "seeder" SplittableRandom. Unlike other
+ * cases, this split must be performed in a thread-safe manner, so
+ * we use an AtomicLong to represent the seed rather than use an
+ * explicit SplittableRandom. To bootstrap the seeder, we start
+ * off using a seed based on current time and host unless the
+ * java.util.secureRandomSeed property is set. This serves as a
+ * slimmed-down (and insecure) variant of SecureRandom that also
+ * avoids stalls that may occur when using /dev/random.
+ *
+ * It is a relatively simple matter to apply the basic design here
+ * to use 128 bit seeds. However, emulating 128bit arithmetic and
+ * carrying around twice the state add more overhead than appears
+ * warranted for current usages.
+ *
+ * File organization: First the non-public methods that constitute
+ * the main algorithm, then the main public methods, followed by
+ * some custom spliterator classes needed for stream methods.
+ */
+
+ /**
+ * The initial gamma value for (unsplit) SplittableRandoms. Must
+ * be odd with at least 12 and no more than 52 bits set. Currently
+ * set to the golden ratio scaled to 64bits.
+ */
+ private static final long INITIAL_GAMMA = 0x9e3779b97f4a7c15L;
+
+ /**
+ * The least non-zero value returned by nextDouble(). This value
+ * is scaled by a random value of 53 bits to produce a result.
+ */
+ private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+
+ /**
+ * The seed. Updated only via method nextSeed.
+ */
+ private long seed;
+
+ /**
+ * The step value.
+ */
+ private final long gamma;
+
+ /**
+ * Internal constructor used by all others except default constructor.
+ */
+ private SplittableRandom(long seed, long gamma) {
+ this.seed = seed;
+ this.gamma = gamma;
+ }
+
+ /**
+ * Computes MurmurHash3 64bit mix function.
+ */
+ private static long mix64(long z) {
+ z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+ z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+ return z ^ (z >>> 33);
+ }
+
+ /**
+ * Returns the 32 high bits of mix64(z) as int.
+ */
+ private static int mix32(long z) {
+ z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+ return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
+ }
+
+ /**
+ * Returns the gamma value to use for a new split instance.
+ */
+ private static long nextGamma(long z) {
+ z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; // Stafford "Mix13"
+ z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
+ z = (z ^ (z >>> 31)) | 1L; // force to be odd
+ int n = Long.bitCount(z); // ensure enough 0 and 1 bits
+ return (n < 12 || n > 52) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
+ }
+
+ /**
+ * Adds gamma to seed.
+ */
+ private long nextSeed() {
+ return seed += gamma;
+ }
+
+ /**
+ * The seed generator for default constructors.
+ */
+ private static final AtomicLong seeder = new AtomicLong(initialSeed());
+
+ private static long initialSeed() {
+ String pp = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java.util.secureRandomSeed"));
+ if (pp != null && pp.equalsIgnoreCase("true")) {
+ byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+ long s = (long)(seedBytes[0]) & 0xffL;
+ for (int i = 1; i < 8; ++i)
+ s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ return s;
+ }
+ int hh = 0; // hashed host address
+ try {
+ hh = InetAddress.getLocalHost().hashCode();
+ } catch (Exception ignore) {
+ }
+ return (mix64((((long)hh) << 32) ^ System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
+ }
+
+ // IllegalArgumentException messages
+ static final String BadBound = "bound must be positive";
+ static final String BadRange = "bound must be greater than origin";
+ static final String BadSize = "size must be non-negative";
+
+ /*
+ * Internal versions of nextX methods used by streams, as well as
+ * the public nextX(origin, bound) methods. These exist mainly to
+ * avoid the need for multiple versions of stream spliterators
+ * across the different exported forms of streams.
+ */
+
+ /**
+ * The form of nextLong used by LongStream Spliterators. If
+ * origin is greater than bound, acts as unbounded form of
+ * nextLong, else as bounded form.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final long internalNextLong(long origin, long bound) {
+ /*
+ * Four Cases:
+ *
+ * 1. If the arguments indicate unbounded form, act as
+ * nextLong().
+ *
+ * 2. If the range is an exact power of two, apply the
+ * associated bit mask.
+ *
+ * 3. If the range is positive, loop to avoid potential bias
+ * when the implicit nextLong() bound (2<sup>64</sup>) is not
+ * evenly divisible by the range. The loop rejects candidates
+ * computed from otherwise over-represented values. The
+ * expected number of iterations under an ideal generator
+ * varies from 1 to 2, depending on the bound. The loop itself
+ * takes an unlovable form. Because the first candidate is
+ * already available, we need a break-in-the-middle
+ * construction, which is concisely but cryptically performed
+ * within the while-condition of a body-less for loop.
+ *
+ * 4. Otherwise, the range cannot be represented as a positive
+ * long. The loop repeatedly generates unbounded longs until
+ * obtaining a candidate meeting constraints (with an expected
+ * number of iterations of less than two).
+ */
+
+ long r = mix64(nextSeed());
+ if (origin < bound) {
+ long n = bound - origin, m = n - 1;
+ if ((n & m) == 0L) // power of two
+ r = (r & m) + origin;
+ else if (n > 0L) { // reject over-represented candidates
+ for (long u = r >>> 1; // ensure nonnegative
+ u + m - (r = u % n) < 0L; // rejection check
+ u = mix64(nextSeed()) >>> 1) // retry
+ ;
+ r += origin;
+ }
+ else { // range not representable as long
+ while (r < origin || r >= bound)
+ r = mix64(nextSeed());
+ }
+ }
+ return r;
+ }
+
+ /**
+ * The form of nextInt used by IntStream Spliterators.
+ * Exactly the same as long version, except for types.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final int internalNextInt(int origin, int bound) {
+ int r = mix32(nextSeed());
+ if (origin < bound) {
+ int n = bound - origin, m = n - 1;
+ if ((n & m) == 0)
+ r = (r & m) + origin;
+ else if (n > 0) {
+ for (int u = r >>> 1;
+ u + m - (r = u % n) < 0;
+ u = mix32(nextSeed()) >>> 1)
+ ;
+ r += origin;
+ }
+ else {
+ while (r < origin || r >= bound)
+ r = mix32(nextSeed());
+ }
+ }
+ return r;
+ }
+
+ /**
+ * The form of nextDouble used by DoubleStream Spliterators.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final double internalNextDouble(double origin, double bound) {
+ double r = (nextLong() >>> 11) * DOUBLE_UNIT;
+ if (origin < bound) {
+ r = r * (bound - origin) + origin;
+ if (r >= bound) // correct for rounding
+ r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+ }
+ return r;
+ }
+
+ /* ---------------- public methods ---------------- */
+
+ /**
+ * Creates a new SplittableRandom instance using the specified
+ * initial seed. SplittableRandom instances created with the same
+ * seed in the same program generate identical sequences of values.
+ *
+ * @param seed the initial seed
+ */
+ public SplittableRandom(long seed) {
+ this(seed, INITIAL_GAMMA);
+ }
+
+ /**
+ * Creates a new SplittableRandom instance that is likely to
+ * generate sequences of values that are statistically independent
+ * of those of any other instances in the current program; and
+ * may, and typically does, vary across program invocations.
+ */
+ public SplittableRandom() { // emulate seeder.split()
+ this.gamma = nextGamma(this.seed = seeder.addAndGet(INITIAL_GAMMA));
+ }
+
+ /**
+ * Constructs and returns a new SplittableRandom instance that
+ * shares no mutable state with this instance. However, with very
+ * high probability, the set of values collectively generated by
+ * the two objects has the same statistical properties as if the
+ * same quantity of values were generated by a single thread using
+ * a single SplittableRandom object. Either or both of the two
+ * objects may be further split using the {@code split()} method,
+ * and the same expected statistical properties apply to the
+ * entire set of generators constructed by such recursive
+ * splitting.
+ *
+ * @return the new SplittableRandom instance
+ */
+ public SplittableRandom split() {
+ long s = nextSeed();
+ return new SplittableRandom(s, nextGamma(s));
+ }
+
+ /**
+ * Returns a pseudorandom {@code int} value.
+ *
+ * @return a pseudorandom {@code int} value
+ */
+ public int nextInt() {
+ return mix32(nextSeed());
+ }
+
+ /**
+ * Returns a pseudorandom {@code int} value between zero (inclusive)
+ * and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive). Must be positive.
+ * @return a pseudorandom {@code int} value between zero
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public int nextInt(int bound) {
+ if (bound <= 0)
+ throw new IllegalArgumentException(BadBound);
+ // Specialize internalNextInt for origin 0
+ int r = mix32(nextSeed());
+ int m = bound - 1;
+ if ((bound & m) == 0) // power of two
+ r &= m;
+ else { // reject over-represented candidates
+ for (int u = r >>> 1;
+ u + m - (r = u % bound) < 0;
+ u = mix32(nextSeed()) >>> 1)
+ ;
+ }
+ return r;
+ }
+
+ /**
+ * Returns a pseudorandom {@code int} value between the specified
+ * origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value returned
+ * @param bound the upper bound (exclusive)
+ * @return a pseudorandom {@code int} value between the origin
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ */
+ public int nextInt(int origin, int bound) {
+ if (origin >= bound)
+ throw new IllegalArgumentException(BadRange);
+ return internalNextInt(origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code long} value.
+ *
+ * @return a pseudorandom {@code long} value
+ */
+ public long nextLong() {
+ return mix64(nextSeed());
+ }
+
+ /**
+ * Returns a pseudorandom {@code long} value between zero (inclusive)
+ * and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive). Must be positive.
+ * @return a pseudorandom {@code long} value between zero
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public long nextLong(long bound) {
+ if (bound <= 0)
+ throw new IllegalArgumentException(BadBound);
+ // Specialize internalNextLong for origin 0
+ long r = mix64(nextSeed());
+ long m = bound - 1;
+ if ((bound & m) == 0L) // power of two
+ r &= m;
+ else { // reject over-represented candidates
+ for (long u = r >>> 1;
+ u + m - (r = u % bound) < 0L;
+ u = mix64(nextSeed()) >>> 1)
+ ;
+ }
+ return r;
+ }
+
+ /**
+ * Returns a pseudorandom {@code long} value between the specified
+ * origin (inclusive) and the specified bound (exclusive).
+ *
+ * @param origin the least value returned
+ * @param bound the upper bound (exclusive)
+ * @return a pseudorandom {@code long} value between the origin
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ */
+ public long nextLong(long origin, long bound) {
+ if (origin >= bound)
+ throw new IllegalArgumentException(BadRange);
+ return internalNextLong(origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code double} value between zero
+ * (inclusive) and one (exclusive).
+ *
+ * @return a pseudorandom {@code double} value between zero
+ * (inclusive) and one (exclusive)
+ */
+ public double nextDouble() {
+ return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
+ }
+
+ /**
+ * Returns a pseudorandom {@code double} value between 0.0
+ * (inclusive) and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive). Must be positive.
+ * @return a pseudorandom {@code double} value between zero
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public double nextDouble(double bound) {
+ if (!(bound > 0.0))
+ throw new IllegalArgumentException(BadBound);
+ double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
+ return (result < bound) ? result : // correct for rounding
+ Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+ }
+
+ /**
+ * Returns a pseudorandom {@code double} value between the specified
+ * origin (inclusive) and bound (exclusive).
+ *
+ * @param origin the least value returned
+ * @param bound the upper bound (exclusive)
+ * @return a pseudorandom {@code double} value between the origin
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
+ */
+ public double nextDouble(double origin, double bound) {
+ if (!(origin < bound))
+ throw new IllegalArgumentException(BadRange);
+ return internalNextDouble(origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code boolean} value.
+ *
+ * @return a pseudorandom {@code boolean} value
+ */
+ public boolean nextBoolean() {
+ return mix32(nextSeed()) < 0;
+ }
+
+ // stream methods, coded in a way intended to better isolate for
+ // maintenance purposes the small differences across forms.
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number
+ * of pseudorandom {@code int} values from this generator and/or
+ * one split from it.
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of pseudorandom {@code int} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ */
+ public IntStream ints(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, streamSize, Integer.MAX_VALUE, 0),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code int}
+ * values from this generator and/or one split from it.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * ints(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code int} values
+ */
+ public IntStream ints() {
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number
+ * of pseudorandom {@code int} values from this generator and/or one split
+ * from it; each value conforms to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code int} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ */
+ public IntStream ints(long streamSize, int randomNumberOrigin,
+ int randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * int} values from this generator and/or one split from it; each value
+ * conforms to the given origin (inclusive) and bound (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code int} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ */
+ public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number
+ * of pseudorandom {@code long} values from this generator and/or
+ * one split from it.
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of pseudorandom {@code long} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ */
+ public LongStream longs(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, streamSize, Long.MAX_VALUE, 0L),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * long} values from this generator and/or one split from it.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code long} values
+ */
+ public LongStream longs() {
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code long} values from this generator and/or one split
+ * from it; each value conforms to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code long} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ */
+ public LongStream longs(long streamSize, long randomNumberOrigin,
+ long randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * long} values from this generator and/or one split from it; each value
+ * conforms to the given origin (inclusive) and bound (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code long} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ */
+ public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code double} values from this generator and/or one split
+ * from it; each value is between zero (inclusive) and one (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of {@code double} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ */
+ public DoubleStream doubles(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * double} values from this generator and/or one split from it; each value
+ * is between zero (inclusive) and one (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code double} values
+ */
+ public DoubleStream doubles() {
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code double} values from this generator and/or one split
+ * from it; each value conforms to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code double} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ */
+ public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+ double randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (!(randomNumberOrigin < randomNumberBound))
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * double} values from this generator and/or one split from it; each value
+ * conforms to the given origin (inclusive) and bound (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code double} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ */
+ public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+ if (!(randomNumberOrigin < randomNumberBound))
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Spliterator for int streams. We multiplex the four int
+ * versions into one class by treating a bound less than origin as
+ * unbounded, and also by treating "infinite" as equivalent to
+ * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+ * approach. The long and double versions of this class are
+ * identical except for types.
+ */
+ static final class RandomIntsSpliterator implements Spliterator.OfInt {
+ final SplittableRandom rng;
+ long index;
+ final long fence;
+ final int origin;
+ final int bound;
+ RandomIntsSpliterator(SplittableRandom rng, long index, long fence,
+ int origin, int bound) {
+ this.rng = rng; this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomIntsSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomIntsSpliterator(rng.split(), i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rng.internalNextInt(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ SplittableRandom r = rng;
+ int o = origin, b = bound;
+ do {
+ consumer.accept(r.internalNextInt(o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for long streams.
+ */
+ static final class RandomLongsSpliterator implements Spliterator.OfLong {
+ final SplittableRandom rng;
+ long index;
+ final long fence;
+ final long origin;
+ final long bound;
+ RandomLongsSpliterator(SplittableRandom rng, long index, long fence,
+ long origin, long bound) {
+ this.rng = rng; this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomLongsSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomLongsSpliterator(rng.split(), i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rng.internalNextLong(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ SplittableRandom r = rng;
+ long o = origin, b = bound;
+ do {
+ consumer.accept(r.internalNextLong(o, b));
+ } while (++i < f);
+ }
+ }
+
+ }
+
+ /**
+ * Spliterator for double streams.
+ */
+ static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+ final SplittableRandom rng;
+ long index;
+ final long fence;
+ final double origin;
+ final double bound;
+ RandomDoublesSpliterator(SplittableRandom rng, long index, long fence,
+ double origin, double bound) {
+ this.rng = rng; this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomDoublesSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomDoublesSpliterator(rng.split(), i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rng.internalNextDouble(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ SplittableRandom r = rng;
+ double o = origin, b = bound;
+ do {
+ consumer.accept(r.internalNextDouble(o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+}
--- a/jdk/src/share/classes/java/util/TimSort.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/TimSort.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009 Google Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -176,7 +177,7 @@
*/
int stackLen = (len < 120 ? 5 :
len < 1542 ? 10 :
- len < 119151 ? 19 : 40);
+ len < 119151 ? 24 : 40);
runBase = new int[stackLen];
runLen = new int[stackLen];
}
--- a/jdk/src/share/classes/java/util/TreeMap.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/TreeMap.java Wed Jul 05 19:10:19 2017 +0200
@@ -973,6 +973,27 @@
}
@Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ Entry<K,V> p = getEntry(key);
+ if (p!=null && Objects.equals(oldValue, p.value)) {
+ p.value = newValue;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public V replace(K key, V value) {
+ Entry<K,V> p = getEntry(key);
+ if (p!=null) {
+ V oldValue = p.value;
+ p.value = value;
+ return oldValue;
+ }
+ return null;
+ }
+
+ @Override
public void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
int expectedModCount = modCount;
--- a/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadLocalRandom.java Wed Jul 05 19:10:19 2017 +0200
@@ -37,11 +37,16 @@
import java.io.ObjectStreamField;
import java.util.Random;
+import java.util.Spliterator;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
+import java.util.stream.StreamSupport;
/**
* A random number generator isolated to the current thread. Like the
@@ -64,6 +69,10 @@
* <p>This class also provides additional commonly used bounded random
* generation methods.
*
+ * <p>Instances of {@code ThreadLocalRandom} are not cryptographically
+ * secure. Consider instead using {@link java.security.SecureRandom}
+ * in security-sensitive applications.
+ *
* @since 1.7
* @author Doug Lea
*/
@@ -85,28 +94,26 @@
* application-level overhead and footprint of most concurrent
* programs.
*
+ * Even though this class subclasses java.util.Random, it uses the
+ * same basic algorithm as java.util.SplittableRandom. (See its
+ * internal documentation for explanations, which are not repeated
+ * here.) Because ThreadLocalRandoms are not splittable
+ * though, we use only a single 64bit gamma.
+ *
* Because this class is in a different package than class Thread,
* field access methods use Unsafe to bypass access control rules.
- * The base functionality of Random methods is conveniently
- * isolated in method next(bits), that just reads and writes the
- * Thread field rather than its own field. However, to conform to
- * the requirements of the Random superclass constructor, the
- * common static ThreadLocalRandom maintains an "initialized"
- * field for the sake of rejecting user calls to setSeed while
- * still allowing a call from constructor. Note that
- * serialization is completely unnecessary because there is only a
- * static singleton. But we generate a serial form containing
- * "rnd" and "initialized" fields to ensure compatibility across
- * versions.
+ * To conform to the requirements of the Random superclass
+ * constructor, the common static ThreadLocalRandom maintains an
+ * "initialized" field for the sake of rejecting user calls to
+ * setSeed while still allowing a call from constructor. Note
+ * that serialization is completely unnecessary because there is
+ * only a static singleton. But we generate a serial form
+ * containing "rnd" and "initialized" fields to ensure
+ * compatibility across versions.
*
- * Per-thread initialization is similar to that in the no-arg
- * Random constructor, but we avoid correlation among not only
- * initial seeds of those created in different threads, but also
- * those created using class Random itself; while at the same time
- * not changing any statistical properties. So we use the same
- * underlying multiplicative sequence, but start the sequence far
- * away from the base version, and then merge (xor) current time
- * and per-thread probe bits to generate initial values.
+ * Implementations of non-core methods are mostly the same as in
+ * SplittableRandom, that were in part derived from a previous
+ * version of this class.
*
* The nextLocalGaussian ThreadLocal supports the very rarely used
* nextGaussian method by providing a holder for the second of a
@@ -115,24 +122,51 @@
* but we provide identical statistical properties.
*/
- // same constants as Random, but must be redeclared because private
- private static final long multiplier = 0x5DEECE66DL;
- private static final long addend = 0xBL;
- private static final long mask = (1L << 48) - 1;
- private static final int PROBE_INCREMENT = 0x61c88647;
-
- /** Generates the basis for per-thread initial seed values */
- private static final AtomicLong seedGenerator =
- new AtomicLong(1269533684904616924L);
-
/** Generates per-thread initialization/probe field */
private static final AtomicInteger probeGenerator =
- new AtomicInteger(0xe80f8647);
+ new AtomicInteger();
+
+ /**
+ * The next seed for default constructors.
+ */
+ private static final AtomicLong seeder =
+ new AtomicLong(mix64(System.currentTimeMillis()) ^
+ mix64(System.nanoTime()));
+
+ /**
+ * The seed increment
+ */
+ private static final long GAMMA = 0x9e3779b97f4a7c15L;
+
+ /**
+ * The increment for generating probe values
+ */
+ private static final int PROBE_INCREMENT = 0x9e3779b9;
+
+ /**
+ * The increment of seeder per new instance
+ */
+ private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
+
+ // Constants from SplittableRandom
+ private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+ private static final float FLOAT_UNIT = 1.0f / (1 << 24);
/** Rarely-used holder for the second of a pair of Gaussians */
private static final ThreadLocal<Double> nextLocalGaussian =
new ThreadLocal<Double>();
+ private static long mix64(long z) {
+ z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+ z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+ return z ^ (z >>> 33);
+ }
+
+ private static int mix32(long z) {
+ z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
+ return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
+ }
+
/**
* Field used only during singleton initialization.
* True when constructor completes.
@@ -155,16 +189,11 @@
* rely on (static) atomic generators to initialize the values.
*/
static final void localInit() {
- int p = probeGenerator.getAndAdd(PROBE_INCREMENT);
+ int p = probeGenerator.addAndGet(PROBE_INCREMENT);
int probe = (p == 0) ? 1 : p; // skip 0
- long current, next;
- do { // same sequence as j.u.Random but different initial value
- current = seedGenerator.get();
- next = current * 181783497276652981L;
- } while (!seedGenerator.compareAndSet(current, next));
- long r = next ^ ((long)probe << 32) ^ System.nanoTime();
+ long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
Thread t = Thread.currentThread();
- UNSAFE.putLong(t, SEED, r);
+ UNSAFE.putLong(t, SEED, seed);
UNSAFE.putInt(t, PROBE, probe);
}
@@ -191,124 +220,264 @@
throw new UnsupportedOperationException();
}
- protected int next(int bits) {
+ final long nextSeed() {
Thread t; long r; // read and update per-thread seed
- UNSAFE.putLong
- (t = Thread.currentThread(), SEED,
- r = (UNSAFE.getLong(t, SEED) * multiplier + addend) & mask);
- return (int) (r >>> (48-bits));
+ UNSAFE.putLong(t = Thread.currentThread(), SEED,
+ r = UNSAFE.getLong(t, SEED) + GAMMA);
+ return r;
+ }
+
+ // We must define this, but never use it.
+ protected int next(int bits) {
+ return (int)(mix64(nextSeed()) >>> (64 - bits));
+ }
+
+ // IllegalArgumentException messages
+ static final String BadBound = "bound must be positive";
+ static final String BadRange = "bound must be greater than origin";
+ static final String BadSize = "size must be non-negative";
+
+ /**
+ * The form of nextLong used by LongStream Spliterators. If
+ * origin is greater than bound, acts as unbounded form of
+ * nextLong, else as bounded form.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final long internalNextLong(long origin, long bound) {
+ long r = mix64(nextSeed());
+ if (origin < bound) {
+ long n = bound - origin, m = n - 1;
+ if ((n & m) == 0L) // power of two
+ r = (r & m) + origin;
+ else if (n > 0L) { // reject over-represented candidates
+ for (long u = r >>> 1; // ensure nonnegative
+ u + m - (r = u % n) < 0L; // rejection check
+ u = mix64(nextSeed()) >>> 1) // retry
+ ;
+ r += origin;
+ }
+ else { // range not representable as long
+ while (r < origin || r >= bound)
+ r = mix64(nextSeed());
+ }
+ }
+ return r;
}
/**
- * Returns a pseudorandom, uniformly distributed value between the
- * given least value (inclusive) and bound (exclusive).
+ * The form of nextInt used by IntStream Spliterators.
+ * Exactly the same as long version, except for types.
+ *
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final int internalNextInt(int origin, int bound) {
+ int r = mix32(nextSeed());
+ if (origin < bound) {
+ int n = bound - origin, m = n - 1;
+ if ((n & m) == 0)
+ r = (r & m) + origin;
+ else if (n > 0) {
+ for (int u = r >>> 1;
+ u + m - (r = u % n) < 0;
+ u = mix32(nextSeed()) >>> 1)
+ ;
+ r += origin;
+ }
+ else {
+ while (r < origin || r >= bound)
+ r = mix32(nextSeed());
+ }
+ }
+ return r;
+ }
+
+ /**
+ * The form of nextDouble used by DoubleStream Spliterators.
*
- * @param least the least value returned
- * @param bound the upper bound (exclusive)
- * @throws IllegalArgumentException if least greater than or equal
- * to bound
- * @return the next value
+ * @param origin the least value, unless greater than bound
+ * @param bound the upper bound (exclusive), must not equal origin
+ * @return a pseudorandom value
+ */
+ final double internalNextDouble(double origin, double bound) {
+ double r = (nextLong() >>> 11) * DOUBLE_UNIT;
+ if (origin < bound) {
+ r = r * (bound - origin) + origin;
+ if (r >= bound) // correct for rounding
+ r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
+ }
+ return r;
+ }
+
+ /**
+ * Returns a pseudorandom {@code int} value.
+ *
+ * @return a pseudorandom {@code int} value
*/
- public int nextInt(int least, int bound) {
- if (least >= bound)
- throw new IllegalArgumentException();
- return nextInt(bound - least) + least;
+ public int nextInt() {
+ return mix32(nextSeed());
+ }
+
+ /**
+ * Returns a pseudorandom {@code int} value between zero (inclusive)
+ * and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive). Must be positive.
+ * @return a pseudorandom {@code int} value between zero
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public int nextInt(int bound) {
+ if (bound <= 0)
+ throw new IllegalArgumentException(BadBound);
+ int r = mix32(nextSeed());
+ int m = bound - 1;
+ if ((bound & m) == 0) // power of two
+ r &= m;
+ else { // reject over-represented candidates
+ for (int u = r >>> 1;
+ u + m - (r = u % bound) < 0;
+ u = mix32(nextSeed()) >>> 1)
+ ;
+ }
+ return r;
}
/**
- * Returns a pseudorandom, uniformly distributed value
- * between 0 (inclusive) and the specified value (exclusive).
+ * Returns a pseudorandom {@code int} value between the specified
+ * origin (inclusive) and the specified bound (exclusive).
*
- * @param n the bound on the random number to be returned. Must be
- * positive.
- * @return the next value
- * @throws IllegalArgumentException if n is not positive
+ * @param origin the least value returned
+ * @param bound the upper bound (exclusive)
+ * @return a pseudorandom {@code int} value between the origin
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
*/
- public long nextLong(long n) {
- if (n <= 0)
- throw new IllegalArgumentException("n must be positive");
- // Divide n by two until small enough for nextInt. On each
- // iteration (at most 31 of them but usually much less),
- // randomly choose both whether to include high bit in result
- // (offset) and whether to continue with the lower vs upper
- // half (which makes a difference only if odd).
- long offset = 0;
- while (n >= Integer.MAX_VALUE) {
- int bits = next(2);
- long half = n >>> 1;
- long nextn = ((bits & 2) == 0) ? half : n - half;
- if ((bits & 1) == 0)
- offset += n - nextn;
- n = nextn;
- }
- return offset + nextInt((int) n);
+ public int nextInt(int origin, int bound) {
+ if (origin >= bound)
+ throw new IllegalArgumentException(BadRange);
+ return internalNextInt(origin, bound);
}
- @Override
- public IntStream ints() {
- return IntStream.generate(() -> current().nextInt());
+ /**
+ * Returns a pseudorandom {@code long} value.
+ *
+ * @return a pseudorandom {@code long} value
+ */
+ public long nextLong() {
+ return mix64(nextSeed());
}
- @Override
- public LongStream longs() {
- return LongStream.generate(() -> current().nextLong());
- }
-
- @Override
- public DoubleStream doubles() {
- return DoubleStream.generate(() -> current().nextDouble());
- }
-
- @Override
- public DoubleStream gaussians() {
- return DoubleStream.generate(() -> current().nextGaussian());
+ /**
+ * Returns a pseudorandom {@code long} value between zero (inclusive)
+ * and the specified bound (exclusive).
+ *
+ * @param bound the upper bound (exclusive). Must be positive.
+ * @return a pseudorandom {@code long} value between zero
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code bound} is not positive
+ */
+ public long nextLong(long bound) {
+ if (bound <= 0)
+ throw new IllegalArgumentException(BadBound);
+ long r = mix64(nextSeed());
+ long m = bound - 1;
+ if ((bound & m) == 0L) // power of two
+ r &= m;
+ else { // reject over-represented candidates
+ for (long u = r >>> 1;
+ u + m - (r = u % bound) < 0L;
+ u = mix64(nextSeed()) >>> 1)
+ ;
+ }
+ return r;
}
/**
- * Returns a pseudorandom, uniformly distributed value between the
- * given least value (inclusive) and bound (exclusive).
+ * Returns a pseudorandom {@code long} value between the specified
+ * origin (inclusive) and the specified bound (exclusive).
*
- * @param least the least value returned
+ * @param origin the least value returned
* @param bound the upper bound (exclusive)
- * @return the next value
- * @throws IllegalArgumentException if least greater than or equal
- * to bound
+ * @return a pseudorandom {@code long} value between the origin
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
*/
- public long nextLong(long least, long bound) {
- if (least >= bound)
- throw new IllegalArgumentException();
- return nextLong(bound - least) + least;
+ public long nextLong(long origin, long bound) {
+ if (origin >= bound)
+ throw new IllegalArgumentException(BadRange);
+ return internalNextLong(origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code double} value between zero
+ * (inclusive) and one (exclusive).
+ *
+ * @return a pseudorandom {@code double} value between zero
+ * (inclusive) and one (exclusive)
+ */
+ public double nextDouble() {
+ return (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT;
}
/**
- * Returns a pseudorandom, uniformly distributed {@code double} value
- * between 0 (inclusive) and the specified value (exclusive).
+ * Returns a pseudorandom {@code double} value between 0.0
+ * (inclusive) and the specified bound (exclusive).
*
- * @param n the bound on the random number to be returned. Must be
- * positive.
- * @return the next value
- * @throws IllegalArgumentException if n is not positive
+ * @param bound the upper bound (exclusive). Must be positive.
+ * @return a pseudorandom {@code double} value between zero
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code bound} is not positive
*/
- public double nextDouble(double n) {
- if (n <= 0)
- throw new IllegalArgumentException("n must be positive");
- return nextDouble() * n;
+ public double nextDouble(double bound) {
+ if (!(bound > 0.0))
+ throw new IllegalArgumentException(BadBound);
+ double result = (mix64(nextSeed()) >>> 11) * DOUBLE_UNIT * bound;
+ return (result < bound) ? result : // correct for rounding
+ Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
}
/**
- * Returns a pseudorandom, uniformly distributed value between the
- * given least value (inclusive) and bound (exclusive).
+ * Returns a pseudorandom {@code double} value between the specified
+ * origin (inclusive) and bound (exclusive).
*
- * @param least the least value returned
+ * @param origin the least value returned
* @param bound the upper bound (exclusive)
- * @return the next value
- * @throws IllegalArgumentException if least greater than or equal
- * to bound
+ * @return a pseudorandom {@code double} value between the origin
+ * (inclusive) and the bound (exclusive)
+ * @throws IllegalArgumentException if {@code origin} is greater than
+ * or equal to {@code bound}
*/
- public double nextDouble(double least, double bound) {
- if (least >= bound)
- throw new IllegalArgumentException();
- return nextDouble() * (bound - least) + least;
+ public double nextDouble(double origin, double bound) {
+ if (!(origin < bound))
+ throw new IllegalArgumentException(BadRange);
+ return internalNextDouble(origin, bound);
+ }
+
+ /**
+ * Returns a pseudorandom {@code boolean} value.
+ *
+ * @return a pseudorandom {@code boolean} value
+ */
+ public boolean nextBoolean() {
+ return mix32(nextSeed()) < 0;
+ }
+
+ /**
+ * Returns a pseudorandom {@code float} value between zero
+ * (inclusive) and one (exclusive).
+ *
+ * @return a pseudorandom {@code float} value between zero
+ * (inclusive) and one (exclusive)
+ */
+ public float nextFloat() {
+ return (mix32(nextSeed()) >>> 8) * FLOAT_UNIT;
}
public double nextGaussian() {
@@ -329,6 +498,445 @@
return v1 * multiplier;
}
+ // stream methods, coded in a way intended to better isolate for
+ // maintenance purposes the small differences across forms.
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code int} values.
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of pseudorandom {@code int} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @since 1.8
+ */
+ public IntStream ints(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (0L, streamSize, Integer.MAX_VALUE, 0),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code int}
+ * values.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * ints(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code int} values
+ * @since 1.8
+ */
+ public IntStream ints() {
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number
+ * of pseudorandom {@code int} values, each conforming to the given
+ * origin (inclusive) and bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code int} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public IntStream ints(long streamSize, int randomNumberOrigin,
+ int randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * int} values, each conforming to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code int} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.intStream
+ (new RandomIntsSpliterator
+ (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code long} values.
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of pseudorandom {@code long} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @since 1.8
+ */
+ public LongStream longs(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (0L, streamSize, Long.MAX_VALUE, 0L),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code long}
+ * values.
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code long} values
+ * @since 1.8
+ */
+ public LongStream longs() {
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code long}, each conforming to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code long} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero, or {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public LongStream longs(long streamSize, long randomNumberOrigin,
+ long randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * long} values, each conforming to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * longs(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code long} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
+ if (randomNumberOrigin >= randomNumberBound)
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.longStream
+ (new RandomLongsSpliterator
+ (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code double} values, each between zero
+ * (inclusive) and one (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @return a stream of {@code double} values
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @since 1.8
+ */
+ public DoubleStream doubles(long streamSize) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (0L, streamSize, Double.MAX_VALUE, 0.0),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * double} values, each between zero (inclusive) and one
+ * (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE)}.
+ *
+ * @return a stream of pseudorandom {@code double} values
+ * @since 1.8
+ */
+ public DoubleStream doubles() {
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
+ false);
+ }
+
+ /**
+ * Returns a stream producing the given {@code streamSize} number of
+ * pseudorandom {@code double} values, each conforming to the given origin
+ * (inclusive) and bound (exclusive).
+ *
+ * @param streamSize the number of values to generate
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code double} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code streamSize} is
+ * less than zero
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public DoubleStream doubles(long streamSize, double randomNumberOrigin,
+ double randomNumberBound) {
+ if (streamSize < 0L)
+ throw new IllegalArgumentException(BadSize);
+ if (!(randomNumberOrigin < randomNumberBound))
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (0L, streamSize, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Returns an effectively unlimited stream of pseudorandom {@code
+ * double} values, each conforming to the given origin (inclusive) and bound
+ * (exclusive).
+ *
+ * @implNote This method is implemented to be equivalent to {@code
+ * doubles(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound)}.
+ *
+ * @param randomNumberOrigin the origin (inclusive) of each random value
+ * @param randomNumberBound the bound (exclusive) of each random value
+ * @return a stream of pseudorandom {@code double} values,
+ * each with the given origin (inclusive) and bound (exclusive)
+ * @throws IllegalArgumentException if {@code randomNumberOrigin}
+ * is greater than or equal to {@code randomNumberBound}
+ * @since 1.8
+ */
+ public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
+ if (!(randomNumberOrigin < randomNumberBound))
+ throw new IllegalArgumentException(BadRange);
+ return StreamSupport.doubleStream
+ (new RandomDoublesSpliterator
+ (0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
+ false);
+ }
+
+ /**
+ * Spliterator for int streams. We multiplex the four int
+ * versions into one class by treating a bound less than origin as
+ * unbounded, and also by treating "infinite" as equivalent to
+ * Long.MAX_VALUE. For splits, it uses the standard divide-by-two
+ * approach. The long and double versions of this class are
+ * identical except for types.
+ */
+ static final class RandomIntsSpliterator implements Spliterator.OfInt {
+ long index;
+ final long fence;
+ final int origin;
+ final int bound;
+ RandomIntsSpliterator(long index, long fence,
+ int origin, int bound) {
+ this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomIntsSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomIntsSpliterator(i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(ThreadLocalRandom.current().internalNextInt(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(IntConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ int o = origin, b = bound;
+ ThreadLocalRandom rng = ThreadLocalRandom.current();
+ do {
+ consumer.accept(rng.internalNextInt(o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+ /**
+ * Spliterator for long streams.
+ */
+ static final class RandomLongsSpliterator implements Spliterator.OfLong {
+ long index;
+ final long fence;
+ final long origin;
+ final long bound;
+ RandomLongsSpliterator(long index, long fence,
+ long origin, long bound) {
+ this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomLongsSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomLongsSpliterator(i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(ThreadLocalRandom.current().internalNextLong(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(LongConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ long o = origin, b = bound;
+ ThreadLocalRandom rng = ThreadLocalRandom.current();
+ do {
+ consumer.accept(rng.internalNextLong(o, b));
+ } while (++i < f);
+ }
+ }
+
+ }
+
+ /**
+ * Spliterator for double streams.
+ */
+ static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
+ long index;
+ final long fence;
+ final double origin;
+ final double bound;
+ RandomDoublesSpliterator(long index, long fence,
+ double origin, double bound) {
+ this.index = index; this.fence = fence;
+ this.origin = origin; this.bound = bound;
+ }
+
+ public RandomDoublesSpliterator trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomDoublesSpliterator(i, index = m, origin, bound);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ public boolean tryAdvance(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(ThreadLocalRandom.current().internalNextDouble(origin, bound));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+
+ public void forEachRemaining(DoubleConsumer consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ index = f;
+ double o = origin, b = bound;
+ ThreadLocalRandom rng = ThreadLocalRandom.current();
+ do {
+ consumer.accept(rng.internalNextDouble(o, b));
+ } while (++i < f);
+ }
+ }
+ }
+
+
// Within-package utilities
/*
@@ -401,23 +1009,26 @@
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("rnd", long.class),
- new ObjectStreamField("initialized", boolean.class)
+ new ObjectStreamField("initialized", boolean.class),
};
/**
* Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
+ * @param s the stream
+ * @throws java.io.IOException if an I/O error occurs
*/
- private void writeObject(java.io.ObjectOutputStream out)
+ private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
- java.io.ObjectOutputStream.PutField fields = out.putFields();
+ java.io.ObjectOutputStream.PutField fields = s.putFields();
fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
fields.put("initialized", true);
- out.writeFields();
+ s.writeFields();
}
/**
* Returns the {@link #current() current} thread's {@code ThreadLocalRandom}.
+ * @return the {@link #current() current} thread's {@code ThreadLocalRandom}
*/
private Object readResolve() {
return current();
--- a/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/StampedLock.java Wed Jul 05 19:10:19 2017 +0200
@@ -226,7 +226,11 @@
* incoming reader arrives while read lock is held but there is a
* queued writer, this incoming reader is queued. (This rule is
* responsible for some of the complexity of method acquireRead,
- * but without it, the lock becomes highly unfair.)
+ * but without it, the lock becomes highly unfair.) Method release
+ * does not (and sometimes cannot) itself wake up cowaiters. This
+ * is done by the primary thread, but helped by any other threads
+ * with nothing better to do in methods acquireRead and
+ * acquireWrite.
*
* These rules apply to threads actually queued. All tryLock forms
* opportunistically try to acquire locks regardless of preference
@@ -267,11 +271,14 @@
/** Number of processors, for spin control */
private static final int NCPU = Runtime.getRuntime().availableProcessors();
- /** Maximum number of retries before blocking on acquisition */
+ /** Maximum number of retries before enqueuing on acquisition */
private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
+ /** Maximum number of retries before blocking at head on acquisition */
+ private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0;
+
/** Maximum number of retries before re-blocking */
- private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 12 : 0;
+ private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0;
/** The period for yielding when waiting for overflow spinlock */
private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
@@ -415,8 +422,8 @@
* @return a stamp that can be used to unlock or convert mode
*/
public long readLock() {
- long s, next; // bypass acquireRead on fully unlocked case only
- return ((((s = state) & ABITS) == 0L &&
+ long s = state, next; // bypass acquireRead on common uncontended case
+ return ((whead == wtail && (s & ABITS) < RFULL &&
U.compareAndSwapLong(this, STATE, s, next = s + RUNIT)) ?
next : acquireRead(false, 0L));
}
@@ -1012,17 +1019,8 @@
if (t.status <= 0)
q = t;
}
- if (q != null) {
- for (WNode r = q;;) { // release co-waiters too
- if ((w = r.thread) != null) {
- r.thread = null;
- U.unpark(w);
- }
- if ((r = q.cowait) == null)
- break;
- U.compareAndSwapObject(q, WCOWAIT, r, r.cowait);
- }
- }
+ if (q != null && (w = q.thread) != null)
+ U.unpark(w);
}
}
@@ -1038,22 +1036,22 @@
private long acquireWrite(boolean interruptible, long deadline) {
WNode node = null, p;
for (int spins = -1;;) { // spin while enqueuing
- long s, ns;
- if (((s = state) & ABITS) == 0L) {
+ long m, s, ns;
+ if ((m = (s = state) & ABITS) == 0L) {
if (U.compareAndSwapLong(this, STATE, s, ns = s + WBIT))
return ns;
}
+ else if (spins < 0)
+ spins = (m == WBIT && wtail == whead) ? SPINS : 0;
else if (spins > 0) {
if (LockSupport.nextSecondarySeed() >= 0)
--spins;
}
else if ((p = wtail) == null) { // initialize queue
- WNode h = new WNode(WMODE, null);
- if (U.compareAndSwapObject(this, WHEAD, null, h))
- wtail = h;
+ WNode hd = new WNode(WMODE, null);
+ if (U.compareAndSwapObject(this, WHEAD, null, hd))
+ wtail = hd;
}
- else if (spins < 0)
- spins = (p == whead) ? SPINS : 0;
else if (node == null)
node = new WNode(WMODE, p);
else if (node.prev != p)
@@ -1064,14 +1062,18 @@
}
}
- for (int spins = SPINS;;) {
- WNode np, pp; int ps; long s, ns; Thread w;
- while ((np = node.prev) != p && np != null)
- (p = np).next = node; // stale
- if (whead == p) {
+ for (int spins = -1;;) {
+ WNode h, np, pp; int ps;
+ if ((h = whead) == p) {
+ if (spins < 0)
+ spins = HEAD_SPINS;
+ else if (spins < MAX_HEAD_SPINS)
+ spins <<= 1;
for (int k = spins;;) { // spin at head
+ long s, ns;
if (((s = state) & ABITS) == 0L) {
- if (U.compareAndSwapLong(this, STATE, s, ns = s+WBIT)) {
+ if (U.compareAndSwapLong(this, STATE, s,
+ ns = s + WBIT)) {
whead = node;
node.prev = null;
return ns;
@@ -1081,33 +1083,45 @@
--k <= 0)
break;
}
- if (spins < MAX_HEAD_SPINS)
- spins <<= 1;
}
- if ((ps = p.status) == 0)
- U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
- else if (ps == CANCELLED) {
- if ((pp = p.prev) != null) {
- node.prev = pp;
- pp.next = node;
+ else if (h != null) { // help release stale waiters
+ WNode c; Thread w;
+ while ((c = h.cowait) != null) {
+ if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+ (w = c.thread) != null)
+ U.unpark(w);
}
}
- else {
- long time; // 0 argument to park means no timeout
- if (deadline == 0L)
- time = 0L;
- else if ((time = deadline - System.nanoTime()) <= 0L)
- return cancelWaiter(node, node, false);
- Thread wt = Thread.currentThread();
- U.putObject(wt, PARKBLOCKER, this); // emulate LockSupport.park
- node.thread = wt;
- if (node.prev == p && p.status == WAITING && // recheck
- (p != whead || (state & ABITS) != 0L))
- U.park(false, time);
- node.thread = null;
- U.putObject(wt, PARKBLOCKER, null);
- if (interruptible && Thread.interrupted())
- return cancelWaiter(node, node, true);
+ if (whead == h) {
+ if ((np = node.prev) != p) {
+ if (np != null)
+ (p = np).next = node; // stale
+ }
+ else if ((ps = p.status) == 0)
+ U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+ else if (ps == CANCELLED) {
+ if ((pp = p.prev) != null) {
+ node.prev = pp;
+ pp.next = node;
+ }
+ }
+ else {
+ long time; // 0 argument to park means no timeout
+ if (deadline == 0L)
+ time = 0L;
+ else if ((time = deadline - System.nanoTime()) <= 0L)
+ return cancelWaiter(node, node, false);
+ Thread wt = Thread.currentThread();
+ U.putObject(wt, PARKBLOCKER, this);
+ node.thread = wt;
+ if (p.status < 0 && (p != h || (state & ABITS) != 0L) &&
+ whead == h && node.prev == p)
+ U.park(false, time); // emulate LockSupport.park
+ node.thread = null;
+ U.putObject(wt, PARKBLOCKER, null);
+ if (interruptible && Thread.interrupted())
+ return cancelWaiter(node, node, true);
+ }
}
}
}
@@ -1122,138 +1136,159 @@
* @return next state, or INTERRUPTED
*/
private long acquireRead(boolean interruptible, long deadline) {
- WNode node = null, group = null, p;
+ WNode node = null, p;
for (int spins = -1;;) {
- for (;;) {
- long s, m, ns; WNode h, q; Thread w; // anti-barging guard
- if (group == null && (h = whead) != null &&
- (q = h.next) != null && q.mode != RMODE)
- break;
- if ((m = (s = state) & ABITS) < RFULL ?
- U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
- (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
- if (group != null) { // help release others
- for (WNode r = group;;) {
- if ((w = r.thread) != null) {
- r.thread = null;
- U.unpark(w);
+ WNode h;
+ if ((h = whead) == (p = wtail)) {
+ for (long m, s, ns;;) {
+ if ((m = (s = state) & ABITS) < RFULL ?
+ U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+ (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L))
+ return ns;
+ else if (m >= WBIT) {
+ if (spins > 0) {
+ if (LockSupport.nextSecondarySeed() >= 0)
+ --spins;
+ }
+ else {
+ if (spins == 0) {
+ WNode nh = whead, np = wtail;
+ if ((nh == h && np == p) || (h = nh) != (p = np))
+ break;
}
- if ((r = group.cowait) == null)
- break;
- U.compareAndSwapObject(group, WCOWAIT, r, r.cowait);
+ spins = SPINS;
}
}
- return ns;
}
- if (m >= WBIT)
- break;
+ }
+ if (p == null) { // initialize queue
+ WNode hd = new WNode(WMODE, null);
+ if (U.compareAndSwapObject(this, WHEAD, null, hd))
+ wtail = hd;
}
- if (spins > 0) {
- if (LockSupport.nextSecondarySeed() >= 0)
- --spins;
- }
- else if ((p = wtail) == null) {
- WNode h = new WNode(WMODE, null);
- if (U.compareAndSwapObject(this, WHEAD, null, h))
- wtail = h;
+ else if (node == null)
+ node = new WNode(RMODE, p);
+ else if (h == p || p.mode != RMODE) {
+ if (node.prev != p)
+ node.prev = p;
+ else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
+ p.next = node;
+ break;
+ }
}
- else if (spins < 0)
- spins = (p == whead) ? SPINS : 0;
- else if (node == null)
- node = new WNode(WMODE, p);
- else if (node.prev != p)
- node.prev = p;
- else if (p.mode == RMODE && p != whead) {
- WNode pp = p.prev; // become co-waiter with group p
- if (pp != null && p == wtail &&
- U.compareAndSwapObject(p, WCOWAIT,
- node.cowait = p.cowait, node)) {
- node.thread = Thread.currentThread();
- for (long time;;) {
+ else if (!U.compareAndSwapObject(p, WCOWAIT,
+ node.cowait = p.cowait, node))
+ node.cowait = null;
+ else {
+ for (;;) {
+ WNode pp, c; Thread w;
+ if ((h = whead) != null && (c = h.cowait) != null &&
+ U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+ (w = c.thread) != null) // help release
+ U.unpark(w);
+ if (h == (pp = p.prev) || h == p || pp == null) {
+ long m, s, ns;
+ do {
+ if ((m = (s = state) & ABITS) < RFULL ?
+ U.compareAndSwapLong(this, STATE, s,
+ ns = s + RUNIT) :
+ (m < WBIT &&
+ (ns = tryIncReaderOverflow(s)) != 0L))
+ return ns;
+ } while (m < WBIT);
+ }
+ if (whead == h && p.prev == pp) {
+ long time;
+ if (pp == null || h == p || p.status > 0) {
+ node = null; // throw away
+ break;
+ }
if (deadline == 0L)
time = 0L;
else if ((time = deadline - System.nanoTime()) <= 0L)
return cancelWaiter(node, p, false);
- if (node.thread == null)
- break;
- if (p.prev != pp || p.status == CANCELLED ||
- p == whead || p.prev != pp) {
- node.thread = null;
- break;
- }
Thread wt = Thread.currentThread();
U.putObject(wt, PARKBLOCKER, this);
- if (node.thread == null) // must recheck
- break;
- U.park(false, time);
+ node.thread = wt;
+ if ((h != pp || (state & ABITS) == WBIT) &&
+ whead == h && p.prev == pp)
+ U.park(false, time);
+ node.thread = null;
U.putObject(wt, PARKBLOCKER, null);
if (interruptible && Thread.interrupted())
return cancelWaiter(node, p, true);
}
- group = p;
}
- node = null; // throw away
- }
- else if (U.compareAndSwapObject(this, WTAIL, p, node)) {
- p.next = node;
- break;
}
}
- for (int spins = SPINS;;) {
- WNode np, pp, r; int ps; long m, s, ns; Thread w;
- while ((np = node.prev) != p && np != null)
- (p = np).next = node;
- if (whead == p) {
- for (int k = spins;;) {
- if ((m = (s = state) & ABITS) != WBIT) {
- if (m < RFULL ?
- U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT):
- (ns = tryIncReaderOverflow(s)) != 0L) {
- whead = node;
- node.prev = null;
- while ((r = node.cowait) != null) {
- if (U.compareAndSwapObject(node, WCOWAIT,
- r, r.cowait) &&
- (w = r.thread) != null) {
- r.thread = null;
- U.unpark(w); // release co-waiter
- }
- }
- return ns;
+ for (int spins = -1;;) {
+ WNode h, np, pp; int ps;
+ if ((h = whead) == p) {
+ if (spins < 0)
+ spins = HEAD_SPINS;
+ else if (spins < MAX_HEAD_SPINS)
+ spins <<= 1;
+ for (int k = spins;;) { // spin at head
+ long m, s, ns;
+ if ((m = (s = state) & ABITS) < RFULL ?
+ U.compareAndSwapLong(this, STATE, s, ns = s + RUNIT) :
+ (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
+ WNode c; Thread w;
+ whead = node;
+ node.prev = null;
+ while ((c = node.cowait) != null) {
+ if (U.compareAndSwapObject(node, WCOWAIT,
+ c, c.cowait) &&
+ (w = c.thread) != null)
+ U.unpark(w);
}
+ return ns;
}
- else if (LockSupport.nextSecondarySeed() >= 0 &&
- --k <= 0)
+ else if (m >= WBIT &&
+ LockSupport.nextSecondarySeed() >= 0 && --k <= 0)
break;
}
- if (spins < MAX_HEAD_SPINS)
- spins <<= 1;
}
- if ((ps = p.status) == 0)
- U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
- else if (ps == CANCELLED) {
- if ((pp = p.prev) != null) {
- node.prev = pp;
- pp.next = node;
+ else if (h != null) {
+ WNode c; Thread w;
+ while ((c = h.cowait) != null) {
+ if (U.compareAndSwapObject(h, WCOWAIT, c, c.cowait) &&
+ (w = c.thread) != null)
+ U.unpark(w);
}
}
- else {
- long time;
- if (deadline == 0L)
- time = 0L;
- else if ((time = deadline - System.nanoTime()) <= 0L)
- return cancelWaiter(node, node, false);
- Thread wt = Thread.currentThread();
- U.putObject(wt, PARKBLOCKER, this);
- node.thread = wt;
- if (node.prev == p && p.status == WAITING &&
- (p != whead || (state & ABITS) != WBIT))
- U.park(false, time);
- node.thread = null;
- U.putObject(wt, PARKBLOCKER, null);
- if (interruptible && Thread.interrupted())
- return cancelWaiter(node, node, true);
+ if (whead == h) {
+ if ((np = node.prev) != p) {
+ if (np != null)
+ (p = np).next = node; // stale
+ }
+ else if ((ps = p.status) == 0)
+ U.compareAndSwapInt(p, WSTATUS, 0, WAITING);
+ else if (ps == CANCELLED) {
+ if ((pp = p.prev) != null) {
+ node.prev = pp;
+ pp.next = node;
+ }
+ }
+ else {
+ long time;
+ if (deadline == 0L)
+ time = 0L;
+ else if ((time = deadline - System.nanoTime()) <= 0L)
+ return cancelWaiter(node, node, false);
+ Thread wt = Thread.currentThread();
+ U.putObject(wt, PARKBLOCKER, this);
+ node.thread = wt;
+ if (p.status < 0 &&
+ (p != h || (state & ABITS) == WBIT) &&
+ whead == h && node.prev == p)
+ U.park(false, time);
+ node.thread = null;
+ U.putObject(wt, PARKBLOCKER, null);
+ if (interruptible && Thread.interrupted())
+ return cancelWaiter(node, node, true);
+ }
}
}
}
@@ -1278,22 +1313,19 @@
if (node != null && group != null) {
Thread w;
node.status = CANCELLED;
- node.thread = null;
// unsplice cancelled nodes from group
for (WNode p = group, q; (q = p.cowait) != null;) {
- if (q.status == CANCELLED)
- U.compareAndSwapObject(p, WNEXT, q, q.next);
+ if (q.status == CANCELLED) {
+ U.compareAndSwapObject(p, WCOWAIT, q, q.cowait);
+ p = group; // restart
+ }
else
p = q;
}
if (group == node) {
- WNode r; // detach and wake up uncancelled co-waiters
- while ((r = node.cowait) != null) {
- if (U.compareAndSwapObject(node, WCOWAIT, r, r.cowait) &&
- (w = r.thread) != null) {
- r.thread = null;
- U.unpark(w);
- }
+ for (WNode r = group.cowait; r != null; r = r.cowait) {
+ if ((w = r.thread) != null)
+ U.unpark(w); // wake up uncancelled co-waiters
}
for (WNode pred = node.prev; pred != null; ) { // unsplice
WNode succ, pp; // find valid successor
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Wed Jul 05 19:10:19 2017 +0200
@@ -32,6 +32,7 @@
import java.security.cert.CertificateException;
import java.util.zip.ZipEntry;
+import sun.misc.JarIndex;
import sun.security.util.ManifestDigester;
import sun.security.util.ManifestEntryVerifier;
import sun.security.util.SignatureFileVerifier;
@@ -139,7 +140,8 @@
return;
}
- if (uname.equals(JarFile.MANIFEST_NAME)) {
+ if (uname.equals(JarFile.MANIFEST_NAME) ||
+ uname.equals(JarIndex.INDEX_NAME)) {
return;
}
--- a/jdk/src/share/classes/java/util/logging/Logger.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/logging/Logger.java Wed Jul 05 19:10:19 2017 +0200
@@ -457,13 +457,15 @@
* of the subsystem, such as java.net
* or javax.swing
* @param resourceBundleName name of ResourceBundle to be used for localizing
- * messages for this logger. May be <CODE>null</CODE> if none of
- * the messages require localization.
+ * messages for this logger. May be {@code null}
+ * if none of the messages require localization.
* @return a suitable Logger
* @throws MissingResourceException if the resourceBundleName is non-null and
* no corresponding resource can be found.
* @throws IllegalArgumentException if the Logger already exists and uses
- * a different resource bundle name.
+ * a different resource bundle name; or if
+ * {@code resourceBundleName} is {@code null} but the named
+ * logger has a resource bundle set.
* @throws NullPointerException if the name is null.
*/
@@ -1731,10 +1733,6 @@
// Synchronized to prevent races in setting the fields.
private synchronized void setupResourceInfo(String name,
Class<?> callersClass) {
- if (name == null) {
- return;
- }
-
if (resourceBundleName != null) {
// this Logger already has a ResourceBundle
@@ -1748,6 +1746,10 @@
resourceBundleName + " != " + name);
}
+ if (name == null) {
+ return;
+ }
+
setCallersClassLoaderRef(callersClass);
if (findResourceBundle(name, true) == null) {
// We've failed to find an expected ResourceBundle.
--- a/jdk/src/share/classes/java/util/regex/Pattern.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java Wed Jul 05 19:10:19 2017 +0200
@@ -219,7 +219,7 @@
*
* <tr><th> </th></tr>
* <tr align="left"><th colspan="2" id="unicode">Classes for Unicode scripts, blocks, categories and binary properties</th></tr>
- * * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
+ * <tr><td valign="top" headers="construct unicode">{@code \p{IsLatin}}</td>
* <td headers="matches">A Latin script character (<a href="#usc">script</a>)</td></tr>
* <tr><td valign="top" headers="construct unicode">{@code \p{InGreek}}</td>
* <td headers="matches">A character in the Greek block (<a href="#ubc">block</a>)</td></tr>
@@ -4456,16 +4456,16 @@
groups[groupIndex+1] = i;
groups[groupIndex] = i - k;
}
- i = i - k;
return true;
}
// backing off
+ i = i - k;
if (capture) {
groups[groupIndex+1] = i;
groups[groupIndex] = i - k;
}
- i = i - k;
j--;
+
}
break;
}
@@ -4883,7 +4883,6 @@
int k = matcher.groups[groupIndex+1];
int groupSize = k - j;
-
// If the referenced group didn't match, neither can this
if (j < 0)
return false;
@@ -4893,7 +4892,6 @@
matcher.hitEnd = true;
return false;
}
-
// Check each new char to make sure it matches what the group
// referenced matched last time around
for (int index=0; index<groupSize; index++)
--- a/jdk/src/share/classes/java/util/stream/Collectors.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Collectors.java Wed Jul 05 19:10:19 2017 +0200
@@ -137,6 +137,11 @@
return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}
+ @SuppressWarnings("unchecked")
+ private static <I, R> Function<I, R> castingIdentity() {
+ return i -> (R) i;
+ }
+
/**
* Simple implementation class for {@code Collector}.
*
@@ -166,7 +171,7 @@
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Set<Characteristics> characteristics) {
- this(supplier, accumulator, combiner, i -> (R) i, characteristics);
+ this(supplier, accumulator, combiner, castingIdentity(), characteristics);
}
@Override
@@ -209,7 +214,7 @@
*/
public static <T, C extends Collection<T>>
Collector<T, ?, C> toCollection(Supplier<C> collectionFactory) {
- return new CollectorImpl<>(collectionFactory, Collection::add,
+ return new CollectorImpl<>(collectionFactory, Collection<T>::add,
(r1, r2) -> { r1.addAll(r2); return r1; },
CH_ID);
}
@@ -1046,30 +1051,23 @@
public static <T, D, A>
Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
Collector<? super T, A, D> downstream) {
- @SuppressWarnings("unchecked")
- BiConsumer<D, ? super T> downstreamAccumulator = (BiConsumer<D, ? super T>) downstream.accumulator();
- BiConsumer<Map<Boolean, A>, T> accumulator = (result, t) -> {
- Partition<D> asPartition = ((Partition<D>) result);
- downstreamAccumulator.accept(predicate.test(t) ? asPartition.forTrue : asPartition.forFalse, t);
- };
+ BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
+ BiConsumer<Partition<A>, T> accumulator = (result, t) ->
+ downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);
BinaryOperator<A> op = downstream.combiner();
- BinaryOperator<Map<Boolean, A>> merger = (m1, m2) -> {
- Partition<A> left = (Partition<A>) m1;
- Partition<A> right = (Partition<A>) m2;
- return new Partition<>(op.apply(left.forTrue, right.forTrue),
- op.apply(left.forFalse, right.forFalse));
- };
- Supplier<Map<Boolean, A>> supplier = () -> new Partition<>(downstream.supplier().get(),
- downstream.supplier().get());
+ BinaryOperator<Partition<A>> merger = (left, right) ->
+ new Partition<>(op.apply(left.forTrue, right.forTrue),
+ op.apply(left.forFalse, right.forFalse));
+ Supplier<Partition<A>> supplier = () ->
+ new Partition<>(downstream.supplier().get(),
+ downstream.supplier().get());
if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
return new CollectorImpl<>(supplier, accumulator, merger, CH_ID);
}
else {
- Function<Map<Boolean, A>, Map<Boolean, D>> finisher = (Map<Boolean, A> par) -> {
- Partition<A> asAPartition = (Partition<A>) par;
- return new Partition<>(downstream.finisher().apply(asAPartition.forTrue),
- downstream.finisher().apply(asAPartition.forFalse));
- };
+ Function<Partition<A>, Map<Boolean, D>> finisher = par ->
+ new Partition<>(downstream.finisher().apply(par.forTrue),
+ downstream.finisher().apply(par.forFalse));
return new CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
}
}
--- a/jdk/src/share/classes/java/util/stream/DistinctOps.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/DistinctOps.java Wed Jul 05 19:10:19 2017 +0200
@@ -101,7 +101,7 @@
if (StreamOpFlag.DISTINCT.isKnown(flags)) {
return sink;
} else if (StreamOpFlag.SORTED.isKnown(flags)) {
- return new Sink.ChainedReference<T>(sink) {
+ return new Sink.ChainedReference<T, T>(sink) {
boolean seenNull;
T lastSeen;
@@ -132,7 +132,7 @@
}
};
} else {
- return new Sink.ChainedReference<T>(sink) {
+ return new Sink.ChainedReference<T, T>(sink) {
Set<T> seen;
@Override
--- a/jdk/src/share/classes/java/util/stream/DoublePipeline.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/DoublePipeline.java Wed Jul 05 19:10:19 2017 +0200
@@ -191,7 +191,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Double>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.applyAsDouble(t));
@@ -208,9 +208,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<U>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
@@ -226,7 +225,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Integer>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.applyAsInt(t));
@@ -243,7 +242,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Long>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.applyAsLong(t));
@@ -259,7 +258,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -296,7 +295,7 @@
StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -319,7 +318,7 @@
0) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Double>(sink) {
@Override
public void accept(double t) {
consumer.accept(t);
--- a/jdk/src/share/classes/java/util/stream/IntPipeline.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/IntPipeline.java Wed Jul 05 19:10:19 2017 +0200
@@ -189,9 +189,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Long>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(int t) {
downstream.accept((long) t);
}
@@ -206,9 +205,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Double>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(int t) {
downstream.accept((double) t);
}
@@ -229,7 +227,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Integer>(sink) {
@Override
public void accept(int t) {
downstream.accept(mapper.applyAsInt(t));
@@ -246,9 +244,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<U> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<U>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(int t) {
downstream.accept(mapper.apply(t));
}
@@ -264,7 +261,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Long>(sink) {
@Override
public void accept(int t) {
downstream.accept(mapper.applyAsLong(t));
@@ -281,7 +278,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Double>(sink) {
@Override
public void accept(int t) {
downstream.accept(mapper.applyAsDouble(t));
@@ -297,7 +294,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Integer>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -334,7 +331,7 @@
StreamOpFlag.NOT_SIZED) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Integer>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -357,7 +354,7 @@
0) {
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Integer>(sink) {
@Override
public void accept(int t) {
consumer.accept(t);
--- a/jdk/src/share/classes/java/util/stream/LongPipeline.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/LongPipeline.java Wed Jul 05 19:10:19 2017 +0200
@@ -186,7 +186,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Double>(sink) {
@Override
public void accept(long t) {
downstream.accept((double) t);
@@ -208,9 +208,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Long>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(long t) {
downstream.accept(mapper.applyAsLong(t));
}
@@ -226,9 +225,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Long> opWrapSink(int flags, Sink<U> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<U>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(long t) {
downstream.accept(mapper.apply(t));
}
@@ -244,9 +242,8 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Integer>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(long t) {
downstream.accept(mapper.applyAsInt(t));
}
@@ -262,7 +259,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Double>(sink) {
@Override
public void accept(long t) {
downstream.accept(mapper.applyAsDouble(t));
@@ -278,7 +275,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Long>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -315,7 +312,7 @@
StreamOpFlag.NOT_SIZED) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Long>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
@@ -338,7 +335,7 @@
0) {
@Override
Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Long>(sink) {
@Override
public void accept(long t) {
consumer.accept(t);
--- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java Wed Jul 05 19:10:19 2017 +0200
@@ -163,17 +163,16 @@
StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
- @SuppressWarnings("unchecked")
public void accept(P_OUT u) {
if (predicate.test(u))
- downstream.accept((Object) u);
+ downstream.accept(u);
}
};
}
@@ -188,7 +187,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, R>(sink) {
@Override
public void accept(P_OUT u) {
downstream.accept(mapper.apply(u));
@@ -205,7 +204,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, Integer>(sink) {
@Override
public void accept(P_OUT u) {
downstream.accept(mapper.applyAsInt(u));
@@ -222,7 +221,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, Long>(sink) {
@Override
public void accept(P_OUT u) {
downstream.accept(mapper.applyAsLong(u));
@@ -239,7 +238,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, Double>(sink) {
@Override
public void accept(P_OUT u) {
downstream.accept(mapper.applyAsDouble(u));
@@ -257,14 +256,13 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, R>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
- @SuppressWarnings("unchecked")
public void accept(P_OUT u) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
Stream<? extends R> result = mapper.apply(u);
@@ -284,7 +282,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, Integer>(sink) {
IntConsumer downstreamAsInt = downstream::accept;
@Override
public void begin(long size) {
@@ -311,7 +309,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, Double>(sink) {
DoubleConsumer downstreamAsDouble = downstream::accept;
@Override
public void begin(long size) {
@@ -338,7 +336,7 @@
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, Long>(sink) {
LongConsumer downstreamAsLong = downstream::accept;
@Override
public void begin(long size) {
@@ -364,9 +362,8 @@
0) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
- return new Sink.ChainedReference<P_OUT>(sink) {
+ return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
- @SuppressWarnings("unchecked")
public void accept(P_OUT u) {
tee.accept(u);
downstream.accept(u);
@@ -495,6 +492,7 @@
}
@Override
+ @SuppressWarnings("unchecked")
public final <R, A> R collect(Collector<? super P_OUT, A, ? extends R> collector) {
A container;
if (isParallel()
--- a/jdk/src/share/classes/java/util/stream/Sink.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Sink.java Wed Jul 05 19:10:19 2017 +0200
@@ -241,11 +241,10 @@
* implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
- static abstract class ChainedReference<T> implements Sink<T> {
- @SuppressWarnings("rawtypes")
- protected final Sink downstream;
+ static abstract class ChainedReference<T, E_OUT> implements Sink<T> {
+ protected final Sink<? super E_OUT> downstream;
- public ChainedReference(Sink downstream) {
+ public ChainedReference(Sink<? super E_OUT> downstream) {
this.downstream = Objects.requireNonNull(downstream);
}
@@ -274,11 +273,10 @@
* The implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
- static abstract class ChainedInt implements Sink.OfInt {
- @SuppressWarnings("rawtypes")
- protected final Sink downstream;
+ static abstract class ChainedInt<E_OUT> implements Sink.OfInt {
+ protected final Sink<? super E_OUT> downstream;
- public ChainedInt(Sink downstream) {
+ public ChainedInt(Sink<? super E_OUT> downstream) {
this.downstream = Objects.requireNonNull(downstream);
}
@@ -307,11 +305,10 @@
* The implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
- static abstract class ChainedLong implements Sink.OfLong {
- @SuppressWarnings("rawtypes")
- protected final Sink downstream;
+ static abstract class ChainedLong<E_OUT> implements Sink.OfLong {
+ protected final Sink<? super E_OUT> downstream;
- public ChainedLong(Sink downstream) {
+ public ChainedLong(Sink<? super E_OUT> downstream) {
this.downstream = Objects.requireNonNull(downstream);
}
@@ -340,11 +337,10 @@
* The implementation of the {@code accept()} method must call the correct
* {@code accept()} method on the downstream {@code Sink}.
*/
- static abstract class ChainedDouble implements Sink.OfDouble {
- @SuppressWarnings("rawtypes")
- protected final Sink downstream;
+ static abstract class ChainedDouble<E_OUT> implements Sink.OfDouble {
+ protected final Sink<? super E_OUT> downstream;
- public ChainedDouble(Sink downstream) {
+ public ChainedDouble(Sink<? super E_OUT> downstream) {
this.downstream = Objects.requireNonNull(downstream);
}
--- a/jdk/src/share/classes/java/util/stream/SliceOps.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/SliceOps.java Wed Jul 05 19:10:19 2017 +0200
@@ -96,6 +96,11 @@
}
}
+ @SuppressWarnings("unchecked")
+ private static <T> IntFunction<T[]> castingArray() {
+ return size -> (T[]) new Object[size];
+ }
+
/**
* Appends a "slice" operation to the provided stream. The slice operation
* may be may be skip-only, limit-only, or skip-and-limit.
@@ -107,12 +112,12 @@
* is to be imposed
*/
public static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream,
- long skip, long limit) {
+ long skip, long limit) {
if (skip < 0)
throw new IllegalArgumentException("Skip must be non-negative: " + skip);
- return new ReferencePipeline.StatefulOp<T,T>(upstream, StreamShape.REFERENCE,
- flags(limit)) {
+ return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE,
+ flags(limit)) {
Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s,
long skip, long limit, long sizeIfKnown) {
if (skip <= sizeIfKnown) {
@@ -146,7 +151,7 @@
// cancellation will be more aggressive cancelling later tasks
// if the target slice size has been reached from a given task,
// cancellation should also clear local results if any
- return new SliceTask<>(this, helper, spliterator, i -> (T[]) new Object[i], skip, limit).
+ return new SliceTask<>(this, helper, spliterator, castingArray(), skip, limit).
invoke().spliterator();
}
}
@@ -182,7 +187,7 @@
@Override
Sink<T> opWrapSink(int flags, Sink<T> sink) {
- return new Sink.ChainedReference<T>(sink) {
+ return new Sink.ChainedReference<T, T>(sink) {
long n = skip;
long m = limit >= 0 ? limit : Long.MAX_VALUE;
@@ -291,7 +296,7 @@
@Override
Sink<Integer> opWrapSink(int flags, Sink<Integer> sink) {
- return new Sink.ChainedInt(sink) {
+ return new Sink.ChainedInt<Integer>(sink) {
long n = skip;
long m = limit >= 0 ? limit : Long.MAX_VALUE;
@@ -400,7 +405,7 @@
@Override
Sink<Long> opWrapSink(int flags, Sink<Long> sink) {
- return new Sink.ChainedLong(sink) {
+ return new Sink.ChainedLong<Long>(sink) {
long n = skip;
long m = limit >= 0 ? limit : Long.MAX_VALUE;
@@ -509,7 +514,7 @@
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
- return new Sink.ChainedDouble(sink) {
+ return new Sink.ChainedDouble<Double>(sink) {
long n = skip;
long m = limit >= 0 ? limit : Long.MAX_VALUE;
@@ -560,13 +565,13 @@
private volatile boolean completed;
- SliceTask(AbstractPipeline<?, P_OUT, ?> op,
+ SliceTask(AbstractPipeline<P_OUT, P_OUT, ?> op,
PipelineHelper<P_OUT> helper,
Spliterator<P_IN> spliterator,
IntFunction<P_OUT[]> generator,
long offset, long size) {
super(helper, spliterator);
- this.op = (AbstractPipeline<P_OUT, P_OUT, ?>) op;
+ this.op = op;
this.generator = generator;
this.targetOffset = offset;
this.targetSize = size;
--- a/jdk/src/share/classes/java/util/stream/SortedOps.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/SortedOps.java Wed Jul 05 19:10:19 2017 +0200
@@ -129,7 +129,7 @@
}
@Override
- public Sink<T> opWrapSink(int flags, Sink sink) {
+ public Sink<T> opWrapSink(int flags, Sink<T> sink) {
Objects.requireNonNull(sink);
// If the input is already naturally sorted and this operation
@@ -280,12 +280,12 @@
/**
* {@link ForkJoinTask} for implementing sort on SIZED reference streams.
*/
- private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T> {
+ private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T, T> {
private final Comparator<? super T> comparator;
private T[] array;
private int offset;
- SizedRefSortingSink(Sink<T> sink, Comparator<? super T> comparator) {
+ SizedRefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) {
super(sink);
this.comparator = comparator;
}
@@ -320,11 +320,11 @@
/**
* {@link Sink} for implementing sort on reference streams.
*/
- private static final class RefSortingSink<T> extends Sink.ChainedReference<T> {
+ private static final class RefSortingSink<T> extends Sink.ChainedReference<T, T> {
private final Comparator<? super T> comparator;
private ArrayList<T> list;
- RefSortingSink(Sink<T> sink, Comparator<? super T> comparator) {
+ RefSortingSink(Sink<? super T> sink, Comparator<? super T> comparator) {
super(sink);
this.comparator = comparator;
}
@@ -352,11 +352,11 @@
/**
* {@link Sink} for implementing sort on SIZED int streams.
*/
- private static final class SizedIntSortingSink extends Sink.ChainedInt {
+ private static final class SizedIntSortingSink extends Sink.ChainedInt<Integer> {
private int[] array;
private int offset;
- SizedIntSortingSink(Sink downstream) {
+ SizedIntSortingSink(Sink<? super Integer> downstream) {
super(downstream);
}
@@ -386,10 +386,10 @@
/**
* {@link Sink} for implementing sort on int streams.
*/
- private static final class IntSortingSink extends Sink.ChainedInt {
+ private static final class IntSortingSink extends Sink.ChainedInt<Integer> {
private SpinedBuffer.OfInt b;
- IntSortingSink(Sink sink) {
+ IntSortingSink(Sink<? super Integer> sink) {
super(sink);
}
@@ -417,11 +417,11 @@
/**
* {@link Sink} for implementing sort on SIZED long streams.
*/
- private static final class SizedLongSortingSink extends Sink.ChainedLong {
+ private static final class SizedLongSortingSink extends Sink.ChainedLong<Long> {
private long[] array;
private int offset;
- SizedLongSortingSink(Sink downstream) {
+ SizedLongSortingSink(Sink<? super Long> downstream) {
super(downstream);
}
@@ -451,10 +451,10 @@
/**
* {@link Sink} for implementing sort on long streams.
*/
- private static final class LongSortingSink extends Sink.ChainedLong {
+ private static final class LongSortingSink extends Sink.ChainedLong<Long> {
private SpinedBuffer.OfLong b;
- LongSortingSink(Sink sink) {
+ LongSortingSink(Sink<? super Long> sink) {
super(sink);
}
@@ -482,11 +482,11 @@
/**
* {@link Sink} for implementing sort on SIZED double streams.
*/
- private static final class SizedDoubleSortingSink extends Sink.ChainedDouble {
+ private static final class SizedDoubleSortingSink extends Sink.ChainedDouble<Double> {
private double[] array;
private int offset;
- SizedDoubleSortingSink(Sink downstream) {
+ SizedDoubleSortingSink(Sink<? super Double> downstream) {
super(downstream);
}
@@ -516,10 +516,10 @@
/**
* {@link Sink} for implementing sort on double streams.
*/
- private static final class DoubleSortingSink extends Sink.ChainedDouble {
+ private static final class DoubleSortingSink extends Sink.ChainedDouble<Double> {
private SpinedBuffer.OfDouble b;
- DoubleSortingSink(Sink sink) {
+ DoubleSortingSink(Sink<? super Double> sink) {
super(sink);
}
--- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java Wed Jul 05 19:10:19 2017 +0200
@@ -663,6 +663,9 @@
while (off + 4 <= len) {
int tag = get16(extra, off);
int sz = get16(extra, off + 2);
+ if (sz < 0 || (off + 4 + sz) > len) {
+ break;
+ }
if (tag == EXTID_EXTT || tag == EXTID_ZIP64) {
skipped += (sz + 4);
}
@@ -684,11 +687,18 @@
while (off + 4 <= len) {
int tag = get16(extra, off);
int sz = get16(extra, off + 2);
+ if (sz < 0 || (off + 4 + sz) > len) {
+ writeBytes(extra, off, len - off);
+ return;
+ }
if (tag != EXTID_EXTT && tag != EXTID_ZIP64) {
writeBytes(extra, off, sz + 4);
}
off += (sz + 4);
}
+ if (off < len) {
+ writeBytes(extra, off, len - off);
+ }
}
}
--- a/jdk/src/share/classes/javax/net/ssl/SNIHostName.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/SNIHostName.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -293,6 +293,7 @@
* the <a href="{@docRoot}/java/util/regex/Pattern.html#sum">
* regular expression pattern</a>
* representing the hostname(s) to match
+ * @return a {@code SNIMatcher} object for {@code SNIHostName}s
* @throws NullPointerException if {@code regex} is
* {@code null}
* @throws java.util.regex.PatternSyntaxException if the regular expression's
--- a/jdk/src/share/classes/javax/net/ssl/X509KeyManager.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/X509KeyManager.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2004, 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
@@ -40,7 +40,7 @@
* <UL>
* <LI> determine the set of aliases that are available for negotiations
* based on the criteria presented,
- * <LI> select the <ITALIC> best alias </ITALIC> based on
+ * <LI> select the <i> best alias</i> based on
* the criteria presented, and
* <LI> obtain the corresponding key material for given aliases.
* </UL>
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Wed Jul 05 19:10:19 2017 +0200
@@ -197,8 +197,7 @@
* {@code KerberosPrincipal} and the two
* {@code KerberosPrincipal} instances are equivalent.
* More formally two {@code KerberosPrincipal} instances are equal
- * if the values returned by {@code getName()} are equal and the
- * values returned by {@code getNameType()} are equal.
+ * if the values returned by {@code getName()} are equal.
*
* @param other the Object to compare to
* @return true if the Object passed in represents the same principal
@@ -211,15 +210,10 @@
if (! (other instanceof KerberosPrincipal)) {
return false;
- } else {
- String myFullName = getName();
- String otherFullName = ((KerberosPrincipal) other).getName();
- if (nameType == ((KerberosPrincipal)other).nameType &&
- myFullName.equals(otherFullName)) {
- return true;
- }
}
- return false;
+ String myFullName = getName();
+ String otherFullName = ((KerberosPrincipal) other).getName();
+ return myFullName.equals(otherFullName);
}
/**
--- a/jdk/src/share/classes/sun/misc/Compare.java Thu Aug 29 16:18:31 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 1996, 1997, 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.
- */
-
-/**
- * Compare: an interface to enable users to define the result of
- * a comparison of two objects.
- *
- * @author Sunita Mani
- */
-
-package sun.misc;
-
-public interface Compare {
-
- /**
- * doCompare
- *
- * @param obj1 first object to compare.
- * @param obj2 second object to compare.
- * @return -1 if obj1 < obj2, 0 if obj1 == obj2, 1 if obj1 > obj2.
- */
- public int doCompare(Object obj1, Object obj2);
-
-}
--- a/jdk/src/share/classes/sun/misc/Sort.java Thu Aug 29 16:18:31 2013 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 1996, 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.
- */
-
-/**
- * Sort: a class that uses the quicksort algorithm to sort an
- * array of objects.
- *
- * @author Sunita Mani
- */
-
-package sun.misc;
-
-public class Sort {
-
- private static void swap(Object arr[], int i, int j) {
- Object tmp;
-
- tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
-
- /**
- * quicksort the array of objects.
- *
- * @param arr[] - an array of objects
- * @param left - the start index - from where to begin sorting
- * @param right - the last index.
- * @param comp - an object that implemnts the Compare interface to resolve thecomparison.
- */
- public static void quicksort(Object arr[], int left, int right, Compare comp) {
- int i, last;
-
- if (left >= right) { /* do nothing if array contains fewer than two */
- return; /* two elements */
- }
- swap(arr, left, (left+right) / 2);
- last = left;
- for (i = left+1; i <= right; i++) {
- if (comp.doCompare(arr[i], arr[left]) < 0) {
- swap(arr, ++last, i);
- }
- }
- swap(arr, left, last);
- quicksort(arr, left, last-1, comp);
- quicksort(arr, last+1, right, comp);
- }
-
- public static void quicksort(Object arr[], Compare comp) {
- quicksort(arr, 0, arr.length-1, comp);
- }
-}
--- a/jdk/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/AbstractPollSelectorImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -193,9 +193,4 @@
if (!selch.isOpen() && !selch.isRegistered())
((SelChImpl)selch).kill();
}
-
- static {
- Util.load();
- }
-
}
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -1138,7 +1138,7 @@
throws IOException;
static {
- Util.load();
+ IOUtil.load();
initIDs();
}
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -1162,7 +1162,7 @@
private static native long initIDs();
static {
- Util.load();
+ IOUtil.load();
allocationGranularity = initIDs();
}
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java Wed Jul 05 19:10:19 2017 +0200
@@ -347,9 +347,23 @@
static native void initIDs();
+ /**
+ * Used to trigger loading of native libraries
+ */
+ public static void load() { }
+
static {
- // Note that IOUtil.initIDs is called from within Util.load.
- Util.load();
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("net");
+ System.loadLibrary("nio");
+ return null;
+ }
+ });
+
+ initIDs();
+
IOV_MAX = iovMax();
}
--- a/jdk/src/share/classes/sun/nio/ch/Net.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java Wed Jul 05 19:10:19 2017 +0200
@@ -582,7 +582,7 @@
private static native void initIDs();
static {
- Util.load();
+ IOUtil.load();
initIDs();
}
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -416,7 +416,7 @@
private static native void initIDs();
static {
- Util.load();
+ IOUtil.load();
initIDs();
nd = new SocketDispatcher();
}
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -1024,7 +1024,7 @@
throws IOException;
static {
- Util.load();
+ IOUtil.load();
nd = new SocketDispatcher();
}
--- a/jdk/src/share/classes/sun/nio/ch/Util.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java Wed Jul 05 19:10:19 2017 +0200
@@ -401,30 +401,4 @@
return bugLevel.equals(bl);
}
-
-
- // -- Initialization --
-
- private static boolean loaded = false;
-
- public static void load() {
- synchronized (Util.class) {
- if (loaded)
- return;
- loaded = true;
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("net");
- System.loadLibrary("nio");
- return null;
- }
- });
-
- // IOUtil must be initialized; Its native methods are called from
- // other places in native nio code so they must be set up.
- IOUtil.initIDs();
- }
- }
-
}
--- a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, 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
@@ -268,8 +268,13 @@
public void revalidate() {
// Adjust some colors
+ Color disabledForeground = UIManager.getColor("Label.disabledForeground");
+ if (disabledForeground == null) {
+ // fall back for Nimbus that doesn't support 'Label.disabledForeground'
+ disabledForeground = UIManager.getColor("Label.disabledText");
+ }
hintTextColor =
- ensureContrast(UIManager.getColor("Label.disabledForeground"),
+ ensureContrast(disabledForeground,
UIManager.getColor("Panel.background"));
disabledTableCellColor =
ensureContrast(new Color(0x808080),
--- a/jdk/src/share/classes/sun/tools/jconsole/JConsole.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/JConsole.java Wed Jul 05 19:10:19 2017 +0200
@@ -858,6 +858,10 @@
try {
updateInterval = Integer.parseInt(arg.substring(10)) *
1000;
+ if (updateInterval <= 0) {
+ usage();
+ return;
+ }
} catch (NumberFormatException ex) {
usage();
return;
--- a/jdk/src/share/classes/sun/tools/jconsole/Messages.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/Messages.java Wed Jul 05 19:10:19 2017 +0200
@@ -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
@@ -146,7 +146,6 @@
public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE;
public static String HELP_ABOUT_DIALOG_TITLE;
- public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK;
public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL;
public static String HELP_MENU_ABOUT_TITLE;
public static String HELP_MENU_USER_GUIDE_TITLE;
@@ -272,6 +271,7 @@
public static String THREADS;
public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME;
public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME;
+ public static String THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE;
public static String THRESHOLD;
public static String TILE;
public static String TIME_RANGE_COLON;
--- a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, 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
@@ -337,6 +337,13 @@
public void paintComponent(Graphics g) {
super.paintComponent(g);
+ int width = getWidth()-rightMargin-leftMargin-10;
+ int height = getHeight()-topMargin-bottomMargin;
+ if (width <= 0 || height <= 0) {
+ // not enough room to paint anything
+ return;
+ }
+
Color oldColor = g.getColor();
Font oldFont = g.getFont();
Color fg = getForeground();
--- a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java Wed Jul 05 19:10:19 2017 +0200
@@ -595,6 +595,8 @@
setBorder(thinEmptyBorder);
+ setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ textArea.setText(Messages.THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE);
addListSelectionListener(ThreadTab.this);
setCellRenderer(new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
--- a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java Wed Jul 05 19:10:19 2017 +0200
@@ -153,9 +153,11 @@
// in order to reserve space for the connect toggle.
public void setUI(TabbedPaneUI ui) {
Insets insets = (Insets) UIManager.getLookAndFeelDefaults().get("TabbedPane.tabAreaInsets");
- insets = (Insets) insets.clone();
- insets.right += connectedIcon24.getIconWidth() + 8;
- UIManager.put("TabbedPane.tabAreaInsets", insets);
+ if (insets != null) {
+ insets = (Insets) insets.clone();
+ insets.right += connectedIcon24.getIconWidth() + 8;
+ UIManager.put("TabbedPane.tabAreaInsets", insets);
+ }
super.setUI(ui);
}
--- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties Wed Jul 05 19:10:19 2017 +0200
@@ -104,7 +104,6 @@
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic
HELP_ABOUT_DIALOG_MASTHEAD_TITLE=About JConsole
HELP_ABOUT_DIALOG_TITLE=JConsole: About
-HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole &User Guide:<br>{0}
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
HELP_MENU_ABOUT_TITLE=&About JConsole
HELP_MENU_USER_GUIDE_TITLE=Online &User Guide
@@ -230,6 +229,7 @@
THREADS=Threads
THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=Thread Information
THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=Chart for number of threads.
+THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE=[No thread selected]
THRESHOLD=Threshold
TILE=&Tile
TIME_RANGE_COLON=&Time Range:
--- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Wed Jul 05 19:10:19 2017 +0200
@@ -104,7 +104,6 @@
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u30DE\u30B9\u30C8\u30D8\u30C3\u30C9\u56F3\u5F62
HELP_ABOUT_DIALOG_MASTHEAD_TITLE=JConsole\u306B\u3064\u3044\u3066
HELP_ABOUT_DIALOG_TITLE=JConsole: \u8A73\u7D30
-HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U):<br>{0}
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
HELP_MENU_ABOUT_TITLE=JConsole\u306B\u3064\u3044\u3066(&A)
HELP_MENU_USER_GUIDE_TITLE=\u30AA\u30F3\u30E9\u30A4\u30F3\u30FB\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U)
--- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Wed Jul 05 19:10:19 2017 +0200
@@ -104,7 +104,6 @@
HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u62A5\u5934\u56FE
HELP_ABOUT_DIALOG_MASTHEAD_TITLE=\u5173\u4E8E JConsole
HELP_ABOUT_DIALOG_TITLE=JConsole: \u5173\u4E8E
-HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole \u7528\u6237\u6307\u5357(&U):<br>{0}
HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
HELP_MENU_ABOUT_TITLE=\u5173\u4E8E JConsole(&A)
HELP_MENU_USER_GUIDE_TITLE=\u8054\u673A\u7528\u6237\u6307\u5357(&U)
--- a/jdk/src/share/lib/security/java.security-linux Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-linux Wed Jul 05 19:10:19 2017 +0200
@@ -181,6 +181,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
@@ -225,6 +226,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
--- a/jdk/src/share/lib/security/java.security-macosx Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-macosx Wed Jul 05 19:10:19 2017 +0200
@@ -182,6 +182,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
@@ -226,6 +227,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
--- a/jdk/src/share/lib/security/java.security-solaris Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-solaris Wed Jul 05 19:10:19 2017 +0200
@@ -183,6 +183,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
@@ -226,6 +227,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
--- a/jdk/src/share/lib/security/java.security-windows Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/lib/security/java.security-windows Wed Jul 05 19:10:19 2017 +0200
@@ -182,6 +182,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
@@ -226,6 +227,7 @@
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
+ com.sun.media.sound.,\
com.sun.proxy.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
--- a/jdk/src/share/native/common/check_code.c Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/share/native/common/check_code.c Wed Jul 05 19:10:19 2017 +0200
@@ -90,6 +90,12 @@
#include "classfile_constants.h"
#include "opcodes.in_out"
+#ifdef __APPLE__
+/* use setjmp/longjmp versions that do not save/restore the signal mask */
+#define setjmp _setjmp
+#define longjmp _longjmp
+#endif
+
#define MAX_ARRAY_DIMENSIONS 255
/* align byte code */
#ifndef ALIGN_UP
--- a/jdk/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/DatagramDispatcher.java Wed Jul 05 19:10:19 2017 +0200
@@ -36,7 +36,7 @@
class DatagramDispatcher extends NativeDispatcher
{
static {
- Util.load();
+ IOUtil.load();
}
int read(FileDescriptor fd, long address, int len) throws IOException {
--- a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java Wed Jul 05 19:10:19 2017 +0200
@@ -316,4 +316,8 @@
private native int poll0(long pollAddress, int numfds, long timeout,
int wfd);
private static native void interrupt(int fd);
+
+ static {
+ IOUtil.load();
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -196,9 +196,4 @@
}
return this;
}
-
- static {
- Util.load();
- }
-
}
--- a/jdk/src/solaris/classes/sun/nio/ch/EPoll.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPoll.java Wed Jul 05 19:10:19 2017 +0200
@@ -113,6 +113,6 @@
throws IOException;
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java Wed Jul 05 19:10:19 2017 +0200
@@ -318,6 +318,7 @@
}
static {
+ IOUtil.load();
init();
}
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollPort.java Wed Jul 05 19:10:19 2017 +0200
@@ -318,6 +318,6 @@
private static native void close0(int fd);
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -196,8 +196,4 @@
}
return this;
}
-
- static {
- Util.load();
- }
}
--- a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -31,7 +31,7 @@
{
static {
- Util.load();
+ IOUtil.load();
init();
}
--- a/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java Wed Jul 05 19:10:19 2017 +0200
@@ -235,6 +235,6 @@
private static native int peerPort0(int fd);
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/KQueue.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/KQueue.java Wed Jul 05 19:10:19 2017 +0200
@@ -115,6 +115,6 @@
throws IOException;
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/KQueuePort.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/KQueuePort.java Wed Jul 05 19:10:19 2017 +0200
@@ -326,6 +326,6 @@
private static native void close0(int fd);
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/NativeThread.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/NativeThread.java Wed Jul 05 19:10:19 2017 +0200
@@ -54,7 +54,7 @@
private static native void init();
static {
- Util.load();
+ IOUtil.load();
init();
}
--- a/jdk/src/solaris/classes/sun/nio/ch/PollArrayWrapper.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/PollArrayWrapper.java Wed Jul 05 19:10:19 2017 +0200
@@ -126,4 +126,7 @@
private static native void interrupt(int fd);
+ static {
+ IOUtil.load();
+ }
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SinkChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -37,7 +37,7 @@
{
// Used to make native read and write calls
- private static NativeDispatcher nd;
+ private static final NativeDispatcher nd = new FileDispatcherImpl();
// The file descriptor associated with this channel
FileDescriptor fd;
@@ -206,10 +206,4 @@
throw new IndexOutOfBoundsException();
return write(Util.subsequence(srcs, offset, length));
}
-
- static {
- Util.load();
- nd = new FileDispatcherImpl();
- }
-
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java Wed Jul 05 19:10:19 2017 +0200
@@ -260,6 +260,6 @@
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SourceChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -37,7 +37,7 @@
{
// Used to make native read and write calls
- private static NativeDispatcher nd;
+ private static final NativeDispatcher nd = new FileDispatcherImpl();
// The file descriptor associated with this channel
FileDescriptor fd;
@@ -206,10 +206,4 @@
}
}
}
-
- static {
- Util.load();
- nd = new FileDispatcherImpl();
- }
-
}
--- a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -345,7 +345,7 @@
throws IOException;
static {
- Util.load();
+ IOUtil.load();
initIDs();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -748,6 +748,6 @@
private static native void checkConnect(int fdVal) throws IOException;
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -1106,7 +1106,7 @@
boolean ready) throws IOException;
static {
- Util.load(); /* loads nio & net native libraries */
+ IOUtil.load(); /* loads nio & net native libraries */
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
--- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -995,7 +995,7 @@
}
static {
- Util.load(); /* loads nio & net native libraries */
+ IOUtil.load(); /* loads nio & net native libraries */
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
--- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -426,7 +426,7 @@
FileDescriptor newfd, InetSocketAddress[] isaa) throws IOException;
static {
- Util.load(); // loads nio & net native libraries
+ IOUtil.load(); // loads nio & net native libraries
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
--- a/jdk/src/windows/classes/sun/nio/ch/DatagramDispatcher.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/DatagramDispatcher.java Wed Jul 05 19:10:19 2017 +0200
@@ -36,7 +36,7 @@
class DatagramDispatcher extends NativeDispatcher
{
static {
- Util.load();
+ IOUtil.load();
}
int read(FileDescriptor fd, long address, int len) throws IOException {
--- a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -32,7 +32,7 @@
class FileDispatcherImpl extends FileDispatcher
{
static {
- Util.load();
+ IOUtil.load();
}
/**
--- a/jdk/src/windows/classes/sun/nio/ch/FileKey.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/FileKey.java Wed Jul 05 19:10:19 2017 +0200
@@ -73,6 +73,7 @@
private static native void initIDs();
static {
+ IOUtil.load();
initIDs();
}
}
--- a/jdk/src/windows/classes/sun/nio/ch/Iocp.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/Iocp.java Wed Jul 05 19:10:19 2017 +0200
@@ -443,7 +443,7 @@
private static native String getErrorMessage(int error);
static {
- Util.load();
+ IOUtil.load();
initIDs();
// thread agnostic I/O on Vista/2008 or newer
--- a/jdk/src/windows/classes/sun/nio/ch/PipeImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/PipeImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -56,7 +56,6 @@
private static final Random rnd;
static {
- Util.load();
byte[] someBytes = new byte[8];
boolean resultOK = IOUtil.randomBytes(someBytes);
if (resultOK) {
--- a/jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java Wed Jul 05 19:10:19 2017 +0200
@@ -36,7 +36,7 @@
{
static {
- Util.load();
+ IOUtil.load();
}
int read(FileDescriptor fd, long address, int len) throws IOException {
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousFileChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -750,6 +750,6 @@
private static native void close0(long handle);
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -363,7 +363,7 @@
private static native void closesocket0(long socket) throws IOException;
static {
- Util.load();
+ IOUtil.load();
initIDs();
}
}
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -919,7 +919,7 @@
private static native void closesocket0(long socket) throws IOException;
static {
- Util.load();
+ IOUtil.load();
initIDs();
}
}
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java Wed Jul 05 19:10:19 2017 +0200
@@ -611,6 +611,6 @@
}
static {
- Util.load();
+ IOUtil.load();
}
}
--- a/jdk/test/ProblemList.txt Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/ProblemList.txt Wed Jul 05 19:10:19 2017 +0200
@@ -208,7 +208,7 @@
# jdk_io
# 7160013
-java/io/File/MaxPathLength.java windows-all
+#java/io/File/MaxPathLength.java windows-all
############################################################################
@@ -336,12 +336,6 @@
# Filed 6653793
com/sun/jdi/RedefineCrossEvent.java generic-all
-# Filed 6987312
-com/sun/jdi/DoubleAgentTest.java generic-all
-
-# Filed 7020857
-com/sun/jdi/FieldWatchpoints.java generic-all
-
# Filed 6402201
com/sun/jdi/ProcessAttachTest.sh generic-all
--- a/jdk/test/TEST.ROOT Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/TEST.ROOT Wed Jul 05 19:10:19 2017 +0200
@@ -9,3 +9,6 @@
# Tests that cannot run concurrently
exclusiveAccess.dirs=java/rmi/Naming java/util/Currency java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi
+
+# Group definitions
+groups=TEST.groups [closed/TEST.groups]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/TEST.groups Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,214 @@
+# 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.
+#
+
+jdk_lang = \
+ java/lang \
+ -java/lang/management \
+ -java/lang/instrument \
+ sun/invoke \
+ sun/misc \
+ sun/reflect \
+ vm
+
+jdk_util = \
+ java/util \
+ sun/util
+
+jdk_math = \
+ java/math
+
+jdk_io = \
+ java/io
+
+jdk_nio = \
+ java/nio \
+ sun/nio
+
+jdk_net = \
+ java/net \
+ com/sun/net \
+ com/oracle/net \
+ sun/net
+
+jdk_time = \
+ java/time
+
+jdk_rmi = \
+ java/rmi \
+ javax/rmi/ssl \
+ sun/rmi
+
+jdk_security1 = \
+ java/security
+
+jdk_security2 = \
+ javax/crypto \
+ javax/xml/crypto \
+ com/sun/crypto
+
+jdk_security3 = \
+ javax/security \
+ com/sun/security \
+ com/sun/org/apache/xml/internal/security \
+ com/oracle/security \
+ sun/security \
+ lib/security
+
+jdk_security = \
+ :jdk_security1 \
+ :jdk_security2 \
+ :jdk_security3
+
+jdk_text = \
+ java/text \
+ sun/text
+
+jdk_management = \
+ java/lang/management \
+ com/sun/management \
+ sun/management
+
+jdk_instrument = \
+ java/lang/instrument
+
+jdk_jmx = \
+ javax/management \
+ com/sun/jmx
+
+jdk_jdi = \
+ com/sun/jdi
+
+#
+# Tool (and tool API) tests are split into core and svc groups
+#
+core_tools = \
+ tools \
+ com/sun/tools/extcheck \
+ sun/tools/java \
+ sun/tools/native2ascii \
+ sun/tools/jrunscript
+
+svc_tools = \
+ com/sun/tools/attach \
+ com/sun/tracing \
+ sun/tools \
+ -sun/tools/java \
+ -sun/tools/native2ascii \
+ -sun/tools/jrunscript \
+ sun/jvmstat \
+ demo/jvmti
+
+jdk_tools = \
+ :core_tools \
+ :svc_tools
+
+#
+# Catch-all for other areas with a small number of tests
+#
+jdk_other = \
+ java/sql \
+ javax/sql \
+ javax/naming \
+ javax/script \
+ javax/smartcardio \
+ javax/xml \
+ -javax/xml/crypto \
+ jdk/asm \
+ jdk/lambda \
+ com/sun/jndi \
+ com/sun/corba \
+ lib/testlibrary \
+ demo/zipfs \
+ sample
+
+#
+# SCTP is its own group as it is highly sensitive to kernel/network config
+#
+jdk_sctp = \
+ com/sun/nio/sctp
+
+
+#
+# core group to run all core area tests
+#
+jdk_core = \
+ :jdk_lang \
+ :jdk_util \
+ :jdk_math \
+ :jdk_io \
+ :jdk_nio \
+ :jdk_net \
+ :jdk_rmi \
+ :jdk_time \
+ :jdk_security \
+ :jdk_text \
+ :core_tools \
+ :jdk_other
+
+#
+# svc group to run all serviceability area tests
+#
+jdk_svc = \
+ :jdk_management \
+ :jdk_instrument \
+ :jdk_jmx \
+ :jdk_jdi \
+ :svc_tools
+
+#############################
+
+#
+# Client area groups
+#
+
+jdk_awt = \
+ java/awt \
+ com/sun/awt \
+ com/apple/eawt \
+ sun/awt
+
+jdk_2d = \
+ javax/print \
+ sun/pisces \
+ sun/java2d
+
+jdk_beans = \
+ java/beans
+
+jdk_swing = \
+ javax/accessibility \
+ javax/swing \
+ com/sun/java/swing
+
+jdk_sound = \
+ javax/sound
+
+jdk_imageio = \
+ javax/imageio
+
+jdk_desktop = \
+ :jdk_awt \
+ :jdk_2d \
+ :jdk_beans \
+ :jdk_swing \
+ :jdk_sound \
+ :jdk_imageio
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/BufferedInputStream/LargeCopyWithMark.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * 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 7129312
+ * @summary BufferedInputStream calculates negative array size with large
+ * streams and mark
+ * @library /lib/testlibrary
+ * @run main/othervm LargeCopyWithMark
+ */
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import static jdk.testlibrary.ProcessTools.*;
+
+
+public class LargeCopyWithMark {
+
+ public static void main(String[] args) throws Exception {
+ if (! System.getProperty("os.arch").contains("64")) {
+ System.out.println("Test runs on 64 bit platforms");
+ return;
+ }
+ ProcessBuilder pb = createJavaProcessBuilder("-Xmx4G",
+ "-ea:LargeCopyWithMark$Child",
+ "LargeCopyWithMark$Child");
+ int res = pb.inheritIO().start().waitFor();
+ if (res != 0) {
+ throw new AssertionError("Test failed: exit code = " + res);
+ }
+ }
+
+ public static class Child {
+ static final int BUFF_SIZE = 8192;
+ static final int BIS_BUFF_SIZE = Integer.MAX_VALUE / 2 + 100;
+ static final long BYTES_TO_COPY = 2L * Integer.MAX_VALUE;
+
+ static {
+ assert BIS_BUFF_SIZE * 2 < 0 : "doubling must overflow";
+ }
+
+ public static void main(String[] args) throws Exception {
+ byte[] buff = new byte[BUFF_SIZE];
+
+ try (InputStream myis = new MyInputStream(BYTES_TO_COPY);
+ InputStream bis = new BufferedInputStream(myis, BIS_BUFF_SIZE);
+ OutputStream myos = new MyOutputStream()) {
+
+ // will require a buffer bigger than BIS_BUFF_SIZE
+ bis.mark(BIS_BUFF_SIZE + 100);
+
+ for (;;) {
+ int count = bis.read(buff, 0, BUFF_SIZE);
+ if (count == -1)
+ break;
+ myos.write(buff, 0, count);
+ }
+ } catch (java.lang.NegativeArraySizeException e) {
+ e.printStackTrace();
+ System.exit(11);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
+
+class MyInputStream extends InputStream {
+ private long bytesLeft;
+ public MyInputStream(long bytesLeft) {
+ this.bytesLeft = bytesLeft;
+ }
+ @Override public int read() throws IOException {
+ return 0;
+ }
+ @Override public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+ @Override public int read(byte[] b, int off, int len) throws IOException {
+ if (bytesLeft <= 0)
+ return -1;
+ long result = Math.min(bytesLeft, (long)len);
+ bytesLeft -= result;
+ return (int)result;
+ }
+ @Override public int available() throws IOException {
+ return (bytesLeft > 0) ? 1 : 0;
+ }
+}
+
+class MyOutputStream extends OutputStream {
+ @Override public void write(int b) throws IOException {}
+ @Override public void write(byte[] b) throws IOException {}
+ @Override public void write(byte[] b, int off, int len) throws IOException {}
+}
--- a/jdk/test/java/io/File/MaxPathLength.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/io/File/MaxPathLength.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -27,6 +27,7 @@
*/
import java.io.*;
+import java.nio.file.Files;
public class MaxPathLength {
private static String sep = File.separator;
@@ -87,10 +88,8 @@
System.err.println("Warning: Test directory structure exists already!");
return;
}
- boolean couldMakeTestDirectory = dirFile.mkdirs();
- if (!couldMakeTestDirectory) {
- throw new RuntimeException ("Could not create test directory structure");
- }
+ Files.createDirectories(dirFile.toPath());
+
try {
if (tryAbsolute)
dirFile = new File(dirFile.getCanonicalPath());
--- a/jdk/test/java/io/pathNames/General.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/io/pathNames/General.java Wed Jul 05 19:10:19 2017 +0200
@@ -28,6 +28,7 @@
import java.io.*;
import java.util.*;
+import java.nio.file.*;
public class General {
@@ -57,7 +58,7 @@
for (int i = 0; i < dl.length; i++) {
File f = new File(subdir, dl[i]);
File df = new File(dir, f.getPath());
- if (df.exists() && df.isFile()) {
+ if (Files.isRegularFile(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
return f.getPath();
}
}
@@ -65,7 +66,7 @@
File f = (subdir.length() == 0) ? new File(dl[i])
: new File(subdir, dl[i]);
File df = new File(dir, f.getPath());
- if (df.exists() && df.isDirectory()) {
+ if (Files.isDirectory(df.toPath(), LinkOption.NOFOLLOW_LINKS)) {
String[] dl2 = df.list();
if (dl2 != null) {
String ff = findSomeFile(dir, f.getPath(), dl2);
@@ -90,7 +91,7 @@
}
for (int i = 0; i < dl.length; i++) {
File f = new File(dir, dl[i]);
- if (f.isFile()) {
+ if (Files.isRegularFile(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
return dl[i];
}
}
@@ -127,7 +128,7 @@
}
for (int i = 0; i < dl.length; i++) {
File f = new File(d, dl[i]);
- if (f.isDirectory()) {
+ if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS)) {
String[] dl2 = f.list();
if (dl2 == null || dl2.length >= 250) {
/* Heuristic to avoid scanning huge directories */
@@ -314,7 +315,7 @@
/* Normal name */
if (f.exists()) {
- if (f.isDirectory() && f.list() != null) {
+ if (Files.isDirectory(f.toPath(), LinkOption.NOFOLLOW_LINKS) && f.list() != null) {
if ((n = findSomeFile(ans, create)) != null)
checkSlashes(d, create, ans + n, ask + n);
if ((n = findSomeDir(ans, create)) != null)
--- a/jdk/test/java/lang/SecurityManager/CheckPackageAccess.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/lang/SecurityManager/CheckPackageAccess.java Wed Jul 05 19:10:19 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6741606 7146431 8000450
+ * @bug 6741606 7146431 8000450 8019830
* @summary Make sure all restricted packages listed in the package.access
* property in the java.security file are blocked
* @run main/othervm CheckPackageAccess
@@ -54,6 +54,7 @@
"com.sun.imageio.",
"com.sun.istack.internal.",
"com.sun.jmx.",
+ "com.sun.media.sound.",
"com.sun.proxy.",
"com.sun.org.apache.bcel.internal.",
"com.sun.org.apache.regexp.internal.",
--- a/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -28,6 +28,9 @@
*/
import java.lang.annotation.Retention;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
@@ -66,17 +69,6 @@
}
}
- static void dumpState(Task task) {
- System.err.println(
- "Task[" + task.getName() + "].state: " +
- task.getState() + " ..."
- );
- for (StackTraceElement ste : task.getStackTrace()) {
- System.err.println("\tat " + ste);
- }
- System.err.println();
- }
-
public static void main(String[] args) throws Exception {
CountDownLatch prepareLatch = new CountDownLatch(2);
AtomicInteger goLatch = new AtomicInteger(1);
@@ -88,18 +80,22 @@
prepareLatch.await();
// let them go
goLatch.set(0);
- // attempt to join them
- taskA.join(5000L);
- taskB.join(5000L);
-
- if (taskA.isAlive() || taskB.isAlive()) {
- dumpState(taskA);
- dumpState(taskB);
- throw new IllegalStateException(
- taskA.getState() == Thread.State.BLOCKED &&
- taskB.getState() == Thread.State.BLOCKED
- ? "deadlock detected"
- : "unexpected condition");
+ // obtain ThreadMXBean
+ ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
+ // wait for threads to finish or dead-lock
+ while (taskA.isAlive() || taskB.isAlive()) {
+ // attempt to join threads
+ taskA.join(500L);
+ taskB.join(500L);
+ // detect dead-lock
+ long[] deadlockedIds = threadBean.findMonitorDeadlockedThreads();
+ if (deadlockedIds != null && deadlockedIds.length > 0) {
+ StringBuilder sb = new StringBuilder("deadlock detected:\n\n");
+ for (ThreadInfo ti : threadBean.getThreadInfo(deadlockedIds, Integer.MAX_VALUE)) {
+ sb.append(ti);
+ }
+ throw new IllegalStateException(sb.toString());
+ }
}
}
}
--- a/jdk/test/java/lang/annotation/TypeAnnotationReflection.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/lang/annotation/TypeAnnotationReflection.java Wed Jul 05 19:10:19 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8004698 8007073
+ * @bug 8004698 8007073 8022343
* @summary Unit test for type annotations
*/
@@ -58,7 +58,7 @@
}
private static void testSuper() throws Exception {
- check(Object.class.getAnnotatedSuperclass().getAnnotations().length == 0);
+ check(Object.class.getAnnotatedSuperclass() == null);
check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0);
AnnotatedType a;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * 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 8022343
+ * @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so
+ */
+
+public class GetAnnotatedSuperclass {
+ private static final Class<?>[] testData = {
+ Object.class,
+ If.class,
+ Object[].class,
+ void.class,
+ int.class,
+ };
+
+ public static void main(String[] args) throws Exception {
+ int failed = 0;
+ for (Class<?> toTest : testData) {
+ Object res = toTest.getAnnotatedSuperclass();
+
+ if (res != null) {
+ failed++;
+ System.out.println(toTest + ".getAnnotatedSuperclass() returns: "
+ + res + ", should be null");
+ }
+ }
+
+ if (failed != 0)
+ throw new RuntimeException("Test failed, check log for details");
+ }
+
+ interface If {}
+}
--- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java Wed Jul 05 19:10:19 2017 +0200
@@ -33,10 +33,10 @@
* @author Mandy Chung
*
* @build ResetPeakMemoryUsage MemoryUtil
- * @run main/othervm -XX:+UseSerialGC -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+UseConcMarkSweepGC -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+UseParallelGC -Xmn8m ResetPeakMemoryUsage
- * @run main/othervm -XX:+UseG1GC -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseSerialGC -Xms256m -XX:MarkSweepAlwaysCompactCount=1 -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -Xms256m -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseParallelGC -Xms256m -Xmn8m ResetPeakMemoryUsage
+ * @run main/othervm -XX:+PrintGCDetails -XX:+UseG1GC -Xms256m -Xmn8m -XX:G1HeapRegionSize=1m ResetPeakMemoryUsage
*/
import java.lang.management.*;
--- a/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/math/BigDecimal/IntegralDivisionTests.java Wed Jul 05 19:10:19 2017 +0200
@@ -22,7 +22,7 @@
*/
/*
* @test
- * @bug 4904082 4917089 6337226
+ * @bug 4904082 4917089 6337226 6378503
* @summary Tests that integral division and related methods return the proper result and scale.
* @author Joseph D. Darcy
*/
@@ -47,6 +47,9 @@
{new BigDecimal("400e1"), new BigDecimal("5"), new BigDecimal("80e1")},
{new BigDecimal("400e1"), new BigDecimal("4.999999999"), new BigDecimal("8e2")},
{new BigDecimal("40e2"), new BigDecimal("5"), new BigDecimal("8e2")},
+ {BigDecimal.valueOf(1, Integer.MIN_VALUE),
+ BigDecimal.valueOf(1, -(Integer.MAX_VALUE & 0x7fffff00)),
+ BigDecimal.valueOf(1, -256)},
};
for(BigDecimal [] testCase: moreTestCases) {
--- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java Wed Jul 05 19:10:19 2017 +0200
@@ -54,60 +54,66 @@
@SuppressWarnings("unchecked")
static void doTest(Path top) throws Exception {
FileSystem fs = top.getFileSystem();
- WatchService watcher = fs.newWatchService();
+ try (WatchService watcher = fs.newWatchService()) {
- // create directories and files
- int nDirs = 5 + rand.nextInt(20);
- int nFiles = 50 + rand.nextInt(50);
- Path[] dirs = new Path[nDirs];
- Path[] files = new Path[nFiles];
- for (int i=0; i<nDirs; i++) {
- dirs[i] = Files.createDirectory(top.resolve("dir" + i));
- }
- for (int i=0; i<nFiles; i++) {
- Path dir = dirs[rand.nextInt(nDirs)];
- files[i] = Files.createFile(dir.resolve("file" + i));
- }
+ // create directories and files
+ int nDirs = 5 + rand.nextInt(20);
+ int nFiles = 50 + rand.nextInt(50);
+ Path[] dirs = new Path[nDirs];
+ Path[] files = new Path[nFiles];
+ for (int i=0; i<nDirs; i++) {
+ dirs[i] = Files.createDirectory(top.resolve("dir" + i));
+ }
+ for (int i=0; i<nFiles; i++) {
+ Path dir = dirs[rand.nextInt(nDirs)];
+ files[i] = Files.createFile(dir.resolve("file" + i));
+ }
- // register the directories (random sensitivity)
- register(dirs, watcher);
+ // register the directories (random sensitivity)
+ register(dirs, watcher);
- // sleep a bit here to ensure that modification to the first file
- // can be detected by polling implementations (ie: last modified time
- // may not change otherwise).
- try { Thread.sleep(1000); } catch (InterruptedException e) { }
+ // sleep a bit here to ensure that modification to the first file
+ // can be detected by polling implementations (ie: last modified time
+ // may not change otherwise).
+ try { Thread.sleep(1000); } catch (InterruptedException e) { }
- // modify files and check that events are received
- for (int i=0; i<10; i++) {
- Path file = files[rand.nextInt(nFiles)];
- System.out.println("Modify: " + file);
- try (OutputStream out = Files.newOutputStream(file)) {
- out.write(new byte[100]);
+ // modify files and check that events are received
+ for (int i=0; i<10; i++) {
+ Path file = files[rand.nextInt(nFiles)];
+ System.out.println("Modify: " + file);
+ try (OutputStream out = Files.newOutputStream(file)) {
+ out.write(new byte[100]);
+ }
+
+ System.out.println("Waiting for event(s)...");
+ boolean eventReceived = false;
+ WatchKey key = watcher.take();
+ do {
+ for (WatchEvent<?> event: key.pollEvents()) {
+ if (event.kind() != ENTRY_MODIFY)
+ throw new RuntimeException("Unexpected event: " + event);
+ Path name = ((WatchEvent<Path>)event).context();
+ if (name.equals(file.getFileName())) {
+ eventReceived = true;
+ break;
+ }
+ }
+ key.reset();
+ key = watcher.poll(1, TimeUnit.SECONDS);
+ } while (key != null && !eventReceived);
+
+ // we should have received at least one ENTRY_MODIFY event
+ if (eventReceived) {
+ System.out.println("Event OK");
+ } else {
+ throw new RuntimeException("No ENTRY_MODIFY event received for " + file);
+ }
+
+ // re-register the directories to force changing their sensitivity
+ // level
+ register(dirs, watcher);
}
- System.out.println("Waiting for event...");
- WatchKey key = watcher.take();
- WatchEvent<?> event = key.pollEvents().iterator().next();
- if (event.kind() != ENTRY_MODIFY)
- throw new RuntimeException("Unexpected event: " + event);
- Path name = ((WatchEvent<Path>)event).context();
- if (!name.equals(file.getFileName()))
- throw new RuntimeException("Unexpected context: " + name);
- System.out.println("Event OK");
-
- // drain events (to avoid interference)
- do {
- key.pollEvents();
- key.reset();
- key = watcher.poll(1, TimeUnit.SECONDS);
- } while (key != null);
-
- // re-register the directories to force changing their sensitivity
- // level
- register(dirs, watcher);
}
-
- // done
- watcher.close();
}
public static void main(String[] args) throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Arrays/TimSortStackSize.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,116 @@
+/*
+ * 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 8011944
+ * @summary Test TimSort stack size
+ */
+import java.util.Arrays;
+import java.util.ArrayDeque;
+
+public class TimSortStackSize {
+
+ public static void main(String[] args) {
+ testComparableTimSort();
+ testTimSort();
+ }
+
+ static void testComparableTimSort() {
+ System.out.printf("testComparableTimSort()%n");
+ Arrays.sort(genData());
+ }
+
+ static void testTimSort() {
+ System.out.printf("testTimSort()%n");
+ Arrays.sort(genData(), Integer::compare);
+ }
+
+ private static final int MIN = 16;
+
+ private static final int BOUND1 = 2 * MIN + 1;
+ private static final int BOUND2 = BOUND1 + MIN + 2;
+ private static final int BOUND3 = BOUND1 + 1 + BOUND2;
+ private static final int BOUND4 = BOUND2 + 1 + BOUND3;
+ private static final int BOUND5 = BOUND3 + 1 + BOUND4;
+
+ static int build(int size, int B, ArrayDeque<Integer> chunks) {
+ chunks.addFirst(B);
+ if (size < BOUND1) {
+ chunks.addFirst(size);
+ return size;
+ }
+
+ int asize = (size + 2) / 2;
+ if (size >= BOUND2 && asize < BOUND1) {
+ asize = BOUND1;
+ } else if (size >= BOUND3 && asize < BOUND2) {
+ asize = BOUND2;
+ } else if (size >= BOUND4 && asize < BOUND3) {
+ asize = BOUND3;
+ } else if (size >= BOUND5 && asize < BOUND4) {
+ asize = BOUND4;
+ }
+ if (size - asize >= B) {
+ throw new AssertionError(" " + size + " , " + asize + " , " + B);
+ }
+ return build(asize, size - asize, chunks);
+ }
+
+ static Integer[] genData() {
+ ArrayDeque<Integer> chunks = new ArrayDeque<Integer>();
+ chunks.addFirst(MIN);
+
+ int B = MIN + 4;
+ int A = B + MIN + 1;
+
+ for (int i = 0; i < 8; i++) {
+ int eps = build(A, B, chunks);
+ B = B + A + 1;
+ A = B + eps + 1;
+ }
+ chunks.addFirst(B);
+ chunks.addFirst(A);
+ int total = 0;
+ for (Integer len : chunks) {
+ total += len;
+ }
+ int pow = MIN;
+ while (pow < total) {
+ pow += pow;
+ }
+ chunks.addLast(pow - total);
+ System.out.println(" Total: " + total);
+ Integer[] array = new Integer[pow];
+ int off = 0;
+ int pos = 0;
+ for (Integer len : chunks) {
+ for (int i = 0; i < len; i++) {
+ array[pos++] = Integer.valueOf(i == 0 ? 0 : 1);
+ }
+ off++;
+ }
+ return array;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Collections/Wrappers.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,146 @@
+/*
+ * 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
+ * @run testng Wrappers
+ * @summary Ensure Collections wrapping classes provide non-default implementations
+ */
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+import static org.testng.Assert.assertFalse;
+
+@Test(groups = "unit")
+public class Wrappers {
+ static Object[][] collections;
+
+ @DataProvider(name="collections")
+ public static Object[][] collectionCases() {
+ if (collections != null) {
+ return collections;
+ }
+
+ List<Object[]> cases = new ArrayList<>();
+ LinkedList<Integer> seedList = new LinkedList<>();
+ ArrayList<Integer> seedRandomAccess = new ArrayList<>();
+ TreeSet<Integer> seedSet = new TreeSet<>();
+ TreeMap<Integer, Integer> seedMap = new TreeMap<>();
+
+ for (int i = 1; i <= 10; i++) {
+ seedList.add(i);
+ seedRandomAccess.add(i);
+ seedSet.add(i);
+ seedMap.put(i, i);
+ }
+
+ cases.add(new Object[] { Collections.unmodifiableCollection(seedList) });
+ cases.add(new Object[] { Collections.unmodifiableList(seedList) });
+ cases.add(new Object[] { Collections.unmodifiableList(seedRandomAccess) });
+ cases.add(new Object[] { Collections.unmodifiableSet(seedSet) });
+ cases.add(new Object[] { Collections.unmodifiableSortedSet(seedSet) });
+ cases.add(new Object[] { Collections.unmodifiableNavigableSet(seedSet) });
+
+ // As sets from map also need to be unmodifiable, thus a wrapping
+ // layer exist and should not have default methods
+ cases.add(new Object[] { Collections.unmodifiableMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.unmodifiableMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.unmodifiableMap(seedMap).values() });
+ cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).values() });
+ cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).values() });
+
+ // Synchronized
+ cases.add(new Object[] { Collections.synchronizedCollection(seedList) });
+ cases.add(new Object[] { Collections.synchronizedList(seedList) });
+ cases.add(new Object[] { Collections.synchronizedList(seedRandomAccess) });
+ cases.add(new Object[] { Collections.synchronizedSet(seedSet) });
+ cases.add(new Object[] { Collections.synchronizedSortedSet(seedSet) });
+ cases.add(new Object[] { Collections.synchronizedNavigableSet(seedSet) });
+
+ // As sets from map also need to be synchronized on the map, thus a
+ // wrapping layer exist and should not have default methods
+ cases.add(new Object[] { Collections.synchronizedMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.synchronizedMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.synchronizedMap(seedMap).values() });
+ cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).values() });
+ cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).entrySet() });
+ cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).keySet() });
+ cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).values() });
+
+ // Checked
+ cases.add(new Object[] { Collections.checkedCollection(seedList, Integer.class) });
+ cases.add(new Object[] { Collections.checkedList(seedList, Integer.class) });
+ cases.add(new Object[] { Collections.checkedList(seedRandomAccess, Integer.class) });
+ cases.add(new Object[] { Collections.checkedSet(seedSet, Integer.class) });
+ cases.add(new Object[] { Collections.checkedSortedSet(seedSet, Integer.class) });
+ cases.add(new Object[] { Collections.checkedNavigableSet(seedSet, Integer.class) });
+ cases.add(new Object[] { Collections.checkedQueue(seedList, Integer.class) });
+
+ // asLifoQueue is another wrapper
+ cases.add(new Object[] { Collections.asLifoQueue(seedList) });
+
+ collections = cases.toArray(new Object[0][]);
+ return collections;
+ }
+
+ static Method[] defaultMethods;
+
+ static {
+ List<Method> list = new ArrayList<>();
+ Method[] methods = Collection.class.getMethods();
+ for (Method m: methods) {
+ if (m.isDefault()) {
+ list.add(m);
+ }
+ }
+ defaultMethods = list.toArray(new Method[0]);
+ }
+
+ @Test(dataProvider = "collections")
+ public static void testAllDefaultMethodsOverridden(Collection c) throws NoSuchMethodException {
+ Class cls = c.getClass();
+ for (Method m: defaultMethods) {
+ Method m2 = cls.getMethod(m.getName(), m.getParameterTypes());
+ // default had been override
+ assertFalse(m2.isDefault(), cls.getCanonicalName());
+ }
+ }
+}
+
--- a/jdk/test/java/util/Comparator/BasicTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/util/Comparator/BasicTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -90,7 +90,7 @@
Thing[] things = new Thing[intValues.length];
for (int i=0; i<intValues.length; i++)
things[i] = new Thing(intValues[i], 0L, 0.0, null);
- Comparator<Thing> comp = Comparator.comparing(new ToIntFunction<Thing>() {
+ Comparator<Thing> comp = Comparator.comparingInt(new ToIntFunction<Thing>() {
@Override
public int applyAsInt(Thing thing) {
return thing.getIntField();
@@ -104,7 +104,7 @@
Thing[] things = new Thing[longValues.length];
for (int i=0; i<longValues.length; i++)
things[i] = new Thing(0, longValues[i], 0.0, null);
- Comparator<Thing> comp = Comparator.comparing(new ToLongFunction<Thing>() {
+ Comparator<Thing> comp = Comparator.comparingLong(new ToLongFunction<Thing>() {
@Override
public long applyAsLong(Thing thing) {
return thing.getLongField();
@@ -118,7 +118,7 @@
Thing[] things = new Thing[doubleValues.length];
for (int i=0; i<doubleValues.length; i++)
things[i] = new Thing(0, 0L, doubleValues[i], null);
- Comparator<Thing> comp = Comparator.comparing(new ToDoubleFunction<Thing>() {
+ Comparator<Thing> comp = Comparator.comparingDouble(new ToDoubleFunction<Thing>() {
@Override
public double applyAsDouble(Thing thing) {
return thing.getDoubleField();
@@ -211,8 +211,8 @@
};
public void testComparatorDefaultMethods() {
- Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
- Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
+ Comparator<People> cmp = Comparator.comparing(People::getFirstName);
+ Comparator<People> cmp2 = Comparator.comparing(People::getLastName);
// reverseOrder
assertComparison(cmp.reversed(), people[1], people[0]);
// thenComparing(Comparator)
@@ -222,20 +222,20 @@
assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
// thenComparing(ToIntFunction)
- assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
+ assertComparison(cmp.thenComparingInt(People::getAge), people[0], people[1]);
+ assertComparison(cmp.thenComparingInt(People::getAge), people[1], people[5]);
// thenComparing(ToLongFunction)
- assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
+ assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[0], people[1]);
+ assertComparison(cmp.thenComparingLong(People::getAgeAsLong), people[1], people[5]);
// thenComparing(ToDoubleFunction)
- assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
- assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
+ assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[0], people[1]);
+ assertComparison(cmp.thenComparingDouble(People::getAgeAsDouble), people[1], people[5]);
}
public void testNullsFirst() {
Comparator<String> strcmp = Comparator.nullsFirst(Comparator.naturalOrder());
- Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
+ Comparator<People> cmp = Comparator.comparing(People::getLastName, strcmp)
.thenComparing(People::getFirstName, strcmp);
// Mary.null vs Mary.Cook - solve by last name
assertComparison(cmp, people[6], people[5]);
@@ -243,7 +243,7 @@
assertComparison(cmp, people[7], people[6]);
// More than one thenComparing
- strcmp = Comparator.nullsFirst(Comparator.comparing((ToIntFunction<String>) String::length)
+ strcmp = Comparator.nullsFirst(Comparator.comparingInt(String::length)
.thenComparing(String.CASE_INSENSITIVE_ORDER));
assertComparison(strcmp, null, "abc");
assertComparison(strcmp, "ab", "abc");
@@ -273,7 +273,7 @@
public void testNullsLast() {
Comparator<String> strcmp = Comparator.nullsLast(Comparator.naturalOrder());
- Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
+ Comparator<People> cmp = Comparator.comparing(People::getLastName, strcmp)
.thenComparing(People::getFirstName, strcmp);
// Mary.null vs Mary.Cook - solve by last name
assertComparison(cmp, people[5], people[6]);
@@ -281,7 +281,7 @@
assertComparison(cmp, people[7], people[6]);
// More than one thenComparing
- strcmp = Comparator.nullsLast(Comparator.comparing((ToIntFunction<String>) String::length)
+ strcmp = Comparator.nullsLast(Comparator.comparingInt(String::length)
.thenComparing(String.CASE_INSENSITIVE_ORDER));
assertComparison(strcmp, "abc", null);
assertComparison(strcmp, "ab", "abc");
@@ -341,28 +341,28 @@
} catch (NullPointerException npe) {}
try {
- Comparator<People> cmp = Comparator.comparing((Function<People, String>) null, Comparator.<String>naturalOrder());
+ Comparator<People> cmp = Comparator.comparing(null, Comparator.<String>naturalOrder());
fail("comparing(null, cmp) should throw NPE");
} catch (NullPointerException npe) {}
try {
- Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName, null);
+ Comparator<People> cmp = Comparator.comparing(People::getFirstName, null);
fail("comparing(f, null) should throw NPE");
} catch (NullPointerException npe) {}
try {
- Comparator<People> cmp = Comparator.comparing((Function<People, String>) null);
+ Comparator<People> cmp = Comparator.comparing(null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
- Comparator<People> cmp = Comparator.comparing((ToIntFunction<People>) null);
+ Comparator<People> cmp = Comparator.comparingInt(null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
- Comparator<People> cmp = Comparator.comparing((ToLongFunction<People>) null);
+ Comparator<People> cmp = Comparator.comparingLong(null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
- Comparator<People> cmp = Comparator.comparing((ToDoubleFunction<People>) null);
+ Comparator<People> cmp = Comparator.comparingDouble(null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
}
--- a/jdk/test/java/util/Map/EntryComparators.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/util/Map/EntryComparators.java Wed Jul 05 19:10:19 2017 +0200
@@ -115,8 +115,8 @@
// Comparator<People> cmp = Comparator.naturalOrder(); // Should fail to compiler as People is not comparable
// We can use simple comparator, but those have been tested above.
// Thus choose to do compose for some level of interation.
- Comparator<People> cmp1 = Comparator.comparing((Function<People, String>) People::getFirstName);
- Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
+ Comparator<People> cmp1 = Comparator.comparing(People::getFirstName);
+ Comparator<People> cmp2 = Comparator.comparing(People::getLastName);
Comparator<People> cmp = cmp1.thenComparing(cmp2);
assertPairComparison(people[0], people[0], people[1], people[1],
--- a/jdk/test/java/util/Random/RandomStreamTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/util/Random/RandomStreamTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -82,13 +82,6 @@
assertEquals(destination.size(), count);
}
- @Test(dataProvider = "suppliers")
- public void testRandomGaussianStream(final Random random, final int count) {
- final List<Double> destination = new ArrayList<>(count);
- random.gaussians().limit(count).forEach(destination::add);
- assertEquals(destination.size(), count);
- }
-
@Test
public void testIntStream() {
final long seed = System.currentTimeMillis();
@@ -132,20 +125,6 @@
}
@Test
- public void testGaussianStream() {
- final long seed = System.currentTimeMillis();
- final Random r1 = new Random(seed);
- final double[] a = new double[SIZE];
- for (int i=0; i < SIZE; i++) {
- a[i] = r1.nextGaussian();
- }
-
- final Random r2 = new Random(seed); // same seed
- final double[] b = r2.gaussians().limit(SIZE).toArray();
- assertEquals(a, b);
- }
-
- @Test
public void testThreadLocalIntStream() throws InterruptedException, ExecutionException, TimeoutException {
ThreadLocalRandom tlr = ThreadLocalRandom.current();
testRandomResultSupplierConcurrently(() -> tlr.ints().limit(SIZE).boxed().collect(toList()));
@@ -163,12 +142,6 @@
testRandomResultSupplierConcurrently(() -> tlr.doubles().limit(SIZE).boxed().collect(toList()));
}
- @Test
- public void testThreadLocalGaussianStream() throws InterruptedException, ExecutionException, TimeoutException {
- ThreadLocalRandom tlr = ThreadLocalRandom.current();
- testRandomResultSupplierConcurrently(() -> tlr.gaussians().limit(SIZE).boxed().collect(toList()));
- }
-
<T> void testRandomResultSupplierConcurrently(Supplier<T> s) throws InterruptedException, ExecutionException, TimeoutException {
// Produce 10 completable future tasks
final int tasks = 10;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Random/RandomTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,430 @@
+/*
+ * 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.
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiConsumer;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @run testng RandomTest
+ * @summary test methods on Random
+ */
+@Test
+public class RandomTest {
+
+ // Note: this test was adapted from the 166 TCK ThreadLocalRandomTest test
+ // and modified to be a TestNG test
+
+ /*
+ * Testing coverage notes:
+ *
+ * We don't test randomness properties, but only that repeated
+ * calls, up to NCALLS tries, produce at least one different
+ * result. For bounded versions, we sample various intervals
+ * across multiples of primes.
+ */
+
+ // max numbers of calls to detect getting stuck on one value
+ static final int NCALLS = 10000;
+
+ // max sampled int bound
+ static final int MAX_INT_BOUND = (1 << 28);
+
+ // max sampled long bound
+ static final long MAX_LONG_BOUND = (1L << 42);
+
+ // Number of replications for other checks
+ static final int REPS = 20;
+
+ /**
+ * Repeated calls to nextInt produce at least two distinct results
+ */
+ public void testNextInt() {
+ Random r = new Random();
+ int f = r.nextInt();
+ int i = 0;
+ while (i < NCALLS && r.nextInt() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextLong produce at least two distinct results
+ */
+ public void testNextLong() {
+ Random r = new Random();
+ long f = r.nextLong();
+ int i = 0;
+ while (i < NCALLS && r.nextLong() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextBoolean produce at least two distinct results
+ */
+ public void testNextBoolean() {
+ Random r = new Random();
+ boolean f = r.nextBoolean();
+ int i = 0;
+ while (i < NCALLS && r.nextBoolean() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextFloat produce at least two distinct results
+ */
+ public void testNextFloat() {
+ Random r = new Random();
+ float f = r.nextFloat();
+ int i = 0;
+ while (i < NCALLS && r.nextFloat() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextDouble produce at least two distinct results
+ */
+ public void testNextDouble() {
+ Random r = new Random();
+ double f = r.nextDouble();
+ int i = 0;
+ while (i < NCALLS && r.nextDouble() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextGaussian produce at least two distinct results
+ */
+ public void testNextGaussian() {
+ Random r = new Random();
+ double f = r.nextGaussian();
+ int i = 0;
+ while (i < NCALLS && r.nextGaussian() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * nextInt(negative) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextIntBoundedNeg() {
+ Random r = new Random();
+ int f = r.nextInt(-17);
+ }
+
+ /**
+ * nextInt(bound) returns 0 <= value < bound; repeated calls produce at
+ * least two distinct results
+ */
+ public void testNextIntBounded() {
+ Random r = new Random();
+ // sample bound space across prime number increments
+ for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+ int f = r.nextInt(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = r.nextInt(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * Invoking sized ints, long, doubles, with negative sizes throws
+ * IllegalArgumentException
+ */
+ public void testBadStreamSize() {
+ Random r = new Random();
+ executeAndCatchIAE(() -> r.ints(-1L));
+ executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
+ executeAndCatchIAE(() -> r.longs(-1L));
+ executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
+ executeAndCatchIAE(() -> r.doubles(-1L));
+ executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
+ }
+
+ /**
+ * Invoking bounded ints, long, doubles, with illegal bounds throws
+ * IllegalArgumentException
+ */
+ public void testBadStreamBounds() {
+ Random r = new Random();
+ executeAndCatchIAE(() -> r.ints(2, 1));
+ executeAndCatchIAE(() -> r.ints(10, 42, 42));
+ executeAndCatchIAE(() -> r.longs(-1L, -1L));
+ executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
+
+ testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
+ }
+
+ // An arbitrary finite double value
+ static final double FINITE = Math.PI;
+
+ void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
+ executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
+ executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
+ executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
+ executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
+ executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+
+ // Returns NaN
+// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
+// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+ executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
+
+ // Returns Double.MAX_VALUE
+// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
+
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+ }
+
+ private void executeAndCatchIAE(Runnable r) {
+ executeAndCatch(IllegalArgumentException.class, r);
+ }
+
+ private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+ Exception caught = null;
+ try {
+ r.run();
+ }
+ catch (Exception e) {
+ caught = e;
+ }
+
+ assertNotNull(caught,
+ String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+ expected.getName()));
+ Assert.assertTrue(expected.isInstance(caught),
+ String.format("Exception thrown %s not an instance of %s",
+ caught.getClass().getName(), expected.getName()));
+ }
+
+ /**
+ * A sequential sized stream of ints generates the given number of values
+ */
+ public void testIntsCount() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.ints(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * A sequential sized stream of longs generates the given number of values
+ */
+ public void testLongsCount() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.longs(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * A sequential sized stream of doubles generates the given number of values
+ */
+ public void testDoublesCount() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.doubles(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * Each of a sequential sized stream of bounded ints is within bounds
+ */
+ public void testBoundedInts() {
+ AtomicInteger fails = new AtomicInteger(0);
+ Random r = new Random();
+ long size = 12345L;
+ for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+ for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+ final int lo = least, hi = bound;
+ r.ints(size, lo, hi).
+ forEach(x -> {
+ if (x < lo || x >= hi)
+ fails.getAndIncrement();
+ });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * Each of a sequential sized stream of bounded longs is within bounds
+ */
+ public void testBoundedLongs() {
+ AtomicInteger fails = new AtomicInteger(0);
+ Random r = new Random();
+ long size = 123L;
+ for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+ for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+ final long lo = least, hi = bound;
+ r.longs(size, lo, hi).
+ forEach(x -> {
+ if (x < lo || x >= hi)
+ fails.getAndIncrement();
+ });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * Each of a sequential sized stream of bounded doubles is within bounds
+ */
+ public void testBoundedDoubles() {
+ AtomicInteger fails = new AtomicInteger(0);
+ Random r = new Random();
+ long size = 456;
+ for (double least = 0.00011; least < 1.0e20; least *= 9) {
+ for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+ final double lo = least, hi = bound;
+ r.doubles(size, lo, hi).
+ forEach(x -> {
+ if (x < lo || x >= hi)
+ fails.getAndIncrement();
+ });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * A parallel unsized stream of ints generates at least 100 values
+ */
+ public void testUnsizedIntsCount() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 100;
+ r.ints().limit(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A parallel unsized stream of longs generates at least 100 values
+ */
+ public void testUnsizedLongsCount() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 100;
+ r.longs().limit(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A parallel unsized stream of doubles generates at least 100 values
+ */
+ public void testUnsizedDoublesCount() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 100;
+ r.doubles().limit(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of ints generates at least 100 values
+ */
+ public void testUnsizedIntsCountSeq() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 100;
+ r.ints().limit(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of longs generates at least 100 values
+ */
+ public void testUnsizedLongsCountSeq() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 100;
+ r.longs().limit(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of doubles generates at least 100 values
+ */
+ public void testUnsizedDoublesCountSeq() {
+ LongAdder counter = new LongAdder();
+ Random r = new Random();
+ long size = 100;
+ r.doubles().limit(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/SplittableRandom/SplittableRandomTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,560 @@
+/*
+ * 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.
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.SplittableRandom;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiConsumer;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * @test
+ * @run testng SplittableRandomTest
+ * @run testng/othervm -Djava.util.secureRandomSeed=true SplittableRandomTest
+ * @summary test methods on SplittableRandom
+ */
+@Test
+public class SplittableRandomTest {
+
+ // Note: this test was copied from the 166 TCK SplittableRandomTest test
+ // and modified to be a TestNG test
+
+ /*
+ * Testing coverage notes:
+ *
+ * 1. Many of the test methods are adapted from ThreadLocalRandomTest.
+ *
+ * 2. These tests do not check for random number generator quality.
+ * But we check for minimal API compliance by requiring that
+ * repeated calls to nextX methods, up to NCALLS tries, produce at
+ * least two distinct results. (In some possible universe, a
+ * "correct" implementation might fail, but the odds are vastly
+ * less than that of encountering a hardware failure while running
+ * the test.) For bounded nextX methods, we sample various
+ * intervals across multiples of primes. In other tests, we repeat
+ * under REPS different values.
+ */
+
+ // max numbers of calls to detect getting stuck on one value
+ static final int NCALLS = 10000;
+
+ // max sampled int bound
+ static final int MAX_INT_BOUND = (1 << 28);
+
+ // max sampled long bound
+ static final long MAX_LONG_BOUND = (1L << 42);
+
+ // Number of replications for other checks
+ static final int REPS = 20;
+
+ /**
+ * Repeated calls to nextInt produce at least two distinct results
+ */
+ public void testNextInt() {
+ SplittableRandom sr = new SplittableRandom();
+ int f = sr.nextInt();
+ int i = 0;
+ while (i < NCALLS && sr.nextInt() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextLong produce at least two distinct results
+ */
+ public void testNextLong() {
+ SplittableRandom sr = new SplittableRandom();
+ long f = sr.nextLong();
+ int i = 0;
+ while (i < NCALLS && sr.nextLong() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextDouble produce at least two distinct results
+ */
+ public void testNextDouble() {
+ SplittableRandom sr = new SplittableRandom();
+ double f = sr.nextDouble();
+ int i = 0;
+ while (i < NCALLS && sr.nextDouble() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Two SplittableRandoms created with the same seed produce the
+ * same values for nextLong.
+ */
+ public void testSeedConstructor() {
+ for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863) {
+ SplittableRandom sr1 = new SplittableRandom(seed);
+ SplittableRandom sr2 = new SplittableRandom(seed);
+ for (int i = 0; i < REPS; ++i)
+ assertEquals(sr1.nextLong(), sr2.nextLong());
+ }
+ }
+
+ /**
+ * A SplittableRandom produced by split() of a default-constructed
+ * SplittableRandom generates a different sequence
+ */
+ public void testSplit1() {
+ SplittableRandom sr = new SplittableRandom();
+ for (int reps = 0; reps < REPS; ++reps) {
+ SplittableRandom sc = sr.split();
+ int i = 0;
+ while (i < NCALLS && sr.nextLong() == sc.nextLong())
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * A SplittableRandom produced by split() of a seeded-constructed
+ * SplittableRandom generates a different sequence
+ */
+ public void testSplit2() {
+ SplittableRandom sr = new SplittableRandom(12345);
+ for (int reps = 0; reps < REPS; ++reps) {
+ SplittableRandom sc = sr.split();
+ int i = 0;
+ while (i < NCALLS && sr.nextLong() == sc.nextLong())
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextInt(negative) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextIntBoundedNeg() {
+ SplittableRandom sr = new SplittableRandom();
+ int f = sr.nextInt(-17);
+ }
+
+ /**
+ * nextInt(least >= bound) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextIntBadBounds() {
+ SplittableRandom sr = new SplittableRandom();
+ int f = sr.nextInt(17, 2);
+ }
+
+ /**
+ * nextInt(bound) returns 0 <= value < bound;
+ * repeated calls produce at least two distinct results
+ */
+ public void testNextIntBounded() {
+ SplittableRandom sr = new SplittableRandom();
+ // sample bound space across prime number increments
+ for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+ int f = sr.nextInt(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = sr.nextInt(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextInt(least, bound) returns least <= value < bound;
+ * repeated calls produce at least two distinct results
+ */
+ public void testNextIntBounded2() {
+ SplittableRandom sr = new SplittableRandom();
+ for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+ for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+ int f = sr.nextInt(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = sr.nextInt(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * nextLong(negative) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextLongBoundedNeg() {
+ SplittableRandom sr = new SplittableRandom();
+ long f = sr.nextLong(-17);
+ }
+
+ /**
+ * nextLong(least >= bound) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextLongBadBounds() {
+ SplittableRandom sr = new SplittableRandom();
+ long f = sr.nextLong(17, 2);
+ }
+
+ /**
+ * nextLong(bound) returns 0 <= value < bound;
+ * repeated calls produce at least two distinct results
+ */
+ public void testNextLongBounded() {
+ SplittableRandom sr = new SplittableRandom();
+ for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+ long f = sr.nextLong(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ long j;
+ while (i < NCALLS &&
+ (j = sr.nextLong(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextLong(least, bound) returns least <= value < bound;
+ * repeated calls produce at least two distinct results
+ */
+ public void testNextLongBounded2() {
+ SplittableRandom sr = new SplittableRandom();
+ for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+ for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+ long f = sr.nextLong(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ long j;
+ while (i < NCALLS &&
+ (j = sr.nextLong(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * nextDouble(bound) throws IllegalArgumentException
+ */
+ public void testNextDoubleBadBound() {
+ SplittableRandom sr = new SplittableRandom();
+ executeAndCatchIAE(() -> sr.nextDouble(0.0));
+ executeAndCatchIAE(() -> sr.nextDouble(-0.0));
+ executeAndCatchIAE(() -> sr.nextDouble(+0.0));
+ executeAndCatchIAE(() -> sr.nextDouble(-1.0));
+ executeAndCatchIAE(() -> sr.nextDouble(Double.NaN));
+ executeAndCatchIAE(() -> sr.nextDouble(Double.NEGATIVE_INFINITY));
+
+ // Returns Double.MAX_VALUE
+// executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
+ }
+
+ /**
+ * nextDouble(origin, bound) throws IllegalArgumentException
+ */
+ public void testNextDoubleBadOriginBound() {
+ testDoubleBadOriginBound(new SplittableRandom()::nextDouble);
+ }
+
+ // An arbitrary finite double value
+ static final double FINITE = Math.PI;
+
+ void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
+ executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
+ executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
+ executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
+ executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
+ executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+
+ // Returns NaN
+// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
+// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+ executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
+
+ // Returns Double.MAX_VALUE
+// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
+
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+ }
+
+ /**
+ * nextDouble(least, bound) returns least <= value < bound;
+ * repeated calls produce at least two distinct results
+ */
+ public void testNextDoubleBounded2() {
+ SplittableRandom sr = new SplittableRandom();
+ for (double least = 0.0001; least < 1.0e20; least *= 8) {
+ for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+ double f = sr.nextDouble(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ double j;
+ while (i < NCALLS &&
+ (j = sr.nextDouble(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * Invoking sized ints, long, doubles, with negative sizes throws
+ * IllegalArgumentException
+ */
+ public void testBadStreamSize() {
+ SplittableRandom r = new SplittableRandom();
+ executeAndCatchIAE(() -> r.ints(-1L));
+ executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
+ executeAndCatchIAE(() -> r.longs(-1L));
+ executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
+ executeAndCatchIAE(() -> r.doubles(-1L));
+ executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
+ }
+
+ /**
+ * Invoking bounded ints, long, doubles, with illegal bounds throws
+ * IllegalArgumentException
+ */
+ public void testBadStreamBounds() {
+ SplittableRandom r = new SplittableRandom();
+ executeAndCatchIAE(() -> r.ints(2, 1));
+ executeAndCatchIAE(() -> r.ints(10, 42, 42));
+ executeAndCatchIAE(() -> r.longs(-1L, -1L));
+ executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
+
+ testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
+ }
+
+ private void executeAndCatchIAE(Runnable r) {
+ executeAndCatch(IllegalArgumentException.class, r);
+ }
+
+ private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+ Exception caught = null;
+ try {
+ r.run();
+ }
+ catch (Exception e) {
+ caught = e;
+ }
+
+ assertNotNull(caught,
+ String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+ expected.getName()));
+ Assert.assertTrue(expected.isInstance(caught),
+ String.format("Exception thrown %s not an instance of %s",
+ caught.getClass().getName(), expected.getName()));
+ }
+
+ /**
+ * A parallel sized stream of ints generates the given number of values
+ */
+ public void testIntsCount() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.ints(size).parallel().forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * A parallel sized stream of longs generates the given number of values
+ */
+ public void testLongsCount() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.longs(size).parallel().forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * A parallel sized stream of doubles generates the given number of values
+ */
+ public void testDoublesCount() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.doubles(size).parallel().forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * Each of a parallel sized stream of bounded ints is within bounds
+ */
+ public void testBoundedInts() {
+ AtomicInteger fails = new AtomicInteger(0);
+ SplittableRandom r = new SplittableRandom();
+ long size = 12345L;
+ for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+ for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+ final int lo = least, hi = bound;
+ r.ints(size, lo, hi).parallel().
+ forEach(x -> {if (x < lo || x >= hi)
+ fails.getAndIncrement(); });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * Each of a parallel sized stream of bounded longs is within bounds
+ */
+ public void testBoundedLongs() {
+ AtomicInteger fails = new AtomicInteger(0);
+ SplittableRandom r = new SplittableRandom();
+ long size = 123L;
+ for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+ for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+ final long lo = least, hi = bound;
+ r.longs(size, lo, hi).parallel().
+ forEach(x -> {if (x < lo || x >= hi)
+ fails.getAndIncrement(); });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * Each of a parallel sized stream of bounded doubles is within bounds
+ */
+ public void testBoundedDoubles() {
+ AtomicInteger fails = new AtomicInteger(0);
+ SplittableRandom r = new SplittableRandom();
+ long size = 456;
+ for (double least = 0.00011; least < 1.0e20; least *= 9) {
+ for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+ final double lo = least, hi = bound;
+ r.doubles(size, lo, hi).parallel().
+ forEach(x -> {if (x < lo || x >= hi)
+ fails.getAndIncrement(); });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * A parallel unsized stream of ints generates at least 100 values
+ */
+ public void testUnsizedIntsCount() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 100;
+ r.ints().limit(size).parallel().forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A parallel unsized stream of longs generates at least 100 values
+ */
+ public void testUnsizedLongsCount() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 100;
+ r.longs().limit(size).parallel().forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A parallel unsized stream of doubles generates at least 100 values
+ */
+ public void testUnsizedDoublesCount() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 100;
+ r.doubles().limit(size).parallel().forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of ints generates at least 100 values
+ */
+ public void testUnsizedIntsCountSeq() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 100;
+ r.ints().limit(size).forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of longs generates at least 100 values
+ */
+ public void testUnsizedLongsCountSeq() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 100;
+ r.longs().limit(size).forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of doubles generates at least 100 values
+ */
+ public void testUnsizedDoublesCountSeq() {
+ LongAdder counter = new LongAdder();
+ SplittableRandom r = new SplittableRandom();
+ long size = 100;
+ r.doubles().limit(size).forEach(x -> {counter.increment();});
+ assertEquals(counter.sum(), size);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/ThreadLocalRandom/ThreadLocalRandomTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,559 @@
+/*
+ * 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.
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiConsumer;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @run testng ThreadLocalRandomTest
+ * @summary test methods on ThreadLocalRandom
+ */
+@Test
+public class ThreadLocalRandomTest {
+
+ // Note: this test was copied from the 166 TCK ThreadLocalRandomTest test
+ // and modified to be a TestNG test
+
+ /*
+ * Testing coverage notes:
+ *
+ * We don't test randomness properties, but only that repeated
+ * calls, up to NCALLS tries, produce at least one different
+ * result. For bounded versions, we sample various intervals
+ * across multiples of primes.
+ */
+
+ // max numbers of calls to detect getting stuck on one value
+ static final int NCALLS = 10000;
+
+ // max sampled int bound
+ static final int MAX_INT_BOUND = (1 << 28);
+
+ // max sampled long bound
+ static final long MAX_LONG_BOUND = (1L << 42);
+
+ // Number of replications for other checks
+ static final int REPS = 20;
+
+ /**
+ * setSeed throws UnsupportedOperationException
+ */
+ @Test(expectedExceptions = UnsupportedOperationException.class)
+ public void testSetSeed() {
+ ThreadLocalRandom.current().setSeed(17);
+ }
+
+ /**
+ * Repeated calls to nextInt produce at least two distinct results
+ */
+ public void testNextInt() {
+ int f = ThreadLocalRandom.current().nextInt();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextInt() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextLong produce at least two distinct results
+ */
+ public void testNextLong() {
+ long f = ThreadLocalRandom.current().nextLong();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextLong() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextBoolean produce at least two distinct results
+ */
+ public void testNextBoolean() {
+ boolean f = ThreadLocalRandom.current().nextBoolean();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextBoolean() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextFloat produce at least two distinct results
+ */
+ public void testNextFloat() {
+ float f = ThreadLocalRandom.current().nextFloat();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextFloat() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextDouble produce at least two distinct results
+ */
+ public void testNextDouble() {
+ double f = ThreadLocalRandom.current().nextDouble();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * Repeated calls to nextGaussian produce at least two distinct results
+ */
+ public void testNextGaussian() {
+ double f = ThreadLocalRandom.current().nextGaussian();
+ int i = 0;
+ while (i < NCALLS && ThreadLocalRandom.current().nextGaussian() == f)
+ ++i;
+ assertTrue(i < NCALLS);
+ }
+
+ /**
+ * nextInt(negative) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextIntBoundedNeg() {
+ int f = ThreadLocalRandom.current().nextInt(-17);
+ }
+
+ /**
+ * nextInt(least >= bound) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextIntBadBounds() {
+ int f = ThreadLocalRandom.current().nextInt(17, 2);
+ }
+
+ /**
+ * nextInt(bound) returns 0 <= value < bound; repeated calls produce at
+ * least two distinct results
+ */
+ public void testNextIntBounded() {
+ // sample bound space across prime number increments
+ for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+ int f = ThreadLocalRandom.current().nextInt(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextInt(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextInt(least, bound) returns least <= value < bound; repeated calls
+ * produce at least two distinct results
+ */
+ public void testNextIntBounded2() {
+ for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+ for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+ int f = ThreadLocalRandom.current().nextInt(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ int j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextInt(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * nextLong(negative) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextLongBoundedNeg() {
+ long f = ThreadLocalRandom.current().nextLong(-17);
+ }
+
+ /**
+ * nextLong(least >= bound) throws IllegalArgumentException
+ */
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNextLongBadBounds() {
+ long f = ThreadLocalRandom.current().nextLong(17, 2);
+ }
+
+ /**
+ * nextLong(bound) returns 0 <= value < bound; repeated calls produce at
+ * least two distinct results
+ */
+ public void testNextLongBounded() {
+ for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+ long f = ThreadLocalRandom.current().nextLong(bound);
+ assertTrue(0 <= f && f < bound);
+ int i = 0;
+ long j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextLong(bound)) == f) {
+ assertTrue(0 <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+
+ /**
+ * nextLong(least, bound) returns least <= value < bound; repeated calls
+ * produce at least two distinct results
+ */
+ public void testNextLongBounded2() {
+ for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+ for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+ long f = ThreadLocalRandom.current().nextLong(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ long j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextLong(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * nextDouble(bound) throws IllegalArgumentException
+ */
+ public void testNextDoubleBadBound() {
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ executeAndCatchIAE(() -> r.nextDouble(0.0));
+ executeAndCatchIAE(() -> r.nextDouble(-0.0));
+ executeAndCatchIAE(() -> r.nextDouble(+0.0));
+ executeAndCatchIAE(() -> r.nextDouble(-1.0));
+ executeAndCatchIAE(() -> r.nextDouble(Double.NaN));
+ executeAndCatchIAE(() -> r.nextDouble(Double.NEGATIVE_INFINITY));
+
+ // Returns Double.MAX_VALUE
+// executeAndCatchIAE(() -> r.nextDouble(Double.POSITIVE_INFINITY));
+ }
+
+ /**
+ * nextDouble(origin, bound) throws IllegalArgumentException
+ */
+ public void testNextDoubleBadOriginBound() {
+ testDoubleBadOriginBound(ThreadLocalRandom.current()::nextDouble);
+ }
+
+ // An arbitrary finite double value
+ static final double FINITE = Math.PI;
+
+ void testDoubleBadOriginBound(BiConsumer<Double, Double> bi) {
+ executeAndCatchIAE(() -> bi.accept(17.0, 2.0));
+ executeAndCatchIAE(() -> bi.accept(0.0, 0.0));
+ executeAndCatchIAE(() -> bi.accept(Double.NaN, FINITE));
+ executeAndCatchIAE(() -> bi.accept(FINITE, Double.NaN));
+ executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY));
+
+ // Returns NaN
+// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, FINITE));
+// executeAndCatchIAE(() -> bi.accept(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+
+ executeAndCatchIAE(() -> bi.accept(FINITE, Double.NEGATIVE_INFINITY));
+
+ // Returns Double.MAX_VALUE
+// executeAndCatchIAE(() -> bi.accept(FINITE, Double.POSITIVE_INFINITY));
+
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY));
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, FINITE));
+ executeAndCatchIAE(() -> bi.accept(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY));
+ }
+
+ /**
+ * nextDouble(least, bound) returns least <= value < bound; repeated calls
+ * produce at least two distinct results
+ */
+ public void testNextDoubleBounded2() {
+ for (double least = 0.0001; least < 1.0e20; least *= 8) {
+ for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+ double f = ThreadLocalRandom.current().nextDouble(least, bound);
+ assertTrue(least <= f && f < bound);
+ int i = 0;
+ double j;
+ while (i < NCALLS &&
+ (j = ThreadLocalRandom.current().nextDouble(least, bound)) == f) {
+ assertTrue(least <= j && j < bound);
+ ++i;
+ }
+ assertTrue(i < NCALLS);
+ }
+ }
+ }
+
+ /**
+ * Invoking sized ints, long, doubles, with negative sizes throws
+ * IllegalArgumentException
+ */
+ public void testBadStreamSize() {
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ executeAndCatchIAE(() -> r.ints(-1L));
+ executeAndCatchIAE(() -> r.ints(-1L, 2, 3));
+ executeAndCatchIAE(() -> r.longs(-1L));
+ executeAndCatchIAE(() -> r.longs(-1L, -1L, 1L));
+ executeAndCatchIAE(() -> r.doubles(-1L));
+ executeAndCatchIAE(() -> r.doubles(-1L, .5, .6));
+ }
+
+ /**
+ * Invoking bounded ints, long, doubles, with illegal bounds throws
+ * IllegalArgumentException
+ */
+ public void testBadStreamBounds() {
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ executeAndCatchIAE(() -> r.ints(2, 1));
+ executeAndCatchIAE(() -> r.ints(10, 42, 42));
+ executeAndCatchIAE(() -> r.longs(-1L, -1L));
+ executeAndCatchIAE(() -> r.longs(10, 1L, -2L));
+
+ testDoubleBadOriginBound((o, b) -> r.doubles(10, o, b));
+ }
+
+ private void executeAndCatchIAE(Runnable r) {
+ executeAndCatch(IllegalArgumentException.class, r);
+ }
+
+ private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
+ Exception caught = null;
+ try {
+ r.run();
+ }
+ catch (Exception e) {
+ caught = e;
+ }
+
+ assertNotNull(caught,
+ String.format("No Exception was thrown, expected an Exception of %s to be thrown",
+ expected.getName()));
+ Assert.assertTrue(expected.isInstance(caught),
+ String.format("Exception thrown %s not an instance of %s",
+ caught.getClass().getName(), expected.getName()));
+ }
+
+ /**
+ * A parallel sized stream of ints generates the given number of values
+ */
+ public void testIntsCount() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.ints(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * A parallel sized stream of longs generates the given number of values
+ */
+ public void testLongsCount() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.longs(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * A parallel sized stream of doubles generates the given number of values
+ */
+ public void testDoublesCount() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 0;
+ for (int reps = 0; reps < REPS; ++reps) {
+ counter.reset();
+ r.doubles(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ size += 524959;
+ }
+ }
+
+ /**
+ * Each of a parallel sized stream of bounded ints is within bounds
+ */
+ public void testBoundedInts() {
+ AtomicInteger fails = new AtomicInteger(0);
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 12345L;
+ for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+ for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+ final int lo = least, hi = bound;
+ r.ints(size, lo, hi).parallel().
+ forEach(x -> {
+ if (x < lo || x >= hi)
+ fails.getAndIncrement();
+ });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * Each of a parallel sized stream of bounded longs is within bounds
+ */
+ public void testBoundedLongs() {
+ AtomicInteger fails = new AtomicInteger(0);
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 123L;
+ for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+ for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+ final long lo = least, hi = bound;
+ r.longs(size, lo, hi).parallel().
+ forEach(x -> {
+ if (x < lo || x >= hi)
+ fails.getAndIncrement();
+ });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * Each of a parallel sized stream of bounded doubles is within bounds
+ */
+ public void testBoundedDoubles() {
+ AtomicInteger fails = new AtomicInteger(0);
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 456;
+ for (double least = 0.00011; least < 1.0e20; least *= 9) {
+ for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+ final double lo = least, hi = bound;
+ r.doubles(size, lo, hi).parallel().
+ forEach(x -> {
+ if (x < lo || x >= hi)
+ fails.getAndIncrement();
+ });
+ }
+ }
+ assertEquals(fails.get(), 0);
+ }
+
+ /**
+ * A parallel unsized stream of ints generates at least 100 values
+ */
+ public void testUnsizedIntsCount() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 100;
+ r.ints().limit(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A parallel unsized stream of longs generates at least 100 values
+ */
+ public void testUnsizedLongsCount() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 100;
+ r.longs().limit(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A parallel unsized stream of doubles generates at least 100 values
+ */
+ public void testUnsizedDoublesCount() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 100;
+ r.doubles().limit(size).parallel().forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of ints generates at least 100 values
+ */
+ public void testUnsizedIntsCountSeq() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 100;
+ r.ints().limit(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of longs generates at least 100 values
+ */
+ public void testUnsizedLongsCountSeq() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 100;
+ r.longs().limit(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+ /**
+ * A sequential unsized stream of doubles generates at least 100 values
+ */
+ public void testUnsizedDoublesCountSeq() {
+ LongAdder counter = new LongAdder();
+ ThreadLocalRandom r = ThreadLocalRandom.current();
+ long size = 100;
+ r.doubles().limit(size).forEach(x -> {
+ counter.increment();
+ });
+ assertEquals(counter.sum(), size);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/locks/StampedLock/ReadersUnlockAfterWriteUnlock.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * 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
+ * @run main/othervm/timeout=60 ReadersUnlockAfterWriteUnlock
+ * @bug 8023234
+ * @summary StampedLock serializes readers on writer unlock
+ * @author Dmitry Chyuko
+ * @author Aleksey Shipilev
+ */
+
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.locks.StampedLock;
+
+public class ReadersUnlockAfterWriteUnlock {
+ static final int RNUM = 2;
+ static final StampedLock sl = new StampedLock();
+ static volatile boolean isDone;
+
+ static CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1);
+ static CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM);
+ static CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1);
+
+ static class Reader extends Thread {
+ final String name;
+ Reader(String name) {
+ super();
+ this.name = name;
+ }
+ public void run() {
+ while (!isDone && !isInterrupted()) {
+ try {
+ iterationStart.await();
+ writerHasLock.await();
+ long rs = sl.readLock();
+
+ // single reader blocks here indefinitely if readers
+ // are serialized
+ readersHaveLocks.await();
+
+ sl.unlockRead(rs);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ for (int r = 0 ; r < RNUM; ++r) {
+ new Reader("r" + r).start();
+ }
+ int i;
+ for (i = 0; i < 1024; ++i) {
+ try {
+ iterationStart.await();
+ long ws = sl.writeLock();
+ writerHasLock.await();
+ Thread.sleep(10);
+ sl.unlockWrite(ws);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ isDone = true;
+ }
+
+}
--- a/jdk/test/java/util/function/BinaryOperator/BasicTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/util/function/BinaryOperator/BasicTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -67,26 +67,26 @@
};
public void testMaxBy() {
- Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp = Comparator.comparing(People::getFirstName);
// lesser
assertSame(maxBy(cmp).apply(people[0], people[1]), people[1]);
// euqal
- cmp = Comparator.comparing((Function<People, String>) People::getLastName);
+ cmp = Comparator.comparing(People::getLastName);
assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
// greater
- cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
+ cmp = Comparator.comparingInt(People::getAge);
assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
}
- public void testLesserOf() {
- Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+ public void testMinBy() {
+ Comparator<People> cmp = Comparator.comparing(People::getFirstName);
// lesser
assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
// euqal
- cmp = Comparator.comparing((Function<People, String>) People::getLastName);
+ cmp = Comparator.comparing(People::getLastName);
assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
// greater
- cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
+ cmp = Comparator.comparingInt(People::getAge);
assertSame(minBy(cmp).apply(people[0], people[1]), people[1]);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getLogger/TestLogger.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @test
+ * @bug 8005899
+ * @build TestLogger testlogger.MyResource
+ * @run main/othervm TestLogger
+ * @run main/othervm -Dsecurity=on TestLogger
+ **/
+public class TestLogger {
+
+ public static final String RESOURCE_BUNDLE = "testlogger.MyResource";
+ public static final String ORG_LOGGER = "org";
+ public static final String FOO_LOGGER = ORG_LOGGER + ".foo.Foo";
+ public static final String BAR_LOGGER = ORG_LOGGER + ".bar.Bar";
+ public static final String GEE_LOGGER = ORG_LOGGER + ".gee.Gee";
+ public static final String GEE_GEE_LOGGER = GEE_LOGGER+".Gee";
+
+ public static void main(String[] args) {
+ final String security = System.getProperty("security", "off");
+ System.out.println("Security is " + security);
+ if ("on".equals(security)) {
+ System.setSecurityManager(new SecurityManager());
+ }
+
+ newLogger(FOO_LOGGER, RESOURCE_BUNDLE);
+ newLogger(FOO_LOGGER);
+ newLogger(BAR_LOGGER);
+ newLogger(BAR_LOGGER, RESOURCE_BUNDLE);
+ newLogger(GEE_LOGGER, null);
+ newLogger(GEE_LOGGER, RESOURCE_BUNDLE);
+ newLogger(ORG_LOGGER);
+ newLogger(GEE_GEE_LOGGER);
+
+ for (String log : new String[] { FOO_LOGGER, BAR_LOGGER, GEE_LOGGER }) {
+ if (!RESOURCE_BUNDLE.equals(Logger.getLogger(log).getResourceBundleName())) {
+ throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log);
+ }
+ try {
+ Logger logger = Logger.getLogger(log, null);
+ if (!RESOURCE_BUNDLE.equals(logger.getResourceBundleName())) {
+ throw new RuntimeException("Shouldn't allow to reset the resource bundle for " + log);
+ }
+ throw new RuntimeException("Expected IllegalArgumentException not thrown for " + log);
+ } catch (IllegalArgumentException e) {
+ System.out.println("Got expected exception for " + log +": " + e);
+ }
+ }
+ for (String log : new String[] { ORG_LOGGER, GEE_GEE_LOGGER }) {
+ if (Logger.getLogger(log).getResourceBundleName() != null) {
+ throw new RuntimeException("Resource bundle is not null for log: "
+ + Logger.getLogger(log).getResourceBundleName());
+ }
+ try {
+ Logger logger = Logger.getLogger(log, null);
+ if (logger.getResourceBundleName() != null) {
+ throw new RuntimeException("Resource bundle is not null for log: "
+ + logger.getResourceBundleName());
+ }
+ System.out.println("Success calling Logger.getLogger(\""+log+"\", null)");
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException("Unexpected exception for " + log +": " + e, e);
+ }
+ }
+ }
+
+ private static List<Logger> strongRefs = new ArrayList<>();
+ private static void newLogger(String name) {
+ strongRefs.add(Logger.getLogger(name));
+ }
+ private static void newLogger(String name, String resourceBundleName) {
+ strongRefs.add(Logger.getLogger(name, resourceBundleName));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getLogger/testlogger/MyResource.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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 testlogger;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+/**
+ * A dummy resource bundle for testing purposes.
+ * @author danielfuchs
+ */
+public class MyResource extends ResourceBundle {
+ Map<String, Object> bundle = new HashMap<>();
+
+ @Override
+ protected Object handleGetObject(String key) {
+ bundle.put(key,"Localized: " + key);
+ return bundle.get(key);
+ }
+
+ @Override
+ public Enumeration<String> getKeys() {
+ final Hashtable<String, Object> h = new Hashtable<>(bundle);
+ return h.keys();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/regex/PatternTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,147 @@
+/*
+ * 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 Unit tests for wrapping classes should delegate to default methods
+ * @library ../stream/bootlib
+ * @build java.util.stream.OpTestCase
+ * @run testng/othervm PatternTest
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.regex.Pattern;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.OpTestCase;
+import java.util.stream.Stream;
+import java.util.stream.TestData;
+
+@Test
+public class PatternTest extends OpTestCase {
+
+ @DataProvider(name = "Stream<String>")
+ public static Object[][] makeStreamTestData() {
+ List<Object[]> data = new ArrayList<>();
+
+ String description = "";
+ String input = "awgqwefg1fefw4vssv1vvv1";
+ Pattern pattern = Pattern.compile("4");
+ List<String> expected = new ArrayList<>();
+ expected.add("awgqwefg1fefw");
+ expected.add("vssv1vvv1");
+
+ // Must match the type signature of the consumer of this data, testStrings
+ // String, String, Pattern, List<String>
+ data.add(new Object[]{description, input, pattern, expected});
+
+ input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh";
+ pattern = Pattern.compile("\u00a3a");
+ expected = new ArrayList<>();
+ expected.add("afbfq");
+ expected.add("bgwgb");
+ expected.add("wngnwggw");
+ expected.add("");
+ expected.add("hjrnhneerh");
+
+ data.add(new Object[]{description, input, pattern, expected});
+
+
+ input = "awgqwefg1fefw4vssv1vvv1";
+ pattern = Pattern.compile("1");
+ expected = new ArrayList<>();
+ expected.add("awgqwefg");
+ expected.add("fefw4vssv");
+ expected.add("vvv");
+
+ data.add(new Object[]{description, input, pattern, expected});
+
+
+ input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv";
+ pattern = Pattern.compile("1");
+ expected = new ArrayList<>();
+ expected.add("a\u4ebafg");
+ expected.add("fefw\u4eba4\u9f9cvssv\u9f9c");
+ expected.add("v\u672c\u672cvv");
+
+ data.add(new Object[]{description, input, pattern, expected});
+
+
+ input = "1\u56da23\u56da456\u56da7890";
+ pattern = Pattern.compile("\u56da");
+ expected = new ArrayList<>();
+ expected.add("1");
+ expected.add("23");
+ expected.add("456");
+ expected.add("7890");
+
+ data.add(new Object[]{description, input, pattern, expected});
+
+
+ input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890";
+ pattern = Pattern.compile("\u56da");
+ expected = new ArrayList<>();
+ expected.add("1");
+ expected.add("23\u9f9c\u672c\u672c");
+ expected.add("456");
+ expected.add("\u9f9c\u672c7890");
+
+ data.add(new Object[]{description, input, pattern, expected});
+
+
+ input = "";
+ pattern = Pattern.compile("\u56da");
+ expected = new ArrayList<>();
+
+ data.add(new Object[]{description, input, pattern, expected});
+
+
+ description = "Multiple separators";
+ input = "This is,testing: with\tdifferent separators.";
+ pattern = Pattern.compile("[ \t,:.]");
+ expected = new ArrayList<>();
+ expected.add("This");
+ expected.add("is");
+ expected.add("testing");
+ expected.add("");
+ expected.add("with");
+ expected.add("different");
+ expected.add("separators");
+
+ data.add(new Object[] {description, input, pattern, expected});
+ return data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "Stream<String>")
+ public void testStrings(String description, String input, Pattern pattern, List<String> expected) {
+ Supplier<Stream<String>> ss = () -> pattern.splitAsStream(input);
+ withData(TestData.Factory.ofSupplier(description, ss))
+ .stream(LambdaTestHelpers.identity())
+ .expectedResult(expected)
+ .exercise();
+ }
+}
--- a/jdk/test/java/util/regex/RegExTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/util/regex/RegExTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -33,7 +33,7 @@
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
* 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
- * 7067045 7014640 7189363 8007395 8013252 8013254 8012646
+ * 7067045 7014640 7189363 8007395 8013252 8013254 8012646 8023647
*/
import java.util.regex.*;
@@ -146,6 +146,7 @@
linebreakTest();
branchTest();
groupCurlyNotFoundSuppTest();
+ groupCurlyBackoffTest();
patternAsPredicate();
if (failure) {
throw new
@@ -3999,6 +4000,15 @@
report("GroupCurly NotFoundSupp");
}
+ // This test is for 8023647
+ private static void groupCurlyBackoffTest() throws Exception {
+ if (!"abc1c".matches("(\\w)+1\\1") ||
+ "abc11".matches("(\\w)+1\\1")) {
+ failCount++;
+ }
+ report("GroupCurly backoff");
+ }
+
// This test is for 8012646
private static void patternAsPredicate() throws Exception {
Predicate<String> p = Pattern.compile("[a-z]+").asPredicate();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/SplittableRandomTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,367 @@
+/*
+ * 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 org.openjdk.tests.java.util;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.SplittableRandom;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.DoubleStream;
+import java.util.stream.DoubleStreamTestScenario;
+import java.util.stream.IntStream;
+import java.util.stream.IntStreamTestScenario;
+import java.util.stream.LongStream;
+import java.util.stream.LongStreamTestScenario;
+import java.util.stream.OpTestCase;
+import java.util.stream.StreamSupport;
+import java.util.stream.TestData;
+
+@Test
+public class SplittableRandomTest extends OpTestCase {
+
+ static class RandomBoxedSpliterator<T> implements Spliterator<T> {
+ final SplittableRandom rng;
+ long index;
+ final long fence;
+ final Function<SplittableRandom, T> rngF;
+
+ RandomBoxedSpliterator(SplittableRandom rng, long index, long fence, Function<SplittableRandom, T> rngF) {
+ this.rng = rng;
+ this.index = index;
+ this.fence = fence;
+ this.rngF = rngF;
+ }
+
+ public RandomBoxedSpliterator<T> trySplit() {
+ long i = index, m = (i + fence) >>> 1;
+ return (m <= i) ? null :
+ new RandomBoxedSpliterator<>(rng.split(), i, index = m, rngF);
+ }
+
+ public long estimateSize() {
+ return fence - index;
+ }
+
+ public int characteristics() {
+ return (Spliterator.SIZED | Spliterator.SUBSIZED |
+ Spliterator.NONNULL | Spliterator.IMMUTABLE);
+ }
+
+ @Override
+ public boolean tryAdvance(Consumer<? super T> consumer) {
+ if (consumer == null) throw new NullPointerException();
+ long i = index, f = fence;
+ if (i < f) {
+ consumer.accept(rngF.apply(rng));
+ index = i + 1;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ static final int SIZE = 1 << 16;
+
+ // Ensure there is a range of a power of 2
+ static final int[] BOUNDS = {256};
+ static final int[] ORIGINS = {-16, 0, 16};
+
+ static <T extends Comparable<T>> ResultAsserter<Iterable<T>> randomAsserter(int size, T origin, T bound) {
+ return (act, exp, ord, par) -> {
+ int count = 0;
+ Set<Comparable<T>> values = new HashSet<>();
+ for (Comparable<T> t : act) {
+ if (origin.compareTo(bound) < 0) {
+ assertTrue(t.compareTo(origin) >= 0);
+ assertTrue(t.compareTo(bound) < 0);
+ }
+ values.add(t);
+ count++;
+ }
+ assertEquals(count, size);
+ // Assert that at least one different result is produced
+ // For the size of the data it is highly improbable that this
+ // will cause a false negative (i.e. a false failure)
+ assertTrue(values.size() > 1);
+ };
+ }
+
+ @DataProvider(name = "ints")
+ public static Object[][] intsDataProvider() {
+ List<Object[]> data = new ArrayList<>();
+
+ // Function to create a stream using a RandomBoxedSpliterator
+
+ Function<Function<SplittableRandom, Integer>, IntStream> rbsf =
+ sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
+ mapToInt(i -> i);
+
+ // Unbounded
+
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new SplittableRandom().ints().limit(%d)", SIZE),
+ () -> new SplittableRandom().ints().limit(SIZE)),
+ randomAsserter(SIZE, Integer.MAX_VALUE, 0)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new SplittableRandom().ints(%d)", SIZE),
+ () -> new SplittableRandom().ints(SIZE)),
+ randomAsserter(SIZE, Integer.MAX_VALUE, 0)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt())", SIZE),
+ () -> rbsf.apply(sr -> sr.nextInt())),
+ randomAsserter(SIZE, Integer.MAX_VALUE, 0)
+ });
+
+ // Bounded
+
+ for (int b : BOUNDS) {
+ for (int o : ORIGINS) {
+ final int origin = o;
+ final int bound = b;
+
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new SplittableRandom().ints(%d, %d).limit(%d)", origin, bound, SIZE),
+ () -> new SplittableRandom().ints(origin, bound).limit(SIZE)),
+ randomAsserter(SIZE, origin, bound)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new SplittableRandom().ints(%d, %d, %d)", SIZE, origin, bound),
+ () -> new SplittableRandom().ints(SIZE, origin, bound)),
+ randomAsserter(SIZE, origin, bound)
+ });
+
+ if (origin == 0) {
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d))", SIZE, bound),
+ () -> rbsf.apply(sr -> sr.nextInt(bound))),
+ randomAsserter(SIZE, origin, bound)
+ });
+ }
+
+ data.add(new Object[]{
+ TestData.Factory.ofIntSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d, %d))", SIZE, origin, bound),
+ () -> rbsf.apply(sr -> sr.nextInt(origin, bound))),
+ randomAsserter(SIZE, origin, bound)
+ });
+ }
+ }
+
+ return data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "ints")
+ public void testInts(TestData.OfInt data, ResultAsserter<Iterable<Integer>> ra) {
+ withData(data).
+ stream(s -> s).
+ without(IntStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+ resultAsserter(ra).
+ exercise();
+ }
+
+ @DataProvider(name = "longs")
+ public static Object[][] longsDataProvider() {
+ List<Object[]> data = new ArrayList<>();
+
+ // Function to create a stream using a RandomBoxedSpliterator
+
+ Function<Function<SplittableRandom, Long>, LongStream> rbsf =
+ sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
+ mapToLong(i -> i);
+
+ // Unbounded
+
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new SplittableRandom().longs().limit(%d)", SIZE),
+ () -> new SplittableRandom().longs().limit(SIZE)),
+ randomAsserter(SIZE, Long.MAX_VALUE, 0L)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new SplittableRandom().longs(%d)", SIZE),
+ () -> new SplittableRandom().longs(SIZE)),
+ randomAsserter(SIZE, Long.MAX_VALUE, 0L)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong())", SIZE),
+ () -> rbsf.apply(sr -> sr.nextLong())),
+ randomAsserter(SIZE, Long.MAX_VALUE, 0L)
+ });
+
+ // Bounded
+
+ for (int b : BOUNDS) {
+ for (int o : ORIGINS) {
+ final long origin = o;
+ final long bound = b;
+
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new SplittableRandom().longs(%d, %d).limit(%d)", origin, bound, SIZE),
+ () -> new SplittableRandom().longs(origin, bound).limit(SIZE)),
+ randomAsserter(SIZE, origin, bound)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new SplittableRandom().longs(%d, %d, %d)", SIZE, origin, bound),
+ () -> new SplittableRandom().longs(SIZE, origin, bound)),
+ randomAsserter(SIZE, origin, bound)
+ });
+
+ if (origin == 0) {
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d))", SIZE, bound),
+ () -> rbsf.apply(sr -> sr.nextLong(bound))),
+ randomAsserter(SIZE, origin, bound)
+ });
+ }
+
+ data.add(new Object[]{
+ TestData.Factory.ofLongSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d, %d))", SIZE, origin, bound),
+ () -> rbsf.apply(sr -> sr.nextLong(origin, bound))),
+ randomAsserter(SIZE, origin, bound)
+ });
+ }
+ }
+
+ return data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "longs")
+ public void testLongs(TestData.OfLong data, ResultAsserter<Iterable<Long>> ra) {
+ withData(data).
+ stream(s -> s).
+ without(LongStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+ resultAsserter(ra).
+ exercise();
+ }
+
+ @DataProvider(name = "doubles")
+ public static Object[][] doublesDataProvider() {
+ List<Object[]> data = new ArrayList<>();
+
+ // Function to create a stream using a RandomBoxedSpliterator
+
+ Function<Function<SplittableRandom, Double>, DoubleStream> rbsf =
+ sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
+ mapToDouble(i -> i);
+
+ // Unbounded
+
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new SplittableRandom().doubles().limit(%d)", SIZE),
+ () -> new SplittableRandom().doubles().limit(SIZE)),
+ randomAsserter(SIZE, Double.MAX_VALUE, 0d)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new SplittableRandom().doubles(%d)", SIZE),
+ () -> new SplittableRandom().doubles(SIZE)),
+ randomAsserter(SIZE, Double.MAX_VALUE, 0d)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble())", SIZE),
+ () -> rbsf.apply(sr -> sr.nextDouble())),
+ randomAsserter(SIZE, Double.MAX_VALUE, 0d)
+ });
+
+ // Bounded
+
+ for (int b : BOUNDS) {
+ for (int o : ORIGINS) {
+ final double origin = o;
+ final double bound = b;
+
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new SplittableRandom().doubles(%f, %f).limit(%d)", origin, bound, SIZE),
+ () -> new SplittableRandom().doubles(origin, bound).limit(SIZE)),
+ randomAsserter(SIZE, origin, bound)
+ });
+
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new SplittableRandom().doubles(%d, %f, %f)", SIZE, origin, bound),
+ () -> new SplittableRandom().doubles(SIZE, origin, bound)),
+ randomAsserter(SIZE, origin, bound)
+ });
+
+ if (origin == 0) {
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f))", SIZE, bound),
+ () -> rbsf.apply(sr -> sr.nextDouble(bound))),
+ randomAsserter(SIZE, origin, bound)
+ });
+ }
+
+ data.add(new Object[]{
+ TestData.Factory.ofDoubleSupplier(
+ String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f, %f))", SIZE, origin, bound),
+ () -> rbsf.apply(sr -> sr.nextDouble(origin, bound))),
+ randomAsserter(SIZE, origin, bound)
+ });
+ }
+ }
+
+ return data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "doubles")
+ public void testDoubles(TestData.OfDouble data, ResultAsserter<Iterable<Double>> ra) {
+ withData(data).
+ stream(s -> s).
+ without(DoubleStreamTestScenario.PAR_STREAM_TO_ARRAY_CLEAR_SIZED).
+ resultAsserter(ra).
+ exercise();
+ }
+}
--- a/jdk/test/java/util/zip/TestExtraTime.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/java/util/zip/TestExtraTime.java Wed Jul 05 19:10:19 2017 +0200
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 4759491 6303183 7012868 8015666
+ * @bug 4759491 6303183 7012868 8015666 8023713
* @summary Test ZOS and ZIS timestamp in extra field correctly
*/
@@ -32,6 +32,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
+import java.util.Arrays;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
@@ -52,24 +53,26 @@
FileTime ctime = FileTime.from(time - 300000, TimeUnit.MILLISECONDS);
TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
- test(mtime, null, null, null);
- // ms-dos 1980 epoch problem
- test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null);
- // non-default tz
- test(mtime, null, null, tz);
+ for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) {
+ test(mtime, null, null, null, extra);
+ // ms-dos 1980 epoch problem
+ test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
+ // non-default tz
+ test(mtime, null, null, tz, extra);
- test(mtime, atime, null, null);
- test(mtime, null, ctime, null);
- test(mtime, atime, ctime, null);
+ test(mtime, atime, null, null, extra);
+ test(mtime, null, ctime, null, extra);
+ test(mtime, atime, ctime, null, extra);
- test(mtime, atime, null, tz);
- test(mtime, null, ctime, tz);
- test(mtime, atime, ctime, tz);
+ test(mtime, atime, null, tz, extra);
+ test(mtime, null, ctime, tz, extra);
+ test(mtime, atime, ctime, tz, extra);
+ }
}
}
static void test(FileTime mtime, FileTime atime, FileTime ctime,
- TimeZone tz) throws Throwable {
+ TimeZone tz, byte[] extra) throws Throwable {
System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
mtime, atime, ctime);
TimeZone tz0 = TimeZone.getDefault();
@@ -78,8 +81,8 @@
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
- ZipEntry ze = new ZipEntry("TestExtreTime.java");
-
+ ZipEntry ze = new ZipEntry("TestExtraTime.java");
+ ze.setExtra(extra);
ze.setLastModifiedTime(mtime);
if (atime != null)
ze.setLastAccessTime(atime);
@@ -87,6 +90,14 @@
ze.setCreationTime(ctime);
zos.putNextEntry(ze);
zos.write(new byte[] { 1,2 ,3, 4});
+
+ // append an extra entry to help check if the length and data
+ // of the extra field are being correctly written (in previous
+ // entry).
+ if (extra != null) {
+ ze = new ZipEntry("TestExtraEntry");
+ zos.putNextEntry(ze);
+ }
zos.close();
if (tz != null) {
TimeZone.setDefault(tz0);
@@ -96,23 +107,23 @@
new ByteArrayInputStream(baos.toByteArray()));
ze = zis.getNextEntry();
zis.close();
- check(mtime, atime, ctime, ze);
+ check(mtime, atime, ctime, ze, extra);
// ZipFile
Path zpath = Paths.get(System.getProperty("test.dir", "."),
- "TestExtraTimp.zip");
+ "TestExtraTime.zip");
Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
ZipFile zf = new ZipFile(zpath.toFile());
- ze = zf.getEntry("TestExtreTime.java");
+ ze = zf.getEntry("TestExtraTime.java");
// ZipFile read entry from cen, which does not have a/ctime,
// for now.
- check(mtime, null, null, ze);
+ check(mtime, null, null, ze, extra);
zf.close();
Files.delete(zpath);
}
static void check(FileTime mtime, FileTime atime, FileTime ctime,
- ZipEntry ze) {
+ ZipEntry ze, byte[] extra) {
/*
System.out.printf(" mtime [%tc]: [%tc]/[%tc]%n",
mtime.to(TimeUnit.MILLISECONDS),
@@ -130,5 +141,17 @@
ctime.to(TimeUnit.SECONDS) !=
ze.getCreationTime().to(TimeUnit.SECONDS))
throw new RuntimeException("Timestamp: storing ctime failed!");
+ if (extra != null) {
+ // if extra data exists, the current implementation put it at
+ // the end of the extra data array (implementation detail)
+ byte[] extra1 = ze.getExtra();
+ if (extra1 == null || extra1.length < extra.length ||
+ !Arrays.equals(Arrays.copyOfRange(extra1,
+ extra1.length - extra.length,
+ extra1.length),
+ extra)) {
+ throw new RuntimeException("Timestamp: storing extra field failed!");
+ }
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/KPEquals.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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 8015669
+ * @summary KerberosPrincipal::equals should ignore name-type
+ * @compile -XDignore.symbol.file KPEquals.java
+ * @run main/othervm KPEquals
+ */
+
+import sun.security.jgss.GSSUtil;
+
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KeyTab;
+
+public class KPEquals {
+
+ public static void main(String[] args) throws Exception {
+ new OneKDC(null).writeJAASConf();
+ Context c = Context.fromJAAS("client");
+ Context s = Context.fromThinAir();
+ KerberosPrincipal kp = new KerberosPrincipal(
+ OneKDC.SERVER + "@" + OneKDC.REALM,
+ KerberosPrincipal.KRB_NT_SRV_INST);
+ s.s().getPrincipals().add(kp);
+ for (KerberosKey k: KeyTab.getInstance(kp).getKeys(kp)) {
+ s.s().getPrivateCredentials().add(k);
+ }
+ c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+ Context.handshake(c, s);
+ }
+}
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,14 +21,16 @@
* questions.
*/
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
/*
* @test
* @bug 4366807
* @summary Need new APIs to get/set session timeout and session cache size.
* @run main/othervm SessionCacheSizeTests
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
*/
import java.io.*;
@@ -113,7 +115,9 @@
/*
* Signal Client, we're ready for his connect.
*/
- serverReady = true;
+ if (createdPorts == serverPorts.length) {
+ serverReady = true;
+ }
int read = 0;
int nConnections = 0;
/*
@@ -310,7 +314,6 @@
* Fork off the other side, then do your work.
*/
SessionCacheSizeTests() throws Exception {
-
/*
* create the SSLServerSocket and SSLSocket factories
*/
@@ -323,46 +326,87 @@
int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length);
int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length);
- if (separateServerThread) {
- for (int i = 0; i < serverPorts.length; i++) {
-
- // distribute remaining connections among the available ports
- if (i < remainingConns)
- startServer(serverPorts[i], (serverConns + 1), true);
- else
- startServer(serverPorts[i], serverConns, true);
+ Exception startException = null;
+ try {
+ if (separateServerThread) {
+ for (int i = 0; i < serverPorts.length; i++) {
+ // distribute remaining connections among the
+ // available ports
+ if (i < remainingConns)
+ startServer(serverPorts[i], (serverConns + 1), true);
+ else
+ startServer(serverPorts[i], serverConns, true);
+ }
+ startClient(false);
+ } else {
+ startClient(true);
+ for (int i = 0; i < serverPorts.length; i++) {
+ if (i < remainingConns)
+ startServer(serverPorts[i], (serverConns + 1), false);
+ else
+ startServer(serverPorts[i], serverConns, false);
+ }
}
- startClient(false);
- } else {
- startClient(true);
- for (int i = 0; i < serverPorts.length; i++) {
- if (i < remainingConns)
- startServer(serverPorts[i], (serverConns + 1), false);
- else
- startServer(serverPorts[i], serverConns, false);
- }
+ } catch (Exception e) {
+ startException = e;
}
/*
* Wait for other side to close down.
*/
if (separateServerThread) {
- serverThread.join();
+ if (serverThread != null) {
+ serverThread.join();
+ }
} else {
- clientThread.join();
+ if (clientThread != null) {
+ clientThread.join();
+ }
}
/*
* When we get here, the test is pretty much over.
- *
- * If the main thread excepted, that propagates back
- * immediately. If the other thread threw an exception, we
- * should report back.
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
*/
- if (serverException != null)
- throw serverException;
- if (clientException != null)
- throw clientException;
+ 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(final int port, final int nConns,
@@ -387,7 +431,13 @@
};
serverThread.start();
} else {
- doServerSide(port, nConns);
+ try {
+ doServerSide(port, nConns);
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
}
}
@@ -409,7 +459,11 @@
};
clientThread.start();
} else {
- doClientSide();
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
}
}
}
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,14 +21,14 @@
* questions.
*/
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
/*
* @test
* @bug 4366807
* @summary Need new APIs to get/set session timeout and session cache size.
* @run main/othervm SessionTimeOutTests
- *
- * SunJSSE does not support dynamic system properties, no way to re-use
- * system properties in samevm/agentvm mode.
*/
import java.io.*;
@@ -263,7 +263,7 @@
for (int i = 0; i < nConnections; i++) {
sslSockets[i].close();
}
- System.out.println("----------------------------------------"
+ System.out.println("----------------------------------------"
+ "-----------------------");
System.out.println("Session timeout test passed");
}
@@ -348,45 +348,88 @@
int serverConns = MAX_ACTIVE_CONNECTIONS / (serverPorts.length);
int remainingConns = MAX_ACTIVE_CONNECTIONS % (serverPorts.length);
- if (separateServerThread) {
- for (int i = 0; i < serverPorts.length; i++) {
- // distribute remaining connections among the available ports
- if (i < remainingConns)
- startServer(serverPorts[i], (serverConns + 1), true);
- else
- startServer(serverPorts[i], serverConns, true);
+ Exception startException = null;
+ try {
+ if (separateServerThread) {
+ for (int i = 0; i < serverPorts.length; i++) {
+ // distribute remaining connections among the
+ // vailable ports
+ if (i < remainingConns)
+ startServer(serverPorts[i], (serverConns + 1), true);
+ else
+ startServer(serverPorts[i], serverConns, true);
+ }
+ startClient(false);
+ } else {
+ startClient(true);
+ for (int i = 0; i < serverPorts.length; i++) {
+ if (i < remainingConns)
+ startServer(serverPorts[i], (serverConns + 1), false);
+ else
+ startServer(serverPorts[i], serverConns, false);
+ }
}
- startClient(false);
- } else {
- startClient(true);
- for (int i = 0; i < serverPorts.length; i++) {
- if (i < remainingConns)
- startServer(serverPorts[i], (serverConns + 1), false);
- else
- startServer(serverPorts[i], serverConns, false);
- }
+ } catch (Exception e) {
+ startException = e;
}
/*
* Wait for other side to close down.
*/
if (separateServerThread) {
- serverThread.join();
+ if (serverThread != null) {
+ serverThread.join();
+ }
} else {
- clientThread.join();
+ if (clientThread != null) {
+ clientThread.join();
+ }
}
/*
* When we get here, the test is pretty much over.
- *
- * If the main thread excepted, that propagates back
- * immediately. If the other thread threw an exception, we
- * should report back.
+ * 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 (serverException != null)
- throw serverException;
- if (clientException != null)
- throw clientException;
+ 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(final int port, final int nConns,
@@ -411,7 +454,13 @@
};
serverThread.start();
} else {
- doServerSide(port, nConns);
+ try {
+ doServerSide(port, nConns);
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = 0;
+ }
}
}
@@ -433,7 +482,11 @@
};
clientThread.start();
} else {
- doClientSide();
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
}
}
}
--- a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java Thu Aug 29 16:18:31 2013 -0700
+++ b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java Wed Jul 05 19:10:19 2017 +0200
@@ -243,7 +243,7 @@
* output it.
*/
if (exception != null) {
- if (exception != startException) {
+ if (exception != startException && startException != null) {
exception.addSuppressed(startException);
}
throw exception;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/jvindex.sh Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,76 @@
+#
+# 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 8022761
+# @summary regression: SecurityException is NOT thrown while trying to pack a wrongly signed Indexed Jar file
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+F=abcde
+KS=jvindex.jks
+JFILE=jvindex.jar
+
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \
+ -keystore $KS"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit"
+
+rm $F $KS $JFILE 2> /dev/null
+
+echo 12345 > $F
+$JAR cvf $JFILE $F
+
+ERR=""
+
+$KT -alias a -dname CN=a -genkey -validity 300 || ERR="$ERR 1"
+
+$JARSIGNER $JFILE a || ERR="$ERR 2"
+$JAR i $JFILE
+
+# Make sure the $F line has "sm" (signed and in manifest)
+$JARSIGNER -verify -verbose $JFILE | grep $F | grep sm || ERR="$ERR 3"
+
+if [ "$ERR" = "" ]; then
+ exit 0
+else
+ echo "ERR is $ERR"
+ exit 1
+fi
+
+
--- a/nashorn/.hgtags Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/.hgtags Wed Jul 05 19:10:19 2017 +0200
@@ -214,3 +214,4 @@
e966ff0a3ffef8a687eaf5a14167bb595b623d02 jdk8-b102
414203de4374e1964a9918c38a95fb245010a9f1 jdk8-b103
afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104
+f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java Wed Jul 05 19:10:19 2017 +0200
@@ -27,7 +27,6 @@
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
-import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX;
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java Wed Jul 05 19:10:19 2017 +0200
@@ -27,7 +27,6 @@
import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
-import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.NEW;
--- a/nashorn/docs/DEVELOPER_README Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/docs/DEVELOPER_README Wed Jul 05 19:10:19 2017 +0200
@@ -16,8 +16,9 @@
SYSTEM PROPERTY: -Dnashorn.args=<string>
This property takes as its value a space separated list of Nashorn
-command line options that should be passed to Nashorn. This might be useful
-in environments where it is hard to tell how a nashorn.jar is launched.
+command line options that should be passed to Nashorn. This might be
+useful in environments where it is hard to tell how a nashorn.jar is
+launched.
Example:
@@ -43,6 +44,10 @@
SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic
+(and integer arithmetic in general)
+
+<currently disabled - this is being refactored for update releases>
+
Arithmetic operations in Nashorn (except bitwise ones) typically
coerce the operands to doubles (as per the JavaScript spec). To switch
this off and remain in integer mode, for example for "var x = a&b; var
@@ -65,13 +70,382 @@
does not overflow. Getting access to a JVM intrinsic that does branch
on overflow would probably alleviate this.
-There is also a problem with this optimistic approach if the symbol
-happens to reside in a local variable slot in the bytecode, as those
-are strongly typed. Then we would need to split large sections of
-control flow, so this is probably not the right way to go, while range
-analysis is. There is a large difference between integer bytecode
-without overflow checks and double bytecode. The former is
-significantly faster.
+The future:
+
+We are transitioning to an optimistic type system that uses int
+arithmetic everywhere until proven wrong. The problem here is mostly
+catch an overflow exception and rolling back the state to a new method
+with less optimistic assumptions for an operation at a particular
+program point. This will most likely not be in the Java 8.0 release
+but likely end up in an update release
+
+For Java 8, several java.lang.Math methods like addExact, subExact and
+mulExact are available to help us. Experiments intrinsifying these
+show a lot of promise, and we have devised a system that basically
+does on stack replacement with exceptions in bytecode to revert
+erroneous assumptions. An explanation of how this works and what we
+are doing can be found here:
+http://www.slideshare.net/lagergren/lagergren-jvmls2013final
+
+Experiments with this show significant ~x2-3 performance increases on
+pretty much everything, provided that optimistic assumptions don't
+fail much. It will affect warmup time negatively, depending on how
+many erroneous too optimistic assumptions are placed in the code at
+compile time. We don't think this will be much of an issue.
+
+For example for a small benchmark that repeatedly executes this
+method taken from the Crypto Octane benchmark
+
+function am3(i,x,w,j,c,n) {
+ var this_array = this.array;
+ var w_array = w.array;
+ var xl = x&0x3fff, xh = x>>14;
+ while(--n >= 0) {
+ var l = this_array[i]&0x3fff;
+ var h = this_array[i++]>>14;
+ var m = xh*l+h*xl;
+ l = xl*l+((m&0x3fff)<<14)+w_array[j]+c;
+ c = (l>>28)+(m>>14)+xh*h;
+ w_array[j++] = l&0xfffffff;
+ }
+
+ return c;
+}
+
+The performance increase more than doubles. We are also working hard
+with the code generation team in the Java Virtual Machine to fix
+things that are lacking in invokedynamic performance, which is another
+area where a lot of ongoing performance work takes place
+
+"Pessimistic" bytecode for am3, guaranteed to be semantically correct:
+
+// access flags 0x9
+ public static am3(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+ L0
+ LINENUMBER 12 L0
+ ALOAD 0
+ INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ ASTORE 8
+ L1
+ LINENUMBER 13 L1
+ ALOAD 3
+ INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ ASTORE 9
+ L2
+ LINENUMBER 14 L2
+ ALOAD 2
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+ SIPUSH 16383
+ IAND
+ ISTORE 10
+ ALOAD 2
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+ BIPUSH 14
+ ISHR
+ ISTORE 11
+ L3
+ LINENUMBER 15 L3
+ GOTO L4
+ L5
+ LINENUMBER 16 L5
+ FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Double T java/lang/Object java/lang/Object I I] []
+ ALOAD 8
+ ALOAD 1
+ INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ SIPUSH 16383
+ IAND
+ INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
+ ASTORE 12
+ L6
+ LINENUMBER 17 L6
+ ALOAD 8
+ ALOAD 1
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+ DUP2
+ DCONST_1
+ DADD
+ INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+ ASTORE 1
+ INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ BIPUSH 14
+ ISHR
+ ISTORE 13
+ L7
+ LINENUMBER 18 L7
+ ILOAD 11
+ I2D
+ ALOAD 12
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+ DMUL
+ ILOAD 13
+ I2D
+ ILOAD 10
+ I2D
+ DMUL
+ DADD
+ DSTORE 14
+ L8
+ LINENUMBER 19 L8
+ ILOAD 10
+ I2D
+ ALOAD 12
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+ DMUL
+ DLOAD 14
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
+ SIPUSH 16383
+ IAND
+ BIPUSH 14
+ ISHL
+ I2D
+ DADD
+ ALOAD 9
+ ALOAD 4
+ INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
+ // arguments: none
+ ]
+ ALOAD 5
+ INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
+ // arguments: none
+ ]
+ ASTORE 12
+ L9
+ LINENUMBER 20 L9
+ ALOAD 12
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+ BIPUSH 28
+ ISHR
+ I2D
+ DLOAD 14
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
+ BIPUSH 14
+ ISHR
+ I2D
+ DADD
+ ILOAD 11
+ I2D
+ ILOAD 13
+ I2D
+ DMUL
+ DADD
+ INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+ ASTORE 5
+ L10
+ LINENUMBER 21 L10
+ ALOAD 9
+ ALOAD 4
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+ DUP2
+ DCONST_1
+ DADD
+ INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+ ASTORE 4
+ ALOAD 12
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
+ LDC 268435455
+ IAND
+ INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ L4
+ FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object T java/lang/Object java/lang/Object I I] []
+ ALOAD 6
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
+ LDC -1.0
+ DADD
+ DUP2
+ INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
+ ASTORE 6
+ DCONST_0
+ DCMPL
+ IFGE L5
+ L11
+ LINENUMBER 24 L11
+ ALOAD 5
+ ARETURN
+
+"Optimistic" bytecode that requires invalidation on e.g overflow. Factor
+x2-3 speedup:
+
+public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I
+ L0
+ LINENUMBER 12 L0
+ ALOAD 0
+ INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ ASTORE 8
+ L1
+ LINENUMBER 13 L1
+ ALOAD 3
+ INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ ASTORE 9
+ L2
+ LINENUMBER 14 L2
+ ILOAD 2
+ SIPUSH 16383
+ IAND
+ ISTORE 10
+ ILOAD 2
+ BIPUSH 14
+ ISHR
+ ISTORE 11
+ L3
+ LINENUMBER 15 L3
+ GOTO L4
+ L5
+ LINENUMBER 16 L5
+ FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] []
+ ALOAD 8
+ ILOAD 1
+ INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ SIPUSH 16383
+ IAND
+ ISTORE 12
+ L6
+ LINENUMBER 17 L6
+ ALOAD 8
+ ILOAD 1
+ DUP
+ ICONST_1
+ IADD
+ ISTORE 1
+ INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ BIPUSH 14
+ ISHR
+ ISTORE 13
+ L7
+ LINENUMBER 18 L7
+ ILOAD 11
+ ILOAD 12
+ BIPUSH 8
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+ ILOAD 13
+ ILOAD 10
+ BIPUSH 9
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+ IADD
+ ISTORE 14
+ L8
+ LINENUMBER 19 L8
+ ILOAD 10
+ ILOAD 12
+ BIPUSH 11
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+ ILOAD 14
+ SIPUSH 16383
+ IAND
+ BIPUSH 14
+ ISHL
+ IADD
+ ALOAD 9
+ ILOAD 4
+ INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ IADD
+ ILOAD 5
+ IADD
+ ISTORE 12
+ L9
+ LINENUMBER 20 L9
+ ILOAD 12
+ BIPUSH 28
+ ISHR
+ ILOAD 14
+ BIPUSH 14
+ ISHR
+ IADD
+ ILOAD 11
+ ILOAD 13
+ BIPUSH 21
+ INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
+ IADD
+ ISTORE 5
+ L10
+ LINENUMBER 21 L10
+ ALOAD 9
+ ILOAD 4
+ DUP
+ ICONST_1
+ IADD
+ ISTORE 4
+ ILOAD 12
+ LDC 268435455
+ IAND
+ INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [
+ // handle kind 0x6 : INVOKESTATIC
+ jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
+ // arguments:
+ 0
+ ]
+ L4
+ FRAME SAME
+ ILOAD 6
+ ICONST_M1
+ IADD
+ DUP
+ ISTORE 6
+ ICONST_0
+ IF_ICMPGE L5
+ L11
+ LINENUMBER 24 L11
+ ILOAD 5
+ IRETURN
SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>
@@ -167,7 +541,7 @@
of byte code (try it e.g. on all the variants of am3 in the Octane
benchmark crypto.js). Thus, this needs to be lazy
-3) Possibly optimistic callsite writes, something on the form
+3) Optimistic callsite writes, something on the form
x = y; //x is a field known to be a primitive. y is only an object as
far as we can tell
@@ -189,6 +563,12 @@
We still have to deal with objects vs primitives for local bytecode
slots, possibly through code copying and versioning.
+The Future:
+
+We expect the usefulness of dual fields to increase significantly
+after the optimistic type system described in the section on
+integer arithmetic above is implemented.
+
SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]],
-Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
@@ -211,7 +591,7 @@
semantics.
-SYSTEM PROPERTY: nashorn.lexer.xmlliterals
+SYSTEM PROPERTY: -Dnashorn.lexer.xmlliterals
If this property it set, it means that the Lexer should attempt to
parse XML literals, which would otherwise generate syntax
@@ -222,7 +602,7 @@
the IR.
-SYSTEM_PROPERTY: nashorn.debug
+SYSTEM_PROPERTY: -Dnashorn.debug
If this property is set to true, Nashorn runs in Debug mode. Debug
mode is slightly slower, as for example statistics counters are enabled
@@ -269,8 +649,8 @@
object layout being invalidated.
-SYSTEM PROPERTY: nashorn.methodhandles.debug,
-nashorn.methodhandles.debug=create
+SYSTEM PROPERTY: -Dnashorn.methodhandles.debug,
+-Dnashorn.methodhandles.debug=create
If this property is enabled, each MethodHandle related call that uses
the java.lang.invoke package gets its MethodHandle intercepted and an
@@ -286,7 +666,7 @@
rather than at runtime usage.
-SYSTEM PROPERTY: nashorn.methodhandles.debug.stacktrace
+SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace
This does the same as nashorn.methodhandles.debug, but when enabled
also dumps the stack trace for every instrumented method handle
@@ -297,14 +677,13 @@
description of this option
-SYSTEM PROPERTY: nashorn.scriptfunction.specialization.disable
+SYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disable
There are several "fast path" implementations of constructors and
functions in the NativeObject classes that, in their original form,
take a variable amount of arguments. Said functions are also declared
to take Object parameters in their original form, as this is what the
JavaScript specification mandates.
-
However, we often know quite a lot more at a callsite of one of these
functions. For example, Math.min is called with a fixed number (2) of
integer arguments. The overhead of boxing these ints to Objects and
@@ -331,7 +710,7 @@
just call the generic one.
-SYSTEM PROPERTY: nashorn.tcs.miss.samplePercent=<x>
+SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent=<x>
When running with the trace callsite option (-tcs), Nashorn will count
and instrument any callsite misses that require relinking. As the
@@ -341,7 +720,7 @@
default value.
-SYSTEM_PROPERTY: nashorn.profilefile=<filename>
+SYSTEM_PROPERTY: -Dnashorn.profilefile=<filename>
When running with the profile callsite options (-pcs), Nashorn will
dump profiling data for all callsites to stderr as a shutdown hook. To
@@ -349,14 +728,34 @@
this system property.
-SYSTEM_PROPERTY: nashorn.regexp.impl=[jdk|joni]
+SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni]
This property defines the regular expression engine to be used by
-Nashorn. The default implementation is "jdk" which is based on the
+Nashorn. Set this flag to "jdk" to get an implementation based on the
JDK's java.util.regex package. Set this property to "joni" to install
an implementation based on Joni, the regular expression engine used by
-the JRuby project.
+the JRuby project. The default value for this flag is "joni"
+
+
+SYSTEM PROPERTY: -Dnashorn.time
+
+This enables timers for various phases of script compilation. The timers
+will be dumped when the Nashorn process exits. We see a percentage value
+of how much time was spent not executing bytecode (i.e. compilation and
+internal tasks) at the end of the report.
+Here is an example:
+
+[JavaScript Parsing] 61 ms
+[Constant Folding] 11 ms
+[Control Flow Lowering] 26 ms
+[Type Attribution] 81 ms
+[Range Analysis] 0 ms
+[Code Splitting] 29 ms
+[Type Finalization] 19 ms
+[Bytecode Generation] 189 ms
+[Code Installation] 7 ms
+Total runtime: 508 ms (Non-runtime: 423 ms [83%])
===============
2. The loggers.
@@ -442,6 +841,9 @@
The --log=codegen option is equivalent to setting the system variable
"nashorn.codegen.debug" to true.
+* fold
+
+Shows constant folding taking place before lowering
* lower
@@ -484,3 +886,160 @@
etc. It will also show the internal representation of respective field
(Object in the normal case, unless running with the dual field
representation)
+
+
+=======================
+3. Undocumented options
+=======================
+
+Here follows a short description of undocumented options for Nashorn.
+To see a list of all undocumented options, use the (undocumented) flag
+"-xhelp".
+
+i.e. jjs -xhelp or java -jar nashorn.jar -xhelp
+
+Undocumented options are not guaranteed to work, run correctly or be
+bug free. They are experimental and for internal or debugging use.
+They are also subject to change without notice.
+
+In practice, though, all options below not explicitly documented as
+EXPERIMENTAL can be relied upon, for example --dump-on-error is useful
+for any JavaScript/Nashorn developer, but there is no guarantee.
+
+A short summary follows:
+
+ -D (-Dname=value. Set a system property. This option can be repeated.)
+
+ -ccs, --class-cache-size (Size of the Class cache size per global scope.)
+
+ -cp, -classpath (-cp path. Specify where to find user class files.)
+
+ -co, --compile-only (Compile script without running. Exit after compilation)
+ param: [true|false] default: false
+
+ -d, --dump-debug-dir (specify a destination directory to dump class files.
+ This must be combined with the --compile-only option to work)
+ param: <path>
+
+ --debug-lines (Generate line number table in .class files.)
+ param: [true|false] default: true
+
+ --debug-locals (Generate local variable table in .class files.)
+ param: [true|false] default: false
+
+ -doe, -dump-on-error (Dump a stack trace on errors.)
+ param: [true|false] default: false
+
+ --early-lvalue-error (invalid lvalue expressions should be reported as early errors.)
+ param: [true|false] default: true
+
+ --empty-statements (Preserve empty statements in AST.)
+ param: [true|false] default: false
+
+ -fv, -fullversion (Print full version info of Nashorn.)
+ param: [true|false] default: false
+
+ --function-statement-error (Report an error when function declaration is used as a statement.)
+ param: [true|false] default: false
+
+ --function-statement-warning (Warn when function declaration is used as a statement.)
+ param: [true|false] default: false
+
+ -fx (Launch script as an fx application.)
+ param: [true|false] default: false
+
+ --global-per-engine (Use single Global instance per script engine instance.)
+ param: [true|false] default: false
+
+ -h, -help (Print help for command line flags.)
+ param: [true|false] default: false
+
+ --lazy-compilation (EXPERIMENTAL: Use lazy code generation strategies - do not compile
+ the entire script at once.)
+ param: [true|false] default: false
+
+ --loader-per-compile (Create a new class loader per compile.)
+ param: [true|false] default: true
+
+ -l, --locale (Set Locale for script execution.)
+ param: <locale> default: en-US
+
+ --log (Enable logging of a given level for a given number of sub systems.
+ [for example: --log=fields:finest,codegen:info])
+ param: <module:level>,*
+
+ -nj, --no-java (No Java support)
+ param: [true|false] default: false
+
+ -nse, --no-syntax-extensions (No non-standard syntax extensions)
+ param: [true|false] default: false
+
+ -nta, --no-typed-arrays (No Typed arrays support)
+ param: [true|false] default: false
+
+ --parse-only (Parse without compiling.)
+ param: [true|false] default: false
+
+ --print-ast (Print abstract syntax tree.)
+ param: [true|false] default: false
+
+ --print-code (Print bytecode.)
+ param: [true|false] default: false
+
+ --print-lower-ast (Print lowered abstract syntax tree.)
+ param: [true|false] default: false
+
+ --print-lower-parse (Print the parse tree after lowering.)
+ param: [true|false] default: false
+
+ --print-mem-usage (Print memory usage of IR after each compile stage.)
+ param: [true|false] default: false
+
+ --print-no-newline (Print function will not print new line char.)
+ param: [true|false] default: false
+
+ --print-parse (Print the parse tree.)
+ param: [true|false] default: false
+
+ --print-symbols (Print the symbol table.)
+ param: [true|false] default: false
+
+ -pcs, --profile-callsites (Dump callsite profile data.)
+ param: [true|false] default: false
+
+ --range-analysis (EXPERIMENTAL: Do range analysis using known compile time types,
+ and try to narrow number types)
+ param: [true|false] default: false
+
+ -scripting (Enable scripting features.)
+ param: [true|false] default: false
+
+ --specialize-calls (EXPERIMENTAL: Specialize all or a set of method according
+ to callsite parameter types)
+ param: [=function_1,...,function_n]
+
+ --stderr (Redirect stderr to a filename or to another tty, e.g. stdout)
+ param: <output console>
+
+ --stdout (Redirect stdout to a filename or to another tty, e.g. stderr)
+ param: <output console>
+
+ -strict (Run scripts in strict mode.)
+ param: [true|false] default: false
+
+ -t, -timezone (Set timezone for script execution.)
+ param: <timezone> default: Europe/Stockholm
+
+ -tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses]
+ enterexit [trace callsite enter/exit], objects [print object properties])
+ param: [=[option,]*]
+
+ --verify-code (Verify byte code before running.)
+ param: [true|false] default: false
+
+ -v, -version (Print version info of Nashorn.)
+ param: [true|false] default: false
+
+ -xhelp (Print extended help for command line flags.)
+ param: [true|false] default: false
+
--- a/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/ChainedCallSite.java Wed Jul 05 19:10:19 2017 +0200
@@ -121,7 +121,6 @@
* to change the value. If your override returns a value less than 1, the code will break.
* @return the maximum number of method handles in the chain.
*/
- @SuppressWarnings("static-method")
protected int getMaxChainLength() {
return 8;
}
--- a/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/DefaultBootstrapper.java Wed Jul 05 19:10:19 2017 +0200
@@ -133,7 +133,7 @@
* @param type the method signature at the call site
* @return a new {@link MonomorphicCallSite} linked with the default dynamic linker.
*/
- public static CallSite publicBootstrap(@SuppressWarnings("unused") MethodHandles.Lookup caller, String name, MethodType type) {
+ public static CallSite publicBootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
return bootstrapInternal(MethodHandles.publicLookup(), name, type);
}
--- a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java Wed Jul 05 19:10:19 2017 +0200
@@ -97,6 +97,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
import jdk.internal.dynalink.linker.GuardedInvocation;
--- a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Wed Jul 05 19:10:19 2017 +0200
@@ -148,6 +148,7 @@
}
}
+ @SuppressWarnings("fallthrough")
@Override
public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
final MethodType callSiteType = callSiteDescriptor.getMethodType();
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Jul 05 19:10:19 2017 +0200
@@ -55,6 +55,7 @@
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
+import javax.script.SimpleBindings;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.GlobalObject;
@@ -74,6 +75,12 @@
*/
public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable {
+ /**
+ * Key used to associate Nashorn global object mirror with arbitrary Bindings instance.
+ */
+ public static final String NASHORN_GLOBAL = "nashorn.global";
+
+ // commonly used access control context objects
private static AccessControlContext createPermAccCtxt(final String permName) {
final Permissions perms = new Permissions();
perms.add(new RuntimePermission(permName));
@@ -83,16 +90,23 @@
private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT);
private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL);
+ // the factory that created this engine
private final ScriptEngineFactory factory;
+ // underlying nashorn Context - 1:1 with engine instance
private final Context nashornContext;
+ // do we want to share single Nashorn global instance across ENGINE_SCOPEs?
+ private final boolean _global_per_engine;
+ // This is the initial default Nashorn global object.
+ // This is used as "shared" global if above option is true.
private final ScriptObject global;
- // initialized bit late to be made 'final'. Property object for "context"
- // property of global object
- private Property contextProperty;
+ // initialized bit late to be made 'final'.
+ // Property object for "context" property of global object.
+ private volatile Property contextProperty;
// default options passed to Nashorn Options object
private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-doe" };
+ // Nashorn script engine error message management
private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
private static final ResourceBundle MESSAGES_BUNDLE;
@@ -100,6 +114,7 @@
MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
}
+ // helper to get Nashorn script engine error message
private static String getMessage(final String msgId, final String... args) {
try {
return new MessageFormat(MESSAGES_BUNDLE.getString(msgId)).format(args);
@@ -108,6 +123,31 @@
}
}
+ // load engine.js and return content as a char[]
+ @SuppressWarnings("resource")
+ private static char[] loadEngineJSSource() {
+ final String script = "resources/engine.js";
+ try {
+ final InputStream is = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<InputStream>() {
+ @Override
+ public InputStream run() throws Exception {
+ final URL url = NashornScriptEngine.class.getResource(script);
+ return url.openStream();
+ }
+ });
+ return Source.readFully(new InputStreamReader(is));
+ } catch (final PrivilegedActionException | IOException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Source object for engine.js
+ private static final Source ENGINE_SCRIPT_SRC = new Source(NashornException.ENGINE_SCRIPT_SOURCE_NAME, loadEngineJSSource());
+
NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
this(factory, DEFAULT_OPTIONS, appLoader);
}
@@ -134,20 +174,13 @@
}
}, CREATE_CONTEXT_ACC_CTXT);
- // create new global object
- this.global = createNashornGlobal();
- // set the default engine scope for the default context
- context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE);
+ // cache this option that is used often
+ this._global_per_engine = nashornContext.getEnv()._global_per_engine;
- // evaluate engine initial script
- try {
- evalEngineScript();
- } catch (final ScriptException e) {
- if (Context.DEBUG) {
- e.printStackTrace();
- }
- throw new RuntimeException(e);
- }
+ // create new global object
+ this.global = createNashornGlobal(context);
+ // set the default ENGINE_SCOPE object for the default context
+ context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE);
}
@Override
@@ -176,8 +209,12 @@
@Override
public Bindings createBindings() {
- final ScriptObject newGlobal = createNashornGlobal();
- return new ScriptObjectMirror(newGlobal, newGlobal);
+ if (_global_per_engine) {
+ // just create normal SimpleBindings.
+ // We use same 'global' for all Bindings.
+ return new SimpleBindings();
+ }
+ return createGlobalMirror(null);
}
// Compilable methods
@@ -213,6 +250,48 @@
return invokeImpl(thiz, name, args);
}
+ @Override
+ public <T> T getInterface(final Class<T> clazz) {
+ return getInterfaceInner(null, clazz);
+ }
+
+ @Override
+ public <T> T getInterface(final Object thiz, final Class<T> clazz) {
+ if (thiz == null) {
+ throw new IllegalArgumentException(getMessage("thiz.cannot.be.null"));
+ }
+ return getInterfaceInner(thiz, clazz);
+ }
+
+ // These are called from the "engine.js" script
+
+ /**
+ * This hook is used to search js global variables exposed from Java code.
+ *
+ * @param self 'this' passed from the script
+ * @param ctxt current ScriptContext in which name is searched
+ * @param name name of the variable searched
+ * @return the value of the named variable
+ */
+ public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
+ if (ctxt != null) {
+ final int scope = ctxt.getAttributesScope(name);
+ final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+ if (scope != -1) {
+ return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
+ }
+
+ if (self == UNDEFINED) {
+ // scope access and so throw ReferenceError
+ throw referenceError(ctxtGlobal, "not.defined", name);
+ }
+ }
+
+ return UNDEFINED;
+ }
+
+ // Implementation only below this point
+
private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) {
if (clazz == null || !clazz.isInterface()) {
throw new IllegalArgumentException(getMessage("interface.class.expected"));
@@ -280,58 +359,56 @@
}
}
- @Override
- public <T> T getInterface(final Class<T> clazz) {
- return getInterfaceInner(null, clazz);
- }
+ // Retrieve nashorn Global object for a given ScriptContext object
+ private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
+ if (_global_per_engine) {
+ // shared single global object for all ENGINE_SCOPE Bindings
+ return global;
+ }
- @Override
- public <T> T getInterface(final Object thiz, final Class<T> clazz) {
- if (thiz == null) {
- throw new IllegalArgumentException(getMessage("thiz.cannot.be.null"));
+ final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
+ // is this Nashorn's own Bindings implementation?
+ if (bindings instanceof ScriptObjectMirror) {
+ final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings);
+ if (sobj != null) {
+ return sobj;
+ }
}
- return getInterfaceInner(thiz, clazz);
+
+ // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
+ Object scope = bindings.get(NASHORN_GLOBAL);
+ if (scope instanceof ScriptObjectMirror) {
+ final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
+ if (sobj != null) {
+ return sobj;
+ }
+ }
+
+ // We didn't find associated nashorn global mirror in the Bindings given!
+ // Create new global instance mirror and associate with the Bindings.
+ final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
+ bindings.put(NASHORN_GLOBAL, mirror);
+ return mirror.getScriptObject();
}
- // These are called from the "engine.js" script
-
- /**
- * This hook is used to search js global variables exposed from Java code.
- *
- * @param self 'this' passed from the script
- * @param ctxt current ScriptContext in which name is searched
- * @param name name of the variable searched
- * @return the value of the named variable
- */
- public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
- final int scope = ctxt.getAttributesScope(name);
- final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
- if (scope != -1) {
- return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
+ // Retrieve nashorn Global object from a given ScriptObjectMirror
+ private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
+ ScriptObject sobj = mirror.getScriptObject();
+ if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) {
+ return sobj;
}
- if (self == UNDEFINED) {
- // scope access and so throw ReferenceError
- throw referenceError(ctxtGlobal, "not.defined", name);
- }
-
- return UNDEFINED;
+ return null;
}
- private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
- final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
- if (bindings instanceof ScriptObjectMirror) {
- ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject();
- if (sobj instanceof GlobalObject) {
- return sobj;
- }
- }
-
- // didn't find global object from context given - return the engine-wide global
- return global;
+ // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
+ private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
+ final ScriptObject newGlobal = createNashornGlobal(ctxt);
+ return new ScriptObjectMirror(newGlobal, newGlobal);
}
- private ScriptObject createNashornGlobal() {
+ // Create a new Nashorn Global object
+ private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
@Override
public ScriptObject run() {
@@ -352,7 +429,7 @@
// current ScriptContext exposed as "context"
// "context" is non-writable from script - but script engine still
// needs to set it and so save the context Property object
- contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, UNDEFINED);
+ contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null);
// current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
// NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
// in the Global of a Context we just created - both the Context and the Global were just created and can not be
@@ -362,38 +439,17 @@
newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED);
// file name default is null
newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null);
+ // evaluate engine.js initialization script this new global object
+ try {
+ evalImpl(compileImpl(ENGINE_SCRIPT_SRC, newGlobal), ctxt, newGlobal);
+ } catch (final ScriptException exp) {
+ throw new RuntimeException(exp);
+ }
return newGlobal;
}
- private void evalEngineScript() throws ScriptException {
- final String script = "resources/engine.js";
- final String name = NashornException.ENGINE_SCRIPT_SOURCE_NAME;
- try {
- final InputStream is = AccessController.doPrivileged(
- new PrivilegedExceptionAction<InputStream>() {
- @Override
- public InputStream run() throws Exception {
- final URL url = NashornScriptEngine.class.getResource(script);
- return url.openStream();
- }
- });
- put(ScriptEngine.FILENAME, name);
- try (final InputStreamReader isr = new InputStreamReader(is)) {
- eval(isr);
- }
- } catch (final PrivilegedActionException | IOException e) {
- if (Context.DEBUG) {
- e.printStackTrace();
- }
- throw new ScriptException(e);
- } finally {
- put(ScriptEngine.FILENAME, null);
- }
- }
-
- // scripts should see "context" and "engine" as variables
- private void setContextVariables(final ScriptContext ctxt) {
- final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+ // scripts should see "context" and "engine" as variables in the given global object
+ private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) {
// set "context" global variable via contextProperty - because this
// property is non-writable
contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
@@ -402,8 +458,10 @@
args = ScriptRuntime.EMPTY_ARRAY;
}
// if no arguments passed, expose it
- args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
- ctxtGlobal.set("arguments", args, false);
+ if (! (args instanceof ScriptObject)) {
+ args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
+ ctxtGlobal.set("arguments", args, false);
+ }
}
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
@@ -456,18 +514,24 @@
}
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException {
+ return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
+ }
+
+ private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}
final ScriptObject oldGlobal = Context.getGlobal();
- final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
if (globalChanged) {
Context.setGlobal(ctxtGlobal);
}
- setContextVariables(ctxt);
+ // set ScriptContext variables if ctxt is non-null
+ if (ctxt != null) {
+ setContextVariables(ctxtGlobal, ctxt);
+ }
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
} catch (final Exception e) {
throwAsScriptException(e);
@@ -517,15 +581,18 @@
}
private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
+ return compileImpl(source, getNashornGlobalFrom(ctxt));
+ }
+
+ private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException {
final ScriptObject oldGlobal = Context.getGlobal();
- final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
- final boolean globalChanged = (oldGlobal != ctxtGlobal);
+ final boolean globalChanged = (oldGlobal != newGlobal);
try {
if (globalChanged) {
- Context.setGlobal(ctxtGlobal);
+ Context.setGlobal(newGlobal);
}
- return nashornContext.compileScript(source, ctxtGlobal);
+ return nashornContext.compileScript(source, newGlobal);
} catch (final Exception e) {
throwAsScriptException(e);
throw new AssertionError("should not reach here");
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jul 05 19:10:19 2017 +0200
@@ -99,12 +99,14 @@
}
final Object val = functionName == null? sobj : sobj.get(functionName);
- if (! (val instanceof ScriptFunction)) {
- throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : ""));
+ if (val instanceof ScriptFunction) {
+ final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
+ return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+ } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) {
+ return ((ScriptObjectMirror)val).call(null, args);
}
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+ throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : ""));
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
@@ -127,12 +129,14 @@
}
final Object val = functionName == null? sobj : sobj.get(functionName);
- if (! (val instanceof ScriptFunction)) {
- throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : ""));
+ if (val instanceof ScriptFunction) {
+ final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
+ return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global);
+ } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) {
+ return ((ScriptObjectMirror)val).newObject(null, args);
}
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global);
+ throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : ""));
} catch (final RuntimeException | Error e) {
throw e;
} catch (final Throwable t) {
@@ -374,6 +378,28 @@
}
/**
+ * Set the __proto__ of this object.
+ * @param proto new proto for this object
+ */
+ public void setProto(final Object proto) {
+ inGlobal(new Callable<Void>() {
+ @Override public Void call() {
+ sobj.setProtoCheck(unwrap(proto, global));
+ return null;
+ }
+ });
+ }
+
+ /**
+ * ECMA [[Class]] property
+ *
+ * @return ECMA [[Class]] property value of this object
+ */
+ public String getClassName() {
+ return sobj.getClassName();
+ }
+
+ /**
* ECMA 8.12.1 [[GetOwnProperty]] (P)
*
* @param key property key
--- a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js Wed Jul 05 19:10:19 2017 +0200
@@ -23,10 +23,9 @@
/**
* This script file is executed by script engine at the construction
- * of the engine. The functions here assume global variables "context"
- * of type javax.script.ScriptContext and "engine" of the type
+ * of the every new Global object. The functions here assume global variables
+ * "context" of type javax.script.ScriptContext and "engine" of the type
* jdk.nashorn.api.scripting.NashornScriptEngine.
- *
**/
Object.defineProperty(this, "__noSuchProperty__", {
@@ -40,7 +39,7 @@
});
function print() {
- var writer = context.getWriter();
+ var writer = context != null? context.writer : engine.context.writer;
if (! (writer instanceof java.io.PrintWriter)) {
writer = new java.io.PrintWriter(writer);
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java Wed Jul 05 19:10:19 2017 +0200
@@ -543,8 +543,6 @@
public Node leaveIdentNode(final IdentNode identNode) {
final String name = identNode.getName();
- start(identNode);
-
if (identNode.isPropertyName()) {
// assign a pseudo symbol to property name
final Symbol pseudoSymbol = pseudoSymbol(name);
@@ -1850,9 +1848,10 @@
append("] ").
append(printNode ? node.toString() : "").
append(" in '").
- append(lc.getCurrentFunction().getName());
+ append(lc.getCurrentFunction().getName()).
+ append('\'');
- if(node instanceof Expression) {
+ if (node instanceof Expression) {
final Symbol symbol = ((Expression)node).getSymbol();
if (symbol == null) {
sb.append(" <NO SYMBOL>");
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Wed Jul 05 19:10:19 2017 +0200
@@ -414,30 +414,34 @@
compiler.getCodeInstaller().verify(bytecode);
}
- // should code be dumped to disk - only valid in compile_only
- // mode?
+ // should code be dumped to disk - only valid in compile_only mode?
if (env._dest_dir != null && env._compile_only) {
final String fileName = className.replace('.', File.separatorChar) + ".class";
- final int index = fileName.lastIndexOf(File.separatorChar);
+ final int index = fileName.lastIndexOf(File.separatorChar);
+ final File dir;
if (index != -1) {
- final File dir = new File(fileName.substring(0, index));
- try {
- if (!dir.exists() && !dir.mkdirs()) {
- throw new IOException(dir.toString());
- }
- final File file = new File(env._dest_dir, fileName);
- try (final FileOutputStream fos = new FileOutputStream(file)) {
- fos.write(bytecode);
- }
- } catch (final IOException e) {
- Compiler.LOG.warning("Skipping class dump for ",
- className,
- ": ",
- ECMAErrors.getMessage(
- "io.error.cant.write",
- dir.toString()));
+ dir = new File(env._dest_dir, fileName.substring(0, index));
+ } else {
+ dir = new File(env._dest_dir);
+ }
+
+ try {
+ if (!dir.exists() && !dir.mkdirs()) {
+ throw new IOException(dir.toString());
}
+ final File file = new File(env._dest_dir, fileName);
+ try (final FileOutputStream fos = new FileOutputStream(file)) {
+ fos.write(bytecode);
+ }
+ Compiler.LOG.info("Wrote class to '" + file.getAbsolutePath() + '\'');
+ } catch (final IOException e) {
+ Compiler.LOG.warning("Skipping class dump for ",
+ className,
+ ": ",
+ ECMAErrors.getMessage(
+ "io.error.cant.write",
+ dir.toString()));
}
}
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java Wed Jul 05 19:10:19 2017 +0200
@@ -40,6 +40,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
+
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -632,6 +633,7 @@
return new NativeArray(list.toArray());
}
+ @SuppressWarnings("null")
private static void concatToList(final ArrayList<Object> list, final Object obj) {
final boolean isScriptArray = isArray(obj);
final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java Wed Jul 05 19:10:19 2017 +0200
@@ -73,6 +73,11 @@
this(Arrays.copyOfRange(other.buffer, begin, end));
}
+ @Override
+ public String getClassName() {
+ return "ArrayBuffer";
+ }
+
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
public static Object byteLength(final Object self) {
return ((NativeArrayBuffer)self).buffer.length;
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -145,6 +145,11 @@
}
@Override
+ public String getClassName() {
+ return "Float32Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -155,6 +155,11 @@
}
@Override
+ public String getClassName() {
+ return "Float64Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -109,6 +109,11 @@
}
@Override
+ public String getClassName() {
+ return "Int16Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -112,6 +112,11 @@
}
@Override
+ public String getClassName() {
+ return "Int32Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -102,6 +102,11 @@
}
@Override
+ public String getClassName() {
+ return "Int8Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java Wed Jul 05 19:10:19 2017 +0200
@@ -32,7 +32,6 @@
import java.util.Collection;
import java.util.Deque;
import java.util.List;
-
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.support.TypeUtilities;
import jdk.nashorn.internal.objects.annotations.Attribute;
@@ -44,6 +43,7 @@
import jdk.nashorn.internal.runtime.ListAdapter;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
/**
@@ -539,4 +539,25 @@
}
return JavaAdapterFactory.getAdapterClassFor(stypes, classOverrides);
}
+
+ /**
+ * When given an object created using {@code Java.extend()} or equivalent mechanism (that is, any JavaScript-to-Java
+ * adapter), returns an object that can be used to invoke superclass methods on that object. E.g.:
+ * <pre>
+ * var cw = new FilterWriterAdapter(sw) {
+ * write: function(s, off, len) {
+ * s = capitalize(s, off, len)
+ * cw_super.write(s, 0, s.length())
+ * }
+ * }
+ * var cw_super = Java.super(cw)
+ * </pre>
+ * @param self the {@code Java} object itself - not used.
+ * @param adapter the original Java adapter instance for which the super adapter is created.
+ * @return a super adapter for the original adapter
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR, name="super")
+ public static Object _super(final Object self, final Object adapter) {
+ return Bootstrap.createSuperAdapter(adapter);
+ }
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Wed Jul 05 19:10:19 2017 +0200
@@ -125,6 +125,28 @@
}
/**
+ * Nashorn extension: Object.setPrototypeOf ( O, proto )
+ * Also found in ES6 draft specification.
+ *
+ * @param self self reference
+ * @param obj object to set prototype for
+ * @param proto prototype object to be used
+ * @return object whose prototype is set
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
+ public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
+ if (obj instanceof ScriptObject) {
+ ((ScriptObject)obj).setProtoCheck(proto);
+ return obj;
+ } else if (obj instanceof ScriptObjectMirror) {
+ ((ScriptObjectMirror)obj).setProto(proto);
+ return obj;
+ }
+
+ throw notAnObject(obj);
+ }
+
+ /**
* ECMA 15.2.3.3 Object.getOwnPropertyDescriptor ( O, P )
*
* @param self self reference
@@ -184,7 +206,7 @@
// FIXME: should we create a proper object with correct number of
// properties?
final ScriptObject newObj = Global.newEmptyInstance();
- newObj.setProtoCheck(proto);
+ newObj.setProto((ScriptObject)proto);
if (props != UNDEFINED) {
NativeObject.defineProperties(self, newObj, props);
}
@@ -647,15 +669,43 @@
final List<AccessorProperty> properties = new ArrayList<>(propertyNames.size() + methodNames.size());
for(final String methodName: methodNames) {
- properties.add(AccessorProperty.create(methodName, Property.NOT_WRITABLE,
- getBoundBeanMethodGetter(source, getBeanOperation(linker, "dyn:getMethod:" + methodName, getterType, source)),
- null));
+ final MethodHandle method;
+ try {
+ method = getBeanOperation(linker, "dyn:getMethod:" + methodName, getterType, source);
+ } catch(final IllegalAccessError e) {
+ // Presumably, this was a caller sensitive method. Ignore it and carry on.
+ continue;
+ }
+ properties.add(AccessorProperty.create(methodName, Property.NOT_WRITABLE, getBoundBeanMethodGetter(source,
+ method), null));
}
for(final String propertyName: propertyNames) {
+ MethodHandle getter;
+ if(readablePropertyNames.contains(propertyName)) {
+ try {
+ getter = getBeanOperation(linker, "dyn:getProp:" + propertyName, getterType, source);
+ } catch(final IllegalAccessError e) {
+ // Presumably, this was a caller sensitive method. Ignore it and carry on.
+ getter = Lookup.EMPTY_GETTER;
+ }
+ } else {
+ getter = Lookup.EMPTY_GETTER;
+ }
final boolean isWritable = writablePropertyNames.contains(propertyName);
- properties.add(AccessorProperty.create(propertyName, isWritable ? 0 : Property.NOT_WRITABLE,
- readablePropertyNames.contains(propertyName) ? getBeanOperation(linker, "dyn:getProp:" + propertyName, getterType, source) : Lookup.EMPTY_GETTER,
- isWritable ? getBeanOperation(linker, "dyn:setProp:" + propertyName, setterType, source) : Lookup.EMPTY_SETTER));
+ MethodHandle setter;
+ if(isWritable) {
+ try {
+ setter = getBeanOperation(linker, "dyn:setProp:" + propertyName, setterType, source);
+ } catch(final IllegalAccessError e) {
+ // Presumably, this was a caller sensitive method. Ignore it and carry on.
+ setter = Lookup.EMPTY_SETTER;
+ }
+ } else {
+ setter = Lookup.EMPTY_SETTER;
+ }
+ if(getter != Lookup.EMPTY_GETTER || setter != Lookup.EMPTY_SETTER) {
+ properties.add(AccessorProperty.create(propertyName, isWritable ? 0 : Property.NOT_WRITABLE, getter, setter));
+ }
}
targetObj.addBoundProperties(source, properties.toArray(new AccessorProperty[properties.size()]));
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java Wed Jul 05 19:10:19 2017 +0200
@@ -65,10 +65,9 @@
private RegExp regexp;
// Reference to global object needed to support static RegExp properties
- private Global globalObject;
+ private final Global globalObject;
// initialized by nasgen
- @SuppressWarnings("unused")
private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java Wed Jul 05 19:10:19 2017 +0200
@@ -1058,9 +1058,8 @@
public static Object trim(final Object self) {
final String str = checkObjectToString(self);
- final int len = str.length();
int start = 0;
- int end = len - 1;
+ int end = str.length() - 1;
while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
start++;
@@ -1069,7 +1068,45 @@
end--;
}
- return start == 0 && end + 1 == len ? str : str.substring(start, end + 1);
+ return str.substring(start, end + 1);
+ }
+
+ /**
+ * Nashorn extension: String.prototype.trimLeft ( )
+ * @param self self reference
+ * @return string trimmed left from whitespace
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object trimLeft(final Object self) {
+
+ final String str = checkObjectToString(self);
+ int start = 0;
+ int end = str.length() - 1;
+
+ while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
+ start++;
+ }
+
+ return str.substring(start, end + 1);
+ }
+
+ /**
+ * Nashorn extension: String.prototype.trimRight ( )
+ * @param self self reference
+ * @return string trimmed right from whitespace
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE)
+ public static Object trimRight(final Object self) {
+
+ final String str = checkObjectToString(self);
+ int start = 0;
+ int end = str.length() - 1;
+
+ while (end >= start && ScriptRuntime.isJSWhitespace(str.charAt(end))) {
+ end--;
+ }
+
+ return str.substring(start, end + 1);
}
private static Object newObj(final Object self, final CharSequence str) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -108,6 +108,11 @@
}
@Override
+ public String getClassName() {
+ return "Uint16Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -127,6 +127,11 @@
}
@Override
+ public String getClassName() {
+ return "Uint32Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Jul 05 19:10:19 2017 +0200
@@ -101,6 +101,11 @@
}
@Override
+ public String getClassName() {
+ return "Uint8Array";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Jul 05 19:10:19 2017 +0200
@@ -118,6 +118,11 @@
}
@Override
+ public String getClassName() {
+ return "Uint8ClampedArray";
+ }
+
+ @Override
protected Factory factory() {
return FACTORY;
}
--- a/nashorn/src/jdk/nashorn/internal/parser/TokenType.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/parser/TokenType.java Wed Jul 05 19:10:19 2017 +0200
@@ -284,7 +284,7 @@
@Override
public String toString() {
- return name;
+ return getNameOrType();
}
static {
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Wed Jul 05 19:10:19 2017 +0200
@@ -91,6 +91,11 @@
*/
public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
+ /* Force DebuggerSupport to be loaded. */
+ static {
+ DebuggerSupport.FORCELOAD = true;
+ }
+
/**
* ContextCodeInstaller that has the privilege of installing classes in the Context.
* Can only be instantiated from inside the context and is opaque to other classes
@@ -889,7 +894,6 @@
return script;
}
- @SuppressWarnings("static-method")
private ScriptLoader createNewLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ScriptLoader>() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/DebuggerSupport.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,330 @@
+/*
+ * 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
+ * under the terms of the GNU General 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 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 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 jdk.nashorn.internal.runtime;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class provides support for external debuggers. Its primary purpose is
+ * is to simplify the debugger tasks and provide better performance.
+ */
+final class DebuggerSupport {
+ /**
+ * Hook to force the loading of the DebuggerSupport class so that it is
+ * available to external debuggers.
+ */
+ static boolean FORCELOAD = true;
+
+ static {
+ /**
+ * Hook to force the loading of the DebuggerValueDesc class so that it is
+ * available to external debuggers.
+ */
+ @SuppressWarnings("unused")
+ DebuggerValueDesc forceLoad = new DebuggerValueDesc(null, false, null, null);
+ }
+
+ /** This class is used to send a bulk description of a value. */
+ static class DebuggerValueDesc {
+ /** Property key (or index) or field name. */
+ final String key;
+
+ /** If the value is expandable. */
+ final boolean expandable;
+
+ /** Property or field value as object. */
+ final Object valueAsObject;
+
+ /** Property or field value as string. */
+ final String valueAsString;
+
+ DebuggerValueDesc(final String key, final boolean expandable, final Object valueAsObject, final String valueAsString) {
+ this.key = key;
+ this.expandable = expandable;
+ this.valueAsObject = valueAsObject;
+ this.valueAsString = valueAsString;
+ }
+ }
+
+ /**
+ * Return the current context global.
+ * @return context global.
+ */
+ static Object getGlobal() {
+ return Context.getGlobalTrusted();
+ }
+
+ /**
+ * Call eval on the current global.
+ * @param scope Scope to use.
+ * @param self Receiver to use.
+ * @param string String to evaluate.
+ * @param returnException true if exceptions are to be returned.
+ * @return Result of eval as string, or, an exception or null depending on returnException.
+ */
+ static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
+ final ScriptObject global = Context.getGlobalTrusted();
+ final ScriptObject initialScope = scope != null ? scope : global;
+ final Object callThis = self != null ? self : global;
+ final Context context = global.getContext();
+
+ try {
+ return context.eval(initialScope, string, callThis, ScriptRuntime.UNDEFINED, false);
+ } catch (Throwable ex) {
+ return returnException ? ex : null;
+ }
+ }
+
+ /**
+ * This method returns a bulk description of an object's properties.
+ * @param object Script object to be displayed by the debugger.
+ * @param all true if to include non-enumerable values.
+ * @return An array of DebuggerValueDesc.
+ */
+ static DebuggerValueDesc[] valueInfos(final Object object, final boolean all) {
+ assert object instanceof ScriptObject;
+ return getDebuggerValueDescs((ScriptObject)object, all, new HashSet<>());
+ }
+
+ /**
+ * This method returns a debugger description of the value.
+ * @param name Name of value (property name).
+ * @param value Data value.
+ * @param all true if to include non-enumerable values.
+ * @return A DebuggerValueDesc.
+ */
+ static DebuggerValueDesc valueInfo(final String name, final Object value, final boolean all) {
+ return valueInfo(name, value, all, new HashSet<>());
+ }
+
+ /**
+ * This method returns a debugger description of the value.
+ * @param name Name of value (property name).
+ * @param value Data value.
+ * @param all true if to include non-enumerable values.
+ * @param duplicates Duplication set to avoid cycles.
+ * @return A DebuggerValueDesc.
+ */
+ private static DebuggerValueDesc valueInfo(final String name, final Object value, final boolean all, final Set<Object> duplicates) {
+ if (value instanceof ScriptObject && !(value instanceof ScriptFunction)) {
+ final ScriptObject object = (ScriptObject)value;
+ return new DebuggerValueDesc(name, !object.isEmpty(), value, objectAsString(object, all, duplicates));
+ }
+ return new DebuggerValueDesc(name, false, value, valueAsString(value));
+ }
+
+ /**
+ * Generate the descriptions for an object's properties.
+ * @param object Object to introspect.
+ * @param all true if to include non-enumerable values.
+ * @param duplicates Duplication set to avoid cycles.
+ * @return An array of DebuggerValueDesc.
+ */
+ private static DebuggerValueDesc[] getDebuggerValueDescs(final ScriptObject object, final boolean all, final Set<Object> duplicates) {
+ if (duplicates.contains(object)) {
+ return null;
+ }
+
+ duplicates.add(object);
+
+ final String[] keys = object.getOwnKeys(all);
+ final DebuggerValueDesc[] descs = new DebuggerValueDesc[keys.length];
+
+ for (int i = 0; i < keys.length; i++) {
+ final String key = keys[i];
+ descs[i] = valueInfo(key, object.get(key), all, duplicates);
+ }
+
+ duplicates.remove(object);
+
+ return descs;
+ }
+
+ /**
+ * Generate a string representation of a Script object.
+ * @param object Script object to represent.
+ * @param all true if to include non-enumerable values.
+ * @param duplicates Duplication set to avoid cycles.
+ * @return String representation.
+ */
+ private static String objectAsString(final ScriptObject object, final boolean all, final Set<Object> duplicates) {
+ final StringBuilder sb = new StringBuilder();
+
+ if (ScriptObject.isArray(object)) {
+ sb.append('[');
+ final long length = object.getLong("length");
+
+ for (long i = 0; i < length; i++) {
+ if (object.has(i)) {
+ final Object valueAsObject = object.get(i);
+ final boolean isUndefined = JSType.of(valueAsObject) == JSType.UNDEFINED;
+
+ if (isUndefined) {
+ if (i != 0) {
+ sb.append(",");
+ }
+ } else {
+ if (i != 0) {
+ sb.append(", ");
+ }
+
+ if (valueAsObject instanceof ScriptObject && !(valueAsObject instanceof ScriptFunction)) {
+ final String objectString = objectAsString((ScriptObject)valueAsObject, all, duplicates);
+ sb.append(objectString != null ? objectString : "{...}");
+ } else {
+ sb.append(valueAsString(valueAsObject));
+ }
+ }
+ } else {
+ if (i != 0) {
+ sb.append(',');
+ }
+ }
+ }
+
+ sb.append(']');
+ } else {
+ sb.append('{');
+ final DebuggerValueDesc[] descs = getDebuggerValueDescs(object, all, duplicates);
+
+ if (descs != null) {
+ for (int i = 0; i < descs.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+
+ final String valueAsString = descs[i].valueAsString;
+ sb.append(descs[i].key);
+ sb.append(": ");
+ sb.append(valueAsString);
+ }
+ }
+
+ sb.append('}');
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * This method returns a string representation of a value.
+ * @param value Arbitrary value to be displayed by the debugger.
+ * @return A string representation of the value or an array of DebuggerValueDesc.
+ */
+ private static String valueAsString(final Object value) {
+ final JSType type = JSType.of(value);
+
+ switch (type) {
+ case BOOLEAN:
+ return value.toString();
+
+ case STRING:
+ return escape((String)value);
+
+ case NUMBER:
+ return JSType.toString(((Number)value).doubleValue());
+
+ case NULL:
+ return "null";
+
+ case UNDEFINED:
+ return "undefined";
+
+ case OBJECT:
+ return ScriptRuntime.safeToString(value);
+
+ case FUNCTION:
+ if (value instanceof ScriptFunction) {
+ return ((ScriptFunction)value).toSource();
+ }
+ return value.toString();
+
+ default:
+ return value.toString();
+ }
+ }
+
+ /**
+ * Escape a string into a form that can be parsed by JavaScript.
+ * @param value String to be escaped.
+ * @return Escaped string.
+ */
+ private static String escape(final String value) {
+ final StringBuilder sb = new StringBuilder();
+
+ sb.append("\"");
+
+ for (final char ch : value.toCharArray()) {
+ switch (ch) {
+ case '\\':
+ sb.append("\\\\");
+ break;
+ case '"':
+ sb.append("\\\"");
+ break;
+ case '\'':
+ sb.append("\\\'");
+ break;
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ default:
+ if (ch < ' ' || ch >= 0xFF) {
+ sb.append("\\u");
+
+ final String hex = Integer.toHexString(ch);
+ for (int i = hex.length(); i < 4; i++) {
+ sb.append('0');
+ }
+ sb.append(hex);
+ } else {
+ sb.append(ch);
+ }
+
+ break;
+ }
+ }
+
+ sb.append("\"");
+
+ return sb.toString();
+ }
+}
+
+
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Wed Jul 05 19:10:19 2017 +0200
@@ -30,11 +30,10 @@
import java.lang.invoke.MethodHandles;
import java.util.Locale;
-import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.beans.StaticClass;
-import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.parser.Lexer;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
/**
* Representation for ECMAScript types - this maps directly to the ECMA script standard
@@ -148,22 +147,10 @@
return JSType.STRING;
}
- if (obj instanceof ScriptObject) {
- return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT;
- }
-
- if (obj instanceof StaticClass) {
+ if (Bootstrap.isCallable(obj)) {
return JSType.FUNCTION;
}
- if (BeansLinker.isDynamicMethod(obj)) {
- return JSType.FUNCTION;
- }
-
- if (obj instanceof ScriptObjectMirror) {
- return ((ScriptObjectMirror)obj).isFunction()? JSType.FUNCTION : JSType.OBJECT;
- }
-
return JSType.OBJECT;
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListener.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListener.java Wed Jul 05 19:10:19 2017 +0200
@@ -54,4 +54,13 @@
*
*/
public void propertyModified(ScriptObject object, Property oldProp, Property newProp);
+
+ /**
+ * Given object's __proto__ has changed.
+ *
+ * @param object object whose __proto__ has changed.
+ * @param oldProto old __proto__
+ * @param newProto new __proto__
+ */
+ public void protoChanged(ScriptObject object, ScriptObject oldProto, ScriptObject newProto);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java Wed Jul 05 19:10:19 2017 +0200
@@ -140,6 +140,21 @@
}
}
+ /**
+ * This method can be called to notify __proto__ modification to this object's listeners.
+ *
+ * @param object The ScriptObject whose __proto__ was changed.
+ * @param oldProto old __proto__
+ * @param newProto new __proto__
+ */
+ protected synchronized final void notifyProtoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) {
+ if (listeners != null) {
+ for (PropertyListener listener : listeners.keySet()) {
+ listener.protoChanged(object, oldProto, newProto);
+ }
+ }
+ }
+
// PropertyListener methods
@Override
@@ -156,4 +171,9 @@
public final void propertyModified(final ScriptObject object, final Property oldProp, final Property newProp) {
notifyPropertyModified(object, oldProp, newProp);
}
+
+ @Override
+ public final void protoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) {
+ notifyProtoChanged(object, oldProto, newProto);
+ }
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java Wed Jul 05 19:10:19 2017 +0200
@@ -230,7 +230,7 @@
}
/**
- * Indicate that a prototype property hash changed.
+ * Indicate that a prototype property has changed.
*
* @param property {@link Property} to invalidate.
*/
@@ -251,6 +251,18 @@
}
/**
+ * Indicate that proto itself has changed in hierachy somewhere.
+ */
+ private void invalidateAllProtoGetSwitchPoints() {
+ assert !isShared() : "proto invalidation on a shared PropertyMap";
+
+ if (protoGetSwitches != null) {
+ final Collection<SwitchPoint> sws = protoGetSwitches.values();
+ SwitchPoint.invalidateAll(sws.toArray(new SwitchPoint[sws.size()]));
+ }
+ }
+
+ /**
* Add a property to the map, re-binding its getters and setters,
* if available, to a given receiver. This is typically the global scope. See
* {@link ScriptObject#addBoundProperties(ScriptObject)}
@@ -878,6 +890,15 @@
invalidateProtoGetSwitchPoint(oldProp);
}
+ @Override
+ public void protoChanged(final ScriptObject object, final ScriptObject oldProto, final ScriptObject newProto) {
+ // We may walk and invalidate SwitchPoints for properties inherited
+ // from 'object' or it's old proto chain. But, it may not be worth it.
+ // For example, a new proto may have a user defined getter/setter for
+ // a data property down the chain. So, invalidating all is better.
+ invalidateAllProtoGetSwitchPoints();
+ }
+
/*
* Debugging and statistics.
*/
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Wed Jul 05 19:10:19 2017 +0200
@@ -86,6 +86,9 @@
/** Launch using as fx application */
public final boolean _fx;
+ /** Use single Global instance per jsr223 engine instance. */
+ public final boolean _global_per_engine;
+
/**
* Behavior when encountering a function declaration in a lexical context where only statements are acceptable
* (function declarations are source elements, but not statements).
@@ -128,9 +131,6 @@
/** Do not support typed arrays. */
public final boolean _no_typed_arrays;
- /** Package to which generated class files are added */
- public final String _package;
-
/** Only parse the source code, do not compile */
public final boolean _parse_only;
@@ -211,12 +211,12 @@
_function_statement = FunctionStatementBehavior.ACCEPT;
}
_fx = options.getBoolean("fx");
+ _global_per_engine = options.getBoolean("global.per.engine");
_lazy_compilation = options.getBoolean("lazy.compilation");
_loader_per_compile = options.getBoolean("loader.per.compile");
_no_java = options.getBoolean("no.java");
_no_syntax_extensions = options.getBoolean("no.syntax.extensions");
_no_typed_arrays = options.getBoolean("no.typed.arrays");
- _package = options.getString("package");
_parse_only = options.getBoolean("parse.only");
_print_ast = options.getBoolean("print.ast");
_print_lower_ast = options.getBoolean("print.lower.ast");
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Jul 05 19:10:19 2017 +0200
@@ -52,6 +52,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
@@ -1008,10 +1009,6 @@
return getMap().findProperty(key);
}
- static String convertKey(final Object key) {
- return (key instanceof String) ? (String)key : JSType.toString(key);
- }
-
/**
* Overridden by {@link jdk.nashorn.internal.objects.NativeArguments} class (internal use.)
* Used for argument access in a vararg function using parameter name.
@@ -1129,6 +1126,9 @@
proto = newProto;
if (isPrototype()) {
+ // tell listeners that my __proto__ has been changed
+ notifyProtoChanged(this, oldProto, newProto);
+
if (oldProto != null) {
oldProto.removePropertyListener(this);
}
@@ -1144,7 +1144,19 @@
* @param newProto Prototype to set.
*/
public final void setProtoCheck(final Object newProto) {
+ if (!isExtensible()) {
+ throw typeError("__proto__.set.non.extensible", ScriptRuntime.safeToString(this));
+ }
+
if (newProto == null || newProto instanceof ScriptObject) {
+ // check for circularity
+ ScriptObject p = (ScriptObject)newProto;
+ while (p != null) {
+ if (p == this) {
+ throw typeError("circular.__proto__.set", ScriptRuntime.safeToString(this));
+ }
+ p = p.getProto();
+ }
setProto((ScriptObject)newProto);
} else {
final ScriptObject global = Context.getGlobalTrusted();
@@ -2006,6 +2018,7 @@
* @param request the link request
* @return GuardedInvocation to be invoked at call site.
*/
+ @SuppressWarnings("null")
public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
@@ -2359,7 +2372,7 @@
return array.getInt(index);
}
- return getInt(index, convertKey(key));
+ return getInt(index, JSType.toString(key));
}
@Override
@@ -2371,7 +2384,7 @@
return array.getInt(index);
}
- return getInt(index, convertKey(key));
+ return getInt(index, JSType.toString(key));
}
@Override
@@ -2383,7 +2396,7 @@
return array.getInt(index);
}
- return getInt(index, convertKey(key));
+ return getInt(index, JSType.toString(key));
}
@Override
@@ -2394,7 +2407,7 @@
return array.getInt(key);
}
- return getInt(key, convertKey(key));
+ return getInt(key, JSType.toString(key));
}
private long getLong(final int index, final String key) {
@@ -2436,7 +2449,7 @@
return array.getLong(index);
}
- return getLong(index, convertKey(key));
+ return getLong(index, JSType.toString(key));
}
@Override
@@ -2448,7 +2461,7 @@
return array.getLong(index);
}
- return getLong(index, convertKey(key));
+ return getLong(index, JSType.toString(key));
}
@Override
@@ -2460,7 +2473,7 @@
return array.getLong(index);
}
- return getLong(index, convertKey(key));
+ return getLong(index, JSType.toString(key));
}
@Override
@@ -2471,7 +2484,7 @@
return array.getLong(key);
}
- return getLong(key, convertKey(key));
+ return getLong(key, JSType.toString(key));
}
private double getDouble(final int index, final String key) {
@@ -2513,7 +2526,7 @@
return array.getDouble(index);
}
- return getDouble(index, convertKey(key));
+ return getDouble(index, JSType.toString(key));
}
@Override
@@ -2525,7 +2538,7 @@
return array.getDouble(index);
}
- return getDouble(index, convertKey(key));
+ return getDouble(index, JSType.toString(key));
}
@Override
@@ -2537,7 +2550,7 @@
return array.getDouble(index);
}
- return getDouble(index, convertKey(key));
+ return getDouble(index, JSType.toString(key));
}
@Override
@@ -2548,7 +2561,7 @@
return array.getDouble(key);
}
- return getDouble(key, convertKey(key));
+ return getDouble(key, JSType.toString(key));
}
private Object get(final int index, final String key) {
@@ -2590,7 +2603,7 @@
return array.getObject(index);
}
- return get(index, convertKey(key));
+ return get(index, JSType.toString(key));
}
@Override
@@ -2602,7 +2615,7 @@
return array.getObject(index);
}
- return get(index, convertKey(key));
+ return get(index, JSType.toString(key));
}
@Override
@@ -2614,7 +2627,7 @@
return array.getObject(index);
}
- return get(index, convertKey(key));
+ return get(index, JSType.toString(key));
}
@Override
@@ -2625,7 +2638,7 @@
return array.getObject(key);
}
- return get(key, convertKey(key));
+ return get(key, JSType.toString(key));
}
/**
@@ -2640,7 +2653,7 @@
final long longIndex = index & JSType.MAX_UINT;
if (!getArray().has(index)) {
- final String key = convertKey(longIndex);
+ final String key = JSType.toString(longIndex);
final FindProperty find = findProperty(key, true);
if (find != null) {
@@ -2786,7 +2799,7 @@
return;
}
- final String propName = convertKey(key);
+ final String propName = JSType.toString(key);
final FindProperty find = findProperty(propName, true);
setObject(find, strict, propName, value);
@@ -3008,7 +3021,7 @@
}
}
- final FindProperty find = findProperty(convertKey(key), true);
+ final FindProperty find = findProperty(JSType.toString(key), true);
return find != null;
}
@@ -3025,7 +3038,7 @@
}
}
- final FindProperty find = findProperty(convertKey(key), true);
+ final FindProperty find = findProperty(JSType.toString(key), true);
return find != null;
}
@@ -3042,7 +3055,7 @@
}
}
- final FindProperty find = findProperty(convertKey(key), true);
+ final FindProperty find = findProperty(JSType.toString(key), true);
return find != null;
}
@@ -3059,7 +3072,7 @@
}
}
- final FindProperty find = findProperty(convertKey(key), true);
+ final FindProperty find = findProperty(JSType.toString(key), true);
return find != null;
}
@@ -3072,7 +3085,7 @@
return true;
}
- final FindProperty find = findProperty(convertKey(key), false);
+ final FindProperty find = findProperty(JSType.toString(key), false);
return find != null;
}
@@ -3085,7 +3098,7 @@
return true;
}
- final FindProperty find = findProperty(convertKey(key), false);
+ final FindProperty find = findProperty(JSType.toString(key), false);
return find != null;
}
@@ -3098,7 +3111,7 @@
return true;
}
- final FindProperty find = findProperty(convertKey(key), false);
+ final FindProperty find = findProperty(JSType.toString(key), false);
return find != null;
}
@@ -3111,7 +3124,7 @@
return true;
}
- final FindProperty find = findProperty(convertKey(key), false);
+ final FindProperty find = findProperty(JSType.toString(key), false);
return find != null;
}
@@ -3181,7 +3194,7 @@
}
private boolean deleteObject(final Object key, final boolean strict) {
- final String propName = convertKey(key);
+ final String propName = JSType.toString(key);
final FindProperty find = findProperty(propName, false);
if (find == null) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Wed Jul 05 19:10:19 2017 +0200
@@ -37,7 +37,9 @@
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import jdk.internal.dynalink.beans.StaticClass;
@@ -188,6 +190,8 @@
case FUNCTION:
if (self instanceof ScriptObject) {
className = ((ScriptObject)self).getClassName();
+ } else if (self instanceof ScriptObjectMirror) {
+ className = ((ScriptObjectMirror)self).getClassName();
} else {
className = self.getClass().getName();
}
@@ -221,49 +225,71 @@
}
/**
- * Used to determine property iterator used in for in.
- * @param obj Object to iterate on.
- * @return Iterator.
+ * Returns an iterator over property identifiers used in the {@code for...in} statement. Note that the ECMAScript
+ * 5.1 specification, chapter 12.6.4. uses the terminology "property names", which seems to imply that the property
+ * identifiers are expected to be strings, but this is not actually spelled out anywhere, and Nashorn will in some
+ * cases deviate from this. Namely, we guarantee to always return an iterator over {@link String} values for any
+ * built-in JavaScript object. We will however return an iterator over {@link Integer} objects for native Java
+ * arrays and {@link List} objects, as well as arbitrary objects representing keys of a {@link Map}. Therefore, the
+ * expression {@code typeof i} within a {@code for(i in obj)} statement can return something other than
+ * {@code string} when iterating over native Java arrays, {@code List}, and {@code Map} objects.
+ * @param obj object to iterate on.
+ * @return iterator over the object's property names.
*/
- public static Iterator<String> toPropertyIterator(final Object obj) {
+ public static Iterator<?> toPropertyIterator(final Object obj) {
if (obj instanceof ScriptObject) {
return ((ScriptObject)obj).propertyIterator();
}
if (obj != null && obj.getClass().isArray()) {
- final int length = Array.getLength(obj);
-
- return new Iterator<String>() {
- private int index = 0;
-
- @Override
- public boolean hasNext() {
- return index < length;
- }
-
- @Override
- public String next() {
- return "" + index++; //TODO numeric property iterator?
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
+ return new RangeIterator(Array.getLength(obj));
}
if (obj instanceof ScriptObjectMirror) {
return ((ScriptObjectMirror)obj).keySet().iterator();
}
+ if (obj instanceof List) {
+ return new RangeIterator(((List<?>)obj).size());
+ }
+
+ if (obj instanceof Map) {
+ return ((Map<?,?>)obj).keySet().iterator();
+ }
+
return Collections.emptyIterator();
}
+ private static final class RangeIterator implements Iterator<Integer> {
+ private final int length;
+ private int index;
+
+ RangeIterator(int length) {
+ this.length = length;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return index < length;
+ }
+
+ @Override
+ public Integer next() {
+ return index++;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
/**
- * Used to determine property value iterator used in for each in.
- * @param obj Object to iterate on.
- * @return Iterator.
+ * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS
+ * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over
+ * map values.
+ * @param obj object to iterate on.
+ * @return iterator over the object's property values.
*/
public static Iterator<?> toValueIterator(final Object obj) {
if (obj instanceof ScriptObject) {
@@ -301,6 +327,10 @@
return ((ScriptObjectMirror)obj).values().iterator();
}
+ if (obj instanceof Map) {
+ return ((Map<?,?>)obj).values().iterator();
+ }
+
if (obj instanceof Iterable) {
return ((Iterable<?>)obj).iterator();
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java Wed Jul 05 19:10:19 2017 +0200
@@ -73,7 +73,7 @@
public boolean delete(final Object key, final boolean strict) {
if (expression instanceof ScriptObject) {
final ScriptObject self = (ScriptObject)expression;
- final String propName = ScriptObject.convertKey(key);
+ final String propName = JSType.toString(key);
final FindProperty find = self.findProperty(propName, true);
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Jul 05 19:10:19 2017 +0200
@@ -36,6 +36,7 @@
import jdk.internal.dynalink.DynamicLinker;
import jdk.internal.dynalink.DynamicLinkerFactory;
import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkerServices;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
@@ -61,7 +62,7 @@
static {
final DynamicLinkerFactory factory = new DynamicLinkerFactory();
factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
- new BoundDynamicMethodLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
+ new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker());
factory.setSyncOnRelink(true);
final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
@@ -88,7 +89,8 @@
return obj instanceof ScriptFunction ||
((obj instanceof ScriptObjectMirror) && ((ScriptObjectMirror)obj).isFunction()) ||
isDynamicMethod(obj) ||
- isFunctionalInterfaceObject(obj);
+ isFunctionalInterfaceObject(obj) ||
+ obj instanceof StaticClass;
}
/**
@@ -262,6 +264,16 @@
}
/**
+ * Creates a super-adapter for an adapter, that is, an adapter to the adapter that allows invocation of superclass
+ * methods on it.
+ * @param adapter the original adapter
+ * @return a new adapter that can be used to invoke super methods on the original adapter.
+ */
+ public static Object createSuperAdapter(final Object adapter) {
+ return new JavaSuperAdapter(adapter);
+ }
+
+ /**
* If the given class is a reflection-specific class (anything in {@code java.lang.reflect} and
* {@code java.lang.invoke} package, as well a {@link Class} and any subclass of {@link ClassLoader}) and there is
* a security manager in the system, then it checks the {@code nashorn.JavaReflection} {@code RuntimePermission}.
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Wed Jul 05 19:10:19 2017 +0200
@@ -67,11 +67,12 @@
// BeansLinker.
final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
final MethodType type = descriptor.getMethodType();
+ final Class<?> dynamicMethodClass = dynamicMethod.getClass();
final CallSiteDescriptor newDescriptor = descriptor.changeMethodType(
- type.changeParameterType(0, dynamicMethod.getClass()).changeParameterType(1, boundThis.getClass()));
+ type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass()));
// Delegate to BeansLinker
- final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethod.getClass()).getGuardedInvocation(
+ final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethodClass).getGuardedInvocation(
linkRequest.replaceArguments(newDescriptor, args), linkerServices);
if(inv == null) {
return null;
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Wed Jul 05 19:10:19 2017 +0200
@@ -173,6 +173,9 @@
private static final String CLASS_INIT = "<clinit>";
private static final String STATIC_GLOBAL_FIELD_NAME = "staticGlobal";
+ // Method name prefix for invoking super-methods
+ static final String SUPER_PREFIX = "super$";
+
/**
* Collection of methods we never override: Object.clone(), Object.finalize().
*/
@@ -240,6 +243,7 @@
}
generateConstructors();
generateMethods();
+ generateSuperMethods();
// }
cw.visitEnd();
}
@@ -507,6 +511,10 @@
private static void endInitMethod(final InstructionAdapter mv) {
mv.visitInsn(RETURN);
+ endMethod(mv);
+ }
+
+ private static void endMethod(final InstructionAdapter mv) {
mv.visitMaxs(0, 0);
mv.visitEnd();
}
@@ -603,13 +611,8 @@
*/
private void generateMethod(final MethodInfo mi) {
final Method method = mi.method;
- final int mod = method.getModifiers();
- final int access = ACC_PUBLIC | (method.isVarArgs() ? ACC_VARARGS : 0);
final Class<?>[] exceptions = method.getExceptionTypes();
- final String[] exceptionNames = new String[exceptions.length];
- for (int i = 0; i < exceptions.length; ++i) {
- exceptionNames[i] = Type.getInternalName(exceptions[i]);
- }
+ final String[] exceptionNames = getExceptionNames(exceptions);
final MethodType type = mi.type;
final String methodDesc = type.toMethodDescriptorString();
final String name = mi.getName();
@@ -617,14 +620,8 @@
final Type asmType = Type.getMethodType(methodDesc);
final Type[] asmArgTypes = asmType.getArgumentTypes();
- // Determine the first index for a local variable
- int nextLocalVar = 1; // this
- for(final Type t: asmArgTypes) {
- nextLocalVar += t.getSize();
- }
-
- final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(access, name, methodDesc, null,
- exceptionNames));
+ final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(getAccessModifiers(method), name,
+ methodDesc, null, exceptionNames));
mv.visitCode();
final Label instanceHandleDefined = new Label();
@@ -646,7 +643,7 @@
}
// No handle is available, fall back to default behavior
- if(Modifier.isAbstract(mod)) {
+ if(Modifier.isAbstract(method.getModifiers())) {
// If the super method is abstract, throw an exception
mv.anew(UNSUPPORTED_OPERATION_TYPE);
mv.dup();
@@ -654,14 +651,7 @@
mv.athrow();
} else {
// If the super method is not abstract, delegate to it.
- mv.visitVarInsn(ALOAD, 0);
- int nextParam = 1;
- for(final Type t: asmArgTypes) {
- mv.load(nextParam, t);
- nextParam += t.getSize();
- }
- mv.invokespecial(superClassName, name, methodDesc);
- mv.areturn(asmReturnType);
+ emitSuperCall(mv, name, methodDesc);
}
final Label setupGlobal = new Label();
@@ -685,6 +675,12 @@
// stack: [creatingGlobal, someHandle]
mv.visitLabel(setupGlobal);
+ // Determine the first index for a local variable
+ int nextLocalVar = 1; // "this" is at 0
+ for(final Type t: asmArgTypes) {
+ nextLocalVar += t.getSize();
+ }
+ // Set our local variable indices
final int currentGlobalVar = nextLocalVar++;
final int globalsDifferVar = nextLocalVar++;
@@ -775,8 +771,7 @@
}
mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, throwableHandler, THROWABLE_TYPE_NAME);
}
- mv.visitMaxs(0, 0);
- mv.visitEnd();
+ endMethod(mv);
}
/**
@@ -817,6 +812,53 @@
return false;
}
+ private void generateSuperMethods() {
+ for(final MethodInfo mi: methodInfos) {
+ if(!Modifier.isAbstract(mi.method.getModifiers())) {
+ generateSuperMethod(mi);
+ }
+ }
+ }
+
+ private void generateSuperMethod(MethodInfo mi) {
+ final Method method = mi.method;
+
+ final String methodDesc = mi.type.toMethodDescriptorString();
+ final String name = mi.getName();
+
+ final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(getAccessModifiers(method),
+ SUPER_PREFIX + name, methodDesc, null, getExceptionNames(method.getExceptionTypes())));
+ mv.visitCode();
+
+ emitSuperCall(mv, name, methodDesc);
+
+ endMethod(mv);
+ }
+
+ private void emitSuperCall(final InstructionAdapter mv, final String name, final String methodDesc) {
+ mv.visitVarInsn(ALOAD, 0);
+ int nextParam = 1;
+ final Type methodType = Type.getMethodType(methodDesc);
+ for(final Type t: methodType.getArgumentTypes()) {
+ mv.load(nextParam, t);
+ nextParam += t.getSize();
+ }
+ mv.invokespecial(superClassName, name, methodDesc);
+ mv.areturn(methodType.getReturnType());
+ }
+
+ private static String[] getExceptionNames(final Class<?>[] exceptions) {
+ final String[] exceptionNames = new String[exceptions.length];
+ for (int i = 0; i < exceptions.length; ++i) {
+ exceptionNames[i] = Type.getInternalName(exceptions[i]);
+ }
+ return exceptionNames;
+ }
+
+ private static int getAccessModifiers(final Method method) {
+ return ACC_PUBLIC | (method.isVarArgs() ? ACC_VARARGS : 0);
+ }
+
/**
* Gathers methods that can be implemented or overridden from the specified type into this factory's
* {@link #methodInfos} set. It will add all non-final, non-static methods that are either public or protected from
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Wed Jul 05 19:10:19 2017 +0200
@@ -34,7 +34,6 @@
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.SecureClassLoader;
-
import jdk.internal.dynalink.beans.StaticClass;
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapter.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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
+ * 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.
+ */
+
+package jdk.nashorn.internal.runtime.linker;
+
+/**
+ * Represents a an adapter for invoking superclass methods on an adapter instance generated by
+ * {@link JavaAdapterBytecodeGenerator}. Note that objects of this class are just wrappers around the adapter instances,
+ * without any behavior. All the behavior is defined in the {@code JavaSuperAdapterLinker}.
+ */
+class JavaSuperAdapter {
+ private final Object adapter;
+
+ JavaSuperAdapter(final Object adapter) {
+ adapter.getClass(); // NPE check
+ this.adapter = adapter;
+ }
+
+ public Object getAdapter() {
+ return adapter;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,180 @@
+/*
+ * 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
+ * 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.
+ */
+
+package jdk.nashorn.internal.runtime.linker;
+
+import static jdk.nashorn.internal.lookup.Lookup.EMPTY_GETTER;
+import static jdk.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.SUPER_PREFIX;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.internal.dynalink.support.Lookup;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * A linker for instances of {@link JavaSuperAdapter}. Only links {@code getMethod} calls, by forwarding them to the
+ * bean linker for the adapter class and prepending {@code super$} to method names.
+ *
+ */
+final class JavaSuperAdapterLinker implements TypeBasedGuardingDynamicLinker {
+ private static final String GET_METHOD = "getMethod";
+ private static final String DYN_GET_METHOD = "dyn:" + GET_METHOD;
+ private static final String DYN_GET_METHOD_FIXED = DYN_GET_METHOD + ":" + SUPER_PREFIX;
+
+ private static final MethodHandle ADD_PREFIX_TO_METHOD_NAME;
+ private static final MethodHandle BIND_DYNAMIC_METHOD;
+ private static final MethodHandle GET_ADAPTER;
+ private static final MethodHandle IS_ADAPTER_OF_CLASS;
+
+ static {
+ final Lookup lookup = new Lookup(MethodHandles.lookup());
+ ADD_PREFIX_TO_METHOD_NAME = lookup.findOwnStatic("addPrefixToMethodName", Object.class, Object.class);
+ BIND_DYNAMIC_METHOD = lookup.findOwnStatic("bindDynamicMethod", Object.class, Object.class, Object.class);
+ GET_ADAPTER = lookup.findVirtual(JavaSuperAdapter.class, "getAdapter", MethodType.methodType(Object.class));
+ IS_ADAPTER_OF_CLASS = lookup.findOwnStatic("isAdapterOfClass", boolean.class, Class.class, Object.class);
+ }
+
+ @Override
+ public boolean canLinkType(final Class<?> type) {
+ return type == JavaSuperAdapter.class;
+ }
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
+ throws Exception {
+ final Object objSuperAdapter = linkRequest.getReceiver();
+ if(!(objSuperAdapter instanceof JavaSuperAdapter)) {
+ return null;
+ }
+
+ final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
+ if(!CallSiteDescriptorFactory.tokenizeOperators(descriptor).contains(GET_METHOD)) {
+ // We only handle getMethod
+ return null;
+ }
+
+ final Object adapter = ((JavaSuperAdapter)objSuperAdapter).getAdapter();
+
+ // Replace argument (javaSuperAdapter, ...) => (adapter, ...) when delegating to BeansLinker
+ final Object[] args = linkRequest.getArguments();
+ args[0] = adapter;
+
+ // Use R(T0, ...) => R(adapter.class, ...) call site type when delegating to BeansLinker.
+ final MethodType type = descriptor.getMethodType();
+ final Class<?> adapterClass = adapter.getClass();
+ final boolean hasFixedName = descriptor.getNameTokenCount() > 2;
+ final String opName = hasFixedName ? (DYN_GET_METHOD_FIXED + descriptor.getNameToken(
+ CallSiteDescriptor.NAME_OPERAND)) : DYN_GET_METHOD;
+
+ final CallSiteDescriptor newDescriptor = NashornCallSiteDescriptor.get(descriptor.getLookup(), opName,
+ type.changeParameterType(0, adapterClass), 0);
+
+ // Delegate to BeansLinker
+ final GuardedInvocation guardedInv = BeansLinker.getLinkerForClass(adapterClass).getGuardedInvocation(
+ linkRequest.replaceArguments(newDescriptor, args), linkerServices);
+
+ final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
+ if(guardedInv == null) {
+ // Short circuit the lookup here for non-existent methods by linking an empty getter. If we just returned
+ // null instead, BeansLinker would find final methods on the JavaSuperAdapter instead: getClass() and
+ // wait().
+ return new GuardedInvocation(MethodHandles.dropArguments(EMPTY_GETTER, 1,type.parameterList().subList(1,
+ type.parameterCount())), guard).asType(descriptor);
+ }
+
+ final MethodHandle invocation = guardedInv.getInvocation();
+ final MethodType invType = invocation.type();
+ // For invocation typed R(T0, ...) create a dynamic method binder of type R(R, T0)
+ final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(invType.returnType(),
+ invType.returnType(), invType.parameterType(0)));
+ // For invocation typed R(T0, T1, ...) create a dynamic method binder of type R(R, T0, T1, ...)
+ final MethodHandle droppingBinder = MethodHandles.dropArguments(typedBinder, 2,
+ invType.parameterList().subList(1, invType.parameterCount()));
+ // Finally, fold the invocation into the binder to produce a method handle that will bind every returned
+ // DynamicMethod object from dyn:getMethod calls to the actual receiver
+ // R(R(T0, T1, ...), T0, T1, ...)
+ final MethodHandle bindingInvocation = MethodHandles.foldArguments(droppingBinder, invocation);
+
+ final MethodHandle typedGetAdapter = asFilterType(GET_ADAPTER, 0, invType, type);
+ final MethodHandle adaptedInvocation;
+ if(hasFixedName) {
+ adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter);
+ } else {
+ // Add a filter that'll prepend "super$" to each name passed to the variable-name "dyn:getMethod".
+ final MethodHandle typedAddPrefix = asFilterType(ADD_PREFIX_TO_METHOD_NAME, 1, invType, type);
+ adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter, typedAddPrefix);
+ }
+
+ return guardedInv.replaceMethods(adaptedInvocation, guard).asType(descriptor);
+ }
+
+ /**
+ * Adapts the type of a method handle used as a filter in a position from a source method type to a target method type.
+ * @param filter the filter method handle
+ * @param pos the position in the argument list that it's filtering
+ * @param targetType the target method type for filtering
+ * @param sourceType the source method type for filtering
+ * @return a type adapted filter
+ */
+ private static MethodHandle asFilterType(final MethodHandle filter, int pos, MethodType targetType, MethodType sourceType) {
+ return filter.asType(MethodType.methodType(targetType.parameterType(pos), sourceType.parameterType(pos)));
+ }
+
+ @SuppressWarnings("unused")
+ private static Object addPrefixToMethodName(final Object name) {
+ return SUPER_PREFIX.concat(String.valueOf(name));
+ }
+
+ /**
+ * Used to transform the return value of getMethod; transform a {@code DynamicMethod} into a
+ * {@code BoundDynamicMethod} while also accounting for the possibility of a non-existent method.
+ * @param dynamicMethod the dynamic method to bind
+ * @param boundThis the adapter underlying a super adapter, to which the dynamic method is bound.
+ * @return a dynamic method bound to the adapter instance.
+ */
+ @SuppressWarnings("unused")
+ private static Object bindDynamicMethod(final Object dynamicMethod, final Object boundThis) {
+ return dynamicMethod == null ? ScriptRuntime.UNDEFINED : Bootstrap.bindDynamicMethod(dynamicMethod, boundThis);
+ }
+
+ /**
+ * Used as the guard of linkages, as the receiver is not guaranteed to be a JavaSuperAdapter.
+ * @param clazz the class the receiver's adapter is tested against.
+ * @param obj receiver
+ * @return true if the receiver is a super adapter, and its underlying adapter is of the specified class
+ */
+ @SuppressWarnings("unused")
+ private static boolean isAdapterOfClass(Class<?> clazz, Object obj) {
+ return obj instanceof JavaSuperAdapter && clazz == (((JavaSuperAdapter)obj).getAdapter()).getClass();
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExp.java Wed Jul 05 19:10:19 2017 +0200
@@ -60,7 +60,7 @@
* @param flags the flags string
*/
protected RegExp(final String source, final String flags) {
- this.source = source;
+ this.source = source.length() == 0 ? "(?:)" : source;
for (int i = 0; i < flags.length(); i++) {
final char ch = flags.charAt(i);
switch (ch) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java Wed Jul 05 19:10:19 2017 +0200
@@ -39,7 +39,6 @@
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
final class ArrayCompiler extends Compiler {
private int[] code;
@@ -345,6 +344,7 @@
private static final int QUANTIFIER_EXPAND_LIMIT_SIZE = 50; // was 50
+ @SuppressWarnings("unused")
private static boolean cknOn(int ckn) {
return ckn > 0;
}
@@ -879,6 +879,7 @@
}
}
+ @SuppressWarnings("unused")
private void addStateCheckNum(int num) {
addInt(num);
}
@@ -887,6 +888,7 @@
addInt(addr);
}
+ @SuppressWarnings("unused")
private void addAbsAddr(int addr) {
addInt(addr);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java Wed Jul 05 19:10:19 2017 +0200
@@ -29,6 +29,7 @@
final int[] bits = new int[BITSET_SIZE];
private static final int BITS_TO_STRING_WRAP = 4;
+ @Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("BitSet");
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java Wed Jul 05 19:10:19 2017 +0200
@@ -26,7 +26,6 @@
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotBol;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotEol;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isPosixRegion;
-import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isCrnl;
import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isNewLine;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
@@ -96,6 +95,7 @@
}
}
+ @Override
protected final int matchAt(int range, int sstart, int sprev) {
this.range = range;
this.sstart = sstart;
@@ -499,7 +499,7 @@
private void opAnyChar() {
if (s >= range) {opFail(); return;}
- if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
+ if (isNewLine(chars[s])) {opFail(); return;}
s++;
sprev = sbegin; // break;
}
@@ -537,7 +537,7 @@
while (s < range) {
char b = chars[s];
if (c == b) pushAlt(ip + 1, s, sprev);
- if (b == EncodingHelper.NEW_LINE) {opFail(); return;}
+ if (isNewLine(b)) {opFail(); return;}
sprev = s;
s++;
}
@@ -616,7 +616,7 @@
if (s == str) {
if (isNotBol(msaOptions)) opFail();
return;
- } else if (EncodingHelper.isNewLine(chars, sprev, end) && s != end) {
+ } else if (isNewLine(chars, sprev, end) && s != end) {
return;
}
opFail();
@@ -625,7 +625,7 @@
private void opEndLine() {
if (s == end) {
if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
- if (str == end || !EncodingHelper.isNewLine(chars, sprev, end)) {
+ if (str == end || !isNewLine(chars, sprev, end)) {
if (isNotEol(msaOptions)) opFail();
}
return;
@@ -633,7 +633,7 @@
if (isNotEol(msaOptions)) opFail();
return;
}
- } else if (isNewLine(chars, s, end) || (Config.USE_CRNL_AS_LINE_TERMINATOR && isCrnl(chars, s, end))) {
+ } else if (isNewLine(chars, s, end)) {
return;
}
opFail();
@@ -652,9 +652,6 @@
}
} else if (isNewLine(chars, s, end) && s + 1 == end) {
return;
- } else if (Config.USE_CRNL_AS_LINE_TERMINATOR && isCrnl(chars, s, end)) {
- int ss = s + 2;
- if (ss == end) return;
}
opFail();
}
@@ -731,8 +728,6 @@
// STRING_CMP
while(n-- > 0) if (chars[pstart++] != chars[s++]) {opFail(); return;}
- int len;
-
// beyond string check
if (sprev < range) {
while (sprev + 1 < s) sprev++;
@@ -768,7 +763,6 @@
if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) {opFail(); return;}
s = value;
- int len;
// if (sprev < chars.length)
while (sprev + 1 < s) sprev++;
}
@@ -796,8 +790,6 @@
s = swork;
- int len;
-
// beyond string check
if (sprev < range) {
while (sprev + 1 < s) sprev++;
@@ -829,7 +821,6 @@
if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) continue loop; // STRING_CMP_VALUE_IC
s = value;
- int len;
// if (sprev < chars.length)
while (sprev + 1 < s) sprev++;
@@ -902,7 +893,6 @@
sprev = s;
if (backrefMatchAtNestedLevel(ic != 0, regex.caseFoldFlag, level, tlen, ip)) { // (s) and (end) implicit
- int len;
while (sprev + 1 < s) sprev++;
ip += tlen; // * SIZE_MEMNUM
} else {
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java Wed Jul 05 19:10:19 2017 +0200
@@ -58,6 +58,7 @@
used = orig.used;
}
+ @Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("CodeRange");
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Config.java Wed Jul 05 19:10:19 2017 +0200
@@ -29,7 +29,6 @@
final int INTERNAL_ENC_CASE_FOLD_MULTI_CHAR = (1<<30);
final int ENC_CASE_FOLD_MIN = INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
final int ENC_CASE_FOLD_DEFAULT = ENC_CASE_FOLD_MIN;
- final boolean USE_CRNL_AS_LINE_TERMINATOR = false;
final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true; /* /\n$/ =~ "\n" */
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java Wed Jul 05 19:10:19 2017 +0200
@@ -24,10 +24,12 @@
import java.util.Arrays;
-public class EncodingHelper {
+public final class EncodingHelper {
- public final static char NEW_LINE = 0xa;
- public final static char RETURN = 0xd;
+ final static int NEW_LINE = 0x000a;
+ final static int RETURN = 0x000d;
+ final static int LINE_SEPARATOR = 0x2028;
+ final static int PARAGRAPH_SEPARATOR = 0x2029;
final static char[] EMPTYCHARS = new char[0];
final static int[][] codeRanges = new int[15][];
@@ -64,15 +66,11 @@
}
public static boolean isNewLine(int code) {
- return code == NEW_LINE;
+ return code == NEW_LINE || code == RETURN || code == LINE_SEPARATOR || code == PARAGRAPH_SEPARATOR;
}
public static boolean isNewLine(char[] chars, int p, int end) {
- return p < end && chars[p] == NEW_LINE;
- }
-
- public static boolean isCrnl(char[] chars, int p, int end) {
- return p + 1 < end && chars[p] == RETURN && chars[p + 1] == NEW_LINE;
+ return p < end && isNewLine(chars[p]);
}
// Encoding.prevCharHead
@@ -194,7 +192,7 @@
int type;
switch (ctype) {
case CharacterType.NEWLINE:
- return code == EncodingHelper.NEW_LINE;
+ return isNewLine(code);
case CharacterType.ALPHA:
return (1 << Character.getType(code) & CharacterType.ALPHA_MASK) != 0;
case CharacterType.BLANK:
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java Wed Jul 05 19:10:19 2017 +0200
@@ -139,6 +139,7 @@
}
}
+ @SuppressWarnings("fallthrough")
/* \M-, \C-, \c, or \... */
private int fetchEscapedValue() {
if (!left()) {
@@ -731,7 +732,7 @@
if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
break;
case '$':
- if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.SEMI_END_BUF : AnchorType.END_LINE);
+ if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.END_BUF : AnchorType.END_LINE);
break;
case '[':
if (syntax.opBracketCC()) token.type = TokenType.CC_CC_OPEN;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java Wed Jul 05 19:10:19 2017 +0200
@@ -141,7 +141,7 @@
continue retry;
}
}
- } else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
+ } else if (!EncodingHelper.isNewLine(chars, p, end)) {
//if () break;
// goto retry_gate;
pprev = p;
@@ -226,7 +226,7 @@
continue retry;
}
}
- } else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
+ } else if (!EncodingHelper.isNewLine(chars, p, end)) {
p = EncodingHelper.prevCharHead(adjrange, p);
if (p == -1) return false;
continue retry;
@@ -330,12 +330,6 @@
maxSemiEnd = end;
if (EncodingHelper.isNewLine(chars, preEnd, end)) {
minSemiEnd = preEnd;
- if (Config.USE_CRNL_AS_LINE_TERMINATOR) {
- preEnd = EncodingHelper.stepBack(str, preEnd, 1);
- if (preEnd != -1 && EncodingHelper.isCrnl(chars, preEnd, end)) {
- minSemiEnd = preEnd;
- }
- }
if (minSemiEnd > str && start <= minSemiEnd) {
// !goto end_buf;!
if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java Wed Jul 05 19:10:19 2017 +0200
@@ -297,8 +297,6 @@
throw new SyntaxException(ERR_END_PATTERN_IN_GROUP);
}
- boolean listCapture = false;
-
fetch();
switch(c) {
case ':': /* (?:...) grouping only */
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java Wed Jul 05 19:10:19 2017 +0200
@@ -32,6 +32,7 @@
this.end = new int[num];
}
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Region: \n");
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ScannerSupport.java Wed Jul 05 19:10:19 2017 +0200
@@ -21,9 +21,6 @@
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
abstract class ScannerSupport extends IntHolder implements ErrorMessages {
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java Wed Jul 05 19:10:19 2017 +0200
@@ -28,14 +28,17 @@
public static final SearchAlgorithm NONE = new SearchAlgorithm() {
+ @Override
public final String getName() {
return "NONE";
}
+ @Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
return textP;
}
+ @Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
return textP;
}
@@ -44,10 +47,12 @@
public static final SearchAlgorithm SLOW = new SearchAlgorithm() {
+ @Override
public final String getName() {
return "EXACT";
}
+ @Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
@@ -78,6 +83,7 @@
return -1;
}
+ @Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
@@ -114,10 +120,12 @@
this.caseFoldFlag = regex.caseFoldFlag;
}
+ @Override
public final String getName() {
return "EXACT_IC";
}
+ @Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
@@ -136,6 +144,7 @@
return -1;
}
+ @Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
@@ -163,14 +172,16 @@
}
return true;
}
- };
+ }
public static final SearchAlgorithm BM = new SearchAlgorithm() {
+ @Override
public final String getName() {
return "EXACT_BM";
}
+ @Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
@@ -212,6 +223,7 @@
private static final int BM_BACKWARD_SEARCH_LENGTH_THRESHOLD = 100;
+ @Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
@@ -263,10 +275,12 @@
public static final SearchAlgorithm MAP = new SearchAlgorithm() {
+ @Override
public final String getName() {
return "MAP";
}
+ @Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
byte[] map = regex.map;
int s = textP;
@@ -278,6 +292,7 @@
return -1;
}
+ @Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
byte[] map = regex.map;
int s = textStart;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/StackMachine.java Wed Jul 05 19:10:19 2017 +0200
@@ -458,7 +458,7 @@
isNull = 0;
break;
} else if (endp != s) {
- isNull = -1;; /* empty, but position changed */
+ isNull = -1; /* empty, but position changed */
}
}
k++;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/WarnCallback.java Wed Jul 05 19:10:19 2017 +0200
@@ -24,6 +24,7 @@
*/
public interface WarnCallback {
WarnCallback DEFAULT = new WarnCallback() {
+ @Override
public void warn(String message) {
System.err.println(message);
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java Wed Jul 05 19:10:19 2017 +0200
@@ -19,7 +19,6 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
-import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.Option;
import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/Node.java Wed Jul 05 19:10:19 2017 +0200
@@ -35,7 +35,7 @@
}
protected void setChild(Node tgt){} // default definition
- protected Node getChild(){return null;}; // default definition
+ protected Node getChild(){return null;} // default definition
public void swap(Node with) {
Node tmp;
@@ -74,6 +74,7 @@
return getName() + ":0x" + Integer.toHexString(System.identityHashCode(this));
}
+ @Override
public final String toString() {
StringBuilder s = new StringBuilder();
s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName()) + ")>");
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java Wed Jul 05 19:10:19 2017 +0200
@@ -223,6 +223,7 @@
other.target = null; // remove target from reduced quantifier
}
+ @SuppressWarnings("fallthrough")
public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, char[] chars, int p, int end) {
if (lower == 1 && upper == 1) return 1;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ErrorMessages.java Wed Jul 05 19:10:19 2017 +0200
@@ -19,8 +19,6 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
-import jdk.nashorn.internal.runtime.regexp.joni.Config;
-
public interface ErrorMessages {
/* from jcodings */
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Jul 05 19:10:19 2017 +0200
@@ -94,6 +94,8 @@
type.error.cant.redefine.property=Cannot redefine property "{0}" of {1}
type.error.property.not.writable="{0}" is not a writable property of {1}
type.error.object.non.extensible=Cannot add new property "{0}" to non-extensible {1}
+type.error.__proto__.set.non.extensible=Cannot set __proto__ of non-extensible {0}
+type.error.circular.__proto__.set=Cannot create__proto__ cycle for {0}
# miscellaneous
type.error.regex.cant.supply.flags=Cannot supply flags when constructing one RegExp from another
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties Wed Jul 05 19:10:19 2017 +0200
@@ -157,6 +157,14 @@
default=false \
}
+nashorn.option.global.per.engine = { \
+ name="--global-per-engine", \
+ desc="Use single Global instance per script engine instance.", \
+ is_undocumented=true, \
+ type=Boolean, \
+ default=false \
+}
+
nashorn.option.log = { \
name="--log", \
is_undocumented=true, \
@@ -216,15 +224,6 @@
default=false \
}
-nashorn.option.package = { \
- name="--package", \
- is_undocumented=true, \
- desc="Package to which generated .class files are added.", \
- params="<package>", \
- type=String, \
- default="" \
-}
-
nashorn.option.parse.only = { \
name="--parse-only", \
is_undocumented=true, \
@@ -289,7 +288,7 @@
nashorn.option.range.analysis = { \
name="--range-analysis", \
is_undocumented=true, \
- desc="Do range analysis using known compile time types, and try to narrow number types" \
+ desc="EXPERIMENTAL: Do range analysis using known compile time types, and try to narrow number types" \
}
nashorn.option.D = { \
@@ -308,12 +307,12 @@
desc="Enable scripting features." \
}
-nashorn.option.specialize.calls = { \
- name="--specialize-calls", \
- is_undocumented=true, \
- type=String, \
- params="[=function_1,...,function_n]", \
- desc="Specialize all or a set of method according to callsite parameter types" \
+nashorn.option.specialize.calls = { \
+ name="--specialize-calls", \
+ is_undocumented=true, \
+ type=String, \
+ params="[=function_1,...,function_n]", \
+ desc="EXPERIMENTAL: Specialize all or a set of method according to callsite parameter types" \
}
nashorn.option.stdout = { \
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js Wed Jul 05 19:10:19 2017 +0200
@@ -144,7 +144,7 @@
return Object.getPrototypeOf(this);
},
set: function(x) {
- throw new TypeError("__proto__ set not supported");
+ Object.setPrototypeOf(this, x);
}
});
--- a/nashorn/src/jdk/nashorn/tools/Shell.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java Wed Jul 05 19:10:19 2017 +0200
@@ -445,7 +445,7 @@
continue;
}
- if (res != null && res != ScriptRuntime.UNDEFINED) {
+ if (res != ScriptRuntime.UNDEFINED) {
err.println(JSType.toString(res));
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8019987.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,171 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8019987: String trimRight and trimLeft could be defined.
+ *
+ * @test
+ * @run
+ */
+
+var TESTSTRING = "abcde";
+
+var SPACES = " ";
+var TESTSTRING_LEFT_SPACES = SPACES + TESTSTRING;
+var TESTSTRING_RIGHT_SPACES = TESTSTRING + SPACES;
+var TESTSTRING_BOTH_SPACES = SPACES + TESTSTRING + SPACES;
+var TESTSTRING_MIDDLE_SPACES = TESTSTRING + SPACES + TESTSTRING;
+
+var WHITESPACE =
+ " \t" + // space and tab
+ "\n\r" + // newline and return
+ "\u2028" + // line separator
+ "\u2029" + // paragraph separator
+ "\u000b" + // tabulation line
+ "\u000c" + // ff (ctrl-l)
+ "\u00a0" + // Latin-1 space
+ "\u1680" + // Ogham space mark
+ "\u180e" + // separator, Mongolian vowel
+ "\u2000" + // en quad
+ "\u2001" + // em quad
+ "\u2002" + // en space
+ "\u2003" + // em space
+ "\u2004" + // three-per-em space
+ "\u2005" + // four-per-em space
+ "\u2006" + // six-per-em space
+ "\u2007" + // figure space
+ "\u2008" + // punctuation space
+ "\u2009" + // thin space
+ "\u200a" + // hair space
+ "\u202f" + // narrow no-break space
+ "\u205f" + // medium mathematical space
+ "\u3000" + // ideographic space
+ "\ufeff"; // byte order mark
+var TESTSTRING_LEFT_WHITESPACE = WHITESPACE + TESTSTRING;
+var TESTSTRING_RIGHT_WHITESPACE = TESTSTRING + WHITESPACE;
+var TESTSTRING_BOTH_WHITESPACE = WHITESPACE + TESTSTRING + WHITESPACE;
+var TESTSTRING_MIDDLE_WHITESPACE = TESTSTRING + WHITESPACE + TESTSTRING;
+
+function escape(string) {
+ var sb = new java.lang.StringBuilder();
+ sb.append("\"");
+
+ for (var i = 0; i < string.length; i++) {
+ var ch = string.charAt(i);
+
+ switch (ch) {
+ case '\\':
+ sb.append("\\\\");
+ break;
+ case '"':
+ sb.append("\\\"");
+ break;
+ case '\'':
+ sb.append("\\\'");
+ break;
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ default:
+ var code = string.charCodeAt(i);
+
+ if (code < 0x20 || code >= 0xFF) {
+ sb.append("\\u");
+
+ var hex = java.lang.Integer.toHexString(code);
+ for (var i = hex.length; i < 4; i++) {
+ sb.append('0');
+ }
+ sb.append(hex);
+ } else {
+ sb.append(ch);
+ }
+
+ break;
+ }
+ }
+
+ sb.append("\"");
+
+ return sb.toString();
+}
+
+var count = 0;
+function test(expected, trimmed) {
+ count++;
+ if (trimmed != expected) {
+ print(count + ": Expected: " + escape(expected) + ", found: " + escape(trimmed));
+ }
+}
+
+test("", SPACES.trim());
+test("", SPACES.trimLeft());
+test("", SPACES.trimRight());
+
+test(TESTSTRING, TESTSTRING_LEFT_SPACES.trim());
+test(TESTSTRING, TESTSTRING_LEFT_SPACES.trimLeft());
+test(TESTSTRING_LEFT_SPACES, TESTSTRING_LEFT_SPACES.trimRight());
+
+test(TESTSTRING, TESTSTRING_RIGHT_SPACES.trim());
+test(TESTSTRING_RIGHT_SPACES, TESTSTRING_RIGHT_SPACES.trimLeft());
+test(TESTSTRING, TESTSTRING_RIGHT_SPACES.trimRight());
+
+test(TESTSTRING, TESTSTRING_BOTH_SPACES.trim());
+test(TESTSTRING_RIGHT_SPACES, TESTSTRING_BOTH_SPACES.trimLeft());
+test(TESTSTRING_LEFT_SPACES, TESTSTRING_BOTH_SPACES.trimRight());
+
+test(TESTSTRING_MIDDLE_SPACES, TESTSTRING_MIDDLE_SPACES.trim());
+test(TESTSTRING_MIDDLE_SPACES, TESTSTRING_MIDDLE_SPACES.trimLeft());
+test(TESTSTRING_MIDDLE_SPACES, TESTSTRING_MIDDLE_SPACES.trimRight());
+
+test("", WHITESPACE.trim());
+test("", WHITESPACE.trimLeft());
+test("", WHITESPACE.trimRight());
+
+test(TESTSTRING, TESTSTRING_LEFT_WHITESPACE.trim());
+test(TESTSTRING, TESTSTRING_LEFT_WHITESPACE.trimLeft());
+test(TESTSTRING_LEFT_WHITESPACE, TESTSTRING_LEFT_WHITESPACE.trimRight());
+
+test(TESTSTRING, TESTSTRING_RIGHT_WHITESPACE.trim());
+test(TESTSTRING_RIGHT_WHITESPACE, TESTSTRING_RIGHT_WHITESPACE.trimLeft());
+test(TESTSTRING, TESTSTRING_RIGHT_WHITESPACE.trimRight());
+
+test(TESTSTRING, TESTSTRING_BOTH_WHITESPACE.trim());
+test(TESTSTRING_RIGHT_WHITESPACE, TESTSTRING_BOTH_WHITESPACE.trimLeft());
+test(TESTSTRING_LEFT_WHITESPACE, TESTSTRING_BOTH_WHITESPACE.trimRight());
+
+test(TESTSTRING_MIDDLE_WHITESPACE, TESTSTRING_MIDDLE_WHITESPACE.trim());
+test(TESTSTRING_MIDDLE_WHITESPACE, TESTSTRING_MIDDLE_WHITESPACE.trimLeft());
+test(TESTSTRING_MIDDLE_WHITESPACE, TESTSTRING_MIDDLE_WHITESPACE.trimRight());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022903.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8022903: Enhance for-in and for-each for Lists and Maps
+ *
+ * @test
+ * @run
+ */
+
+var colors = new java.util.ArrayList()
+colors.add("red")
+colors.add("purple")
+colors.add("pink")
+
+for(var index in colors) {
+ print("colors[" + index + "]=" + colors[index])
+}
+
+for each(var color in colors) {
+ print(color)
+}
+
+var capitals = new java.util.LinkedHashMap()
+capitals.Sweden = "Stockholm"
+capitals.Hungary = "Budapet"
+capitals.Croatia = "Zagreb"
+
+for(var key in capitals) {
+ print("capital of " + key + " is " + capitals[key])
+}
+
+for each(var capital in capitals) {
+ print(capital)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022903.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,12 @@
+colors[0]=red
+colors[1]=purple
+colors[2]=pink
+red
+purple
+pink
+capital of Sweden is Stockholm
+capital of Hungary is Budapet
+capital of Croatia is Zagreb
+Stockholm
+Budapet
+Zagreb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023368.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023368: Instance __proto__ property should exist and be writable.
+ *
+ * @test
+ * @run
+ */
+
+load("nashorn:mozilla_compat.js");
+
+// function to force same callsites
+function check(obj) {
+ print(obj.func());
+ print(obj.x);
+ print(obj.toString());
+}
+
+function Func() {
+}
+
+Func.prototype.func = function() {
+ return "Func.prototype.func";
+}
+
+Func.prototype.x = "hello";
+
+var obj = new Func();
+var obj2 = Object.create(obj);
+
+// check direct and indirect __proto__ change
+check(obj);
+check(obj2);
+obj.__proto__ = {
+ func: function() {
+ return "obj.__proto__.func @ " + __LINE__;
+ },
+ x: 344
+};
+
+check(obj);
+check(obj2);
+
+// check indirect (1 and 2 levels) __proto__ function change
+obj.__proto__.__proto__ = {
+ toString: function() {
+ return "new object.toString";
+ }
+};
+
+check(obj);
+check(obj2);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023368.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,18 @@
+Func.prototype.func
+hello
+[object Object]
+Func.prototype.func
+hello
+[object Object]
+obj.__proto__.func @ 57
+344
+[object Object]
+obj.__proto__.func @ 57
+344
+[object Object]
+obj.__proto__.func @ 57
+344
+new object.toString
+obj.__proto__.func @ 57
+344
+new object.toString
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023368_2.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023368: Instance __proto__ property should exist and be writable.
+ *
+ * @test
+ * @run
+ */
+
+// check Object.setPrototypeOf extension rather than using __proto__
+
+// function to force same callsites
+function check(obj) {
+ print(obj.func());
+ print(obj.x);
+ print(obj.toString());
+}
+
+function Func() {
+}
+
+Func.prototype.func = function() {
+ return "Func.prototype.func";
+}
+
+Func.prototype.x = "hello";
+
+var obj = new Func();
+var obj2 = Object.create(obj);
+
+// check direct and indirect __proto__ change
+check(obj);
+check(obj2);
+Object.setPrototypeOf(obj, {
+ func: function() {
+ return "obj.__proto__.func @ " + __LINE__;
+ },
+ x: 344
+});
+
+check(obj);
+check(obj2);
+
+// check indirect (1 and 2 levels) __proto__ function change
+Object.setPrototypeOf(Object.getPrototypeOf(obj), {
+ toString: function() {
+ return "new object.toString";
+ }
+});
+
+check(obj);
+check(obj2);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023368_2.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,18 @@
+Func.prototype.func
+hello
+[object Object]
+Func.prototype.func
+hello
+[object Object]
+obj.__proto__.func @ 57
+344
+[object Object]
+obj.__proto__.func @ 57
+344
+[object Object]
+obj.__proto__.func @ 57
+344
+new object.toString
+obj.__proto__.func @ 57
+344
+new object.toString
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023373.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023373: allow super invocation for adapters
+ *
+ * @test
+ * @run
+ */
+
+var CharArray = Java.type("char[]")
+var jString = Java.type("java.lang.String")
+var Character = Java.type("java.lang.Character")
+
+function capitalize(s) {
+ if(s instanceof CharArray) {
+ return new jString(s).toUpperCase()
+ }
+ if(s instanceof jString) {
+ return s.toUpperCase()
+ }
+ return Character.toUpperCase(s) // must be int
+}
+
+var sw = new (Java.type("java.io.StringWriter"))
+
+var FilterWriterAdapter = Java.extend(Java.type("java.io.FilterWriter"))
+
+var cw = new FilterWriterAdapter(sw) {
+ write: function(s, off, len) {
+ s = capitalize(s)
+ // Must handle overloads by arity
+ if(off === undefined) {
+ cw.super$write(s, 0, s.length())
+ } else if (typeof s === "string") {
+ cw.super$write(s, off, len)
+ }
+ }
+}
+
+cw.write("abcd")
+cw.write("e".charAt(0))
+cw.write("fgh".toCharArray())
+cw.write("**ijk**", 2, 3)
+cw.write("***lmno**".toCharArray(), 3, 4)
+cw.flush()
+print(sw)
+
+// Can invoke super for Object methods
+print("cw has super hashCode(): " + (typeof cw.super$hashCode === "function"))
+print("cw has super equals(): " + (typeof cw.super$equals === "function"))
+// Can't invoke super for final methods
+print("cw has no super getClass(): " + (typeof cw.super$getClass === "undefined"))
+print("cw has no super wait(): " + (typeof cw.super$wait === "undefined"))
+
+var r = new (Java.type("java.lang.Runnable"))(function() {})
+// Can't invoke super for abstract methods
+print("r has no super run(): " + (typeof r.super$run === "undefined"))
+// Interfaces can also invoke super Object methods
+print("r has super hashCode(): " + (typeof r.super$hashCode === "function"))
+print("r has super equals(): " + (typeof r.super$equals === "function"))
+// But still can't invoke final methods
+print("r has no super getClass(): " + (typeof r.super$getClass === "undefined"))
+print("r has no super wait(): " + (typeof r.super$wait === "undefined"))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023373.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,10 @@
+ABCDEFGHIJKLMNO
+cw has super hashCode(): true
+cw has super equals(): true
+cw has no super getClass(): true
+cw has no super wait(): true
+r has no super run(): true
+r has super hashCode(): true
+r has super equals(): true
+r has no super getClass(): true
+r has no super wait(): true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023531.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023531: new RegExp('').toString() should return '/(?:)/'
+ *
+ * @test
+ * @run
+ */
+
+if (new RegExp("").toString() !== "/(?:)/") {
+ throw new Error();
+} else if (!(new RegExp("").test(""))) {
+ throw new Error();
+}
+
+if (new RegExp("", "g").toString() !== "/(?:)/g") {
+ throw new Error();
+} else if (!(new RegExp("", "g").test(""))) {
+ throw new Error();
+}
+
+if (new RegExp("", "i").toString() !== "/(?:)/i") {
+ throw new Error();
+} else if (!(new RegExp("", "i").test(""))) {
+ throw new Error();
+}
+
+if (new RegExp("", "m").toString() !== "/(?:)/m") {
+ throw new Error();
+} else if (!(new RegExp("", "m").test(""))) {
+ throw new Error();
+}
+
+if (RegExp("").toString() !== "/(?:)/") {
+ throw new Error();
+} else if (!RegExp("").test("")) {
+ throw new Error();
+}
+
+if (RegExp("", "g").toString() !== "/(?:)/g") {
+ throw new Error();
+} else if (!RegExp("", "g").test("")) {
+ throw new Error();
+}
+
+if (RegExp("", "i").toString() !== "/(?:)/i") {
+ throw new Error();
+} else if (!RegExp("", "i").test("")) {
+ throw new Error();
+}
+
+if (RegExp("", "m").toString() !== "/(?:)/m") {
+ throw new Error();
+} else if (!RegExp("", "m").test("")) {
+ throw new Error();
+}
+
+var re = /abc/;
+re.compile("");
+if (re.toString() !== "/(?:)/") {
+ throw new Error();
+} else if (!re.test("")) {
+ throw new Error();
+}
+
+re.compile("", "g");
+if (re.toString() !== "/(?:)/g") {
+ throw new Error();
+} else if (!re.test("")) {
+ throw new Error();
+}
+
+re.compile("", "i");
+if (re.toString() !== "/(?:)/i") {
+ throw new Error();
+} else if (!re.test("")) {
+ throw new Error();
+}
+
+re.compile("", "m");
+if (re.toString() !== "/(?:)/m") {
+ throw new Error();
+} else if (!re.test("")) {
+ throw new Error();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023551.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
+ *
+ * @test
+ * @run
+ */
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+
+function func(x) {
+ print("func: " + x);
+}
+
+e.put("func", func);
+e.invokeFunction("func", "hello");
+
+var obj = e.eval("({ foo: func })");
+e.invokeMethod(obj, "foo", "world");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023551.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,2 @@
+func: hello
+func: world
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023630.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023630: Implement Java.super() as the preferred way to call super methods
+ *
+ * @test
+ * @run
+ */
+
+var CharArray = Java.type("char[]")
+var jString = Java.type("java.lang.String")
+var Character = Java.type("java.lang.Character")
+
+function capitalize(s) {
+ if(s instanceof CharArray) {
+ return new jString(s).toUpperCase()
+ }
+ if(s instanceof jString) {
+ return s.toUpperCase()
+ }
+ return Character.toUpperCase(s) // must be int
+}
+
+var sw = new (Java.type("java.io.StringWriter"))
+
+var FilterWriterAdapter = Java.extend(Java.type("java.io.FilterWriter"))
+
+var cw = new FilterWriterAdapter(sw) {
+ write: function(s, off, len) {
+ s = capitalize(s)
+ // Must handle overloads by arity
+ if(off === undefined) {
+ cw_super.write(s, 0, s.length())
+ } else if (typeof s === "string") {
+ cw_super.write(s, off, len)
+ }
+ }
+}
+var cw_super = Java.super(cw)
+
+cw.write("abcd")
+cw.write("e".charAt(0))
+cw.write("fgh".toCharArray())
+cw.write("**ijk**", 2, 3)
+cw.write("***lmno**".toCharArray(), 3, 4)
+cw.flush()
+print(sw)
+
+// Can invoke super for Object methods
+print("cw_super has hashCode(): " + (typeof cw_super.hashCode === "function"))
+print("cw_super has super equals(): " + (typeof cw_super.equals === "function"))
+// Can't invoke super for final methods
+print("cw_super has no getClass(): " + (typeof cw_super.getClass === "undefined"))
+print("cw_super has no wait(): " + (typeof cw_super.wait === "undefined"))
+
+var r = new (Java.type("java.lang.Runnable"))(function() {})
+var r_super = Java.super(r)
+
+// Can't invoke super for abstract methods
+print("r_super has no run(): " + (typeof r_super.run === "undefined"))
+// Interfaces can also invoke super Object methods
+print("r_super has hashCode(): " + (typeof r_super.hashCode === "function"))
+print("r_super has equals(): " + (typeof r_super.equals === "function"))
+// But still can't invoke final methods
+print("r_super has no getClass(): " + (typeof r_super.getClass === "undefined"))
+print("r_super has no wait(): " + (typeof r_super.wait === "undefined"))
+
+var name = "write"
+print("cw_super can access write through [] getter: " + (typeof cw_super[name] === "function"))
+var name = "hashCode"
+print("cw_super can access hashCode through [] getter: " + (typeof cw_super[name] === "function"))
+var name = "getClass"
+print("cw_super can not access getClass through [] getter: " + (typeof cw_super[name] === "undefined"))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023630.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,13 @@
+ABCDEFGHIJKLMNO
+cw_super has hashCode(): true
+cw_super has super equals(): true
+cw_super has no getClass(): true
+cw_super has no wait(): true
+r_super has no run(): true
+r_super has hashCode(): true
+r_super has equals(): true
+r_super has no getClass(): true
+r_super has no wait(): true
+cw_super can access write through [] getter: true
+cw_super can access hashCode through [] getter: true
+cw_super can not access getClass through [] getter: true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023650.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023650: Regexp m flag does not recognize CRNL or CR
+ *
+ * @test
+ * @run
+ */
+
+if (!/^Connection: close$/m.test('\r\n\r\nConnection: close\r\n\r\n')) {
+ throw new Error();
+}
+
+if (!/^Connection: close$/m.test('\n\nConnection: close\n\n')) {
+ throw new Error();
+}
+
+if (!/^Connection: close$/m.test('\r\rConnection: close\r\r')) {
+ throw new Error();
+}
+
+if (!/^Connection: close$/m.test('\u2028\u2028Connection: close\u2028\u2028')) {
+ throw new Error();
+}
+
+if (!/^Connection: close$/m.test('\u2029\u2029Connection: close\u2029\u2029')) {
+ throw new Error();
+}
+
+var result = /a(.*)/.exec("a\r");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/m.exec("a\r");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/.exec("a\n");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/m.exec("a\n");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/.exec("a\r\n");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/m.exec("a\r\n");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/.exec("a\u2028");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+result = /a(.*)/m.exec("a\u2029");
+if (!result || result[0] != 'a' || result[1] != '') {
+ throw new Error();
+}
+
+if (/a$/.test("a\n")) {
+ throw new Error();
+}
+
+if (/a$/.test("a\r")) {
+ throw new Error();
+}
+
+if (/a$/.test("a\r\n")) {
+ throw new Error();
+}
+
+if (/a$/.test("a\u2028")) {
+ throw new Error();
+}
+
+if (/a$/.test("a\u2029")) {
+ throw new Error();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023780.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023780: Gracefully handle @CS methods while binding bean properties
+ *
+ * @test
+ * @run
+ */
+
+var obj = {}
+Object.bindProperties(obj, java.lang.Thread.currentThread());
+
+print(typeof obj.getName === "function")
+print(typeof obj.getCurrentContext === "undefined")
+
+print(Object.hasOwnProperty("name"))
+print(!Object.hasOwnProperty("currentContext"))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023780.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,4 @@
+true
+true
+true
+true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023784.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023784: Object.prototype.toString should contain the class name for all instances
+ *
+ * @test
+ * @run
+ */
+
+// two parts to this bug -- typed array don't have proper [[Class]] property
+
+print(Object.prototype.toString.call(new ArrayBuffer(1)));
+print(Object.prototype.toString.call(new Int8Array(1)));
+print(Object.prototype.toString.call(new Int16Array(1)));
+print(Object.prototype.toString.call(new Int32Array(1)));
+print(Object.prototype.toString.call(new Uint8Array(1)));
+print(Object.prototype.toString.call(new Uint8ClampedArray(1)));
+print(Object.prototype.toString.call(new Uint16Array(1)));
+print(Object.prototype.toString.call(new Uint32Array(1)));
+print(Object.prototype.toString.call(new Float32Array(1)));
+print(Object.prototype.toString.call(new Float64Array(1)));
+
+// second part is that Object.prototype.toString does not handle mirror
+// in the manner expected.
+
+var global = loadWithNewGlobal({
+ name: "test",
+ script: "this"
+});
+
+print(Object.prototype.toString.call(new global.Object()));
+print(Object.prototype.toString.call(new global.Array()));
+print(Object.prototype.toString.call(new global.RegExp()));
+print(Object.prototype.toString.call(new global.Error("error!")));
+print(Object.prototype.toString.call(global.Object));
+print(Object.prototype.toString.call(new global.ArrayBuffer(1)));
+print(Object.prototype.toString.call(new global.Int8Array(1)));
+print(Object.prototype.toString.call(new global.Int16Array(1)));
+print(Object.prototype.toString.call(new global.Int32Array(1)));
+print(Object.prototype.toString.call(new global.Uint8Array(1)));
+print(Object.prototype.toString.call(new global.Uint8ClampedArray(1)));
+print(Object.prototype.toString.call(new global.Uint16Array(1)));
+print(Object.prototype.toString.call(new global.Uint32Array(1)));
+print(Object.prototype.toString.call(new global.Float32Array(1)));
+print(Object.prototype.toString.call(new global.Float64Array(1)));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8023784.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,25 @@
+[object ArrayBuffer]
+[object Int8Array]
+[object Int16Array]
+[object Int32Array]
+[object Uint8Array]
+[object Uint8ClampedArray]
+[object Uint16Array]
+[object Uint32Array]
+[object Float32Array]
+[object Float64Array]
+[object Object]
+[object Array]
+[object RegExp]
+[object Error]
+[object Function]
+[object ArrayBuffer]
+[object Int8Array]
+[object Int16Array]
+[object Int32Array]
+[object Uint8Array]
+[object Uint8ClampedArray]
+[object Uint16Array]
+[object Uint32Array]
+[object Float32Array]
+[object Float64Array]
--- a/nashorn/test/script/basic/NASHORN-377.js.EXPECTED Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/test/script/basic/NASHORN-377.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -1,5 +1,5 @@
8 8 true undefined
-[object Object] [object Object] [object Object]
+[object ArrayBuffer] [object ArrayBuffer] [object Int8Array]
0 8 8 1
0 8 8 1
0 8 8 1
--- a/nashorn/test/script/basic/NASHORN-397.js Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/test/script/basic/NASHORN-397.js Wed Jul 05 19:10:19 2017 +0200
@@ -35,7 +35,10 @@
fail("typeof(5).x is not 'number'");
}
-if (typeof (java.lang.System.out) != 'object') {
+// It is function because PrintStream implements Closeable, which is
+// marked with @FunctionalInterface. Yes, this means calling a stream
+// like "stream()" closes it.
+if (typeof (java.lang.System.out) != 'function') {
fail("typeof java.lang.System.out is not 'object'");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/circular_proto.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023368: Instance __proto__ property should exist and be writable.
+ *
+ * @test
+ * @run
+ */
+
+// check that we cannot create __proto__ cycle
+load("nashorn:mozilla_compat.js");
+
+var obj = {};
+var obj2 = Object.create(obj);
+
+// attempt to create __proto__ cycle
+try {
+ obj.__proto__ = obj2;
+ fail("Should have thrown TypeError");
+} catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("Expected TypeError, got " + e);
+ }
+ print(e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/circular_proto.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,1 @@
+TypeError: Cannot create__proto__ cycle for [object Object]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/mirror_proto_assign.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023368: Instance __proto__ property should exist and be writable.
+ *
+ * @test
+ * @run
+ */
+
+// check that Object.setPrototypeOf works for mirror objects as well.
+
+var global = loadWithNewGlobal({
+ name: "test",
+ script: "var obj = {}; this"
+});
+
+var proto = global.eval("({ foo: 323 })");
+
+Object.setPrototypeOf(global.obj, proto);
+
+function func(obj) {
+ // check proto inherited value
+ print("obj.foo = " + obj.foo);
+}
+
+func(global.obj);
+
+var newProto = global.eval("({ foo: 'hello' })");
+Object.setPrototypeOf(global.obj, newProto);
+
+func(global.obj);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/mirror_proto_assign.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,2 @@
+obj.foo = 323
+obj.foo = hello
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/nonextensible_proto_assign.js Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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
+ * 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.
+ */
+
+/**
+ * JDK-8023368: Instance __proto__ property should exist and be writable.
+ *
+ * @test
+ * @run
+ */
+
+load("nashorn:mozilla_compat.js")
+
+// check that we cannot assign to __proto__ of a non-extensible object
+try {
+ var obj = {}
+ Object.preventExtensions(obj);
+ obj.__proto__ = { };
+ fail("Should have thrown TypeError");
+} catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("Expected TypeError, got " + e);
+ }
+ print(e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/nonextensible_proto_assign.js.EXPECTED Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,1 @@
+TypeError: Cannot set __proto__ of non-extensible [object Object]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/InvocableTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,525 @@
+/*
+ * 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
+ * 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.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import java.util.Objects;
+import javax.script.Invocable;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+import org.testng.Assert;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for javax.script.Invocable implementation of nashorn.
+ */
+public class InvocableTest {
+
+ private void log(String msg) {
+ org.testng.Reporter.log(msg, true);
+ }
+
+ @Test
+ public void invokeMethodTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();");
+ final Object obj = e.get("myExample");
+ final Object res = ((Invocable) e).invokeMethod(obj, "hello");
+ assertEquals(res, "Hello World!");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ @Test
+ /**
+ * Check that we can call invokeMethod on an object that we got by
+ * evaluating script with different Context set.
+ */
+ public void invokeMethodDifferentContextTest() {
+ ScriptEngineManager m = new ScriptEngineManager();
+ ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ // define an object with method on it
+ Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })");
+
+ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+ e.setContext(ctxt);
+
+ // invoke 'func' on obj - but with current script context changed
+ final Object res = ((Invocable) e).invokeMethod(obj, "hello");
+ assertEquals(res, "Hello World!");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ @Test
+ /**
+ * Check that invokeMethod throws NPE on null method name.
+ */
+ public void invokeMethodNullNameTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ final Object obj = e.eval("({})");
+ final Object res = ((Invocable) e).invokeMethod(obj, null);
+ fail("should have thrown NPE");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NullPointerException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that invokeMethod throws NoSuchMethodException on missing method.
+ */
+ public void invokeMethodMissingTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ final Object obj = e.eval("({})");
+ final Object res = ((Invocable) e).invokeMethod(obj, "nonExistentMethod");
+ fail("should have thrown NoSuchMethodException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NoSuchMethodException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that calling method on non-script object 'thiz' results in
+ * IllegalArgumentException.
+ */
+ public void invokeMethodNonScriptObjectThizTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ ((Invocable) e).invokeMethod(new Object(), "toString");
+ fail("should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that calling method on null 'thiz' results in
+ * IllegalArgumentException.
+ */
+ public void invokeMethodNullThizTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ ((Invocable) e).invokeMethod(null, "toString");
+ fail("should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that calling method on mirror created by another engine results in
+ * IllegalArgumentException.
+ */
+ public void invokeMethodMixEnginesTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine engine1 = m.getEngineByName("nashorn");
+ final ScriptEngine engine2 = m.getEngineByName("nashorn");
+
+ try {
+ Object obj = engine1.eval("({ run: function() {} })");
+ // pass object from engine1 to engine2 as 'thiz' for invokeMethod
+ ((Invocable) engine2).invokeMethod(obj, "run");
+ fail("should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void getInterfaceTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Invocable inv = (Invocable) e;
+
+ // try to get interface from global functions
+ try {
+ e.eval("function run() { print('run'); };");
+ final Runnable runnable = inv.getInterface(Runnable.class);
+ runnable.run();
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+
+ // try interface on specific script object
+ try {
+ e.eval("var obj = { run: function() { print('run from obj'); } };");
+ Object obj = e.get("obj");
+ final Runnable runnable = inv.getInterface(obj, Runnable.class);
+ runnable.run();
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ public interface Foo {
+
+ public void bar();
+ }
+
+ public interface Foo2 extends Foo {
+
+ public void bar2();
+ }
+
+ @Test
+ public void getInterfaceMissingTest() {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine engine = manager.getEngineByName("nashorn");
+
+ // don't define any function.
+ try {
+ engine.eval("");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+
+ Runnable runnable = ((Invocable) engine).getInterface(Runnable.class);
+ if (runnable != null) {
+ fail("runnable is not null!");
+ }
+
+ // now define "run"
+ try {
+ engine.eval("function run() { print('this is run function'); }");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ runnable = ((Invocable) engine).getInterface(Runnable.class);
+ // should not return null now!
+ runnable.run();
+
+ // define only one method of "Foo2"
+ try {
+ engine.eval("function bar() { print('bar function'); }");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+
+ Foo2 foo2 = ((Invocable) engine).getInterface(Foo2.class);
+ if (foo2 != null) {
+ throw new RuntimeException("foo2 is not null!");
+ }
+
+ // now define other method of "Foo2"
+ try {
+ engine.eval("function bar2() { print('bar2 function'); }");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ foo2 = ((Invocable) engine).getInterface(Foo2.class);
+ foo2.bar();
+ foo2.bar2();
+ }
+
+ @Test
+ /**
+ * Try passing non-interface Class object for interface implementation.
+ */
+ public void getNonInterfaceGetInterfaceTest() {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine engine = manager.getEngineByName("nashorn");
+ try {
+ log(Objects.toString(((Invocable) engine).getInterface(Object.class)));
+ fail("Should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ fail("IllegalArgumentException expected, got " + exp);
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that we can get interface out of a script object even after
+ * switching to use different ScriptContext.
+ */
+ public void getInterfaceDifferentContext() {
+ ScriptEngineManager m = new ScriptEngineManager();
+ ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ Object obj = e.eval("({ run: function() { } })");
+
+ // change script context
+ ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+ e.setContext(ctxt);
+
+ Runnable r = ((Invocable) e).getInterface(obj, Runnable.class);
+ r.run();
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ @Test
+ /**
+ * Check that getInterface on non-script object 'thiz' results in
+ * IllegalArgumentException.
+ */
+ public void getInterfaceNonScriptObjectThizTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ ((Invocable) e).getInterface(new Object(), Runnable.class);
+ fail("should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that getInterface on null 'thiz' results in
+ * IllegalArgumentException.
+ */
+ public void getInterfaceNullThizTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ ((Invocable) e).getInterface(null, Runnable.class);
+ fail("should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that calling getInterface on mirror created by another engine
+ * results in IllegalArgumentException.
+ */
+ public void getInterfaceMixEnginesTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine engine1 = m.getEngineByName("nashorn");
+ final ScriptEngine engine2 = m.getEngineByName("nashorn");
+
+ try {
+ Object obj = engine1.eval("({ run: function() {} })");
+ // pass object from engine1 to engine2 as 'thiz' for getInterface
+ ((Invocable) engine2).getInterface(obj, Runnable.class);
+ fail("should have thrown IllegalArgumentException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof IllegalArgumentException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * check that null function name results in NPE.
+ */
+ public void invokeFunctionNullNameTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ final Object res = ((Invocable) e).invokeFunction(null);
+ fail("should have thrown NPE");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NullPointerException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that attempt to call missing function results in
+ * NoSuchMethodException.
+ */
+ public void invokeFunctionMissingTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ final Object res = ((Invocable) e).invokeFunction("NonExistentFunc");
+ fail("should have thrown NoSuchMethodException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NoSuchMethodException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ /**
+ * Check that invokeFunction calls functions only from current context's
+ * Bindings.
+ */
+ public void invokeFunctionDifferentContextTest() {
+ ScriptEngineManager m = new ScriptEngineManager();
+ ScriptEngine e = m.getEngineByName("nashorn");
+
+ try {
+ // define an object with method on it
+ Object obj = e.eval("function hello() { return 'Hello World!'; }");
+ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+ // change engine's current context
+ e.setContext(ctxt);
+
+ ((Invocable) e).invokeFunction("hello"); // no 'hello' in new context!
+ fail("should have thrown NoSuchMethodException");
+ } catch (final Exception exp) {
+ if (!(exp instanceof NoSuchMethodException)) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void invokeFunctionExceptionTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ e.eval("function func() { throw new TypeError(); }");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+ fail(t.getMessage());
+ }
+
+ try {
+ ((Invocable) e).invokeFunction("func");
+ fail("should have thrown exception");
+ } catch (final ScriptException se) {
+ // ECMA TypeError property wrapped as a ScriptException
+ log("got " + se + " as expected");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+ fail(t.getMessage());
+ }
+ }
+
+ @Test
+ public void invokeMethodExceptionTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+ fail(t.getMessage());
+ }
+
+ try {
+ final Object sobj = e.get("sobj");
+ ((Invocable) e).invokeMethod(sobj, "foo");
+ fail("should have thrown exception");
+ } catch (final ScriptException se) {
+ // ECMA TypeError property wrapped as a ScriptException
+ log("got " + se + " as expected");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+ fail(t.getMessage());
+ }
+ }
+
+ @Test
+ /**
+ * Tests whether invocation of a JavaScript method through a variable arity
+ * Java method will pass the vararg array. Both non-vararg and vararg
+ * JavaScript methods are tested.
+ *
+ * @throws ScriptException
+ */
+ public void variableArityInterfaceTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ e.eval(
+ "function test1(i, strings) {"
+ + " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)"
+ + "}"
+ + "function test2() {"
+ + " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])"
+ + "}");
+ final VariableArityTestInterface itf = ((Invocable) e).getInterface(VariableArityTestInterface.class);
+ Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]");
+ Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,248 @@
+/*
+ * 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
+ * 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.
+ */
+package jdk.nashorn.api.scripting;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import javax.script.SimpleScriptContext;
+import org.testng.Assert;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import org.testng.annotations.Test;
+
+/**
+ * Tests for jsr223 Bindings "scope" (engine, global scopes)
+ */
+public class ScopeTest {
+
+ @Test
+ public void createBindingsTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ Bindings b = e.createBindings();
+ b.put("foo", 42.0);
+ Object res = null;
+ try {
+ res = e.eval("foo == 42.0", b);
+ } catch (final ScriptException | NullPointerException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+
+ assertEquals(res, Boolean.TRUE);
+ }
+
+ @Test
+ public void engineScopeTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE);
+
+ // check few ECMA standard built-in global properties
+ assertNotNull(engineScope.get("Object"));
+ assertNotNull(engineScope.get("TypeError"));
+ assertNotNull(engineScope.get("eval"));
+
+ // can access via ScriptEngine.get as well
+ assertNotNull(e.get("Object"));
+ assertNotNull(e.get("TypeError"));
+ assertNotNull(e.get("eval"));
+
+ // Access by either way should return same object
+ assertEquals(engineScope.get("Array"), e.get("Array"));
+ assertEquals(engineScope.get("EvalError"), e.get("EvalError"));
+ assertEquals(engineScope.get("undefined"), e.get("undefined"));
+
+ // try exposing a new variable from scope
+ engineScope.put("myVar", "foo");
+ try {
+ assertEquals(e.eval("myVar"), "foo");
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+
+ // update "myVar" in script an check the value from scope
+ try {
+ e.eval("myVar = 'nashorn';");
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+
+ // now check modified value from scope and engine
+ assertEquals(engineScope.get("myVar"), "nashorn");
+ assertEquals(e.get("myVar"), "nashorn");
+ }
+
+ @Test
+ public void multiGlobalTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ try {
+ Object obj1 = e.eval("Object");
+ Object obj2 = e.eval("Object", newCtxt);
+ Assert.assertNotEquals(obj1, obj2);
+ Assert.assertNotNull(obj1);
+ Assert.assertNotNull(obj2);
+ Assert.assertEquals(obj1.toString(), obj2.toString());
+
+ e.eval("x = 'hello'");
+ e.eval("x = 'world'", newCtxt);
+ Object x1 = e.getContext().getAttribute("x");
+ Object x2 = newCtxt.getAttribute("x");
+ Assert.assertNotEquals(x1, x2);
+ Assert.assertEquals(x1, "hello");
+ Assert.assertEquals(x2, "world");
+
+ x1 = e.eval("x");
+ x2 = e.eval("x", newCtxt);
+ Assert.assertNotEquals(x1, x2);
+ Assert.assertEquals(x1, "hello");
+ Assert.assertEquals(x2, "world");
+
+ final ScriptContext origCtxt = e.getContext();
+ e.setContext(newCtxt);
+ e.eval("y = new Object()");
+ e.eval("y = new Object()", origCtxt);
+
+ Object y1 = origCtxt.getAttribute("y");
+ Object y2 = newCtxt.getAttribute("y");
+ Assert.assertNotEquals(y1, y2);
+ Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt));
+ Assert.assertEquals("[object Object]", y1.toString());
+ Assert.assertEquals("[object Object]", y2.toString());
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+ }
+
+ @Test
+ public void userEngineScopeBindingsTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ e.eval("function func() {}");
+
+ final ScriptContext newContext = new SimpleScriptContext();
+ newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
+ // we are using a new bindings - so it should have 'func' defined
+ Object value = e.eval("typeof func", newContext);
+ assertTrue(value.equals("undefined"));
+ }
+
+ @Test
+ public void userEngineScopeBindingsNoLeakTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptContext newContext = new SimpleScriptContext();
+ newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
+ e.eval("function foo() {}", newContext);
+
+ // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist
+ assertTrue(e.eval("typeof foo").equals("undefined"));
+ }
+
+ @Test
+ public void userEngineScopeBindingsRetentionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptContext newContext = new SimpleScriptContext();
+ newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
+ e.eval("function foo() {}", newContext);
+
+ // definition retained with user's ENGINE_SCOPE Binding
+ assertTrue(e.eval("typeof foo", newContext).equals("function"));
+
+ final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
+ // but not in another ENGINE_SCOPE binding
+ newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
+ assertTrue(e.eval("typeof foo", newContext).equals("undefined"));
+
+ // restore ENGINE_SCOPE and check again
+ newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE);
+ assertTrue(e.eval("typeof foo", newContext).equals("function"));
+ }
+
+ @Test
+ // check that engine.js definitions are visible in all new global instances
+ public void checkBuiltinsInNewBindingsTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ // check default global instance has engine.js definitions
+ final Bindings g = (Bindings) e.eval("this");
+ Object value = g.get("__noSuchProperty__");
+ assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
+ value = g.get("print");
+ assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
+
+ // check new global instance created has engine.js definitions
+ Bindings b = e.createBindings();
+ value = b.get("__noSuchProperty__");
+ assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
+ value = b.get("print");
+ assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
+
+ // put a mapping into GLOBAL_SCOPE
+ final Bindings globalScope = e.getContext().getBindings(ScriptContext.GLOBAL_SCOPE);
+ globalScope.put("x", "hello");
+
+ // GLOBAL_SCOPE mapping should be visible from default ScriptContext eval
+ assertTrue(e.eval("x").equals("hello"));
+
+ final ScriptContext ctx = new SimpleScriptContext();
+ ctx.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE);
+ ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval
+ assertTrue(e.eval("x", ctx).equals("hello"));
+
+ // try some arbitray Bindings for ENGINE_SCOPE
+ Bindings sb = new SimpleBindings();
+ ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE);
+
+ // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval
+ assertTrue(e.eval("x", ctx).equals("hello"));
+
+ // engine.js builtins are still defined even with arbitrary Bindings
+ assertTrue(e.eval("typeof print", ctx).equals("function"));
+ assertTrue(e.eval("typeof __noSuchProperty__", ctx).equals("function"));
+
+ // ENGINE_SCOPE definition should 'hide' GLOBAL_SCOPE definition
+ sb.put("x", "newX");
+ assertTrue(e.eval("x", ctx).equals("newX"));
+ }
+}
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -26,29 +26,21 @@
package jdk.nashorn.api.scripting;
import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
+import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
import java.util.concurrent.Callable;
-import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
-import javax.script.Invocable;
-import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
-import org.testng.Assert;
import org.testng.annotations.Test;
/**
@@ -239,214 +231,6 @@
}
@Test
- public void createBindingsTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- Bindings b = e.createBindings();
- b.put("foo", 42.0);
- Object res = null;
- try {
- res = e.eval("foo == 42.0", b);
- } catch (final ScriptException | NullPointerException se) {
- se.printStackTrace();
- fail(se.getMessage());
- }
-
- assertEquals(res, Boolean.TRUE);
- }
-
- @Test
- public void getInterfaceTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- final Invocable inv = (Invocable)e;
-
- // try to get interface from global functions
- try {
- e.eval("function run() { print('run'); };");
- final Runnable runnable = inv.getInterface(Runnable.class);
- runnable.run();
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
-
- // try interface on specific script object
- try {
- e.eval("var obj = { run: function() { print('run from obj'); } };");
- Object obj = e.get("obj");
- final Runnable runnable = inv.getInterface(obj, Runnable.class);
- runnable.run();
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
-
- public interface Foo {
- public void bar();
- }
-
- public interface Foo2 extends Foo {
- public void bar2();
- }
-
- @Test
- public void getInterfaceMissingTest() {
- final ScriptEngineManager manager = new ScriptEngineManager();
- final ScriptEngine engine = manager.getEngineByName("nashorn");
-
- // don't define any function.
- try {
- engine.eval("");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
-
- Runnable runnable = ((Invocable)engine).getInterface(Runnable.class);
- if (runnable != null) {
- fail("runnable is not null!");
- }
-
- // now define "run"
- try {
- engine.eval("function run() { print('this is run function'); }");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- runnable = ((Invocable)engine).getInterface(Runnable.class);
- // should not return null now!
- runnable.run();
-
- // define only one method of "Foo2"
- try {
- engine.eval("function bar() { print('bar function'); }");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
-
- Foo2 foo2 = ((Invocable)engine).getInterface(Foo2.class);
- if (foo2 != null) {
- throw new RuntimeException("foo2 is not null!");
- }
-
- // now define other method of "Foo2"
- try {
- engine.eval("function bar2() { print('bar2 function'); }");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- foo2 = ((Invocable)engine).getInterface(Foo2.class);
- foo2.bar();
- foo2.bar2();
- }
-
- @Test
- /**
- * Try passing non-interface Class object for interface implementation.
- */
- public void getNonInterfaceGetInterfaceTest() {
- final ScriptEngineManager manager = new ScriptEngineManager();
- final ScriptEngine engine = manager.getEngineByName("nashorn");
- try {
- log(Objects.toString(((Invocable)engine).getInterface(Object.class)));
- fail("Should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- fail("IllegalArgumentException expected, got " + exp);
- }
- }
- }
-
- @Test
- /**
- * Check that we can get interface out of a script object even after
- * switching to use different ScriptContext.
- */
- public void getInterfaceDifferentContext() {
- ScriptEngineManager m = new ScriptEngineManager();
- ScriptEngine e = m.getEngineByName("nashorn");
- try {
- Object obj = e.eval("({ run: function() { } })");
-
- // change script context
- ScriptContext ctxt = new SimpleScriptContext();
- ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
- e.setContext(ctxt);
-
- Runnable r = ((Invocable)e).getInterface(obj, Runnable.class);
- r.run();
- }catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
-
- @Test
- /**
- * Check that getInterface on non-script object 'thiz' results in IllegalArgumentException.
- */
- public void getInterfaceNonScriptObjectThizTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- ((Invocable)e).getInterface(new Object(), Runnable.class);
- fail("should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that getInterface on null 'thiz' results in IllegalArgumentException.
- */
- public void getInterfaceNullThizTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- ((Invocable)e).getInterface(null, Runnable.class);
- fail("should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that calling getInterface on mirror created by another engine results in IllegalArgumentException.
- */
- public void getInterfaceMixEnginesTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine engine1 = m.getEngineByName("nashorn");
- final ScriptEngine engine2 = m.getEngineByName("nashorn");
-
- try {
- Object obj = engine1.eval("({ run: function() {} })");
- // pass object from engine1 to engine2 as 'thiz' for getInterface
- ((Invocable)engine2).getInterface(obj, Runnable.class);
- fail("should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
public void accessGlobalTest() {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
@@ -617,90 +401,7 @@
exp.printStackTrace();
fail(exp.getMessage());
}
- // dos2unix - fix line endings if running on windows
- assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n");
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void reflectionTest() throws ScriptException {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- e.eval("var obj = { x: 344, y: 'nashorn' }");
-
- int count = 0;
- Map<Object, Object> map = (Map<Object, Object>)e.get("obj");
- assertFalse(map.isEmpty());
- assertTrue(map.keySet().contains("x"));
- assertTrue(map.containsKey("x"));
- assertTrue(map.values().contains("nashorn"));
- assertTrue(map.containsValue("nashorn"));
- for (final Map.Entry<?, ?> ex : map.entrySet()) {
- final Object key = ex.getKey();
- if (key.equals("x")) {
- assertTrue(344 == ((Number)ex.getValue()).doubleValue());
- count++;
- } else if (key.equals("y")) {
- assertEquals(ex.getValue(), "nashorn");
- count++;
- }
- }
- assertEquals(2, count);
- assertEquals(2, map.size());
-
- // add property
- map.put("z", "hello");
- assertEquals(e.eval("obj.z"), "hello");
- assertEquals(map.get("z"), "hello");
- assertTrue(map.keySet().contains("z"));
- assertTrue(map.containsKey("z"));
- assertTrue(map.values().contains("hello"));
- assertTrue(map.containsValue("hello"));
- assertEquals(map.size(), 3);
-
- final Map<Object, Object> newMap = new HashMap<>();
- newMap.put("foo", 23.0);
- newMap.put("bar", true);
- map.putAll(newMap);
-
- assertEquals(e.eval("obj.foo"), 23.0);
- assertEquals(e.eval("obj.bar"), true);
-
- // remove using map method
- map.remove("foo");
- assertEquals(e.eval("typeof obj.foo"), "undefined");
-
- count = 0;
- e.eval("var arr = [ true, 'hello' ]");
- map = (Map<Object, Object>)e.get("arr");
- assertFalse(map.isEmpty());
- assertTrue(map.containsKey("length"));
- assertTrue(map.containsValue("hello"));
- for (final Map.Entry<?, ?> ex : map.entrySet()) {
- final Object key = ex.getKey();
- if (key.equals("0")) {
- assertEquals(ex.getValue(), Boolean.TRUE);
- count++;
- } else if (key.equals("1")) {
- assertEquals(ex.getValue(), "hello");
- count++;
- }
- }
- assertEquals(count, 2);
- assertEquals(map.size(), 2);
-
- // add element
- map.put("2", "world");
- assertEquals(map.get("2"), "world");
- assertEquals(map.size(), 3);
-
- // remove all
- map.clear();
- assertTrue(map.isEmpty());
- assertEquals(e.eval("typeof arr[0]"), "undefined");
- assertEquals(e.eval("typeof arr[1]"), "undefined");
- assertEquals(e.eval("typeof arr[2]"), "undefined");
+ assertEquals(sw.toString(), println("hello world"));
}
@Test
@@ -715,150 +416,6 @@
fail(exp.getMessage());
}
}
-
- @Test
- public void invokeMethodTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();");
- final Object obj = e.get("myExample");
- final Object res = ((Invocable)e).invokeMethod(obj, "hello");
- assertEquals(res, "Hello World!");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
-
- @Test
- /**
- * Check that we can call invokeMethod on an object that we got by evaluating
- * script with different Context set.
- */
- public void invokeMethodDifferentContextTest() {
- ScriptEngineManager m = new ScriptEngineManager();
- ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- // define an object with method on it
- Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })");
-
- final ScriptContext ctxt = new SimpleScriptContext();
- ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
- e.setContext(ctxt);
-
- // invoke 'func' on obj - but with current script context changed
- final Object res = ((Invocable)e).invokeMethod(obj, "hello");
- assertEquals(res, "Hello World!");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
-
- @Test
- /**
- * Check that invokeMethod throws NPE on null method name.
- */
- public void invokeMethodNullNameTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- final Object obj = e.eval("({})");
- final Object res = ((Invocable)e).invokeMethod(obj, null);
- fail("should have thrown NPE");
- } catch (final Exception exp) {
- if (! (exp instanceof NullPointerException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that invokeMethod throws NoSuchMethodException on missing method.
- */
- public void invokeMethodMissingTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- final Object obj = e.eval("({})");
- final Object res = ((Invocable)e).invokeMethod(obj, "nonExistentMethod");
- fail("should have thrown NoSuchMethodException");
- } catch (final Exception exp) {
- if (! (exp instanceof NoSuchMethodException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that calling method on non-script object 'thiz' results in IllegalArgumentException.
- */
- public void invokeMethodNonScriptObjectThizTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- ((Invocable)e).invokeMethod(new Object(), "toString");
- fail("should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that calling method on null 'thiz' results in IllegalArgumentException.
- */
- public void invokeMethodNullThizTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- ((Invocable)e).invokeMethod(null, "toString");
- fail("should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
-
- @Test
- /**
- * Check that calling method on mirror created by another engine results in IllegalArgumentException.
- */
- public void invokeMethodMixEnginesTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine engine1 = m.getEngineByName("nashorn");
- final ScriptEngine engine2 = m.getEngineByName("nashorn");
-
- try {
- Object obj = engine1.eval("({ run: function() {} })");
- // pass object from engine1 to engine2 as 'thiz' for invokeMethod
- ((Invocable)engine2).invokeMethod(obj, "run");
- fail("should have thrown IllegalArgumentException");
- } catch (final Exception exp) {
- if (! (exp instanceof IllegalArgumentException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
@Test
public void noEnumerablePropertiesTest() {
final ScriptEngineManager m = new ScriptEngineManager();
@@ -920,308 +477,6 @@
}
@Test
- public void jsobjectTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- try {
- e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }");
- JSObject obj = (JSObject) e.get("obj");
-
- // try basic get on existing properties
- if (! obj.getMember("bar").equals("hello")) {
- fail("obj.bar != 'hello'");
- }
-
- if (! obj.getSlot(1).equals("world")) {
- fail("obj[1] != 'world'");
- }
-
- if (! obj.call("func", new Object[0]).equals("hello")) {
- fail("obj.call('func') != 'hello'");
- }
-
- // try setting properties
- obj.setMember("bar", "new-bar");
- obj.setSlot(1, "new-element-1");
- if (! obj.getMember("bar").equals("new-bar")) {
- fail("obj.bar != 'new-bar'");
- }
-
- if (! obj.getSlot(1).equals("new-element-1")) {
- fail("obj[1] != 'new-element-1'");
- }
-
- // try adding properties
- obj.setMember("prop", "prop-value");
- obj.setSlot(12, "element-12");
- if (! obj.getMember("prop").equals("prop-value")) {
- fail("obj.prop != 'prop-value'");
- }
-
- if (! obj.getSlot(12).equals("element-12")) {
- fail("obj[12] != 'element-12'");
- }
-
- // delete properties
- obj.removeMember("prop");
- if ("prop-value".equals(obj.getMember("prop"))) {
- fail("obj.prop is not deleted!");
- }
-
- // Simple eval tests
- assertEquals(obj.eval("typeof Object"), "function");
- assertEquals(obj.eval("'nashorn'.substring(3)"), "horn");
- } catch (final Exception exp) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
-
- @Test
- /**
- * check that null function name results in NPE.
- */
- public void invokeFunctionNullNameTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- final Object res = ((Invocable)e).invokeFunction(null);
- fail("should have thrown NPE");
- } catch (final Exception exp) {
- if (! (exp instanceof NullPointerException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that attempt to call missing function results in NoSuchMethodException.
- */
- public void invokeFunctionMissingTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- final Object res = ((Invocable)e).invokeFunction("NonExistentFunc");
- fail("should have thrown NoSuchMethodException");
- } catch (final Exception exp) {
- if (! (exp instanceof NoSuchMethodException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- /**
- * Check that invokeFunction calls functions only from current context's Bindings.
- */
- public void invokeFunctionDifferentContextTest() {
- ScriptEngineManager m = new ScriptEngineManager();
- ScriptEngine e = m.getEngineByName("nashorn");
-
- try {
- // define an object with method on it
- Object obj = e.eval("function hello() { return 'Hello World!'; }");
- final ScriptContext ctxt = new SimpleScriptContext();
- ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
- // change engine's current context
- e.setContext(ctxt);
-
- ((Invocable)e).invokeFunction("hello"); // no 'hello' in new context!
- fail("should have thrown NoSuchMethodException");
- } catch (final Exception exp) {
- if (! (exp instanceof NoSuchMethodException)) {
- exp.printStackTrace();
- fail(exp.getMessage());
- }
- }
- }
-
- @Test
- public void invokeFunctionExceptionTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- try {
- e.eval("function func() { throw new TypeError(); }");
- } catch (final Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
-
- try {
- ((Invocable)e).invokeFunction("func");
- fail("should have thrown exception");
- } catch (final ScriptException se) {
- // ECMA TypeError property wrapped as a ScriptException
- log("got " + se + " as expected");
- } catch (final Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
- }
-
- @Test
- public void invokeMethodExceptionTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- try {
- e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }");
- } catch (final Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
-
- try {
- final Object sobj = e.get("sobj");
- ((Invocable)e).invokeMethod(sobj, "foo");
- fail("should have thrown exception");
- } catch (final ScriptException se) {
- // ECMA TypeError property wrapped as a ScriptException
- log("got " + se + " as expected");
- } catch (final Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
- }
-
- @Test
- public void scriptObjectMirrorToStringTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- try {
- Object obj = e.eval("new TypeError('wrong type')");
- assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value");
- } catch (final Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
-
- try {
- Object obj = e.eval("function func() { print('hello'); }");
- assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value");
- } catch (final Throwable t) {
- t.printStackTrace();
- fail(t.getMessage());
- }
- }
-
- @Test
- public void engineScopeTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE);
-
- // check few ECMA standard built-in global properties
- assertNotNull(engineScope.get("Object"));
- assertNotNull(engineScope.get("TypeError"));
- assertNotNull(engineScope.get("eval"));
-
- // can access via ScriptEngine.get as well
- assertNotNull(e.get("Object"));
- assertNotNull(e.get("TypeError"));
- assertNotNull(e.get("eval"));
-
- // Access by either way should return same object
- assertEquals(engineScope.get("Array"), e.get("Array"));
- assertEquals(engineScope.get("EvalError"), e.get("EvalError"));
- assertEquals(engineScope.get("undefined"), e.get("undefined"));
-
- // try exposing a new variable from scope
- engineScope.put("myVar", "foo");
- try {
- assertEquals(e.eval("myVar"), "foo");
- } catch (final ScriptException se) {
- se.printStackTrace();
- fail(se.getMessage());
- }
-
- // update "myVar" in script an check the value from scope
- try {
- e.eval("myVar = 'nashorn';");
- } catch (final ScriptException se) {
- se.printStackTrace();
- fail(se.getMessage());
- }
-
- // now check modified value from scope and engine
- assertEquals(engineScope.get("myVar"), "nashorn");
- assertEquals(e.get("myVar"), "nashorn");
- }
-
- @Test
- public void multiGlobalTest() {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- final Bindings b = e.createBindings();
- final ScriptContext newCtxt = new SimpleScriptContext();
- newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
-
- try {
- Object obj1 = e.eval("Object");
- Object obj2 = e.eval("Object", newCtxt);
- Assert.assertNotEquals(obj1, obj2);
- Assert.assertNotNull(obj1);
- Assert.assertNotNull(obj2);
- Assert.assertEquals(obj1.toString(), obj2.toString());
-
- e.eval("x = 'hello'");
- e.eval("x = 'world'", newCtxt);
- Object x1 = e.getContext().getAttribute("x");
- Object x2 = newCtxt.getAttribute("x");
- Assert.assertNotEquals(x1, x2);
- Assert.assertEquals(x1, "hello");
- Assert.assertEquals(x2, "world");
-
- x1 = e.eval("x");
- x2 = e.eval("x", newCtxt);
- Assert.assertNotEquals(x1, x2);
- Assert.assertEquals(x1, "hello");
- Assert.assertEquals(x2, "world");
-
- final ScriptContext origCtxt = e.getContext();
- e.setContext(newCtxt);
- e.eval("y = new Object()");
- e.eval("y = new Object()", origCtxt);
-
- Object y1 = origCtxt.getAttribute("y");
- Object y2 = newCtxt.getAttribute("y");
- Assert.assertNotEquals(y1, y2);
- Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt));
- Assert.assertEquals("[object Object]", y1.toString());
- Assert.assertEquals("[object Object]", y2.toString());
- } catch (final ScriptException se) {
- se.printStackTrace();
- fail(se.getMessage());
- }
- }
-
- @Test
- /**
- * Tests whether invocation of a JavaScript method through a variable arity Java method will pass the vararg array.
- * Both non-vararg and vararg JavaScript methods are tested.
- * @throws ScriptException
- */
- public void variableArityInterfaceTest() throws ScriptException {
- final ScriptEngineManager m = new ScriptEngineManager();
- final ScriptEngine e = m.getEngineByName("nashorn");
- e.eval(
- "function test1(i, strings) {" +
- " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" +
- "}" +
- "function test2() {" +
- " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" +
- "}"
- );
- final VariableArityTestInterface itf = ((Invocable)e).getInterface(VariableArityTestInterface.class);
- Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]");
- Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]");
- }
-
- @Test
// check that print function prints arg followed by newline char
public void printTest() {
final ScriptEngineManager m = new ScriptEngineManager();
@@ -1235,8 +490,7 @@
fail(t.getMessage());
}
- // dos2unix - fix line endings if running on windows
- assertEquals(sw.toString().replaceAll("\r", ""), "hello\n");
+ assertEquals(sw.toString(), println("hello"));
}
@Test
@@ -1253,7 +507,14 @@
fail(t.getMessage());
}
- // dos2unix - fix line endings if running on windows
- assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n");
+ assertEquals(sw.toString(), println("34 true hello"));
+ }
+
+ private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+ // Returns String that would be the result of calling PrintWriter.println
+ // of the given String. (This is to handle platform specific newline).
+ private static String println(final String str) {
+ return str + LINE_SEPARATOR;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -0,0 +1,230 @@
+/*
+ * 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
+ * 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.
+ */
+
+package jdk.nashorn.api.scripting;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import org.testng.annotations.Test;
+
+/**
+ * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API.
+ */
+public class ScriptObjectMirrorTest {
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void reflectionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ e.eval("var obj = { x: 344, y: 'nashorn' }");
+
+ int count = 0;
+ Map<Object, Object> map = (Map<Object, Object>) e.get("obj");
+ assertFalse(map.isEmpty());
+ assertTrue(map.keySet().contains("x"));
+ assertTrue(map.containsKey("x"));
+ assertTrue(map.values().contains("nashorn"));
+ assertTrue(map.containsValue("nashorn"));
+ for (final Map.Entry<?, ?> ex : map.entrySet()) {
+ final Object key = ex.getKey();
+ if (key.equals("x")) {
+ assertTrue(344 == ((Number) ex.getValue()).doubleValue());
+ count++;
+ } else if (key.equals("y")) {
+ assertEquals(ex.getValue(), "nashorn");
+ count++;
+ }
+ }
+ assertEquals(2, count);
+ assertEquals(2, map.size());
+
+ // add property
+ map.put("z", "hello");
+ assertEquals(e.eval("obj.z"), "hello");
+ assertEquals(map.get("z"), "hello");
+ assertTrue(map.keySet().contains("z"));
+ assertTrue(map.containsKey("z"));
+ assertTrue(map.values().contains("hello"));
+ assertTrue(map.containsValue("hello"));
+ assertEquals(map.size(), 3);
+
+ final Map<Object, Object> newMap = new HashMap<>();
+ newMap.put("foo", 23.0);
+ newMap.put("bar", true);
+ map.putAll(newMap);
+
+ assertEquals(e.eval("obj.foo"), 23.0);
+ assertEquals(e.eval("obj.bar"), true);
+
+ // remove using map method
+ map.remove("foo");
+ assertEquals(e.eval("typeof obj.foo"), "undefined");
+
+ count = 0;
+ e.eval("var arr = [ true, 'hello' ]");
+ map = (Map<Object, Object>) e.get("arr");
+ assertFalse(map.isEmpty());
+ assertTrue(map.containsKey("length"));
+ assertTrue(map.containsValue("hello"));
+ for (final Map.Entry<?, ?> ex : map.entrySet()) {
+ final Object key = ex.getKey();
+ if (key.equals("0")) {
+ assertEquals(ex.getValue(), Boolean.TRUE);
+ count++;
+ } else if (key.equals("1")) {
+ assertEquals(ex.getValue(), "hello");
+ count++;
+ }
+ }
+ assertEquals(count, 2);
+ assertEquals(map.size(), 2);
+
+ // add element
+ map.put("2", "world");
+ assertEquals(map.get("2"), "world");
+ assertEquals(map.size(), 3);
+
+ // remove all
+ map.clear();
+ assertTrue(map.isEmpty());
+ assertEquals(e.eval("typeof arr[0]"), "undefined");
+ assertEquals(e.eval("typeof arr[1]"), "undefined");
+ assertEquals(e.eval("typeof arr[2]"), "undefined");
+ }
+
+ @Test
+ public void jsobjectTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }");
+ JSObject obj = (JSObject) e.get("obj");
+
+ // try basic get on existing properties
+ if (!obj.getMember("bar").equals("hello")) {
+ fail("obj.bar != 'hello'");
+ }
+
+ if (!obj.getSlot(1).equals("world")) {
+ fail("obj[1] != 'world'");
+ }
+
+ if (!obj.call("func", new Object[0]).equals("hello")) {
+ fail("obj.call('func') != 'hello'");
+ }
+
+ // try setting properties
+ obj.setMember("bar", "new-bar");
+ obj.setSlot(1, "new-element-1");
+ if (!obj.getMember("bar").equals("new-bar")) {
+ fail("obj.bar != 'new-bar'");
+ }
+
+ if (!obj.getSlot(1).equals("new-element-1")) {
+ fail("obj[1] != 'new-element-1'");
+ }
+
+ // try adding properties
+ obj.setMember("prop", "prop-value");
+ obj.setSlot(12, "element-12");
+ if (!obj.getMember("prop").equals("prop-value")) {
+ fail("obj.prop != 'prop-value'");
+ }
+
+ if (!obj.getSlot(12).equals("element-12")) {
+ fail("obj[12] != 'element-12'");
+ }
+
+ // delete properties
+ obj.removeMember("prop");
+ if ("prop-value".equals(obj.getMember("prop"))) {
+ fail("obj.prop is not deleted!");
+ }
+
+ // Simple eval tests
+ assertEquals(obj.eval("typeof Object"), "function");
+ assertEquals(obj.eval("'nashorn'.substring(3)"), "horn");
+ } catch (final Exception exp) {
+ exp.printStackTrace();
+ fail(exp.getMessage());
+ }
+ }
+
+ @Test
+ public void scriptObjectMirrorToStringTest() {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ try {
+ Object obj = e.eval("new TypeError('wrong type')");
+ assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+ fail(t.getMessage());
+ }
+
+ try {
+ Object obj = e.eval("function func() { print('hello'); }");
+ assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value");
+ } catch (final Throwable t) {
+ t.printStackTrace();
+ fail(t.getMessage());
+ }
+ }
+
+ @Test
+ public void mirrorNewObjectGlobalFunctionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptEngine e2 = m.getEngineByName("nashorn");
+
+ e.eval("function func() {}");
+ e2.put("foo", e.get("func"));
+ final Object e2global = e2.eval("this");
+ final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo");
+ assertTrue(newObj instanceof ScriptObjectMirror);
+ }
+
+ @Test
+ public void mirrorNewObjectInstanceFunctionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptEngine e2 = m.getEngineByName("nashorn");
+
+ e.eval("function func() {}");
+ e2.put("func", e.get("func"));
+ final Object e2obj = e2.eval("({ foo: func })");
+ final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo");
+ assertTrue(newObj instanceof ScriptObjectMirror);
+ }
+}
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Wed Jul 05 19:10:19 2017 +0200
@@ -32,7 +32,10 @@
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
+import javax.script.ScriptContext;
import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import javax.script.SimpleScriptContext;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import org.testng.annotations.Test;
@@ -196,4 +199,25 @@
}
fail("Cannot find nashorn factory!");
}
+
+ @Test
+ public void globalPerEngineTest() throws ScriptException {
+ final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
+ final String[] options = new String[] { "--global-per-engine" };
+ final ScriptEngine e = fac.getScriptEngine(options);
+
+ e.eval("function foo() {}");
+
+ final ScriptContext newCtx = new SimpleScriptContext();
+ newCtx.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
+
+ // all global definitions shared and so 'foo' should be
+ // visible in new Bindings as well.
+ assertTrue(e.eval("typeof foo", newCtx).equals("function"));
+
+ e.eval("function bar() {}", newCtx);
+
+ // bar should be visible in default context
+ assertTrue(e.eval("typeof bar").equals("function"));
+ }
}
--- a/nashorn/tools/fxshell/jdk/nashorn/tools/FXShell.java Thu Aug 29 16:18:31 2013 -0700
+++ b/nashorn/tools/fxshell/jdk/nashorn/tools/FXShell.java Wed Jul 05 19:10:19 2017 +0200
@@ -32,13 +32,9 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javafx.application.Application;
import javafx.stage.Stage;
import javax.script.Invocable;
-import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
@@ -180,6 +176,7 @@
*
* @return Last evaluation result (discarded.)
*/
+ @SuppressWarnings("resource")
private Object load(String path) {
try {
FileInputStream file = new FileInputStream(path);
--- a/test/Makefile Thu Aug 29 16:18:31 2013 -0700
+++ b/test/Makefile Wed Jul 05 19:10:19 2017 +0200
@@ -49,61 +49,22 @@
fi
endef
-# Test target list for langtools repository
-LANGTOOLS_TEST_LIST = langtools_jtreg
-
-# Test target list for jdk repository
-JDK_ALL_TEST_LIST = \
- jdk_beans1 \
- jdk_io \
- jdk_lang \
- jdk_math \
- jdk_other \
- jdk_net \
- jdk_nio \
- jdk_security1 \
- jdk_text \
- jdk_util \
- jdk_time \
- jdk_awt \
- jdk_beans2 jdk_beans3 \
- jdk_management \
- jdk_jmx \
- jdk_security2 jdk_security3 \
- jdk_rmi \
- jdk_sound \
- jdk_swing \
- jdk_tools \
- jdk_jdi \
- jdk_jfr
-
-# Theses are meta test targets in jdk
-JDK_META_TEST_LIST = jdk_all jdk_default jdk_core
-
-# These are the current jck test targets in the jdk repository
-JDK_JCK7_LIST = jck7devtools jck7compiler jck7runtime
-
# Default test target (core)
-default: jdk_core $(LANGTOOLS_TEST_LIST)
+default: jdk_core langtools_jtreg
# All testing
-all: $(JDK_ALL_TEST_LIST) $(LANGTOOLS_TEST_LIST)
+all: jdk_all langtools_all
# Test targets
-$(LANGTOOLS_TEST_LIST):
- @$(NO_STOPPING)$(call SUBDIR_TEST, $(LANGTOOLS_DIR), $(subst langtools_,,$@))
+langtools_% :
+ @$(NO_STOPPING)$(call SUBDIR_TEST, $(LANGTOOLS_DIR), JT_JAVA=$(PRODUCT_HOME) JTREG_HOME=$(JT_HOME) TEST="$(subst langtools_,,$@)" $(subst langtools_,,$@))
-$(JDK_ALL_TEST_LIST) $(JDK_META_TEST_LIST) $(JDK_JCK7_LIST):
- @$(NO_STOPPING)$(call SUBDIR_TEST, $(JDK_DIR), $@)
-
-clean:
+jdk_% :
+ @$(NO_STOPPING)$(call SUBDIR_TEST, $(JDK_DIR), TEST="$@" $@)
################################################################
# Phony targets (e.g. these are not filenames)
-.PHONY: all clean \
- $(JDK_ALL_TEST_LIST) $(JDK_META_TEST_LIST) $(JDK_JCK7_LIST) \
- $(LANGTOOLS_TEST_LIST)
+.PHONY: all clean
################################################################
-