--- a/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -343,3 +343,4 @@
d00ad2d9049ac60815f70bff445e95df85648bd2 jdk-9+98
f9bcdce2df26678c3fe468130b535c0342c69b89 jdk-9+99
4379223f8806626852c46c52d4e7a27a584b406e jdk-9+100
+80f67512daa15cf37b4825c1c62a675d524d7c49 jdk-9+101
--- a/.hgtags-top-repo Fri Jan 15 23:38:25 2016 +0000
+++ b/.hgtags-top-repo Sat Jan 16 00:28:28 2016 +0000
@@ -343,3 +343,4 @@
48987460c7d49a29013963ee44d090194396bb61 jdk-9+98
7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99
c1f30ac14db0eaff398429c04cd9fab92e1b4b2a jdk-9+100
+c4d72a1620835b5d657b7b6792c2879367d0154f jdk-9+101
--- a/common/autoconf/basics.m4 Fri Jan 15 23:38:25 2016 +0000
+++ b/common/autoconf/basics.m4 Sat Jan 16 00:28:28 2016 +0000
@@ -23,6 +23,74 @@
# questions.
#
+# Create a function/macro that takes a series of named arguments. The call is
+# similar to AC_DEFUN, but the setup of the function looks like this:
+# BASIC_DEFUN_NAMED([MYFUNC], [FOO *BAR], [$@], [
+# ... do something
+# AC_MSG_NOTICE([Value of BAR is ARG_BAR])
+# ])
+# A star (*) in front of a named argument means that it is required and it's
+# presence will be verified. To pass e.g. the first value as a normal indexed
+# argument, use [m4_shift($@)] as the third argument instead of [$@]. These
+# arguments are referenced in the function by their name prefixed by ARG_, e.g.
+# "ARG_FOO".
+#
+# The generated function can be called like this:
+# MYFUNC(FOO: [foo-val], BAR:
+# [
+# $ECHO hello world
+# ])
+#
+#
+# Argument 1: Name of the function to define
+# Argument 2: List of legal named arguments, with a * prefix for required arguments
+# Argument 3: Argument array to treat as named, typically $@
+# Argument 4: The main function body
+AC_DEFUN([BASIC_DEFUN_NAMED],
+[
+ AC_DEFUN($1, [
+ m4_foreach(arg, m4_split($2), [
+ m4_if(m4_bregexp(arg, [^\*]), -1,
+ [
+ m4_set_add(legal_named_args, arg)
+ ],
+ [
+ m4_set_add(legal_named_args, m4_substr(arg, 1))
+ m4_set_add(required_named_args, m4_substr(arg, 1))
+ ]
+ )
+ ])
+
+ m4_foreach([arg], [$3], [
+ m4_define(arg_name, m4_substr(arg, 0, m4_bregexp(arg, [: ])))
+ m4_set_contains(legal_named_args, arg_name, [],[AC_MSG_ERROR([Internal error: arg_name is not a valid named argument to [$1]. Valid arguments are 'm4_set_contents(legal_named_args, [ ])'.])])
+ m4_set_remove(required_named_args, arg_name)
+ m4_set_remove(legal_named_args, arg_name)
+ m4_pushdef([ARG_][]arg_name, m4_substr(arg, m4_incr(m4_incr(m4_bregexp(arg, [: ])))))
+ m4_set_add(defined_args, arg_name)
+ m4_undefine([arg_name])
+ ])
+ m4_set_empty(required_named_args, [], [
+ AC_MSG_ERROR([Internal error: Required named arguments are missing for [$1]. Missing arguments: 'm4_set_contents(required_named_args, [ ])'])
+ ])
+ m4_foreach([arg], m4_indir([m4_dquote]m4_set_listc([legal_named_args])), [
+ m4_pushdef([ARG_][]arg, [])
+ m4_set_add(defined_args, arg)
+ ])
+ m4_set_delete(legal_named_args)
+ m4_set_delete(required_named_args)
+
+ # Execute function body
+ $4
+
+ m4_foreach([arg], m4_indir([m4_dquote]m4_set_listc([defined_args])), [
+ m4_popdef([ARG_][]arg)
+ ])
+
+ m4_set_delete(defined_args)
+ ])
+])
+
# Test if $1 is a valid argument to $3 (often is $JAVA passed as $3)
# If so, then append $1 to $2 \
# Also set JVM_ARG_OK to true/false depending on outcome.
@@ -1122,7 +1190,6 @@
# Move configure.log from current directory to the build output root
if test -e ./configure.log; then
- echo found it
$MV -f ./configure.log "$OUTPUT_ROOT/configure.log" 2> /dev/null
fi
--- a/common/autoconf/flags.m4 Fri Jan 15 23:38:25 2016 +0000
+++ b/common/autoconf/flags.m4 Sat Jan 16 00:28:28 2016 +0000
@@ -425,7 +425,7 @@
# Add runtime stack smashing and undefined behavior checks.
# Not all versions of gcc support -fstack-protector
STACK_PROTECTOR_CFLAG="-fstack-protector-all"
- FLAGS_COMPILER_CHECK_ARGUMENTS([$STACK_PROTECTOR_CFLAG], [], [STACK_PROTECTOR_CFLAG=""])
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$STACK_PROTECTOR_CFLAG], IF_FALSE: [STACK_PROTECTOR_CFLAG=""])
CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
@@ -742,7 +742,7 @@
-I${JDK_TOPDIR}/src/java.base/share/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
- -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
+ -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
# The shared libraries are compiled using the picflag.
@@ -896,17 +896,18 @@
AC_SUBST(LDFLAGS_TESTEXE)
])
-# FLAGS_COMPILER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE],
-# [RUN-IF-FALSE])
+# FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
+# IF_FALSE: [RUN-IF-FALSE])
# ------------------------------------------------------------
# Check that the c and c++ compilers support an argument
-AC_DEFUN([FLAGS_COMPILER_CHECK_ARGUMENTS],
+BASIC_DEFUN_NAMED([FLAGS_COMPILER_CHECK_ARGUMENTS],
+ [*ARGUMENT IF_TRUE IF_FALSE], [$@],
[
- AC_MSG_CHECKING([if compiler supports "$1"])
+ AC_MSG_CHECKING([if compiler supports "ARG_ARGUMENT"])
supports=yes
saved_cflags="$CFLAGS"
- CFLAGS="$CFLAGS $1"
+ CFLAGS="$CFLAGS ARG_ARGUMENT"
AC_LANG_PUSH([C])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int i;]])], [],
[supports=no])
@@ -914,7 +915,7 @@
CFLAGS="$saved_cflags"
saved_cxxflags="$CXXFLAGS"
- CXXFLAGS="$CXXFLAG $1"
+ CXXFLAGS="$CXXFLAG ARG_ARGUMENT"
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int i;]])], [],
[supports=no])
@@ -923,23 +924,26 @@
AC_MSG_RESULT([$supports])
if test "x$supports" = "xyes" ; then
- m4_ifval([$2], [$2], [:])
+ :
+ ARG_IF_TRUE
else
- m4_ifval([$3], [$3], [:])
+ :
+ ARG_IF_FALSE
fi
])
-# FLAGS_LINKER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE],
-# [RUN-IF-FALSE])
+# FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
+# IF_FALSE: [RUN-IF-FALSE])
# ------------------------------------------------------------
# Check that the linker support an argument
-AC_DEFUN([FLAGS_LINKER_CHECK_ARGUMENTS],
+BASIC_DEFUN_NAMED([FLAGS_LINKER_CHECK_ARGUMENTS],
+ [*ARGUMENT IF_TRUE IF_FALSE], [$@],
[
- AC_MSG_CHECKING([if linker supports "$1"])
+ AC_MSG_CHECKING([if linker supports "ARG_ARGUMENT"])
supports=yes
saved_ldflags="$LDFLAGS"
- LDFLAGS="$LDFLAGS $1"
+ LDFLAGS="$LDFLAGS ARG_ARGUMENT"
AC_LANG_PUSH([C])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
[], [supports=no])
@@ -948,9 +952,11 @@
AC_MSG_RESULT([$supports])
if test "x$supports" = "xyes" ; then
- m4_ifval([$2], [$2], [:])
+ :
+ ARG_IF_TRUE
else
- m4_ifval([$3], [$3], [:])
+ :
+ ARG_IF_FALSE
fi
])
@@ -965,14 +971,14 @@
*)
ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
esac
- FLAGS_COMPILER_CHECK_ARGUMENTS([$ZERO_ARCHFLAG], [], [ZERO_ARCHFLAG=""])
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$ZERO_ARCHFLAG], IF_FALSE: [ZERO_ARCHFLAG=""])
AC_SUBST(ZERO_ARCHFLAG)
# Check that the compiler supports -mX (or -qX on AIX) flags
# Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does
- FLAGS_COMPILER_CHECK_ARGUMENTS([${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}],
- [COMPILER_SUPPORTS_TARGET_BITS_FLAG=true],
- [COMPILER_SUPPORTS_TARGET_BITS_FLAG=false])
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}],
+ IF_TRUE: [COMPILER_SUPPORTS_TARGET_BITS_FLAG=true],
+ IF_FALSE: [COMPILER_SUPPORTS_TARGET_BITS_FLAG=false])
AC_SUBST(COMPILER_SUPPORTS_TARGET_BITS_FLAG)
AC_ARG_ENABLE([warnings-as-errors], [AS_HELP_STRING([--disable-warnings-as-errors],
@@ -1013,9 +1019,9 @@
;;
gcc)
# Prior to gcc 4.4, a -Wno-X where X is unknown for that version of gcc will cause an error
- FLAGS_COMPILER_CHECK_ARGUMENTS([-Wno-this-is-a-warning-that-do-not-exist],
- [GCC_CAN_DISABLE_WARNINGS=true],
- [GCC_CAN_DISABLE_WARNINGS=false]
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [-Wno-this-is-a-warning-that-do-not-exist],
+ IF_TRUE: [GCC_CAN_DISABLE_WARNINGS=true],
+ IF_FALSE: [GCC_CAN_DISABLE_WARNINGS=false]
)
if test "x$GCC_CAN_DISABLE_WARNINGS" = "xtrue"; then
DISABLE_WARNING_PREFIX="-Wno-"
@@ -1026,9 +1032,9 @@
# Repeate the check for the BUILD_CC
CC_OLD="$CC"
CC="$BUILD_CC"
- FLAGS_COMPILER_CHECK_ARGUMENTS([-Wno-this-is-a-warning-that-do-not-exist],
- [BUILD_CC_CAN_DISABLE_WARNINGS=true],
- [BUILD_CC_CAN_DISABLE_WARNINGS=false]
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [-Wno-this-is-a-warning-that-do-not-exist],
+ IF_TRUE: [BUILD_CC_CAN_DISABLE_WARNINGS=true],
+ IF_FALSE: [BUILD_CC_CAN_DISABLE_WARNINGS=false]
)
if test "x$BUILD_CC_CAN_DISABLE_WARNINGS" = "xtrue"; then
BUILD_CC_DISABLE_WARNING_PREFIX="-Wno-"
--- a/common/autoconf/generated-configure.sh Fri Jan 15 23:38:25 2016 +0000
+++ b/common/autoconf/generated-configure.sh Sat Jan 16 00:28:28 2016 +0000
@@ -3451,6 +3451,31 @@
# questions.
#
+# Create a function/macro that takes a series of named arguments. The call is
+# similar to AC_DEFUN, but the setup of the function looks like this:
+# BASIC_DEFUN_NAMED([MYFUNC], [FOO *BAR], [$@], [
+# ... do something
+# AC_MSG_NOTICE([Value of BAR is ARG_BAR])
+# ])
+# A star (*) in front of a named argument means that it is required and it's
+# presence will be verified. To pass e.g. the first value as a normal indexed
+# argument, use [m4_shift($@)] as the third argument instead of [$@]. These
+# arguments are referenced in the function by their name prefixed by ARG_, e.g.
+# "ARG_FOO".
+#
+# The generated function can be called like this:
+# MYFUNC(FOO: [foo-val], BAR:
+# [
+# $ECHO hello world
+# ])
+#
+#
+# Argument 1: Name of the function to define
+# Argument 2: List of legal named arguments, with a * prefix for required arguments
+# Argument 3: Argument array to treat as named, typically $@
+# Argument 4: The main function body
+
+
# Test if $1 is a valid argument to $3 (often is $JAVA passed as $3)
# If so, then append $1 to $2 \
# Also set JVM_ARG_OK to true/false depending on outcome.
@@ -3886,20 +3911,24 @@
-# FLAGS_COMPILER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE],
-# [RUN-IF-FALSE])
+# FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
+# IF_FALSE: [RUN-IF-FALSE])
# ------------------------------------------------------------
# Check that the c and c++ compilers support an argument
-# FLAGS_LINKER_CHECK_ARGUMENTS([ARGUMENT], [RUN-IF-TRUE],
-# [RUN-IF-FALSE])
+
+
+# FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [ARGUMENT], IF_TRUE: [RUN-IF-TRUE],
+# IF_FALSE: [RUN-IF-FALSE])
# ------------------------------------------------------------
# Check that the linker support an argument
+
+
#
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -4810,7 +4839,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1452261921
+DATE_WHEN_GENERATED=1452780299
###############################################################################
#
@@ -45358,6 +45387,54 @@
# "-Og" suppported for GCC 4.8 and later
CFLAG_OPTIMIZE_DEBUG_FLAG="-Og"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"$CFLAG_OPTIMIZE_DEBUG_FLAG\"" >&5
$as_echo_n "checking if compiler supports \"$CFLAG_OPTIMIZE_DEBUG_FLAG\"... " >&6; }
supports=yes
@@ -45417,15 +45494,76 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
+ :
HAS_CFLAG_OPTIMIZE_DEBUG=true
else
+ :
HAS_CFLAG_OPTIMIZE_DEBUG=false
fi
+
+
+
+
+
+
+
+
+
+
+
# "-z relro" supported in GNU binutils 2.17 and later
LINKER_RELRO_FLAG="-Wl,-z,relro"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if linker supports \"$LINKER_RELRO_FLAG\"" >&5
$as_echo_n "checking if linker supports \"$LINKER_RELRO_FLAG\"... " >&6; }
supports=yes
@@ -45467,15 +45605,76 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
+ :
HAS_LINKER_RELRO=true
else
+ :
HAS_LINKER_RELRO=false
fi
+
+
+
+
+
+
+
+
+
+
+
# "-z now" supported in GNU binutils 2.11 and later
LINKER_NOW_FLAG="-Wl,-z,now"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if linker supports \"$LINKER_NOW_FLAG\"" >&5
$as_echo_n "checking if linker supports \"$LINKER_NOW_FLAG\"... " >&6; }
supports=yes
@@ -45517,11 +45716,24 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
+ :
HAS_LINKER_NOW=true
else
+ :
HAS_LINKER_NOW=false
fi
+
+
+
+
+
+
+
+
+
+
+
fi
# Check for broken SuSE 'ld' for which 'Only anonymous version tag is allowed
@@ -46842,6 +47054,49 @@
# Not all versions of gcc support -fstack-protector
STACK_PROTECTOR_CFLAG="-fstack-protector-all"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"$STACK_PROTECTOR_CFLAG\"" >&5
$as_echo_n "checking if compiler supports \"$STACK_PROTECTOR_CFLAG\"... " >&6; }
supports=yes
@@ -46902,11 +47157,24 @@
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
:
- else
+
+ else
+ :
STACK_PROTECTOR_CFLAG=""
fi
+
+
+
+
+
+
+
+
+
+
+
CFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
CXXFLAGS_DEBUG_OPTIONS="$STACK_PROTECTOR_CFLAG --param ssp-buffer-size=1"
;;
@@ -47384,6 +47652,49 @@
ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"$ZERO_ARCHFLAG\"" >&5
$as_echo_n "checking if compiler supports \"$ZERO_ARCHFLAG\"... " >&6; }
supports=yes
@@ -47444,15 +47755,76 @@
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
:
- else
+
+ else
+ :
ZERO_ARCHFLAG=""
fi
+
+
+
+
+
+
+
+
+
+
+
# Check that the compiler supports -mX (or -qX on AIX) flags
# Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}\"" >&5
$as_echo_n "checking if compiler supports \"${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}\"... " >&6; }
supports=yes
@@ -47512,13 +47884,26 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
+ :
COMPILER_SUPPORTS_TARGET_BITS_FLAG=true
else
+ :
COMPILER_SUPPORTS_TARGET_BITS_FLAG=false
fi
+
+
+
+
+
+
+
+
+
+
+
# Check whether --enable-warnings-as-errors was given.
if test "${enable_warnings_as_errors+set}" = set; then :
enableval=$enable_warnings_as_errors;
@@ -47565,6 +47950,54 @@
gcc)
# Prior to gcc 4.4, a -Wno-X where X is unknown for that version of gcc will cause an error
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"-Wno-this-is-a-warning-that-do-not-exist\"" >&5
$as_echo_n "checking if compiler supports \"-Wno-this-is-a-warning-that-do-not-exist\"... " >&6; }
supports=yes
@@ -47624,12 +48057,25 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
+ :
GCC_CAN_DISABLE_WARNINGS=true
else
+ :
GCC_CAN_DISABLE_WARNINGS=false
fi
+
+
+
+
+
+
+
+
+
+
+
if test "x$GCC_CAN_DISABLE_WARNINGS" = "xtrue"; then
DISABLE_WARNING_PREFIX="-Wno-"
else
@@ -47640,6 +48086,54 @@
CC_OLD="$CC"
CC="$BUILD_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # Execute function body
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports \"-Wno-this-is-a-warning-that-do-not-exist\"" >&5
$as_echo_n "checking if compiler supports \"-Wno-this-is-a-warning-that-do-not-exist\"... " >&6; }
supports=yes
@@ -47699,12 +48193,25 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
$as_echo "$supports" >&6; }
if test "x$supports" = "xyes" ; then
+ :
BUILD_CC_CAN_DISABLE_WARNINGS=true
else
+ :
BUILD_CC_CAN_DISABLE_WARNINGS=false
fi
+
+
+
+
+
+
+
+
+
+
+
if test "x$BUILD_CC_CAN_DISABLE_WARNINGS" = "xtrue"; then
BUILD_CC_DISABLE_WARNING_PREFIX="-Wno-"
else
@@ -61523,7 +62030,6 @@
# Move configure.log from current directory to the build output root
if test -e ./configure.log; then
- echo found it
$MV -f ./configure.log "$OUTPUT_ROOT/configure.log" 2> /dev/null
fi
--- a/common/autoconf/toolchain.m4 Fri Jan 15 23:38:25 2016 +0000
+++ b/common/autoconf/toolchain.m4 Sat Jan 16 00:28:28 2016 +0000
@@ -75,8 +75,8 @@
# For full static builds, we're overloading the SHARED_LIBRARY
# variables in order to limit the amount of changes required.
# It would be better to remove SHARED and just use LIBRARY and
- # LIBRARY_SUFFIX for libraries that can be built either
- # shared or static and use STATIC_* for libraries that are
+ # LIBRARY_SUFFIX for libraries that can be built either
+ # shared or static and use STATIC_* for libraries that are
# always built statically.
if test "x$STATIC_BUILD" = xtrue; then
SHARED_LIBRARY='lib[$]1.a'
@@ -824,21 +824,21 @@
# "-Og" suppported for GCC 4.8 and later
CFLAG_OPTIMIZE_DEBUG_FLAG="-Og"
- FLAGS_COMPILER_CHECK_ARGUMENTS([$CFLAG_OPTIMIZE_DEBUG_FLAG],
- [HAS_CFLAG_OPTIMIZE_DEBUG=true],
- [HAS_CFLAG_OPTIMIZE_DEBUG=false])
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$CFLAG_OPTIMIZE_DEBUG_FLAG],
+ IF_TRUE: [HAS_CFLAG_OPTIMIZE_DEBUG=true],
+ IF_FALSE: [HAS_CFLAG_OPTIMIZE_DEBUG=false])
# "-z relro" supported in GNU binutils 2.17 and later
LINKER_RELRO_FLAG="-Wl,-z,relro"
- FLAGS_LINKER_CHECK_ARGUMENTS([$LINKER_RELRO_FLAG],
- [HAS_LINKER_RELRO=true],
- [HAS_LINKER_RELRO=false])
+ FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [$LINKER_RELRO_FLAG],
+ IF_TRUE: [HAS_LINKER_RELRO=true],
+ IF_FALSE: [HAS_LINKER_RELRO=false])
# "-z now" supported in GNU binutils 2.11 and later
LINKER_NOW_FLAG="-Wl,-z,now"
- FLAGS_LINKER_CHECK_ARGUMENTS([$LINKER_NOW_FLAG],
- [HAS_LINKER_NOW=true],
- [HAS_LINKER_NOW=false])
+ FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [$LINKER_NOW_FLAG],
+ IF_TRUE: [HAS_LINKER_NOW=true],
+ IF_FALSE: [HAS_LINKER_NOW=false])
fi
# Check for broken SuSE 'ld' for which 'Only anonymous version tag is allowed
--- a/corba/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/corba/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -343,3 +343,4 @@
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
791d0d3ac0138faeb6110bd840a4545bc1950df2 jdk-9+100
+30dfb3bd3d06b4bb80a087babc0d1841edba187b jdk-9+101
--- a/hotspot/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/hotspot/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -503,3 +503,4 @@
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
bdb0acafc63c42e84d9d8195bf2e2b25ee9c3306 jdk-9+100
+9f45d3d57d6948cf526fbc2e2891a9a74ac6941a jdk-9+101
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp Fri Jan 15 23:38:25 2016 +0000
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,7 @@
{ CC"Java_jdk_internal_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterJDKInternalMiscUnsafeMethods) },
{ CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterSunMiscUnsafeMethods) },
{ CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
- { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },
+ { CC"Java_jdk_internal_perf_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },
{ CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) },
#if INCLUDE_JVMCI
{ CC"Java_jdk_vm_ci_runtime_JVMCI_initializeRuntime", NULL, FN_PTR(JVM_GetJVMCIRuntime) },
--- a/hotspot/src/share/vm/prims/perf.cpp Fri Jan 15 23:38:25 2016 +0000
+++ b/hotspot/src/share/vm/prims/perf.cpp Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
#include "runtime/perfMemory.hpp"
/*
- * Implementation of class sun.misc.Perf
+ * Implementation of class jdk.internal.perf.Perf
*/
--- a/jaxp/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -343,3 +343,4 @@
52b01339235f24c93b679bd6b8fb36a1072ad0ac jdk-9+98
52774b544850c791f1d1c67db2601b33739b18c9 jdk-9+99
d45bcd374f6057851e3c2dcd45607cd362afadfa jdk-9+100
+d3e834ff74e724a2b92a558e18e8cbf81c6dbc59 jdk-9+101
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -32,7 +32,6 @@
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
@@ -43,6 +42,7 @@
import static javax.xml.catalog.BaseEntry.CatalogEntryType;
import static javax.xml.catalog.CatalogFeatures.DEFER_TRUE;
import javax.xml.catalog.CatalogFeatures.Feature;
+import static javax.xml.catalog.CatalogMessages.formatMessage;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
@@ -109,25 +109,20 @@
*/
public CatalogImpl(CatalogImpl parent, CatalogFeatures f, String... file) throws CatalogException {
super(CatalogEntryType.CATALOG);
- this.parent = parent;
- if (parent == null) {
- level = 0;
- } else {
- level = parent.level + 1;
+ if (f == null) {
+ throw new NullPointerException(
+ formatMessage(CatalogMessages.ERR_NULL_ARGUMENT, new Object[]{"CatalogFeatures"}));
}
- if (f == null) {
- this.features = CatalogFeatures.defaults();
- } else {
- this.features = f;
+
+ if (file.length > 0) {
+ CatalogMessages.reportNPEOnNull("The path to the catalog file", file[0]);
}
- setPrefer(features.get(Feature.PREFER));
- setDeferred(features.get(Feature.DEFER));
- setResolve(features.get(Feature.RESOLVE));
+
+ init(parent, f);
//Path of catalog files
String[] catalogFile = file;
- if (level == 0
- && (file == null || (file.length == 0 || file[0] == null))) {
+ if (level == 0 && file.length == 0) {
String files = features.get(Feature.FILES);
if (files != null) {
catalogFile = files.split(";[ ]*");
@@ -166,6 +161,23 @@
}
}
+ private void init(CatalogImpl parent, CatalogFeatures f) {
+ this.parent = parent;
+ if (parent == null) {
+ level = 0;
+ } else {
+ level = parent.level + 1;
+ }
+ if (f == null) {
+ this.features = CatalogFeatures.defaults();
+ } else {
+ this.features = f;
+ }
+ setPrefer(features.get(Feature.PREFER));
+ setDeferred(features.get(Feature.DEFER));
+ setResolve(features.get(Feature.RESOLVE));
+ }
+
/**
* Resets the Catalog instance to its initial state.
*/
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogManager.java Sat Jan 16 00:28:28 2016 +0000
@@ -38,33 +38,38 @@
}
/**
- * Creates a Catalog object using the specified feature settings and path to
- * a catalog file. If the features is null, the default features will be used.
- * If the path is empty, System property {@code javax.xml.catalog.files} will
- * be read to locate the initial list of catalog files.
+ * Creates a {@code Catalog} object using the specified feature settings and
+ * path to one or more catalog files.
* <p>
- * If more than one catalog files are specified through the path argument or
+ * If {@code paths} is empty, system property {@code javax.xml.catalog.files}
+ * will be read to locate the initial list of catalog files.
+ * <p>
+ * If more than one catalog files are specified through the paths argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
+ * <p>
+ * As specified in
+ * <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
+ * XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
+ * No error will be reported. In case all entries are invalid, the resolver
+ * will return as no mapping is found.
*
* @param features the catalog features
- * @param path path(s) to one or more catalogs.
+ * @param paths path(s) to one or more catalogs.
*
- * @return a catalog instance
- * @throws CatalogException If no catalog can be found whether through the
- * specified path or the System property {@code javax.xml.catalog.files}, or
- * an error occurs while parsing the catalog
+ * @return an instance of a {@code Catalog}
+ * @throws CatalogException If an error occurs while parsing the catalog
*/
- public static Catalog catalog(CatalogFeatures features, String... path) {
- return new CatalogImpl(features, path);
+ public static Catalog catalog(CatalogFeatures features, String... paths) {
+ return new CatalogImpl(features, paths);
}
/**
- * Creates an instance of a CatalogResolver using the specified catalog.
+ * Creates an instance of a {@code CatalogResolver} using the specified catalog.
*
* @param catalog the catalog instance
- * @return an instance of a CatalogResolver
+ * @return an instance of a {@code CatalogResolver}
*/
public static CatalogResolver catalogResolver(Catalog catalog) {
if (catalog == null) CatalogMessages.reportNPEOnNull("catalog", null);
@@ -72,10 +77,10 @@
}
/**
- * Creates an instance of a CatalogUriResolver using the specified catalog.
+ * Creates an instance of a {@code CatalogUriResolver} using the specified catalog.
*
* @param catalog the catalog instance
- * @return an instance of a CatalogResolver
+ * @return an instance of a {@code CatalogResolver}
*/
public static CatalogUriResolver catalogUriResolver(Catalog catalog) {
if (catalog == null) CatalogMessages.reportNPEOnNull("catalog", null);
@@ -83,50 +88,60 @@
}
/**
- * Creates an instance of a CatalogResolver using the specified feature settings
- * and path to a catalog file. If the features is null, the default features will
- * be used. If the path is empty, System property {@code javax.xml.catalog.files}
+ * Creates an instance of a {@code CatalogResolver} using the specified feature
+ * settings and path to one or more catalog files.
+ * <p>
+ * If {@code paths} is empty, system property {@code javax.xml.catalog.files}
* will be read to locate the initial list of catalog files.
* <p>
- * If more than one catalog files are specified through the path argument or
+ * If more than one catalog files are specified through the paths argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
+ * <p>
+ * As specified in
+ * <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
+ * XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
+ * No error will be reported. In case all entries are invalid, the resolver
+ * will return as no mapping is found.
*
* @param features the catalog features
- * @param path the path(s) to one or more catalogs
+ * @param paths the path(s) to one or more catalogs
*
- * @return an instance of a CatalogResolver
- * @throws CatalogException If no catalog can be found whether through the
- * specified path or the System property {@code javax.xml.catalog.files}, or
- * an error occurs while parsing the catalog
+ * @return an instance of a {@code CatalogResolver}
+ * @throws CatalogException If an error occurs while parsing the catalog
*/
- public static CatalogResolver catalogResolver(CatalogFeatures features, String... path) {
- Catalog catalog = catalog(features, path);
+ public static CatalogResolver catalogResolver(CatalogFeatures features, String... paths) {
+ Catalog catalog = catalog(features, paths);
return new CatalogResolverImpl(catalog);
}
/**
- * Creates an instance of a CatalogUriResolver using the specified feature settings
- * and path to a catalog file. If the features is null, the default features will
- * be used. If the path is empty, System property {@code javax.xml.catalog.files}
+ * Creates an instance of a {@code CatalogUriResolver} using the specified
+ * feature settings and path to one or more catalog files.
+ * <p>
+ * If {@code paths} is empty, system property {@code javax.xml.catalog.files}
* will be read to locate the initial list of catalog files.
* <p>
- * If more than one catalog files are specified through the path argument or
+ * If more than one catalog files are specified through the paths argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
+ * <p>
+ * As specified in
+ * <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
+ * XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
+ * No error will be reported. In case all entries are invalid, the resolver
+ * will return as no mapping is found.
*
* @param features the catalog features
- * @param path the path(s) to one or more catalogs
+ * @param paths the path(s) to one or more catalogs
*
- * @return an instance of a CatalogResolver
- * @throws CatalogException If no catalog can be found whether through the
- * specified path or the System property {@code javax.xml.catalog.files}, or
- * an error occurs while parsing the catalog
+ * @return an instance of a {@code CatalogUriResolver}
+ * @throws CatalogException If an error occurs while parsing the catalog
*/
- public static CatalogUriResolver catalogUriResolver(CatalogFeatures features, String... path) {
- Catalog catalog = catalog(features, path);
+ public static CatalogUriResolver catalogUriResolver(CatalogFeatures features, String... paths) {
+ Catalog catalog = catalog(features, paths);
return new CatalogUriResolverImpl(catalog);
}
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/CatalogUriResolver.java Sat Jan 16 00:28:28 2016 +0000
@@ -43,9 +43,9 @@
* absolute if the absolute URI is required
*
* @return a {@link javax.xml.transform.Source} object if a mapping is found.
- * If no mapping is found, returns a {@link javax.xml.transform.Source} object
- * containing an empty {@link java.io.Reader} if the
- * {@code javax.xml.catalog.resolve} property is set to {@code ignore};
+ * If no mapping is found, returns an empty {@link javax.xml.transform.Source}
+ * object if the {@code javax.xml.catalog.resolve} property is set to
+ * {@code ignore};
* returns a {@link javax.xml.transform.Source} object with the original URI
* (href, or href resolved with base if base is not null) if the
* {@code javax.xml.catalog.resolve} property is set to {@code continue}.
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/RewriteSystem.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/RewriteSystem.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -72,6 +72,7 @@
public String getSystemIdStartString () {
return systemIdStartString;
}
+
/**
* Get the rewritePrefix attribute.
* @return The rewritePrefix attribute value.
@@ -80,7 +81,6 @@
return rewritePrefix;
}
-
/**
* Try to match the specified systemId with the entry. Return the match if it
* is successful and the length of the systemIdStartString is longer than the
@@ -91,14 +91,20 @@
* @return The replacement URI if the match is successful, null if not.
*/
public String match(String systemId, int currentMatch) {
- if (systemIdStartString.length() <= systemId.length() &&
+ if (systemIdStartString.length() < systemId.length() &&
systemIdStartString.equals(systemId.substring(0, systemIdStartString.length()))) {
if (currentMatch < systemIdStartString.length()) {
String prefix = rewritePrefix.toExternalForm();
- if (!prefix.endsWith(SLASH) && !systemId.startsWith(SLASH)) {
- return prefix + SLASH + systemId.substring(systemIdStartString.length());
+ String sysId;
+ if (systemIdStartString.endsWith(SLASH)) {
+ sysId = systemId.substring(systemIdStartString.length());
} else {
- return prefix + systemId.substring(systemIdStartString.length());
+ sysId = systemId.substring(systemIdStartString.length() + 1);
+ }
+ if (prefix.endsWith(SLASH)) {
+ return prefix + sysId;
+ } else {
+ return prefix + SLASH + sysId;
}
}
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/catalog/RewriteUri.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/catalog/RewriteUri.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -72,6 +72,7 @@
public String getURIStartString () {
return uriStartString;
}
+
/**
* Get the rewritePrefix attribute.
* @return The rewritePrefix attribute value.
@@ -91,14 +92,20 @@
*/
@Override
public String match(String systemId, int currentMatch) {
- if (uriStartString.length() <= systemId.length() &&
+ if (uriStartString.length() < systemId.length() &&
uriStartString.equals(systemId.substring(0, uriStartString.length()))) {
if (currentMatch < uriStartString.length()) {
String prefix = rewritePrefix.toExternalForm();
- if (!prefix.endsWith(SLASH) && !systemId.startsWith(SLASH)) {
- return prefix + SLASH + systemId.substring(uriStartString.length());
+ String sysId;
+ if (uriStartString.endsWith(SLASH)) {
+ sysId = systemId.substring(uriStartString.length());
} else {
- return prefix + systemId.substring(uriStartString.length());
+ sysId = systemId.substring(uriStartString.length() + 1);
+ }
+ if (prefix.endsWith(SLASH)) {
+ return prefix + sysId;
+ } else {
+ return prefix + SLASH + sysId;
}
}
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/Source.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/Source.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -52,4 +52,17 @@
* if setSystemId was not called.
*/
public String getSystemId();
+
+ /**
+ * Indicates whether the {@code Source} object is empty. Empty means
+ * that there is no input available from this Source.
+ *
+ * @implSpec The default implementation of this method throws
+ * {@link UnsupportedOperationException}.
+ *
+ * @return true if the {@code Source} object is empty, false otherwise
+ */
+ default boolean isEmpty() {
+ throw new UnsupportedOperationException("The isEmpty method is not supported.");
+ }
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/dom/DOMSource.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/dom/DOMSource.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -122,6 +122,7 @@
*
* @param systemID Base URL for this DOM tree.
*/
+ @Override
public void setSystemId(String systemID) {
this.systemID = systemID;
}
@@ -132,7 +133,25 @@
*
* @return Base URL for this DOM tree.
*/
+ @Override
public String getSystemId() {
return this.systemID;
}
+
+ /**
+ * Indicates whether the {@code DOMSource} object is empty. Empty is
+ * defined as follows:
+ * <ul>
+ * <li>if the system identifier and node are {@code null};
+ * </li>
+ * <li>if the system identifier is null, and the {@code node} has no child nodes.
+ * </li>
+ * </ul>
+ *
+ * @return true if the {@code DOMSource} object is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return systemID == null && (node == null || !node.hasChildNodes());
+ }
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/sax/SAXSource.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/sax/SAXSource.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -147,6 +147,7 @@
*
* @param systemId The system identifier as a URI string.
*/
+ @Override
public void setSystemId(String systemId) {
if (null == inputSource) {
@@ -162,6 +163,7 @@
*
* @return Base URL for the <code>Source</code>, or <code>null</code>.
*/
+ @Override
public String getSystemId() {
if (inputSource == null) {
@@ -207,4 +209,22 @@
return null;
}
}
+
+ /**
+ * Indicates whether the {@code SAXSource} object is empty. Empty is
+ * defined as follows:
+ * <ul>
+ * <li>if the system identifier and {@code InputSource} are {@code null};
+ * </li>
+ * <li>if the system identifier is {@code null}, and the {@code InputSource}
+ * is empty.
+ * </li>
+ * </ul>
+ *
+ * @return true if the {@code SAXSource} object is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return getSystemId() == null && (inputSource == null || inputSource.isEmpty());
+ }
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/stax/StAXSource.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/stax/StAXSource.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -209,6 +209,7 @@
* @throws UnsupportedOperationException Is <strong>always</strong>
* thrown by this method.
*/
+ @Override
public void setSystemId(final String systemId) {
throw new UnsupportedOperationException(
@@ -229,8 +230,21 @@
*
* @return System identifier used by this <code>StAXSource</code>.
*/
+ @Override
public String getSystemId() {
return systemId;
}
+
+ /**
+ * Indicates whether the {@code StAXSource} object is empty. Since a
+ * {@code StAXSource} object can never be empty, this method always returns
+ * false.
+ *
+ * @return unconditionally false
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
}
--- a/jaxp/src/java.xml/share/classes/javax/xml/transform/stream/StreamSource.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/transform/stream/StreamSource.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,10 @@
package javax.xml.transform.stream;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -233,6 +235,7 @@
*
* @param systemId The system identifier as a URL string.
*/
+ @Override
public void setSystemId(String systemId) {
this.systemId = systemId;
}
@@ -243,6 +246,7 @@
* @return The system identifier that was set with setSystemId, or null
* if setSystemId was not called.
*/
+ @Override
public String getSystemId() {
return systemId;
}
@@ -259,6 +263,59 @@
this.systemId = f.toURI().toASCIIString();
}
+ /**
+ * Indicates whether the {@code StreamSource} object is empty. Empty is
+ * defined as follows:
+ * <ul>
+ * <li>All of the input sources, including the public identifier, system
+ * identifier, byte stream, and character stream, are {@code null}.
+ * </li>
+ * <li>The public identifier and system identifier are {@code null}, and
+ * byte and character stream are either {@code null} or contain no byte or
+ * character.
+ * <p>
+ * Note that this method will reset the byte stream if it is provided, or
+ * the character stream if the byte stream is not provided.
+ * </li>
+ * </ul>
+ * <p>
+ * In case of error while checking the byte or character stream, the method
+ * will return false to allow the XML processor to handle the error.
+ *
+ * @return true if the {@code StreamSource} object is empty, false otherwise
+ */
+ @Override
+ public boolean isEmpty() {
+ return (publicId == null && systemId == null && isStreamEmpty());
+ }
+
+ private boolean isStreamEmpty() {
+ boolean empty = true;
+ try {
+ if (inputStream != null) {
+ inputStream.reset();
+ int bytesRead = inputStream.available();
+ if (bytesRead > 0) {
+ return false;
+ }
+ }
+
+ if (reader != null) {
+ reader.reset();
+ int c = reader.read();
+ reader.reset();
+ if (c != -1) {
+ return false;
+ }
+ }
+ } catch (IOException ex) {
+ //in case of error, return false
+ return false;
+ }
+
+ return empty;
+ }
+
//////////////////////////////////////////////////////////////////////
// Internal state.
//////////////////////////////////////////////////////////////////////
--- a/jaxp/src/java.xml/share/classes/org/xml/sax/InputSource.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/org/xml/sax/InputSource.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
package org.xml.sax;
+import java.io.IOException;
import java.io.Reader;
import java.io.InputStream;
@@ -343,8 +344,57 @@
return characterStream;
}
+ /**
+ * Indicates whether the {@code InputSource} object is empty. Empty is
+ * defined as follows:
+ * <ul>
+ * <li>All of the input sources, including the public identifier, system
+ * identifier, byte stream, and character stream, are {@code null}.
+ * </li>
+ * <li>The public identifier and system identifier are {@code null}, and
+ * byte and character stream are either {@code null} or contain no byte
+ * or character.
+ * <p>
+ * Note that this method will reset the byte stream if it is provided, or
+ * the character stream if the byte stream is not provided.
+ * </li>
+ * </ul>
+ * <p>
+ * In case of error while checking the byte or character stream, the method
+ * will return false to allow the XML processor to handle the error.
+ *
+ * @return true if the {@code InputSource} object is empty, false otherwise
+ */
+ public boolean isEmpty() {
+ return (publicId == null && systemId == null && isStreamEmpty());
+ }
+ private boolean isStreamEmpty() {
+ boolean empty = true;
+ try {
+ if (byteStream != null) {
+ byteStream.reset();
+ int bytesRead = byteStream.available();
+ if (bytesRead > 0) {
+ return false;
+ }
+ }
+ if (characterStream != null) {
+ characterStream.reset();
+ int c = characterStream.read();
+ characterStream.reset();
+ if (c != -1) {
+ return false;
+ }
+ }
+ } catch (IOException ex) {
+ //in case of error, return false
+ return false;
+ }
+
+ return empty;
+ }
////////////////////////////////////////////////////////////////////
// Internal state.
////////////////////////////////////////////////////////////////////
--- a/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/catalog/DeferFeatureTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -56,23 +56,14 @@
@DataProvider(name = "catalog-countOfLoadedCatalogFile")
private Object[][] data() {
- return new Object[][] {
- // This catalog specifies null catalog explicitly,
- // and the count of loaded catalogs should be 0.
- { createCatalog(null), 0 },
-
- // This catalog specifies null catalog implicitly,
- // and the count of loaded catalogs should be 0.
- { createCatalog(CatalogFeatures.defaults()), 0 },
-
- // This catalog loads null catalog with true DEFER,
- // and the count of loaded catalogs should be 0.
- { createCatalog(createDeferFeature(DEFER_TRUE)), 0 },
-
- // This catalog loads null catalog with false DEFER.
- // It should load all of none-current catalogs and the
- // count of loaded catalogs should be 3.
- { createCatalog(createDeferFeature(DEFER_FALSE)), 3 } };
+ return new Object[][]{
+ // By default, alternative catalogs are not loaded.
+ {createCatalog(CatalogFeatures.defaults()), 0},
+ // Alternative catalogs are not loaded when DEFER is set to true.
+ {createCatalog(createDeferFeature(DEFER_TRUE)), 0},
+ // The 3 alternative catalogs are not pre-loaded
+ //when DEFER is set to false.
+ {createCatalog(createDeferFeature(DEFER_FALSE)), 3}};
}
private CatalogFeatures createDeferFeature(String defer) {
--- a/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/catalog/CatalogTestUtils.java Sat Jan 16 00:28:28 2016 +0000
@@ -83,7 +83,7 @@
* Creates CatalogResolver with a set of catalogs.
*/
static CatalogResolver catalogResolver(String... catalogName) {
- return catalogResolver(null, catalogName);
+ return catalogResolver(CatalogFeatures.defaults(), catalogName);
}
/*
@@ -91,15 +91,16 @@
*/
static CatalogResolver catalogResolver(CatalogFeatures features,
String... catalogName) {
- return CatalogManager.catalogResolver(features,
- getCatalogPaths(catalogName));
+ return (catalogName == null) ?
+ CatalogManager.catalogResolver(features) :
+ CatalogManager.catalogResolver(features, getCatalogPaths(catalogName));
}
/*
* Creates catalogUriResolver with a set of catalogs.
*/
static CatalogUriResolver catalogUriResolver(String... catalogName) {
- return catalogUriResolver(null, catalogName);
+ return catalogUriResolver(CatalogFeatures.defaults(), catalogName);
}
/*
@@ -107,8 +108,9 @@
*/
static CatalogUriResolver catalogUriResolver(
CatalogFeatures features, String... catalogName) {
- return CatalogManager.catalogUriResolver(features,
- getCatalogPaths(catalogName));
+ return (catalogName == null) ?
+ CatalogManager.catalogUriResolver(features) :
+ CatalogManager.catalogUriResolver(features, getCatalogPaths(catalogName));
}
// Gets the paths of the specified catalogs.
--- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Sat Jan 16 00:28:28 2016 +0000
@@ -89,7 +89,7 @@
/**
* BOM table for storing BOM header.
*/
- private final static Map<String, byte[]> bom = new HashMap();
+ private final static Map<String, byte[]> bom = new HashMap<>();
/**
* Initialize all BOM headers.
--- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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,14 +27,13 @@
import javax.xml.catalog.CatalogFeatures.Feature;
import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver;
+import javax.xml.catalog.CatalogUriResolver;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
-import static jaxp.library.JAXPTestUtilities.getPathByClassName;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
@@ -42,12 +41,66 @@
import org.xml.sax.ext.DefaultHandler2;
/*
- * @bug 8081248
+ * @bug 8081248, 8144966, 8146606
* @summary Tests basic Catalog functions.
*/
public class CatalogTest {
/*
+ @bug 8146606
+ Verifies that the resulting systemId does not contain duplicate slashes
+ */
+ public void testRewriteSystem() {
+ String catalog = getClass().getResource("rewriteCatalog.xml").getFile();
+
+ try {
+ CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
+ String actualSystemId = resolver.resolveEntity(null, "http://remote.com/dtd/book.dtd").getSystemId();
+ Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes");
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+
+ }
+
+ /*
+ @bug 8146606
+ Verifies that the resulting systemId does not contain duplicate slashes
+ */
+ public void testRewriteUri() {
+ String catalog = getClass().getResource("rewriteCatalog.xml").getFile();
+
+ try {
+
+ CatalogUriResolver resolver = CatalogManager.catalogUriResolver(CatalogFeatures.defaults(), catalog);
+ String actualSystemId = resolver.resolve("http://remote.com/import/import.xsl", null).getSystemId();
+ Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes");
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ /*
+ @bug 8144966
+ Verifies that passing null as CatalogFeatures will result in a NPE.
+ */
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testFeatureNull() {
+ CatalogResolver resolver = CatalogManager.catalogResolver(null, "");
+
+ }
+
+ /*
+ @bug 8144966
+ Verifies that passing null as the path will result in a NPE.
+ */
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testPathNull() {
+ String path = null;
+ CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), path);
+ }
+
+ /*
Tests basic catalog feature by using a CatalogResolver instance to
resolve a DTD reference to a locally specified DTD file. If the resolution
is successful, the Handler shall return the value of the entity reference
@@ -61,7 +114,7 @@
}
String url = getClass().getResource(xml).getFile();
try {
- CatalogResolver cr = CatalogManager.catalogResolver(null, catalog);
+ CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
XMLReader reader = saxParser.getXMLReader();
reader.setEntityResolver(cr);
MyHandler handler = new MyHandler(saxParser);
@@ -84,7 +137,7 @@
String test = "testInvalidCatalog";
try {
- CatalogResolver resolver = CatalogManager.catalogResolver(null, catalog);
+ CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
String actualSystemId = resolver.resolveEntity(null, "http://remote/xml/dtd/sys/alice/docAlice.dtd").getSystemId();
} catch (Exception e) {
String msg = e.getMessage();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/rewriteCatalog.xml Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<catalog
+ xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+
+ <rewriteSystem systemIdStartString="http://remote.com/dtd"
+ rewritePrefix="file:///share/docbook/docbook/pass"/>
+
+ <rewriteURI uriStartString="http://remote.com/import" rewritePrefix="file:///local/import" />
+
+</catalog>
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/Sources.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2016, 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 common;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamSource;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/*
+ * @bug 8144967
+ * @summary Tests related to the javax.xml.transform.Source
+ * and org.xml.sax.InputSource
+ */
+public class Sources {
+
+ /**
+ * @bug 8144967
+ * Tests whether a Source object is empty
+ * @param source the Source object
+ */
+ @Test(dataProvider = "emptySources")
+ public void testIsEmpty(Source source) {
+ Assert.assertTrue(source.isEmpty(), "The source is not empty");
+ }
+
+ /**
+ * @bug 8144967
+ * Tests that the source is not empty
+ * @param source the Source object
+ */
+ @Test(dataProvider = "nonEmptySources")
+ public void testIsNotEmpty(Source source) {
+ Assert.assertTrue(!source.isEmpty(), "The source is empty");
+ }
+
+ /**
+ * @bug 8144967
+ * Tests whether an InputSource object is empty
+ * @param source the InputSource object
+ */
+ @Test(dataProvider = "emptyInputSource")
+ public void testISIsEmpty(InputSource source) {
+ Assert.assertTrue(source.isEmpty(), "The source is not empty");
+ }
+
+ /*
+ * DataProvider: sources that are empty
+ */
+ @DataProvider(name = "emptySources")
+ Object[][] getSources() throws URISyntaxException {
+
+ return new Object[][]{
+ {new DOMSource()},
+ {new DOMSource(getDocument())},
+ {new SAXSource()},
+ {new SAXSource(new InputSource(new StringReader("")))},
+ {new SAXSource(getXMLReader(), new InputSource(new StringReader("")))},
+ {new StreamSource()},
+ {new StreamSource(new ByteArrayInputStream("".getBytes()))},
+ {new StreamSource(new StringReader(""))},
+ {new StreamSource(new StringReader(""), null)},
+ {new StreamSource((String) null)}
+ };
+ }
+
+ /*
+ * DataProvider: sources that are not empty
+ */
+ @DataProvider(name = "nonEmptySources")
+ Object[][] getSourcesEx() throws URISyntaxException {
+ StAXSource ss = null;
+ try {
+ ss = new StAXSource(getXMLEventReader());
+ } catch (XMLStreamException ex) {}
+
+ return new Object[][]{
+ //This will set a non-null systemId on the resulting StreamSource
+ {new StreamSource(new File(""))},
+ //Can't tell because XMLStreamReader is a pull parser, cursor advancement
+ //would have been required in order to examine the reader.
+ {new StAXSource(getXMLStreamReader())},
+ {ss}
+ };
+ }
+
+ /*
+ * DataProvider: sources that are empty
+ */
+ @DataProvider(name = "emptyInputSource")
+ Object[][] getInputSources() throws URISyntaxException {
+ byte[] utf8Bytes = null;
+ try {
+ utf8Bytes = "".getBytes("UTF8");
+ } catch (UnsupportedEncodingException ex) {
+ throw new RuntimeException(ex.getMessage());
+ }
+ return new Object[][]{
+ {new InputSource()},
+ {new InputSource(new ByteArrayInputStream(utf8Bytes))},
+ {new InputSource(new StringReader(""))},
+ {new InputSource((String) null)}
+ };
+ }
+
+ /**
+ * Returns an instance of Document.
+ *
+ * @return an instance of Document.
+ */
+ private Document getDocument() {
+ Document doc = null;
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ doc = dbf.newDocumentBuilder().newDocument();
+ } catch (ParserConfigurationException ex) {}
+ return doc;
+ }
+
+ /**
+ * Returns an instance of XMLReader.
+ *
+ * @return an instance of XMLReader.
+ */
+ private XMLReader getXMLReader() {
+ XMLReader reader = null;
+ try {
+ reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+ } catch (ParserConfigurationException | SAXException ex) {}
+ return reader;
+ }
+
+ /**
+ * Returns an instance of XMLStreamReader.
+ *
+ * @return an instance of XMLStreamReader.
+ */
+ private XMLStreamReader getXMLStreamReader() {
+ XMLStreamReader r = null;
+ try {
+ XMLInputFactory xif = XMLInputFactory.newInstance();
+ r = xif.createXMLStreamReader(new ByteArrayInputStream("".getBytes()));
+ } catch (XMLStreamException ex) {}
+
+ return r;
+ }
+
+ /**
+ * Returns an instance of XMLEventReader.
+ *
+ * @return an instance of XMLEventReader.
+ */
+ private XMLEventReader getXMLEventReader() {
+ XMLEventReader r = null;
+ try {
+ r = XMLInputFactory.newInstance().createXMLEventReader(
+ new ByteArrayInputStream("".getBytes()));
+ } catch (XMLStreamException ex) {}
+
+ return r;
+ }
+}
--- a/jaxws/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/jaxws/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -346,3 +346,4 @@
67c84077edc3db6b24998b35970b37c01aae985e jdk-9+98
97b31ca0dd77483cf20ff99a033a455673639578 jdk-9+99
d0a97e57d2336238edf6a4cd60aafe67deb7258d jdk-9+100
+3e99318616da903e0dc8f07f9f9203dc1bd49921 jdk-9+101
--- a/jdk/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -343,3 +343,4 @@
f86ee68d1107dad41a27efc34306e0e56244a12e jdk-9+98
e1a789be1535741274c9779f4d4ca3495196b5c3 jdk-9+99
3d452840f48299a36842760d17c0c8402f0e1266 jdk-9+100
+5e8370fb3ed925335164afe340d1e54beab2d4d5 jdk-9+101
--- a/jdk/make/gendata/GendataBreakIterator.gmk Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/make/gendata/GendataBreakIterator.gmk Sat Jan 16 00:28:28 2016 +0000
@@ -48,7 +48,6 @@
$(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR, \
SETUP := GENERATE_OLDBYTECODE, \
SRC := $(TEXT_SRCDIR), \
- INCLUDES := $(TEXT_PKG), \
INCLUDE_FILES := $(TEXT_SOURCES), \
BIN := $(BREAK_ITERATOR_CLASSES)))
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Sat Jan 16 00:28:28 2016 +0000
@@ -50,6 +50,8 @@
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
+
+import jdk.internal.perf.PerfCounter;
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.reflect.CallerSensitive;
@@ -423,9 +425,9 @@
c = findClass(name);
// this is the defining class loader; record the stats
- sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
- sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
- sun.misc.PerfCounter.getFindClasses().increment();
+ PerfCounter.getParentDelegationTime().addTime(t1 - t0);
+ PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
+ PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Sat Jan 16 00:28:28 2016 +0000
@@ -61,6 +61,9 @@
* local variable array is an {@link PrimitiveValue} object;
* otherwise, the element is an {@code Object}.
*
+ * <p>The returned array may contain null entries if a local variable is not
+ * live.
+ *
* @return the local variable array of this stack frame.
*/
public Object[] getLocals();
--- a/jdk/src/java.base/share/classes/java/lang/System.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Sat Jan 16 00:28:28 2016 +0000
@@ -1535,6 +1535,8 @@
* @return an instance of {@link Logger} that can be used by the calling
* class.
* @throws NullPointerException if {@code name} is {@code null}.
+ *
+ * @since 9
*/
@CallerSensitive
public static Logger getLogger(String name) {
@@ -1572,6 +1574,8 @@
* resource bundle for message localization.
* @throws NullPointerException if {@code name} is {@code null} or
* {@code bundle} is {@code null}.
+ *
+ * @since 9
*/
@CallerSensitive
public static Logger getLogger(String name, ResourceBundle bundle) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -3120,6 +3120,8 @@
MethodHandle handler) {
MethodType ttype = target.type();
MethodType htype = handler.type();
+ if (!Throwable.class.isAssignableFrom(exType))
+ throw new ClassCastException(exType.getName());
if (htype.parameterCount() < 1 ||
!htype.parameterType(0).isAssignableFrom(exType))
throw newIllegalArgumentException("handler does not accept exception type "+exType);
--- a/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Cleaner.java Sat Jan 16 00:28:28 2016 +0000
@@ -28,7 +28,7 @@
import java.util.Objects;
import java.util.concurrent.ThreadFactory;
-import jdk.internal.misc.CleanerImpl;
+import jdk.internal.ref.CleanerImpl;
/**
* {@code Cleaner} manages a set of object references and corresponding cleaning actions.
--- a/jdk/src/java.base/share/classes/java/net/SocketImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/SocketImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -376,19 +376,23 @@
* @since 1.9
*/
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (name == StandardSocketOptions.SO_KEEPALIVE) {
+ if (name == StandardSocketOptions.SO_KEEPALIVE &&
+ (getSocket() != null)) {
setOption(SocketOptions.SO_KEEPALIVE, value);
- } else if (name == StandardSocketOptions.SO_SNDBUF) {
+ } else if (name == StandardSocketOptions.SO_SNDBUF &&
+ (getSocket() != null)) {
setOption(SocketOptions.SO_SNDBUF, value);
} else if (name == StandardSocketOptions.SO_RCVBUF) {
setOption(SocketOptions.SO_RCVBUF, value);
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
setOption(SocketOptions.SO_REUSEADDR, value);
- } else if (name == StandardSocketOptions.SO_LINGER) {
+ } else if (name == StandardSocketOptions.SO_LINGER &&
+ (getSocket() != null)) {
setOption(SocketOptions.SO_LINGER, value);
} else if (name == StandardSocketOptions.IP_TOS) {
setOption(SocketOptions.IP_TOS, value);
- } else if (name == StandardSocketOptions.TCP_NODELAY) {
+ } else if (name == StandardSocketOptions.TCP_NODELAY &&
+ (getSocket() != null)) {
setOption(SocketOptions.TCP_NODELAY, value);
} else {
throw new UnsupportedOperationException("unsupported option");
@@ -412,19 +416,23 @@
*/
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (name == StandardSocketOptions.SO_KEEPALIVE) {
+ if (name == StandardSocketOptions.SO_KEEPALIVE &&
+ (getSocket() != null)) {
return (T)getOption(SocketOptions.SO_KEEPALIVE);
- } else if (name == StandardSocketOptions.SO_SNDBUF) {
+ } else if (name == StandardSocketOptions.SO_SNDBUF &&
+ (getSocket() != null)) {
return (T)getOption(SocketOptions.SO_SNDBUF);
} else if (name == StandardSocketOptions.SO_RCVBUF) {
return (T)getOption(SocketOptions.SO_RCVBUF);
} else if (name == StandardSocketOptions.SO_REUSEADDR) {
return (T)getOption(SocketOptions.SO_REUSEADDR);
- } else if (name == StandardSocketOptions.SO_LINGER) {
+ } else if (name == StandardSocketOptions.SO_LINGER &&
+ (getSocket() != null)) {
return (T)getOption(SocketOptions.SO_LINGER);
} else if (name == StandardSocketOptions.IP_TOS) {
return (T)getOption(SocketOptions.IP_TOS);
- } else if (name == StandardSocketOptions.TCP_NODELAY) {
+ } else if (name == StandardSocketOptions.TCP_NODELAY &&
+ (getSocket() != null)) {
return (T)getOption(SocketOptions.TCP_NODELAY);
} else {
throw new UnsupportedOperationException("unsupported option");
--- a/jdk/src/java.base/share/classes/java/net/URI.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Sat Jan 16 00:28:28 2016 +0000
@@ -1146,13 +1146,30 @@
if (part != null) {
return part;
}
- StringBuilder sb = new StringBuilder();
- appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
+
+ String s = string;
+ if (s != null) {
+ // if string is defined, components will have been parsed
+ int start = 0;
+ int end = s.length();
+ if (scheme != null) {
+ start = scheme.length() + 1;
+ }
+ if (fragment != null) {
+ end -= fragment.length() + 1;
+ }
+ if (path != null && path.length() == end - start) {
+ part = path;
+ } else {
+ part = s.substring(start, end);
+ }
+ } else {
+ StringBuilder sb = new StringBuilder();
+ appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
host, port, getPath(), getQuery());
- if (sb.length() == 0) {
- return null;
+ part = sb.toString();
}
- return schemeSpecificPart = sb.toString();
+ return schemeSpecificPart = part;
}
/**
@@ -3056,7 +3073,6 @@
//
void parse(boolean rsa) throws URISyntaxException {
requireServerAuthority = rsa;
- int ssp; // Start of scheme-specific part
int n = input.length();
int p = scan(0, n, "/?#", ":");
if ((p >= 0) && at(p, n, ':')) {
@@ -3066,21 +3082,20 @@
checkChars(1, p, L_SCHEME, H_SCHEME, "scheme name");
scheme = input.substring(0, p);
p++; // Skip ':'
- ssp = p;
if (at(p, n, '/')) {
p = parseHierarchical(p, n);
} else {
+ // opaque; need to create the schemeSpecificPart
int q = scan(p, n, "#");
if (q <= p)
failExpecting("scheme-specific part", p);
checkChars(p, q, L_URIC, H_URIC, "opaque part");
+ schemeSpecificPart = input.substring(p, q);
p = q;
}
} else {
- ssp = 0;
p = parseHierarchical(0, n);
}
- schemeSpecificPart = input.substring(ssp, p);
if (at(p, n, '#')) {
checkChars(p + 1, n, L_URIC, H_URIC, "fragment");
fragment = input.substring(p + 1, n);
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Sat Jan 16 00:28:28 2016 +0000
@@ -52,6 +52,7 @@
import jdk.internal.misc.JavaNetAccess;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.perf.PerfCounter;
import sun.misc.Resource;
import sun.misc.URLClassPath;
import sun.net.www.ParseUtil;
@@ -459,14 +460,14 @@
// Use (direct) ByteBuffer:
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
- sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
+ PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
return defineClass(name, bb, cs);
} else {
byte[] b = res.getBytes();
// must read certificates AFTER reading bytes.
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
- sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
+ PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
return defineClass(name, b, 0, b.length, cs);
}
}
--- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,12 +27,12 @@
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
-import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.misc.JavaSecurityAccess;
import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
@@ -472,11 +472,15 @@
*
* This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
* with additional support for checking and removing weak keys that are no
- * longer in use.
+ * longer in use. There can be cases where the permission collection may
+ * have a chain of strong references back to the ProtectionDomain, which
+ * ordinarily would prevent the entry from being removed from the map. To
+ * address that, we wrap the permission collection in a SoftReference so
+ * that it can be reclaimed by the garbage collector due to memory demand.
*/
private static class PDCache implements ProtectionDomainCache {
private final ConcurrentHashMap<WeakProtectionDomainKey,
- PermissionCollection>
+ SoftReference<PermissionCollection>>
pdMap = new ConcurrentHashMap<>();
private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
@@ -485,15 +489,15 @@
processQueue(queue, pdMap);
WeakProtectionDomainKey weakPd =
new WeakProtectionDomainKey(pd, queue);
- pdMap.putIfAbsent(weakPd, pc);
+ pdMap.put(weakPd, new SoftReference<>(pc));
}
@Override
public PermissionCollection get(ProtectionDomain pd) {
processQueue(queue, pdMap);
- WeakProtectionDomainKey weakPd =
- new WeakProtectionDomainKey(pd, queue);
- return pdMap.get(weakPd);
+ WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd);
+ SoftReference<PermissionCollection> sr = pdMap.get(weakPd);
+ return (sr == null) ? null : sr.get();
}
/**
@@ -533,11 +537,20 @@
this((pd == null ? NULL_KEY : pd.key), rq);
}
+ WeakProtectionDomainKey(ProtectionDomain pd) {
+ this(pd == null ? NULL_KEY : pd.key);
+ }
+
private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
super(key, rq);
hash = key.hashCode();
}
+ private WeakProtectionDomainKey(Key key) {
+ super(key);
+ hash = key.hashCode();
+ }
+
/**
* Returns the identity hash code of the original referent.
*/
--- a/jdk/src/java.base/share/classes/java/time/LocalDate.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -1369,6 +1369,23 @@
if (daysToAdd == 0) {
return this;
}
+ long dom = day + daysToAdd;
+ if (dom > 0) {
+ if (dom <= 28) {
+ return new LocalDate(year, month, (int) dom);
+ } else if (dom <= 59) { // 59th Jan is 28th Feb, 59th Feb is 31st Mar
+ long monthLen = lengthOfMonth();
+ if (dom <= monthLen) {
+ return new LocalDate(year, month, (int) dom);
+ } else if (month < 12) {
+ return new LocalDate(year, month + 1, (int) (dom - monthLen));
+ } else {
+ YEAR.checkValidValue(year + 1);
+ return new LocalDate(year + 1, 1, (int) (dom - monthLen));
+ }
+ }
+ }
+
long mjDay = Math.addExact(toEpochDay(), daysToAdd);
return LocalDate.ofEpochDay(mjDay);
}
--- a/jdk/src/java.base/share/classes/java/util/Locale.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java Sat Jan 16 00:28:28 2016 +0000
@@ -3144,6 +3144,18 @@
&& range.equals(other.range)
&& weight == other.weight;
}
+
+ /**
+ * Returns an informative string representation of this {@code LanguageRange}
+ * object, consisting of language range and weight if the range is
+ * weighted and the weight is less than the max weight.
+ *
+ * @return a string representation of this {@code LanguageRange} object.
+ */
+ @Override
+ public String toString() {
+ return (weight == MAX_WEIGHT) ? range : range + ";q=" + weight;
+ }
}
/**
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Sat Jan 16 00:28:28 2016 +0000
@@ -54,6 +54,7 @@
import java.util.stream.StreamSupport;
import jdk.internal.misc.JavaUtilZipFileAccess;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.perf.PerfCounter;
import static java.util.zip.ZipConstants.*;
import static java.util.zip.ZipConstants64.*;
@@ -210,8 +211,8 @@
this.name = name;
long t0 = System.nanoTime();
this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
- sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
- sun.misc.PerfCounter.getZipFileCount().increment();
+ PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
+ PerfCounter.getZipFileCount().increment();
}
/**
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,788 +0,0 @@
-/*
- * Copyright (c) 2015, 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.internal.misc;
-
-import java.lang.ref.Cleaner;
-import java.lang.ref.Cleaner.Cleanable;
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Objects;
-import java.util.concurrent.ThreadFactory;
-import java.util.function.Function;
-
-import sun.misc.InnocuousThread;
-
-/**
- * CleanerImpl manages a set of object references and corresponding cleaning actions.
- * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
- */
-public final class CleanerImpl implements Runnable {
-
- /**
- * An object to access the CleanerImpl from a Cleaner; set by Cleaner init.
- */
- private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null;
-
- /**
- * Heads of a CleanableList for each reference type.
- */
- final PhantomCleanable<?> phantomCleanableList;
-
- final WeakCleanable<?> weakCleanableList;
-
- final SoftCleanable<?> softCleanableList;
-
- // The ReferenceQueue of pending cleaning actions
- final ReferenceQueue<Object> queue;
-
- /**
- * Called by Cleaner static initialization to provide the function
- * to map from Cleaner to CleanerImpl.
- * @param access a function to map from Cleaner to CleanerImpl
- */
- public static void setCleanerImplAccess(Function<Cleaner, CleanerImpl> access) {
- if (cleanerImplAccess == null) {
- cleanerImplAccess = access;
- }
- }
-
- /**
- * Called to get the CleanerImpl for a Cleaner.
- * @param cleaner the cleaner
- * @return the corresponding CleanerImpl
- */
- private static CleanerImpl getCleanerImpl(Cleaner cleaner) {
- return cleanerImplAccess.apply(cleaner);
- }
-
- /**
- * Constructor for CleanerImpl.
- */
- public CleanerImpl() {
- queue = new ReferenceQueue<>();
- phantomCleanableList = new PhantomCleanableRef(this);
- weakCleanableList = new WeakCleanableRef(this);
- softCleanableList = new SoftCleanableRef(this);
- }
-
- /**
- * Starts the Cleaner implementation.
- * When started waits for Cleanables to be queued.
- * @param service the cleaner
- * @param threadFactory the thread factory
- */
- public void start(Cleaner service, ThreadFactory threadFactory) {
- // schedule a nop cleaning action for the service, so the associated thread
- // will continue to run at least until the service is reclaimable.
- new PhantomCleanableRef(service, service, () -> {});
-
- if (threadFactory == null) {
- threadFactory = CleanerImpl.InnocuousThreadFactory.factory();
- }
-
- // now that there's at least one cleaning action, for the service,
- // we can start the associated thread, which runs until
- // all cleaning actions have been run.
- Thread thread = threadFactory.newThread(this);
- thread.setDaemon(true);
- thread.start();
- }
-
- /**
- * Process queued Cleanables as long as the cleanable lists are not empty.
- * A Cleanable is in one of the lists for each Object and for the Cleaner
- * itself.
- * Terminates when the Cleaner is no longer reachable and
- * has been cleaned and there are no more Cleanable instances
- * for which the object is reachable.
- * <p>
- * If the thread is a ManagedLocalsThread, the threadlocals
- * are erased before each cleanup
- */
- public void run() {
- Thread t = Thread.currentThread();
- InnocuousThread mlThread = (t instanceof InnocuousThread)
- ? (InnocuousThread) t
- : null;
- while (!phantomCleanableList.isListEmpty() ||
- !weakCleanableList.isListEmpty() ||
- !softCleanableList.isListEmpty()) {
- if (mlThread != null) {
- // Clear the thread locals
- mlThread.eraseThreadLocals();
- }
- try {
- // Wait for a Ref, with a timeout to avoid getting hung
- // due to a race with clear/clean
- Cleanable ref = (Cleanable) queue.remove(60 * 1000L);
- if (ref != null) {
- ref.clean();
- }
- } catch (InterruptedException i) {
- continue; // ignore the interruption
- } catch (Throwable e) {
- // ignore exceptions from the cleanup action
- }
- }
- }
-
- /**
- * PhantomCleanable subclasses efficiently encapsulate cleanup state and
- * the cleaning action.
- * Subclasses implement the abstract {@link #performCleanup()} method
- * to provide the cleaning action.
- * When constructed, the object reference and the {@link Cleanable Cleanable}
- * are registered with the {@link Cleaner}.
- * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
- * referent becomes phantom reachable.
- */
- public static abstract class PhantomCleanable<T> extends PhantomReference<T>
- implements Cleaner.Cleanable {
-
- /**
- * Links to previous and next in a doubly-linked list.
- */
- PhantomCleanable<?> prev = this, next = this;
-
- /**
- * The CleanerImpl for this Cleanable.
- */
- private final CleanerImpl cleanerImpl;
-
- /**
- * Constructs new {@code PhantomCleanable} with
- * {@code non-null referent} and {@code non-null cleaner}.
- * The {@code cleaner} is not retained; it is only used to
- * register the newly constructed {@link Cleaner.Cleanable Cleanable}.
- *
- * @param referent the referent to track
- * @param cleaner the {@code Cleaner} to register with
- */
- public PhantomCleanable(T referent, Cleaner cleaner) {
- super(Objects.requireNonNull(referent), getCleanerImpl(cleaner).queue);
- this.cleanerImpl = getCleanerImpl(cleaner);
- insert();
-
- // TODO: Replace getClass() with ReachabilityFence when it is available
- cleaner.getClass();
- referent.getClass();
- }
-
- /**
- * Construct a new root of the list; not inserted.
- */
- PhantomCleanable(CleanerImpl cleanerImpl) {
- super(null, null);
- this.cleanerImpl = cleanerImpl;
- }
-
- /**
- * Insert this PhantomCleanable after the list head.
- */
- private void insert() {
- final PhantomCleanable<?> list = cleanerImpl.phantomCleanableList;
- synchronized (list) {
- prev = list;
- next = list.next;
- next.prev = this;
- list.next = this;
- }
- }
-
- /**
- * Remove this PhantomCleanable from the list.
- *
- * @return true if Cleanable was removed or false if not because
- * it had already been removed before
- */
- private boolean remove() {
- PhantomCleanable<?> list = cleanerImpl.phantomCleanableList;
- synchronized (list) {
- if (next != this) {
- next.prev = prev;
- prev.next = next;
- prev = this;
- next = this;
- return true;
- }
- return false;
- }
- }
-
- /**
- * Returns true if the list's next reference refers to itself.
- *
- * @return true if the list is empty
- */
- boolean isListEmpty() {
- PhantomCleanable<?> list = cleanerImpl.phantomCleanableList;
- synchronized (list) {
- return list == list.next;
- }
- }
-
- /**
- * Unregister this PhantomCleanable and invoke {@link #performCleanup()},
- * ensuring at-most-once semantics.
- */
- @Override
- public final void clean() {
- if (remove()) {
- super.clear();
- performCleanup();
- }
- }
-
- /**
- * Unregister this PhantomCleanable and clear the reference.
- * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
- */
- @Override
- public void clear() {
- if (remove()) {
- super.clear();
- }
- }
-
- /**
- * The {@code performCleanup} abstract method is overridden
- * to implement the cleaning logic.
- * The {@code performCleanup} method should not be called except
- * by the {@link #clean} method which ensures at most once semantics.
- */
- protected abstract void performCleanup();
-
- /**
- * This method always throws {@link UnsupportedOperationException}.
- * Enqueuing details of {@link Cleaner.Cleanable}
- * are a private implementation detail.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public final boolean isEnqueued() {
- throw new UnsupportedOperationException("isEnqueued");
- }
-
- /**
- * This method always throws {@link UnsupportedOperationException}.
- * Enqueuing details of {@link Cleaner.Cleanable}
- * are a private implementation detail.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public final boolean enqueue() {
- throw new UnsupportedOperationException("enqueue");
- }
- }
-
- /**
- * WeakCleanable subclasses efficiently encapsulate cleanup state and
- * the cleaning action.
- * Subclasses implement the abstract {@link #performCleanup()} method
- * to provide the cleaning action.
- * When constructed, the object reference and the {@link Cleanable Cleanable}
- * are registered with the {@link Cleaner}.
- * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
- * referent becomes weakly reachable.
- */
- public static abstract class WeakCleanable<T> extends WeakReference<T>
- implements Cleaner.Cleanable {
-
- /**
- * Links to previous and next in a doubly-linked list.
- */
- WeakCleanable<?> prev = this, next = this;
-
- /**
- * The CleanerImpl for this Cleanable.
- */
- private final CleanerImpl cleanerImpl;
-
- /**
- * Constructs new {@code WeakCleanableReference} with
- * {@code non-null referent} and {@code non-null cleaner}.
- * The {@code cleaner} is not retained by this reference; it is only used
- * to register the newly constructed {@link Cleaner.Cleanable Cleanable}.
- *
- * @param referent the referent to track
- * @param cleaner the {@code Cleaner} to register new reference with
- */
- public WeakCleanable(T referent, Cleaner cleaner) {
- super(Objects.requireNonNull(referent), getCleanerImpl(cleaner).queue);
- cleanerImpl = getCleanerImpl(cleaner);
- insert();
-
- // TODO: Replace getClass() with ReachabilityFence when it is available
- cleaner.getClass();
- referent.getClass();
- }
-
- /**
- * Construct a new root of the list; not inserted.
- */
- WeakCleanable(CleanerImpl cleanerImpl) {
- super(null, null);
- this.cleanerImpl = cleanerImpl;
- }
-
- /**
- * Insert this WeakCleanableReference after the list head.
- */
- private void insert() {
- final WeakCleanable<?> list = cleanerImpl.weakCleanableList;
- synchronized (list) {
- prev = list;
- next = list.next;
- next.prev = this;
- list.next = this;
- }
- }
-
- /**
- * Remove this WeakCleanableReference from the list.
- *
- * @return true if Cleanable was removed or false if not because
- * it had already been removed before
- */
- private boolean remove() {
- WeakCleanable<?> list = cleanerImpl.weakCleanableList;
- synchronized (list) {
- if (next != this) {
- next.prev = prev;
- prev.next = next;
- prev = this;
- next = this;
- return true;
- }
- return false;
- }
- }
-
- /**
- * Returns true if the list's next reference refers to itself.
- *
- * @return true if the list is empty
- */
- boolean isListEmpty() {
- WeakCleanable<?> list = cleanerImpl.weakCleanableList;
- synchronized (list) {
- return list == list.next;
- }
- }
-
- /**
- * Unregister this WeakCleanable reference and invoke {@link #performCleanup()},
- * ensuring at-most-once semantics.
- */
- @Override
- public final void clean() {
- if (remove()) {
- super.clear();
- performCleanup();
- }
- }
-
- /**
- * Unregister this WeakCleanable and clear the reference.
- * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
- */
- @Override
- public void clear() {
- if (remove()) {
- super.clear();
- }
- }
-
- /**
- * The {@code performCleanup} abstract method is overridden
- * to implement the cleaning logic.
- * The {@code performCleanup} method should not be called except
- * by the {@link #clean} method which ensures at most once semantics.
- */
- protected abstract void performCleanup();
-
- /**
- * This method always throws {@link UnsupportedOperationException}.
- * Enqueuing details of {@link java.lang.ref.Cleaner.Cleanable}
- * are a private implementation detail.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public final boolean isEnqueued() {
- throw new UnsupportedOperationException("isEnqueued");
- }
-
- /**
- * This method always throws {@link UnsupportedOperationException}.
- * Enqueuing details of {@link java.lang.ref.Cleaner.Cleanable}
- * are a private implementation detail.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public final boolean enqueue() {
- throw new UnsupportedOperationException("enqueue");
- }
- }
-
- /**
- * SoftCleanable subclasses efficiently encapsulate cleanup state and
- * the cleaning action.
- * Subclasses implement the abstract {@link #performCleanup()} method
- * to provide the cleaning action.
- * When constructed, the object reference and the {@link Cleanable Cleanable}
- * are registered with the {@link Cleaner}.
- * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
- * referent becomes softly reachable.
- */
- public static abstract class SoftCleanable<T> extends SoftReference<T>
- implements Cleaner.Cleanable {
-
- /**
- * Links to previous and next in a doubly-linked list.
- */
- SoftCleanable<?> prev = this, next = this;
-
- /**
- * The CleanerImpl for this Cleanable.
- */
- private final CleanerImpl cleanerImpl;
-
- /**
- * Constructs new {@code SoftCleanableReference} with
- * {@code non-null referent} and {@code non-null cleaner}.
- * The {@code cleaner} is not retained by this reference; it is only used
- * to register the newly constructed {@link Cleaner.Cleanable Cleanable}.
- *
- * @param referent the referent to track
- * @param cleaner the {@code Cleaner} to register with
- */
- public SoftCleanable(T referent, Cleaner cleaner) {
- super(Objects.requireNonNull(referent), getCleanerImpl(cleaner).queue);
- cleanerImpl = getCleanerImpl(cleaner);
- insert();
-
- // TODO: Replace getClass() with ReachabilityFence when it is available
- cleaner.getClass();
- referent.getClass();
- }
-
- /**
- * Construct a new root of the list; not inserted.
- */
- SoftCleanable(CleanerImpl cleanerImpl) {
- super(null, null);
- this.cleanerImpl = cleanerImpl;
- }
-
- /**
- * Insert this SoftCleanableReference after the list head.
- */
- private void insert() {
- final SoftCleanable<?> list = cleanerImpl.softCleanableList;
- synchronized (list) {
- prev = list;
- next = list.next;
- next.prev = this;
- list.next = this;
- }
- }
-
- /**
- * Remove this SoftCleanableReference from the list.
- *
- * @return true if Cleanable was removed or false if not because
- * it had already been removed before
- */
- private boolean remove() {
- SoftCleanable<?> list = cleanerImpl.softCleanableList;
- synchronized (list) {
- if (next != this) {
- next.prev = prev;
- prev.next = next;
- prev = this;
- next = this;
- return true;
- }
- return false;
- }
- }
-
- /**
- * Returns true if the list's next reference refers to itself.
- *
- * @return true if the list is empty
- */
- boolean isListEmpty() {
- SoftCleanable<?> list = cleanerImpl.softCleanableList;
- synchronized (list) {
- return list == list.next;
- }
- }
-
- /**
- * Unregister this SoftCleanable reference and invoke {@link #performCleanup()},
- * ensuring at-most-once semantics.
- */
- @Override
- public final void clean() {
- if (remove()) {
- super.clear();
- performCleanup();
- }
- }
-
- /**
- * Unregister this SoftCleanable and clear the reference.
- * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
- */
- @Override
- public void clear() {
- if (remove()) {
- super.clear();
- }
- }
-
- /**
- * The {@code performCleanup} abstract method is overridden
- * to implement the cleaning logic.
- * The {@code performCleanup} method should not be called except
- * by the {@link #clean} method which ensures at most once semantics.
- */
- protected abstract void performCleanup();
-
- /**
- * This method always throws {@link UnsupportedOperationException}.
- * Enqueuing details of {@link Cleaner.Cleanable}
- * are a private implementation detail.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public final boolean isEnqueued() {
- throw new UnsupportedOperationException("isEnqueued");
- }
-
- /**
- * This method always throws {@link UnsupportedOperationException}.
- * Enqueuing details of {@link Cleaner.Cleanable}
- * are a private implementation detail.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public final boolean enqueue() {
- throw new UnsupportedOperationException("enqueue");
- }
- }
-
- /**
- * Perform cleaning on an unreachable PhantomReference.
- */
- public static final class PhantomCleanableRef extends PhantomCleanable<Object> {
- private final Runnable action;
-
- /**
- * Constructor for a phantom cleanable reference.
- * @param obj the object to monitor
- * @param cleaner the cleaner
- * @param action the action Runnable
- */
- public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
- super(obj, cleaner);
- this.action = action;
- }
-
- /**
- * Constructor used only for root of phantom cleanable list.
- * @param cleanerImpl the cleanerImpl
- */
- PhantomCleanableRef(CleanerImpl cleanerImpl) {
- super(cleanerImpl);
- this.action = null;
- }
-
- @Override
- protected void performCleanup() {
- action.run();
- }
-
- /**
- * Prevent access to referent even when it is still alive.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public Object get() {
- throw new UnsupportedOperationException("get");
- }
-
- /**
- * Direct clearing of the referent is not supported.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public void clear() {
- throw new UnsupportedOperationException("clear");
- }
- }
-
- /**
- * Perform cleaning on an unreachable WeakReference.
- */
- public static final class WeakCleanableRef extends WeakCleanable<Object> {
- private final Runnable action;
-
- /**
- * Constructor for a weak cleanable reference.
- * @param obj the object to monitor
- * @param cleaner the cleaner
- * @param action the action Runnable
- */
- WeakCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
- super(obj, cleaner);
- this.action = action;
- }
-
- /**
- * Constructor used only for root of weak cleanable list.
- * @param cleanerImpl the cleanerImpl
- */
- WeakCleanableRef(CleanerImpl cleanerImpl) {
- super(cleanerImpl);
- this.action = null;
- }
-
- @Override
- protected void performCleanup() {
- action.run();
- }
-
- /**
- * Prevent access to referent even when it is still alive.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public Object get() {
- throw new UnsupportedOperationException("get");
- }
-
- /**
- * Direct clearing of the referent is not supported.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public void clear() {
- throw new UnsupportedOperationException("clear");
- }
- }
-
- /**
- * Perform cleaning on an unreachable SoftReference.
- */
- public static final class SoftCleanableRef extends SoftCleanable<Object> {
- private final Runnable action;
-
- /**
- * Constructor for a soft cleanable reference.
- * @param obj the object to monitor
- * @param cleaner the cleaner
- * @param action the action Runnable
- */
- SoftCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
- super(obj, cleaner);
- this.action = action;
- }
-
- /**
- * Constructor used only for root of soft cleanable list.
- * @param cleanerImpl the cleanerImpl
- */
- SoftCleanableRef(CleanerImpl cleanerImpl) {
- super(cleanerImpl);
- this.action = null;
- }
-
- @Override
- protected void performCleanup() {
- action.run();
- }
-
- /**
- * Prevent access to referent even when it is still alive.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public Object get() {
- throw new UnsupportedOperationException("get");
- }
-
- /**
- * Direct clearing of the referent is not supported.
- *
- * @throws UnsupportedOperationException always
- */
- @Override
- public void clear() {
- throw new UnsupportedOperationException("clear");
- }
-
- }
-
- /**
- * A ThreadFactory for InnocuousThreads.
- * The factory is a singleton.
- */
- static final class InnocuousThreadFactory implements ThreadFactory {
- final static ThreadFactory factory = new InnocuousThreadFactory();
-
- static ThreadFactory factory() {
- return factory;
- }
-
- public Thread newThread(Runnable r) {
- return AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
- Thread t = new InnocuousThread(r);
- t.setPriority(Thread.MAX_PRIORITY - 2);
- t.setName("Cleaner-" + t.getId());
- return t;
- });
- }
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/perf/Perf.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,547 @@
+/*
+ * Copyright (c) 2002, 2006, 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.internal.perf;
+
+import java.nio.ByteBuffer;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import jdk.internal.ref.CleanerFactory;
+
+/**
+ * The Perf class provides the ability to attach to an instrumentation
+ * buffer maintained by a Java virtual machine. The instrumentation
+ * buffer may be for the Java virtual machine running the methods of
+ * this class or it may be for another Java virtual machine on the
+ * same system.
+ * <p>
+ * In addition, this class provides methods to create instrumentation
+ * objects in the instrumentation buffer for the Java virtual machine
+ * that is running these methods. It also contains methods for acquiring
+ * the value of a platform specific high resolution clock for time
+ * stamp and interval measurement purposes.
+ *
+ * @author Brian Doherty
+ * @since 1.4.2
+ * @see #getPerf
+ * @see jdk.internal.perf.Perf.GetPerfAction
+ * @see java.nio.ByteBuffer
+ */
+public final class Perf {
+
+ private static Perf instance;
+
+ private static final int PERF_MODE_RO = 0;
+ private static final int PERF_MODE_RW = 1;
+
+ private Perf() { } // prevent instantiation
+
+ /**
+ * The GetPerfAction class is a convenience class for acquiring access
+ * to the singleton Perf instance using the
+ * <code>AccessController.doPrivileged()</code> method.
+ * <p>
+ * An instance of this class can be used as the argument to
+ * <code>AccessController.doPrivileged(PrivilegedAction)</code>.
+ * <p> Here is a suggested idiom for use of this class:
+ *
+ * <blockquote><pre>{@code
+ * class MyTrustedClass {
+ * private static final Perf perf =
+ * AccessController.doPrivileged(new Perf.GetPerfAction<Perf>());
+ * ...
+ * }
+ * }</pre></blockquote>
+ * <p>
+ * In the presence of a security manager, the <code>MyTrustedClass</code>
+ * class in the above example will need to be granted the
+ * <em>"sun.misc.Perf.getPerf"</em> <code>RuntimePermission</code>
+ * permission in order to successfully acquire the singleton Perf instance.
+ * <p>
+ * Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
+ * is not a JDK specified permission.
+ *
+ * @see java.security.AccessController#doPrivileged(PrivilegedAction)
+ * @see java.lang.RuntimePermission
+ */
+ public static class GetPerfAction implements PrivilegedAction<Perf>
+ {
+ /**
+ * Run the <code>Perf.getPerf()</code> method in a privileged context.
+ *
+ * @see #getPerf
+ */
+ public Perf run() {
+ return getPerf();
+ }
+ }
+
+ /**
+ * Return a reference to the singleton Perf instance.
+ * <p>
+ * The getPerf() method returns the singleton instance of the Perf
+ * class. The returned object provides the caller with the capability
+ * for accessing the instrumentation buffer for this or another local
+ * Java virtual machine.
+ * <p>
+ * If a security manager is installed, its <code>checkPermission</code>
+ * method is called with a <code>RuntimePermission</code> with a target
+ * of <em>"sun.misc.Perf.getPerf"</em>. A security exception will result
+ * if the caller has not been granted this permission.
+ * <p>
+ * Access to the returned <code>Perf</code> object should be protected
+ * by its caller and not passed on to untrusted code. This object can
+ * be used to attach to the instrumentation buffer provided by this Java
+ * virtual machine or for those of other Java virtual machines running
+ * on the same system. The instrumentation buffer may contain senstitive
+ * information. API's built on top of this interface may want to provide
+ * finer grained access control to the contents of individual
+ * instrumentation objects contained within the buffer.
+ * <p>
+ * Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
+ * is not a JDK specified permission.
+ *
+ * @return A reference to the singleton Perf instance.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkPermission</code> method doesn't allow access
+ * to the <em>"jdk.internal.perf.Perf.getPerf""</em> target.
+ * @see java.lang.RuntimePermission
+ * @see #attach
+ */
+ public static Perf getPerf()
+ {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ Permission perm = new RuntimePermission("jdk.internal.perf.Perf.getPerf");
+ security.checkPermission(perm);
+ }
+
+ return instance;
+ }
+
+ /**
+ * Attach to the instrumentation buffer for the specified Java virtual
+ * machine.
+ * <p>
+ * This method will attach to the instrumentation buffer for the
+ * specified virtual machine. It returns a <code>ByteBuffer</code> object
+ * that is initialized to access the instrumentation buffer for the
+ * indicated Java virtual machine. The <code>lvmid</code> parameter is
+ * a integer value that uniquely identifies the target local Java virtual
+ * machine. It is typically, but not necessarily, the process id of
+ * the target Java virtual machine.
+ * <p>
+ * If the <code>lvmid</code> identifies a Java virtual machine different
+ * from the one running this method, then the coherency characteristics
+ * of the buffer are implementation dependent. Implementations that do
+ * not support named, coherent, shared memory may return a
+ * <code>ByteBuffer</code> object that contains only a snap shot of the
+ * data in the instrumentation buffer. Implementations that support named,
+ * coherent, shared memory, may return a <code>ByteBuffer</code> object
+ * that will be changing dynamically over time as the target Java virtual
+ * machine updates its mapping of this buffer.
+ * <p>
+ * If the <code>lvmid</code> is 0 or equal to the actual <code>lvmid</code>
+ * for the Java virtual machine running this method, then the returned
+ * <code>ByteBuffer</code> object will always be coherent and dynamically
+ * changing.
+ * <p>
+ * The attach mode specifies the access permissions requested for the
+ * instrumentation buffer of the target virtual machine. The permitted
+ * access permissions are:
+ * <ul>
+ * <li>"r" - Read only access. This Java virtual machine has only
+ * read access to the instrumentation buffer for the target Java
+ * virtual machine.
+ * <li>"rw" - Read/Write access. This Java virtual machine has read and
+ * write access to the instrumentation buffer for the target Java virtual
+ * machine. This mode is currently not supported and is reserved for
+ * future enhancements.
+ * </ul>
+ *
+ * @param lvmid an integer that uniquely identifies the
+ * target local Java virtual machine.
+ * @param mode a string indicating the attach mode.
+ * @return ByteBuffer a direct allocated byte buffer
+ * @throws IllegalArgumentException The lvmid or mode was invalid.
+ * @throws IOException An I/O error occurred while trying to acquire
+ * the instrumentation buffer.
+ * @throws OutOfMemoryError The instrumentation buffer could not be mapped
+ * into the virtual machine's address space.
+ * @see java.nio.ByteBuffer
+ */
+ public ByteBuffer attach(int lvmid, String mode)
+ throws IllegalArgumentException, IOException
+ {
+ if (mode.compareTo("r") == 0) {
+ return attachImpl(null, lvmid, PERF_MODE_RO);
+ }
+ else if (mode.compareTo("rw") == 0) {
+ return attachImpl(null, lvmid, PERF_MODE_RW);
+ }
+ else {
+ throw new IllegalArgumentException("unknown mode");
+ }
+ }
+
+ /**
+ * Attach to the instrumentation buffer for the specified Java virtual
+ * machine owned by the given user.
+ * <p>
+ * This method behaves just as the <code>attach(int lvmid, String mode)
+ * </code> method, except that it only searches for Java virtual machines
+ * owned by the specified user.
+ *
+ * @param user A <code>String</code> object containing the
+ * name of the user that owns the target Java
+ * virtual machine.
+ * @param lvmid an integer that uniquely identifies the
+ * target local Java virtual machine.
+ * @param mode a string indicating the attach mode.
+ * @return ByteBuffer a direct allocated byte buffer
+ * @throws IllegalArgumentException The lvmid or mode was invalid.
+ * @throws IOException An I/O error occurred while trying to acquire
+ * the instrumentation buffer.
+ * @throws OutOfMemoryError The instrumentation buffer could not be mapped
+ * into the virtual machine's address space.
+ * @see java.nio.ByteBuffer
+ */
+ public ByteBuffer attach(String user, int lvmid, String mode)
+ throws IllegalArgumentException, IOException
+ {
+ if (mode.compareTo("r") == 0) {
+ return attachImpl(user, lvmid, PERF_MODE_RO);
+ }
+ else if (mode.compareTo("rw") == 0) {
+ return attachImpl(user, lvmid, PERF_MODE_RW);
+ }
+ else {
+ throw new IllegalArgumentException("unknown mode");
+ }
+ }
+
+ /**
+ * Call the implementation specific attach method.
+ * <p>
+ * This method calls into the Java virtual machine to perform the platform
+ * specific attach method. Buffers returned from this method are
+ * internally managed as <code>PhantomRefereces</code> to provide for
+ * guaranteed, secure release of the native resources.
+ *
+ * @param user A <code>String</code> object containing the
+ * name of the user that owns the target Java
+ * virtual machine.
+ * @param lvmid an integer that uniquely identifies the
+ * target local Java virtual machine.
+ * @param mode a string indicating the attach mode.
+ * @return ByteBuffer a direct allocated byte buffer
+ * @throws IllegalArgumentException The lvmid or mode was invalid.
+ * @throws IOException An I/O error occurred while trying to acquire
+ * the instrumentation buffer.
+ * @throws OutOfMemoryError The instrumentation buffer could not be mapped
+ * into the virtual machine's address space.
+ */
+ private ByteBuffer attachImpl(String user, int lvmid, int mode)
+ throws IllegalArgumentException, IOException
+ {
+ final ByteBuffer b = attach(user, lvmid, mode);
+
+ if (lvmid == 0) {
+ // The native instrumentation buffer for this Java virtual
+ // machine is never unmapped.
+ return b;
+ }
+ else {
+ // This is an instrumentation buffer for another Java virtual
+ // machine with native resources that need to be managed. We
+ // create a duplicate of the native ByteBuffer and manage it
+ // with a Cleaner. When the duplicate becomes phantom reachable,
+ // the native resources will be released.
+
+ final ByteBuffer dup = b.duplicate();
+
+ CleanerFactory.cleaner()
+ .register(dup, new CleanerAction(instance, b));
+ return dup;
+ }
+ }
+
+ private static class CleanerAction implements Runnable {
+ private final ByteBuffer bb;
+ private final Perf perf;
+ CleanerAction(Perf perf, ByteBuffer bb) {
+ this.perf = perf;
+ this.bb = bb;
+ }
+ public void run() {
+ try {
+ perf.detach(bb);
+ } catch (Throwable th) {
+ // avoid crashing the reference handler thread,
+ // but provide for some diagnosability
+ assert false : th.toString();
+ }
+ }
+ }
+
+ /**
+ * Native method to perform the implementation specific attach mechanism.
+ * <p>
+ * The implementation of this method may return distinct or identical
+ * <code>ByteBuffer</code> objects for two distinct calls requesting
+ * attachment to the same Java virtual machine.
+ * <p>
+ * For the Sun HotSpot JVM, two distinct calls to attach to the same
+ * target Java virtual machine will result in two distinct ByteBuffer
+ * objects returned by this method. This may change in a future release.
+ *
+ * @param user A <code>String</code> object containing the
+ * name of the user that owns the target Java
+ * virtual machine.
+ * @param lvmid an integer that uniquely identifies the
+ * target local Java virtual machine.
+ * @param mode a string indicating the attach mode.
+ * @return ByteBuffer a direct allocated byte buffer
+ * @throws IllegalArgumentException The lvmid or mode was invalid.
+ * @throws IOException An I/O error occurred while trying to acquire
+ * the instrumentation buffer.
+ * @throws OutOfMemoryError The instrumentation buffer could not be mapped
+ * into the virtual machine's address space.
+ */
+ private native ByteBuffer attach(String user, int lvmid, int mode)
+ throws IllegalArgumentException, IOException;
+
+ /**
+ * Native method to perform the implementation specific detach mechanism.
+ * <p>
+ * If this method is passed a <code>ByteBuffer</code> object that is
+ * not created by the <code>attach</code> method, then the results of
+ * this method are undefined, with unpredictable and potentially damaging
+ * effects to the Java virtual machine. To prevent accidental or malicious
+ * use of this method, all native ByteBuffer created by the <code>
+ * attach</code> method are managed internally as PhantomReferences
+ * and resources are freed by the system.
+ * <p>
+ * If this method is passed a <code>ByteBuffer</code> object created
+ * by the <code>attach</code> method with a lvmid for the Java virtual
+ * machine running this method (lvmid=0, for example), then the detach
+ * request is silently ignored.
+ *
+ * @param bb A direct allocated byte buffer created by the
+ * <code>attach</code> method.
+ * @see java.nio.ByteBuffer
+ * @see #attach
+ */
+ private native void detach(ByteBuffer bb);
+
+ /**
+ * Create a <code>long</code> scalar entry in the instrumentation buffer
+ * with the given variability characteristic, units, and initial value.
+ * <p>
+ * Access to the instrument is provided through the returned <code>
+ * ByteBuffer</code> object. Typically, this object should be wrapped
+ * with <code>LongBuffer</code> view object.
+ *
+ * @param variability the variability characteristic for this entry.
+ * @param units the units for this entry.
+ * @param name the name of this entry.
+ * @param value the initial value for this entry.
+ * @return ByteBuffer a direct allocated ByteBuffer object that
+ * allows write access to a native memory location
+ * containing a <code>long</code> value.
+ *
+ * see sun.misc.perf.Variability
+ * see sun.misc.perf.Units
+ * @see java.nio.ByteBuffer
+ */
+ public native ByteBuffer createLong(String name, int variability,
+ int units, long value);
+
+ /**
+ * Create a <code>String</code> entry in the instrumentation buffer with
+ * the given variability characteristic, units, and initial value.
+ * <p>
+ * The maximum length of the <code>String</code> stored in this string
+ * instrument is given in by <code>maxLength</code> parameter. Updates
+ * to this instrument with <code>String</code> values with lengths greater
+ * than <code>maxLength</code> will be truncated to <code>maxLength</code>.
+ * The truncated value will be terminated by a null character.
+ * <p>
+ * The underlying implementation may further limit the length of the
+ * value, but will continue to preserve the null terminator.
+ * <p>
+ * Access to the instrument is provided through the returned <code>
+ * ByteBuffer</code> object.
+ *
+ * @param variability the variability characteristic for this entry.
+ * @param units the units for this entry.
+ * @param name the name of this entry.
+ * @param value the initial value for this entry.
+ * @param maxLength the maximum string length for this string
+ * instrument.
+ * @return ByteBuffer a direct allocated ByteBuffer that allows
+ * write access to a native memory location
+ * containing a <code>long</code> value.
+ *
+ * see sun.misc.perf.Variability
+ * see sun.misc.perf.Units
+ * @see java.nio.ByteBuffer
+ */
+ public ByteBuffer createString(String name, int variability,
+ int units, String value, int maxLength)
+ {
+ byte[] v = getBytes(value);
+ byte[] v1 = new byte[v.length+1];
+ System.arraycopy(v, 0, v1, 0, v.length);
+ v1[v.length] = '\0';
+ return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength));
+ }
+
+ /**
+ * Create a <code>String</code> entry in the instrumentation buffer with
+ * the given variability characteristic, units, and initial value.
+ * <p>
+ * The maximum length of the <code>String</code> stored in this string
+ * instrument is implied by the length of the <code>value</code> parameter.
+ * Subsequent updates to the value of this instrument will be truncated
+ * to this implied maximum length. The truncated value will be terminated
+ * by a null character.
+ * <p>
+ * The underlying implementation may further limit the length of the
+ * initial or subsequent value, but will continue to preserve the null
+ * terminator.
+ * <p>
+ * Access to the instrument is provided through the returned <code>
+ * ByteBuffer</code> object.
+ *
+ * @param variability the variability characteristic for this entry.
+ * @param units the units for this entry.
+ * @param name the name of this entry.
+ * @param value the initial value for this entry.
+ * @return ByteBuffer a direct allocated ByteBuffer that allows
+ * write access to a native memory location
+ * containing a <code>long</code> value.
+ *
+ * see sun.misc.perf.Variability
+ * see sun.misc.perf.Units
+ * @see java.nio.ByteBuffer
+ */
+ public ByteBuffer createString(String name, int variability,
+ int units, String value)
+ {
+ byte[] v = getBytes(value);
+ byte[] v1 = new byte[v.length+1];
+ System.arraycopy(v, 0, v1, 0, v.length);
+ v1[v.length] = '\0';
+ return createByteArray(name, variability, units, v1, v1.length);
+ }
+
+ /**
+ * Create a <code>byte</code> vector entry in the instrumentation buffer
+ * with the given variability characteristic, units, and initial value.
+ * <p>
+ * The <code>maxLength</code> parameter limits the size of the byte
+ * array instrument such that the initial or subsequent updates beyond
+ * this length are silently ignored. No special handling of truncated
+ * updates is provided.
+ * <p>
+ * The underlying implementation may further limit the length of the
+ * length of the initial or subsequent value.
+ * <p>
+ * Access to the instrument is provided through the returned <code>
+ * ByteBuffer</code> object.
+ *
+ * @param variability the variability characteristic for this entry.
+ * @param units the units for this entry.
+ * @param name the name of this entry.
+ * @param value the initial value for this entry.
+ * @param maxLength the maximum length of this byte array.
+ * @return ByteBuffer a direct allocated byte buffer that allows
+ * write access to a native memory location
+ * containing a <code>long</code> value.
+ *
+ * see sun.misc.perf.Variability
+ * see sun.misc.perf.Units
+ * @see java.nio.ByteBuffer
+ */
+ public native ByteBuffer createByteArray(String name, int variability,
+ int units, byte[] value,
+ int maxLength);
+
+
+ /**
+ * convert string to an array of UTF-8 bytes
+ */
+ private static byte[] getBytes(String s)
+ {
+ byte[] bytes = null;
+
+ try {
+ bytes = s.getBytes("UTF-8");
+ }
+ catch (UnsupportedEncodingException e) {
+ // ignore, UTF-8 encoding is always known
+ }
+
+ return bytes;
+ }
+
+ /**
+ * Return the value of the High Resolution Counter.
+ *
+ * The High Resolution Counter returns the number of ticks since
+ * since the start of the Java virtual machine. The resolution of
+ * the counter is machine dependent and can be determined from the
+ * value return by the {@link #highResFrequency} method.
+ *
+ * @return the number of ticks of machine dependent resolution since
+ * the start of the Java virtual machine.
+ *
+ * @see #highResFrequency
+ * @see java.lang.System#currentTimeMillis()
+ */
+ public native long highResCounter();
+
+ /**
+ * Returns the frequency of the High Resolution Counter, in ticks per
+ * second.
+ *
+ * This value can be used to convert the value of the High Resolution
+ * Counter, as returned from a call to the {@link #highResCounter} method,
+ * into the number of seconds since the start of the Java virtual machine.
+ *
+ * @return the frequency of the High Resolution Counter.
+ * @see #highResCounter
+ */
+ public native long highResFrequency();
+
+ private static native void registerNatives();
+
+ static {
+ registerNatives();
+ instance = new Perf();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/perf/PerfCounter.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2009, 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.internal.perf;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.LongBuffer;
+import java.security.AccessController;
+
+/**
+ * Performance counter support for internal JRE classes.
+ * This class defines a fixed list of counters for the platform
+ * to use as an interim solution until RFE# 6209222 is implemented.
+ * The perf counters will be created in the jvmstat perf buffer
+ * that the HotSpot VM creates. The default size is 32K and thus
+ * the number of counters is bounded. You can alter the size
+ * with {@code -XX:PerfDataMemorySize=<bytes>} option. If there is
+ * insufficient memory in the jvmstat perf buffer, the C heap memory
+ * will be used and thus the application will continue to run if
+ * the counters added exceeds the buffer size but the counters
+ * will be missing.
+ *
+ * See HotSpot jvmstat implementation for certain circumstances
+ * that the jvmstat perf buffer is not supported.
+ *
+ */
+public class PerfCounter {
+ private static final Perf perf =
+ AccessController.doPrivileged(new Perf.GetPerfAction());
+
+ // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp
+ private static final int V_Constant = 1;
+ private static final int V_Monotonic = 2;
+ private static final int V_Variable = 3;
+ private static final int U_None = 1;
+
+ private final String name;
+ private final LongBuffer lb;
+
+ private PerfCounter(String name, int type) {
+ this.name = name;
+ ByteBuffer bb = perf.createLong(name, type, U_None, 0L);
+ bb.order(ByteOrder.nativeOrder());
+ this.lb = bb.asLongBuffer();
+ }
+
+ static PerfCounter newPerfCounter(String name) {
+ return new PerfCounter(name, V_Variable);
+ }
+
+ static PerfCounter newConstantPerfCounter(String name) {
+ PerfCounter c = new PerfCounter(name, V_Constant);
+ return c;
+ }
+
+ /**
+ * Returns the current value of the perf counter.
+ */
+ public synchronized long get() {
+ return lb.get(0);
+ }
+
+ /**
+ * Sets the value of the perf counter to the given newValue.
+ */
+ public synchronized void set(long newValue) {
+ lb.put(0, newValue);
+ }
+
+ /**
+ * Adds the given value to the perf counter.
+ */
+ public synchronized void add(long value) {
+ long res = get() + value;
+ lb.put(0, res);
+ }
+
+ /**
+ * Increments the perf counter with 1.
+ */
+ public void increment() {
+ add(1);
+ }
+
+ /**
+ * Adds the given interval to the perf counter.
+ */
+ public void addTime(long interval) {
+ add(interval);
+ }
+
+ /**
+ * Adds the elapsed time from the given start time (ns) to the perf counter.
+ */
+ public void addElapsedTimeFrom(long startTime) {
+ add(System.nanoTime() - startTime);
+ }
+
+ @Override
+ public String toString() {
+ return name + " = " + get();
+ }
+
+ static class CoreCounters {
+ static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime");
+ static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses");
+ static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime");
+ static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime");
+ static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles");
+ static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime");
+ }
+
+ static class WindowsClientCounters {
+ static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available");
+ }
+
+ /**
+ * Number of findClass calls
+ */
+ public static PerfCounter getFindClasses() {
+ return CoreCounters.lc;
+ }
+
+ /**
+ * Time (ns) spent in finding classes that includes
+ * lookup and read class bytes and defineClass
+ */
+ public static PerfCounter getFindClassTime() {
+ return CoreCounters.lct;
+ }
+
+ /**
+ * Time (ns) spent in finding classes
+ */
+ public static PerfCounter getReadClassBytesTime() {
+ return CoreCounters.rcbt;
+ }
+
+ /**
+ * Time (ns) spent in the parent delegation to
+ * the parent of the defining class loader
+ */
+ public static PerfCounter getParentDelegationTime() {
+ return CoreCounters.pdt;
+ }
+
+ /**
+ * Number of zip files opened.
+ */
+ public static PerfCounter getZipFileCount() {
+ return CoreCounters.zfc;
+ }
+
+ /**
+ * Time (ns) spent in opening the zip files that
+ * includes building the entries hash table
+ */
+ public static PerfCounter getZipFileOpenTime() {
+ return CoreCounters.zfot;
+ }
+
+ /**
+ * D3D graphic pipeline available
+ */
+ public static PerfCounter getD3DAvailable() {
+ return WindowsClientCounters.d3dAvailable;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerFactory.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, 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.internal.ref;
+
+import java.lang.ref.Cleaner;
+
+/**
+ * CleanerFactory provides a Cleaner for use within OpenJDK modules.
+ * The cleaner is created on the first reference to the CleanerFactory.
+ */
+public final class CleanerFactory {
+
+ /* The common Cleaner. */
+ private final static Cleaner commonCleaner = Cleaner.create();
+
+ /**
+ * Cleaner for use within OpenJDK modules.
+ *
+ * @return a Cleaner for use within OpenJDK modules
+ */
+ public static Cleaner cleaner() {
+ return commonCleaner;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2015, 2016, 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.internal.ref;
+
+import java.lang.ref.Cleaner;
+import java.lang.ref.Cleaner.Cleanable;
+import java.lang.ref.ReferenceQueue;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.ThreadFactory;
+import java.util.function.Function;
+
+import sun.misc.InnocuousThread;
+
+/**
+ * CleanerImpl manages a set of object references and corresponding cleaning actions.
+ * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}.
+ */
+public final class CleanerImpl {
+
+ /**
+ * An object to access the CleanerImpl from a Cleaner; set by Cleaner init.
+ */
+ private static Function<Cleaner, CleanerImpl> cleanerImplAccess = null;
+
+ /**
+ * Heads of a CleanableList for each reference type.
+ */
+ final PhantomCleanable<?> phantomCleanableList;
+
+ final WeakCleanable<?> weakCleanableList;
+
+ final SoftCleanable<?> softCleanableList;
+
+ // The ReferenceQueue of pending cleaning actions
+ final ReferenceQueue<Object> queue;
+
+ /**
+ * Called by Cleaner static initialization to provide the function
+ * to map from Cleaner to CleanerImpl.
+ * @param access a function to map from Cleaner to CleanerImpl
+ */
+ public static void setCleanerImplAccess(Function<Cleaner, CleanerImpl> access) {
+ if (cleanerImplAccess == null) {
+ cleanerImplAccess = access;
+ } else {
+ throw new InternalError("cleanerImplAccess");
+ }
+ }
+
+ /**
+ * Called to get the CleanerImpl for a Cleaner.
+ * @param cleaner the cleaner
+ * @return the corresponding CleanerImpl
+ */
+ static CleanerImpl getCleanerImpl(Cleaner cleaner) {
+ return cleanerImplAccess.apply(cleaner);
+ }
+
+ /**
+ * Constructor for CleanerImpl.
+ */
+ public CleanerImpl() {
+ queue = new ReferenceQueue<>();
+ phantomCleanableList = new PhantomCleanableRef();
+ weakCleanableList = new WeakCleanableRef();
+ softCleanableList = new SoftCleanableRef();
+ }
+
+ /**
+ * Starts the Cleaner implementation.
+ * Ensure this is the CleanerImpl for the Cleaner.
+ * When started waits for Cleanables to be queued.
+ * @param cleaner the cleaner
+ * @param threadFactory the thread factory
+ */
+ public void start(Cleaner cleaner, ThreadFactory threadFactory) {
+ if (getCleanerImpl(cleaner) != this) {
+ throw new AssertionError("wrong cleaner");
+ }
+ // schedule a nop cleaning action for the cleaner, so the associated thread
+ // will continue to run at least until the cleaner is reclaimable.
+ new PhantomCleanableRef(cleaner, cleaner, () -> {});
+
+ if (threadFactory == null) {
+ threadFactory = CleanerImpl.InnocuousThreadFactory.factory();
+ }
+
+ // now that there's at least one cleaning action, for the cleaner,
+ // we can start the associated thread, which runs until
+ // all cleaning actions have been run.
+ Thread thread = threadFactory.newThread(this::run);
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ /**
+ * Process queued Cleanables as long as the cleanable lists are not empty.
+ * A Cleanable is in one of the lists for each Object and for the Cleaner
+ * itself.
+ * Terminates when the Cleaner is no longer reachable and
+ * has been cleaned and there are no more Cleanable instances
+ * for which the object is reachable.
+ * <p>
+ * If the thread is a ManagedLocalsThread, the threadlocals
+ * are erased before each cleanup
+ */
+ private void run() {
+ Thread t = Thread.currentThread();
+ InnocuousThread mlThread = (t instanceof InnocuousThread)
+ ? (InnocuousThread) t
+ : null;
+ while (!phantomCleanableList.isListEmpty() ||
+ !weakCleanableList.isListEmpty() ||
+ !softCleanableList.isListEmpty()) {
+ if (mlThread != null) {
+ // Clear the thread locals
+ mlThread.eraseThreadLocals();
+ }
+ try {
+ // Wait for a Ref, with a timeout to avoid getting hung
+ // due to a race with clear/clean
+ Cleanable ref = (Cleanable) queue.remove(60 * 1000L);
+ if (ref != null) {
+ ref.clean();
+ }
+ } catch (InterruptedException i) {
+ continue; // ignore the interruption
+ } catch (Throwable e) {
+ // ignore exceptions from the cleanup action
+ }
+ }
+ }
+
+ /**
+ * Perform cleaning on an unreachable PhantomReference.
+ */
+ public static final class PhantomCleanableRef extends PhantomCleanable<Object> {
+ private final Runnable action;
+
+ /**
+ * Constructor for a phantom cleanable reference.
+ * @param obj the object to monitor
+ * @param cleaner the cleaner
+ * @param action the action Runnable
+ */
+ public PhantomCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
+ super(obj, cleaner);
+ this.action = action;
+ }
+
+ /**
+ * Constructor used only for root of phantom cleanable list.
+ */
+ PhantomCleanableRef() {
+ super();
+ this.action = null;
+ }
+
+ @Override
+ protected void performCleanup() {
+ action.run();
+ }
+
+ /**
+ * Prevent access to referent even when it is still alive.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object get() {
+ throw new UnsupportedOperationException("get");
+ }
+
+ /**
+ * Direct clearing of the referent is not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("clear");
+ }
+ }
+
+ /**
+ * Perform cleaning on an unreachable WeakReference.
+ */
+ public static final class WeakCleanableRef extends WeakCleanable<Object> {
+ private final Runnable action;
+
+ /**
+ * Constructor for a weak cleanable reference.
+ * @param obj the object to monitor
+ * @param cleaner the cleaner
+ * @param action the action Runnable
+ */
+ WeakCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
+ super(obj, cleaner);
+ this.action = action;
+ }
+
+ /**
+ * Constructor used only for root of weak cleanable list.
+ */
+ WeakCleanableRef() {
+ super();
+ this.action = null;
+ }
+
+ @Override
+ protected void performCleanup() {
+ action.run();
+ }
+
+ /**
+ * Prevent access to referent even when it is still alive.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object get() {
+ throw new UnsupportedOperationException("get");
+ }
+
+ /**
+ * Direct clearing of the referent is not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("clear");
+ }
+ }
+
+ /**
+ * Perform cleaning on an unreachable SoftReference.
+ */
+ public static final class SoftCleanableRef extends SoftCleanable<Object> {
+ private final Runnable action;
+
+ /**
+ * Constructor for a soft cleanable reference.
+ * @param obj the object to monitor
+ * @param cleaner the cleaner
+ * @param action the action Runnable
+ */
+ SoftCleanableRef(Object obj, Cleaner cleaner, Runnable action) {
+ super(obj, cleaner);
+ this.action = action;
+ }
+
+ /**
+ * Constructor used only for root of soft cleanable list.
+ */
+ SoftCleanableRef() {
+ super();
+ this.action = null;
+ }
+
+ @Override
+ protected void performCleanup() {
+ action.run();
+ }
+
+ /**
+ * Prevent access to referent even when it is still alive.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object get() {
+ throw new UnsupportedOperationException("get");
+ }
+
+ /**
+ * Direct clearing of the referent is not supported.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException("clear");
+ }
+
+ }
+
+ /**
+ * A ThreadFactory for InnocuousThreads.
+ * The factory is a singleton.
+ */
+ static final class InnocuousThreadFactory implements ThreadFactory {
+ final static ThreadFactory factory = new InnocuousThreadFactory();
+
+ static ThreadFactory factory() {
+ return factory;
+ }
+
+ public Thread newThread(Runnable r) {
+ return AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
+ Thread t = new InnocuousThread(r);
+ t.setPriority(Thread.MAX_PRIORITY - 2);
+ t.setName("Cleaner-" + t.getId());
+ return t;
+ });
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/PhantomCleanable.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2015, 2016, 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.internal.ref;
+
+import java.lang.ref.Cleaner;
+import java.lang.ref.PhantomReference;
+import java.util.Objects;
+
+/**
+ * PhantomCleanable subclasses efficiently encapsulate cleanup state and
+ * the cleaning action.
+ * Subclasses implement the abstract {@link #performCleanup()} method
+ * to provide the cleaning action.
+ * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable}
+ * are registered with the {@link Cleaner}.
+ * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
+ * referent becomes phantom reachable.
+ */
+public abstract class PhantomCleanable<T> extends PhantomReference<T>
+ implements Cleaner.Cleanable {
+
+ /**
+ * Links to previous and next in a doubly-linked list.
+ */
+ PhantomCleanable<?> prev = this, next = this;
+
+ /**
+ * The list of PhantomCleanable; synchronizes insert and remove.
+ */
+ private final PhantomCleanable<?> list;
+
+ /**
+ * Constructs new {@code PhantomCleanable} with
+ * {@code non-null referent} and {@code non-null cleaner}.
+ * The {@code cleaner} is not retained; it is only used to
+ * register the newly constructed {@link Cleaner.Cleanable Cleanable}.
+ *
+ * @param referent the referent to track
+ * @param cleaner the {@code Cleaner} to register with
+ */
+ public PhantomCleanable(T referent, Cleaner cleaner) {
+ super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue);
+ this.list = CleanerImpl.getCleanerImpl(cleaner).phantomCleanableList;
+ insert();
+
+ // TODO: Replace getClass() with ReachabilityFence when it is available
+ cleaner.getClass();
+ referent.getClass();
+ }
+
+ /**
+ * Construct a new root of the list; not inserted.
+ */
+ PhantomCleanable() {
+ super(null, null);
+ this.list = this;
+ }
+
+ /**
+ * Insert this PhantomCleanable after the list head.
+ */
+ private void insert() {
+ synchronized (list) {
+ prev = list;
+ next = list.next;
+ next.prev = this;
+ list.next = this;
+ }
+ }
+
+ /**
+ * Remove this PhantomCleanable from the list.
+ *
+ * @return true if Cleanable was removed or false if not because
+ * it had already been removed before
+ */
+ private boolean remove() {
+ synchronized (list) {
+ if (next != this) {
+ next.prev = prev;
+ prev.next = next;
+ prev = this;
+ next = this;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the list's next reference refers to itself.
+ *
+ * @return true if the list is empty
+ */
+ boolean isListEmpty() {
+ synchronized (list) {
+ return list == list.next;
+ }
+ }
+
+ /**
+ * Unregister this PhantomCleanable and invoke {@link #performCleanup()},
+ * ensuring at-most-once semantics.
+ */
+ @Override
+ public final void clean() {
+ if (remove()) {
+ super.clear();
+ performCleanup();
+ }
+ }
+
+ /**
+ * Unregister this PhantomCleanable and clear the reference.
+ * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
+ */
+ @Override
+ public void clear() {
+ if (remove()) {
+ super.clear();
+ }
+ }
+
+ /**
+ * The {@code performCleanup} abstract method is overridden
+ * to implement the cleaning logic.
+ * The {@code performCleanup} method should not be called except
+ * by the {@link #clean} method which ensures at most once semantics.
+ */
+ protected abstract void performCleanup();
+
+ /**
+ * This method always throws {@link UnsupportedOperationException}.
+ * Enqueuing details of {@link Cleaner.Cleanable}
+ * are a private implementation detail.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public final boolean isEnqueued() {
+ throw new UnsupportedOperationException("isEnqueued");
+ }
+
+ /**
+ * This method always throws {@link UnsupportedOperationException}.
+ * Enqueuing details of {@link Cleaner.Cleanable}
+ * are a private implementation detail.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public final boolean enqueue() {
+ throw new UnsupportedOperationException("enqueue");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/SoftCleanable.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2015, 2016, 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.internal.ref;
+
+import java.lang.ref.Cleaner;
+import java.lang.ref.SoftReference;
+import java.util.Objects;
+
+/**
+ * SoftCleanable subclasses efficiently encapsulate cleanup state and
+ * the cleaning action.
+ * Subclasses implement the abstract {@link #performCleanup()} method
+ * to provide the cleaning action.
+ * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable}
+ * are registered with the {@link Cleaner}.
+ * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
+ * referent becomes softly reachable.
+ */
+public abstract class SoftCleanable<T> extends SoftReference<T>
+ implements Cleaner.Cleanable {
+
+ /**
+ * Links to previous and next in a doubly-linked list.
+ */
+ SoftCleanable<?> prev = this, next = this;
+
+ /**
+ * The list of SoftCleanable; synchronizes insert and remove.
+ */
+ private final SoftCleanable<?> list;
+
+ /**
+ * Constructs new {@code SoftCleanableReference} with
+ * {@code non-null referent} and {@code non-null cleaner}.
+ * The {@code cleaner} is not retained by this reference; it is only used
+ * to register the newly constructed {@link Cleaner.Cleanable Cleanable}.
+ *
+ * @param referent the referent to track
+ * @param cleaner the {@code Cleaner} to register with
+ */
+ public SoftCleanable(T referent, Cleaner cleaner) {
+ super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue);
+ list = CleanerImpl.getCleanerImpl(cleaner).softCleanableList;
+ insert();
+
+ // TODO: Replace getClass() with ReachabilityFence when it is available
+ cleaner.getClass();
+ referent.getClass();
+ }
+
+ /**
+ * Construct a new root of the list; not inserted.
+ */
+ SoftCleanable() {
+ super(null, null);
+ this.list = this;
+ }
+
+ /**
+ * Insert this SoftCleanableReference after the list head.
+ */
+ private void insert() {
+ synchronized (list) {
+ prev = list;
+ next = list.next;
+ next.prev = this;
+ list.next = this;
+ }
+ }
+
+ /**
+ * Remove this SoftCleanableReference from the list.
+ *
+ * @return true if Cleanable was removed or false if not because
+ * it had already been removed before
+ */
+ private boolean remove() {
+ synchronized (list) {
+ if (next != this) {
+ next.prev = prev;
+ prev.next = next;
+ prev = this;
+ next = this;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the list's next reference refers to itself.
+ *
+ * @return true if the list is empty
+ */
+ boolean isListEmpty() {
+ synchronized (list) {
+ return list == list.next;
+ }
+ }
+
+ /**
+ * Unregister this SoftCleanable reference and invoke {@link #performCleanup()},
+ * ensuring at-most-once semantics.
+ */
+ @Override
+ public final void clean() {
+ if (remove()) {
+ super.clear();
+ performCleanup();
+ }
+ }
+
+ /**
+ * Unregister this SoftCleanable and clear the reference.
+ * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
+ */
+ @Override
+ public void clear() {
+ if (remove()) {
+ super.clear();
+ }
+ }
+
+ /**
+ * The {@code performCleanup} abstract method is overridden
+ * to implement the cleaning logic.
+ * The {@code performCleanup} method should not be called except
+ * by the {@link #clean} method which ensures at most once semantics.
+ */
+ protected abstract void performCleanup();
+
+ /**
+ * This method always throws {@link UnsupportedOperationException}.
+ * Enqueuing details of {@link Cleaner.Cleanable}
+ * are a private implementation detail.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public final boolean isEnqueued() {
+ throw new UnsupportedOperationException("isEnqueued");
+ }
+
+ /**
+ * This method always throws {@link UnsupportedOperationException}.
+ * Enqueuing details of {@link Cleaner.Cleanable}
+ * are a private implementation detail.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public final boolean enqueue() {
+ throw new UnsupportedOperationException("enqueue");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/ref/WeakCleanable.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,178 @@
+package jdk.internal.ref;
+
+/*
+ * Copyright (c) 2015, 2016, 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.
+ */
+
+import java.lang.ref.Cleaner;
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+
+/**
+ * WeakCleanable subclasses efficiently encapsulate cleanup state and
+ * the cleaning action.
+ * Subclasses implement the abstract {@link #performCleanup()} method
+ * to provide the cleaning action.
+ * When constructed, the object reference and the {@link Cleaner.Cleanable Cleanable}
+ * are registered with the {@link Cleaner}.
+ * The Cleaner invokes {@link Cleaner.Cleanable#clean() clean} after the
+ * referent becomes weakly reachable.
+ */
+public abstract class WeakCleanable<T> extends WeakReference<T>
+ implements Cleaner.Cleanable {
+
+ /**
+ * Links to previous and next in a doubly-linked list.
+ */
+ WeakCleanable<?> prev = this, next = this;
+
+ /**
+ * The list of WeakCleanable; synchronizes insert and remove.
+ */
+ private final WeakCleanable<?> list;
+
+ /**
+ * Constructs new {@code WeakCleanableReference} with
+ * {@code non-null referent} and {@code non-null cleaner}.
+ * The {@code cleaner} is not retained by this reference; it is only used
+ * to register the newly constructed {@link Cleaner.Cleanable Cleanable}.
+ *
+ * @param referent the referent to track
+ * @param cleaner the {@code Cleaner} to register new reference with
+ */
+ public WeakCleanable(T referent, Cleaner cleaner) {
+ super(Objects.requireNonNull(referent), CleanerImpl.getCleanerImpl(cleaner).queue);
+ list = CleanerImpl.getCleanerImpl(cleaner).weakCleanableList;
+ insert();
+
+ // TODO: Replace getClass() with ReachabilityFence when it is available
+ cleaner.getClass();
+ referent.getClass();
+ }
+
+ /**
+ * Construct a new root of the list; not inserted.
+ */
+ WeakCleanable() {
+ super(null, null);
+ this.list = this;
+ }
+
+ /**
+ * Insert this WeakCleanableReference after the list head.
+ */
+ private void insert() {
+ synchronized (list) {
+ prev = list;
+ next = list.next;
+ next.prev = this;
+ list.next = this;
+ }
+ }
+
+ /**
+ * Remove this WeakCleanableReference from the list.
+ *
+ * @return true if Cleanable was removed or false if not because
+ * it had already been removed before
+ */
+ private boolean remove() {
+ synchronized (list) {
+ if (next != this) {
+ next.prev = prev;
+ prev.next = next;
+ prev = this;
+ next = this;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the list's next reference refers to itself.
+ *
+ * @return true if the list is empty
+ */
+ boolean isListEmpty() {
+ synchronized (list) {
+ return list == list.next;
+ }
+ }
+
+ /**
+ * Unregister this WeakCleanable reference and invoke {@link #performCleanup()},
+ * ensuring at-most-once semantics.
+ */
+ @Override
+ public final void clean() {
+ if (remove()) {
+ super.clear();
+ performCleanup();
+ }
+ }
+
+ /**
+ * Unregister this WeakCleanable and clear the reference.
+ * Due to inherent concurrency, {@link #performCleanup()} may still be invoked.
+ */
+ @Override
+ public void clear() {
+ if (remove()) {
+ super.clear();
+ }
+ }
+
+ /**
+ * The {@code performCleanup} abstract method is overridden
+ * to implement the cleaning logic.
+ * The {@code performCleanup} method should not be called except
+ * by the {@link #clean} method which ensures at most once semantics.
+ */
+ protected abstract void performCleanup();
+
+ /**
+ * This method always throws {@link UnsupportedOperationException}.
+ * Enqueuing details of {@link Cleaner.Cleanable}
+ * are a private implementation detail.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public final boolean isEnqueued() {
+ throw new UnsupportedOperationException("isEnqueued");
+ }
+
+ /**
+ * This method always throws {@link UnsupportedOperationException}.
+ * Enqueuing details of {@link Cleaner.Cleanable}
+ * are a private implementation detail.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public final boolean enqueue() {
+ throw new UnsupportedOperationException("enqueue");
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/misc/CEFormatException.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1995, 2011, 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 sun.misc;
-
-import java.io.IOException;
-
-public class CEFormatException extends IOException {
- static final long serialVersionUID = -7139121221067081482L;
- public CEFormatException(String s) {
- super(s);
- }
-}
-
--- a/jdk/src/java.base/share/classes/sun/misc/CEStreamExhausted.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 1995, 2011, 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 sun.misc;
-
-import java.io.IOException;
-
-/** This exception is thrown when EOF is reached */
-public class CEStreamExhausted extends IOException {
- static final long serialVersionUID = -5889118049525891904L;
-}
-
--- a/jdk/src/java.base/share/classes/sun/misc/JarFilter.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2001, 2006, 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 sun.misc;
-
-import java.io.File;
-import java.io.FilenameFilter;
-
-/**
- * This class checks that only jar and zip files are included in the file list.
- * This class is used in extension installation support (ExtensionDependency).
- *
- * @deprecated this class will be removed in a future release.
- * @author Michael Colburn
- */
-@Deprecated
-public class JarFilter implements FilenameFilter {
-
- public boolean accept(File dir, String name) {
- String lower = name.toLowerCase();
- return lower.endsWith(".jar") || lower.endsWith(".zip");
- }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/Perf.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,538 +0,0 @@
-/*
- * Copyright (c) 2002, 2006, 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 sun.misc;
-
-import java.nio.ByteBuffer;
-import java.security.Permission;
-import java.security.PrivilegedAction;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-/**
- * The Perf class provides the ability to attach to an instrumentation
- * buffer maintained by a Java virtual machine. The instrumentation
- * buffer may be for the Java virtual machine running the methods of
- * this class or it may be for another Java virtual machine on the
- * same system.
- * <p>
- * In addition, this class provides methods to create instrumentation
- * objects in the instrumentation buffer for the Java virtual machine
- * that is running these methods. It also contains methods for acquiring
- * the value of a platform specific high resolution clock for time
- * stamp and interval measurement purposes.
- *
- * @author Brian Doherty
- * @since 1.4.2
- * @see #getPerf
- * @see sun.misc.Perf$GetPerfAction
- * @see java.nio.ByteBuffer
- */
-public final class Perf {
-
- private static Perf instance;
-
- private static final int PERF_MODE_RO = 0;
- private static final int PERF_MODE_RW = 1;
-
- private Perf() { } // prevent instantiation
-
- /**
- * The GetPerfAction class is a convenience class for acquiring access
- * to the singleton Perf instance using the
- * <code>AccessController.doPrivileged()</code> method.
- * <p>
- * An instance of this class can be used as the argument to
- * <code>AccessController.doPrivileged(PrivilegedAction)</code>.
- * <p> Here is a suggested idiom for use of this class:
- *
- * <blockquote><pre>{@code
- * class MyTrustedClass {
- * private static final Perf perf =
- * AccessController.doPrivileged(new Perf.GetPerfAction<Perf>());
- * ...
- * }
- * }</pre></blockquote>
- * <p>
- * In the presence of a security manager, the <code>MyTrustedClass</code>
- * class in the above example will need to be granted the
- * <em>"sun.misc.Perf.getPerf"</em> <code>RuntimePermission</code>
- * permission in order to successfully acquire the singleton Perf instance.
- * <p>
- * Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
- * is not a JDK specified permission.
- *
- * @see java.security.AccessController#doPrivileged(PrivilegedAction)
- * @see java.lang.RuntimePermission
- */
- public static class GetPerfAction implements PrivilegedAction<Perf>
- {
- /**
- * Run the <code>Perf.getPerf()</code> method in a privileged context.
- *
- * @see #getPerf
- */
- public Perf run() {
- return getPerf();
- }
- }
-
- /**
- * Return a reference to the singleton Perf instance.
- * <p>
- * The getPerf() method returns the singleton instance of the Perf
- * class. The returned object provides the caller with the capability
- * for accessing the instrumentation buffer for this or another local
- * Java virtual machine.
- * <p>
- * If a security manager is installed, its <code>checkPermission</code>
- * method is called with a <code>RuntimePermission</code> with a target
- * of <em>"sun.misc.Perf.getPerf"</em>. A security exception will result
- * if the caller has not been granted this permission.
- * <p>
- * Access to the returned <code>Perf</code> object should be protected
- * by its caller and not passed on to untrusted code. This object can
- * be used to attach to the instrumentation buffer provided by this Java
- * virtual machine or for those of other Java virtual machines running
- * on the same system. The instrumentation buffer may contain senstitive
- * information. API's built on top of this interface may want to provide
- * finer grained access control to the contents of individual
- * instrumentation objects contained within the buffer.
- * <p>
- * Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
- * is not a JDK specified permission.
- *
- * @return A reference to the singleton Perf instance.
- * @throws AccessControlException if a security manager exists and
- * its <code>checkPermission</code> method doesn't allow
- * access to the <em>"sun.misc.Perf.getPerf"</em> target.
- * @see java.lang.RuntimePermission
- * @see #attach
- */
- public static Perf getPerf()
- {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- Permission perm = new RuntimePermission("sun.misc.Perf.getPerf");
- security.checkPermission(perm);
- }
-
- return instance;
- }
-
- /**
- * Attach to the instrumentation buffer for the specified Java virtual
- * machine.
- * <p>
- * This method will attach to the instrumentation buffer for the
- * specified virtual machine. It returns a <code>ByteBuffer</code> object
- * that is initialized to access the instrumentation buffer for the
- * indicated Java virtual machine. The <code>lvmid</code> parameter is
- * a integer value that uniquely identifies the target local Java virtual
- * machine. It is typically, but not necessarily, the process id of
- * the target Java virtual machine.
- * <p>
- * If the <code>lvmid</code> identifies a Java virtual machine different
- * from the one running this method, then the coherency characteristics
- * of the buffer are implementation dependent. Implementations that do
- * not support named, coherent, shared memory may return a
- * <code>ByteBuffer</code> object that contains only a snap shot of the
- * data in the instrumentation buffer. Implementations that support named,
- * coherent, shared memory, may return a <code>ByteBuffer</code> object
- * that will be changing dynamically over time as the target Java virtual
- * machine updates its mapping of this buffer.
- * <p>
- * If the <code>lvmid</code> is 0 or equal to the actual <code>lvmid</code>
- * for the Java virtual machine running this method, then the returned
- * <code>ByteBuffer</code> object will always be coherent and dynamically
- * changing.
- * <p>
- * The attach mode specifies the access permissions requested for the
- * instrumentation buffer of the target virtual machine. The permitted
- * access permissions are:
- * <ul>
- * <li>"r" - Read only access. This Java virtual machine has only
- * read access to the instrumentation buffer for the target Java
- * virtual machine.
- * <li>"rw" - Read/Write access. This Java virtual machine has read and
- * write access to the instrumentation buffer for the target Java virtual
- * machine. This mode is currently not supported and is reserved for
- * future enhancements.
- * </ul>
- *
- * @param lvmid an integer that uniquely identifies the
- * target local Java virtual machine.
- * @param mode a string indicating the attach mode.
- * @return ByteBuffer a direct allocated byte buffer
- * @throws IllegalArgumentException The lvmid or mode was invalid.
- * @throws IOException An I/O error occurred while trying to acquire
- * the instrumentation buffer.
- * @throws OutOfMemoryError The instrumentation buffer could not be mapped
- * into the virtual machine's address space.
- * @see java.nio.ByteBuffer
- */
- public ByteBuffer attach(int lvmid, String mode)
- throws IllegalArgumentException, IOException
- {
- if (mode.compareTo("r") == 0) {
- return attachImpl(null, lvmid, PERF_MODE_RO);
- }
- else if (mode.compareTo("rw") == 0) {
- return attachImpl(null, lvmid, PERF_MODE_RW);
- }
- else {
- throw new IllegalArgumentException("unknown mode");
- }
- }
-
- /**
- * Attach to the instrumentation buffer for the specified Java virtual
- * machine owned by the given user.
- * <p>
- * This method behaves just as the <code>attach(int lvmid, String mode)
- * </code> method, except that it only searches for Java virtual machines
- * owned by the specified user.
- *
- * @param user A <code>String</code> object containing the
- * name of the user that owns the target Java
- * virtual machine.
- * @param lvmid an integer that uniquely identifies the
- * target local Java virtual machine.
- * @param mode a string indicating the attach mode.
- * @return ByteBuffer a direct allocated byte buffer
- * @throws IllegalArgumentException The lvmid or mode was invalid.
- * @throws IOException An I/O error occurred while trying to acquire
- * the instrumentation buffer.
- * @throws OutOfMemoryError The instrumentation buffer could not be mapped
- * into the virtual machine's address space.
- * @see java.nio.ByteBuffer
- */
- public ByteBuffer attach(String user, int lvmid, String mode)
- throws IllegalArgumentException, IOException
- {
- if (mode.compareTo("r") == 0) {
- return attachImpl(user, lvmid, PERF_MODE_RO);
- }
- else if (mode.compareTo("rw") == 0) {
- return attachImpl(user, lvmid, PERF_MODE_RW);
- }
- else {
- throw new IllegalArgumentException("unknown mode");
- }
- }
-
- /**
- * Call the implementation specific attach method.
- * <p>
- * This method calls into the Java virtual machine to perform the platform
- * specific attach method. Buffers returned from this method are
- * internally managed as <code>PhantomRefereces</code> to provide for
- * guaranteed, secure release of the native resources.
- *
- * @param user A <code>String</code> object containing the
- * name of the user that owns the target Java
- * virtual machine.
- * @param lvmid an integer that uniquely identifies the
- * target local Java virtual machine.
- * @param mode a string indicating the attach mode.
- * @return ByteBuffer a direct allocated byte buffer
- * @throws IllegalArgumentException The lvmid or mode was invalid.
- * @throws IOException An I/O error occurred while trying to acquire
- * the instrumentation buffer.
- * @throws OutOfMemoryError The instrumentation buffer could not be mapped
- * into the virtual machine's address space.
- */
- private ByteBuffer attachImpl(String user, int lvmid, int mode)
- throws IllegalArgumentException, IOException
- {
- final ByteBuffer b = attach(user, lvmid, mode);
-
- if (lvmid == 0) {
- // The native instrumentation buffer for this Java virtual
- // machine is never unmapped.
- return b;
- }
- else {
- // This is an instrumentation buffer for another Java virtual
- // machine with native resources that need to be managed. We
- // create a duplicate of the native ByteBuffer and manage it
- // with a Cleaner object (PhantomReference). When the duplicate
- // becomes only phantomly reachable, the native resources will
- // be released.
-
- final ByteBuffer dup = b.duplicate();
- Cleaner.create(dup, new Runnable() {
- public void run() {
- try {
- instance.detach(b);
- }
- catch (Throwable th) {
- // avoid crashing the reference handler thread,
- // but provide for some diagnosability
- assert false : th.toString();
- }
- }
- });
- return dup;
- }
- }
-
- /**
- * Native method to perform the implementation specific attach mechanism.
- * <p>
- * The implementation of this method may return distinct or identical
- * <code>ByteBuffer</code> objects for two distinct calls requesting
- * attachment to the same Java virtual machine.
- * <p>
- * For the Sun HotSpot JVM, two distinct calls to attach to the same
- * target Java virtual machine will result in two distinct ByteBuffer
- * objects returned by this method. This may change in a future release.
- *
- * @param user A <code>String</code> object containing the
- * name of the user that owns the target Java
- * virtual machine.
- * @param lvmid an integer that uniquely identifies the
- * target local Java virtual machine.
- * @param mode a string indicating the attach mode.
- * @return ByteBuffer a direct allocated byte buffer
- * @throws IllegalArgumentException The lvmid or mode was invalid.
- * @throws IOException An I/O error occurred while trying to acquire
- * the instrumentation buffer.
- * @throws OutOfMemoryError The instrumentation buffer could not be mapped
- * into the virtual machine's address space.
- */
- private native ByteBuffer attach(String user, int lvmid, int mode)
- throws IllegalArgumentException, IOException;
-
- /**
- * Native method to perform the implementation specific detach mechanism.
- * <p>
- * If this method is passed a <code>ByteBuffer</code> object that is
- * not created by the <code>attach</code> method, then the results of
- * this method are undefined, with unpredictable and potentially damaging
- * effects to the Java virtual machine. To prevent accidental or malicious
- * use of this method, all native ByteBuffer created by the <code>
- * attach</code> method are managed internally as PhantomReferences
- * and resources are freed by the system.
- * <p>
- * If this method is passed a <code>ByteBuffer</code> object created
- * by the <code>attach</code> method with a lvmid for the Java virtual
- * machine running this method (lvmid=0, for example), then the detach
- * request is silently ignored.
- *
- * @param ByteBuffer A direct allocated byte buffer created by the
- * <code>attach</code> method.
- * @see java.nio.ByteBuffer
- * @see #attach
- */
- private native void detach(ByteBuffer bb);
-
- /**
- * Create a <code>long</code> scalar entry in the instrumentation buffer
- * with the given variability characteristic, units, and initial value.
- * <p>
- * Access to the instrument is provided through the returned <code>
- * ByteBuffer</code> object. Typically, this object should be wrapped
- * with <code>LongBuffer</code> view object.
- *
- * @param variability the variability characteristic for this entry.
- * @param units the units for this entry.
- * @param name the name of this entry.
- * @param value the initial value for this entry.
- * @return ByteBuffer a direct allocated ByteBuffer object that
- * allows write access to a native memory location
- * containing a <code>long</code> value.
- *
- * see sun.misc.perf.Variability
- * see sun.misc.perf.Units
- * @see java.nio.ByteBuffer
- */
- public native ByteBuffer createLong(String name, int variability,
- int units, long value);
-
- /**
- * Create a <code>String</code> entry in the instrumentation buffer with
- * the given variability characteristic, units, and initial value.
- * <p>
- * The maximum length of the <code>String</code> stored in this string
- * instrument is given in by <code>maxLength</code> parameter. Updates
- * to this instrument with <code>String</code> values with lengths greater
- * than <code>maxLength</code> will be truncated to <code>maxLength</code>.
- * The truncated value will be terminated by a null character.
- * <p>
- * The underlying implementation may further limit the length of the
- * value, but will continue to preserve the null terminator.
- * <p>
- * Access to the instrument is provided through the returned <code>
- * ByteBuffer</code> object.
- *
- * @param variability the variability characteristic for this entry.
- * @param units the units for this entry.
- * @param name the name of this entry.
- * @param value the initial value for this entry.
- * @param maxLength the maximum string length for this string
- * instrument.
- * @return ByteBuffer a direct allocated ByteBuffer that allows
- * write access to a native memory location
- * containing a <code>long</code> value.
- *
- * see sun.misc.perf.Variability
- * see sun.misc.perf.Units
- * @see java.nio.ByteBuffer
- */
- public ByteBuffer createString(String name, int variability,
- int units, String value, int maxLength)
- {
- byte[] v = getBytes(value);
- byte[] v1 = new byte[v.length+1];
- System.arraycopy(v, 0, v1, 0, v.length);
- v1[v.length] = '\0';
- return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength));
- }
-
- /**
- * Create a <code>String</code> entry in the instrumentation buffer with
- * the given variability characteristic, units, and initial value.
- * <p>
- * The maximum length of the <code>String</code> stored in this string
- * instrument is implied by the length of the <code>value</code> parameter.
- * Subsequent updates to the value of this instrument will be truncated
- * to this implied maximum length. The truncated value will be terminated
- * by a null character.
- * <p>
- * The underlying implementation may further limit the length of the
- * initial or subsequent value, but will continue to preserve the null
- * terminator.
- * <p>
- * Access to the instrument is provided through the returned <code>
- * ByteBuffer</code> object.
- *
- * @param variability the variability characteristic for this entry.
- * @param units the units for this entry.
- * @param name the name of this entry.
- * @param value the initial value for this entry.
- * @return ByteBuffer a direct allocated ByteBuffer that allows
- * write access to a native memory location
- * containing a <code>long</code> value.
- *
- * see sun.misc.perf.Variability
- * see sun.misc.perf.Units
- * @see java.nio.ByteBuffer
- */
- public ByteBuffer createString(String name, int variability,
- int units, String value)
- {
- byte[] v = getBytes(value);
- byte[] v1 = new byte[v.length+1];
- System.arraycopy(v, 0, v1, 0, v.length);
- v1[v.length] = '\0';
- return createByteArray(name, variability, units, v1, v1.length);
- }
-
- /**
- * Create a <code>byte</code> vector entry in the instrumentation buffer
- * with the given variability characteristic, units, and initial value.
- * <p>
- * The <code>maxLength</code> parameter limits the size of the byte
- * array instrument such that the initial or subsequent updates beyond
- * this length are silently ignored. No special handling of truncated
- * updates is provided.
- * <p>
- * The underlying implementation may further limit the length of the
- * length of the initial or subsequent value.
- * <p>
- * Access to the instrument is provided through the returned <code>
- * ByteBuffer</code> object.
- *
- * @param variability the variability characteristic for this entry.
- * @param units the units for this entry.
- * @param name the name of this entry.
- * @param value the initial value for this entry.
- * @param maxLength the maximum length of this byte array.
- * @return ByteBuffer a direct allocated byte buffer that allows
- * write access to a native memory location
- * containing a <code>long</code> value.
- *
- * see sun.misc.perf.Variability
- * see sun.misc.perf.Units
- * @see java.nio.ByteBuffer
- */
- public native ByteBuffer createByteArray(String name, int variability,
- int units, byte[] value,
- int maxLength);
-
-
- /**
- * convert string to an array of UTF-8 bytes
- */
- private static byte[] getBytes(String s)
- {
- byte[] bytes = null;
-
- try {
- bytes = s.getBytes("UTF-8");
- }
- catch (UnsupportedEncodingException e) {
- // ignore, UTF-8 encoding is always known
- }
-
- return bytes;
- }
-
- /**
- * Return the value of the High Resolution Counter.
- *
- * The High Resolution Counter returns the number of ticks since
- * since the start of the Java virtual machine. The resolution of
- * the counter is machine dependent and can be determined from the
- * value return by the {@link #highResFrequency} method.
- *
- * @return the number of ticks of machine dependent resolution since
- * the start of the Java virtual machine.
- *
- * @see #highResFrequency
- * @see java.lang.System#currentTimeMillis()
- */
- public native long highResCounter();
-
- /**
- * Returns the frequency of the High Resolution Counter, in ticks per
- * second.
- *
- * This value can be used to convert the value of the High Resolution
- * Counter, as returned from a call to the {@link #highResCounter} method,
- * into the number of seconds since the start of the Java virtual machine.
- *
- * @return the frequency of the High Resolution Counter.
- * @see #highResCounter
- */
- public native long highResFrequency();
-
- private static native void registerNatives();
-
- static {
- registerNatives();
- instance = new Perf();
- }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/PerfCounter.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2009, 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 sun.misc;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.LongBuffer;
-import java.security.AccessController;
-
-/**
- * Performance counter support for internal JRE classes.
- * This class defines a fixed list of counters for the platform
- * to use as an interim solution until RFE# 6209222 is implemented.
- * The perf counters will be created in the jvmstat perf buffer
- * that the HotSpot VM creates. The default size is 32K and thus
- * the number of counters is bounded. You can alter the size
- * with {@code -XX:PerfDataMemorySize=<bytes>} option. If there is
- * insufficient memory in the jvmstat perf buffer, the C heap memory
- * will be used and thus the application will continue to run if
- * the counters added exceeds the buffer size but the counters
- * will be missing.
- *
- * See HotSpot jvmstat implementation for certain circumstances
- * that the jvmstat perf buffer is not supported.
- *
- */
-public class PerfCounter {
- private static final Perf perf =
- AccessController.doPrivileged(new Perf.GetPerfAction());
-
- // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp
- private static final int V_Constant = 1;
- private static final int V_Monotonic = 2;
- private static final int V_Variable = 3;
- private static final int U_None = 1;
-
- private final String name;
- private final LongBuffer lb;
-
- private PerfCounter(String name, int type) {
- this.name = name;
- ByteBuffer bb = perf.createLong(name, type, U_None, 0L);
- bb.order(ByteOrder.nativeOrder());
- this.lb = bb.asLongBuffer();
- }
-
- static PerfCounter newPerfCounter(String name) {
- return new PerfCounter(name, V_Variable);
- }
-
- static PerfCounter newConstantPerfCounter(String name) {
- PerfCounter c = new PerfCounter(name, V_Constant);
- return c;
- }
-
- /**
- * Returns the current value of the perf counter.
- */
- public synchronized long get() {
- return lb.get(0);
- }
-
- /**
- * Sets the value of the perf counter to the given newValue.
- */
- public synchronized void set(long newValue) {
- lb.put(0, newValue);
- }
-
- /**
- * Adds the given value to the perf counter.
- */
- public synchronized void add(long value) {
- long res = get() + value;
- lb.put(0, res);
- }
-
- /**
- * Increments the perf counter with 1.
- */
- public void increment() {
- add(1);
- }
-
- /**
- * Adds the given interval to the perf counter.
- */
- public void addTime(long interval) {
- add(interval);
- }
-
- /**
- * Adds the elapsed time from the given start time (ns) to the perf counter.
- */
- public void addElapsedTimeFrom(long startTime) {
- add(System.nanoTime() - startTime);
- }
-
- @Override
- public String toString() {
- return name + " = " + get();
- }
-
- static class CoreCounters {
- static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime");
- static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses");
- static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime");
- static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime");
- static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles");
- static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime");
- }
-
- static class WindowsClientCounters {
- static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available");
- }
-
- /**
- * Number of findClass calls
- */
- public static PerfCounter getFindClasses() {
- return CoreCounters.lc;
- }
-
- /**
- * Time (ns) spent in finding classes that includes
- * lookup and read class bytes and defineClass
- */
- public static PerfCounter getFindClassTime() {
- return CoreCounters.lct;
- }
-
- /**
- * Time (ns) spent in finding classes
- */
- public static PerfCounter getReadClassBytesTime() {
- return CoreCounters.rcbt;
- }
-
- /**
- * Time (ns) spent in the parent delegation to
- * the parent of the defining class loader
- */
- public static PerfCounter getParentDelegationTime() {
- return CoreCounters.pdt;
- }
-
- /**
- * Number of zip files opened.
- */
- public static PerfCounter getZipFileCount() {
- return CoreCounters.zfc;
- }
-
- /**
- * Time (ns) spent in opening the zip files that
- * includes building the entries hash table
- */
- public static PerfCounter getZipFileOpenTime() {
- return CoreCounters.zfot;
- }
-
- /**
- * D3D graphic pipeline available
- */
- public static PerfCounter getD3DAvailable() {
- return WindowsClientCounters.d3dAvailable;
- }
-}
--- a/jdk/src/java.base/share/classes/sun/misc/PerformanceLogger.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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 sun.misc;
-
-import java.util.Vector;
-import java.io.FileWriter;
-import java.io.File;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-
-/**
- * This class is intended to be a central place for the jdk to
- * log timing events of interest. There is pre-defined event
- * of startTime, as well as a general
- * mechanism of setting arbitrary times in an array.
- * All unreserved times in the array can be used by callers
- * in application-defined situations. The caller is responsible
- * for setting and getting all times and for doing whatever
- * analysis is interesting; this class is merely a central container
- * for those timing values.
- * Note that, due to the variables in this class being static,
- * use of particular time values by multiple applets will cause
- * confusing results. For example, if plugin runs two applets
- * simultaneously, the initTime for those applets will collide
- * and the results may be undefined.
- * <P>
- * To automatically track startup performance in an app or applet,
- * use the command-line parameter sun.perflog as follows:<BR>
- * <pre>{@code
- * -Dsun.perflog[=file:<filename>]
- * }</pre>
- * <BR>
- * where simply using the parameter with no value will enable output
- * to the console and a value of "{@code file:<filename>}" will cause
- * that given filename to be created and used for all output.
- * <P>
- * By default, times are measured using System.currentTimeMillis(). To use
- * System.nanoTime() instead, add the command-line parameter:<BR>
- -Dsun.perflog.nano=true
- * <BR>
- * <P>
- * <B>Warning: Use at your own risk!</B>
- * This class is intended for internal testing
- * purposes only and may be removed at any time. More
- * permanent monitoring and profiling APIs are expected to be
- * developed for future releases and this class will cease to
- * exist once those APIs are in place.
- * @author Chet Haase
- */
-public class PerformanceLogger {
-
- // Timing values of global interest
- private static final int START_INDEX = 0; // VM start
- private static final int LAST_RESERVED = START_INDEX;
-
- private static boolean perfLoggingOn = false;
- private static boolean useNanoTime = false;
- private static Vector<TimeData> times;
- private static String logFileName = null;
- private static Writer logWriter = null;
- private static long baseTime;
-
- static {
- String perfLoggingProp =
- java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("sun.perflog"));
- if (perfLoggingProp != null) {
- perfLoggingOn = true;
-
- // Check if we should use nanoTime
- String perfNanoProp =
- java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("sun.perflog.nano"));
- if (perfNanoProp != null) {
- useNanoTime = true;
- }
-
- // Now, figure out what the user wants to do with the data
- if (perfLoggingProp.regionMatches(true, 0, "file:", 0, 5)) {
- logFileName = perfLoggingProp.substring(5);
- }
- if (logFileName != null) {
- if (logWriter == null) {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- try {
- File logFile = new File(logFileName);
- logFile.createNewFile();
- logWriter = new FileWriter(logFile);
- } catch (Exception e) {
- System.out.println(e + ": Creating logfile " +
- logFileName +
- ". Log to console");
- }
- return null;
- }
- });
- }
- }
- if (logWriter == null) {
- logWriter = new OutputStreamWriter(System.out);
- }
- }
- times = new Vector<TimeData>(10);
- // Reserve predefined slots
- for (int i = 0; i <= LAST_RESERVED; ++i) {
- times.add(new TimeData("Time " + i + " not set", 0));
- }
- }
-
- /**
- * Returns status of whether logging is enabled or not. This is
- * provided as a convenience method so that users do not have to
- * perform the same GetPropertyAction check as above to determine whether
- * to enable performance logging.
- */
- public static boolean loggingEnabled() {
- return perfLoggingOn;
- }
-
-
- /**
- * Internal class used to store time/message data together.
- */
- static class TimeData {
- String message;
- long time;
-
- TimeData(String message, long time) {
- this.message = message;
- this.time = time;
- }
-
- String getMessage() {
- return message;
- }
-
- long getTime() {
- return time;
- }
- }
-
- /**
- * Return the current time, in millis or nanos as appropriate
- */
- private static long getCurrentTime() {
- if (useNanoTime) {
- return System.nanoTime();
- } else {
- return System.currentTimeMillis();
- }
- }
-
- /**
- * Sets the start time. Ideally, this is the earliest time available
- * during the startup of a Java applet or application. This time is
- * later used to analyze the difference between the initial startup
- * time and other events in the system (such as an applet's init time).
- */
- public static void setStartTime(String message) {
- if (loggingEnabled()) {
- long nowTime = getCurrentTime();
- setStartTime(message, nowTime);
- }
- }
-
- /**
- * Sets the base time, output can then
- * be displayed as offsets from the base time;.
- */
- public static void setBaseTime(long time) {
- if (loggingEnabled()) {
- baseTime = time;
- }
- }
-
- /**
- * Sets the start time.
- * This version of the method is
- * given the time to log, instead of expecting this method to
- * get the time itself. This is done in case the time was
- * recorded much earlier than this method was called.
- */
- public static void setStartTime(String message, long time) {
- if (loggingEnabled()) {
- times.set(START_INDEX, new TimeData(message, time));
- }
- }
-
- /**
- * Gets the start time, which should be the time when
- * the java process started, prior to the VM actually being
- * loaded.
- */
- public static long getStartTime() {
- if (loggingEnabled()) {
- return times.get(START_INDEX).getTime();
- } else {
- return 0;
- }
- }
-
- /**
- * Sets the value of a given time and returns the index of the
- * slot that that time was stored in.
- */
- public static int setTime(String message) {
- if (loggingEnabled()) {
- long nowTime = getCurrentTime();
- return setTime(message, nowTime);
- } else {
- return 0;
- }
- }
-
- /**
- * Sets the value of a given time and returns the index of the
- * slot that that time was stored in.
- * This version of the method is
- * given the time to log, instead of expecting this method to
- * get the time itself. This is done in case the time was
- * recorded much earlier than this method was called.
- */
- public static int setTime(String message, long time) {
- if (loggingEnabled()) {
- // times is already synchronized, but we need to ensure that
- // the size used in times.set() is the same used when returning
- // the index of that operation.
- synchronized (times) {
- times.add(new TimeData(message, time));
- return (times.size() - 1);
- }
- } else {
- return 0;
- }
- }
-
- /**
- * Returns time at given index.
- */
- public static long getTimeAtIndex(int index) {
- if (loggingEnabled()) {
- return times.get(index).getTime();
- } else {
- return 0;
- }
- }
-
- /**
- * Returns message at given index.
- */
- public static String getMessageAtIndex(int index) {
- if (loggingEnabled()) {
- return times.get(index).getMessage();
- } else {
- return null;
- }
- }
-
- /**
- * Outputs all data to parameter-specified Writer object
- */
- public static void outputLog(Writer writer) {
- if (loggingEnabled()) {
- try {
- synchronized(times) {
- for (int i = 0; i < times.size(); ++i) {
- TimeData td = times.get(i);
- if (td != null) {
- writer.write(i + " " + td.getMessage() + ": " +
- (td.getTime() - baseTime) + "\n");
-
- }
- }
- }
- writer.flush();
- } catch (Exception e) {
- System.out.println(e + ": Writing performance log to " +
- writer);
- }
- }
- }
-
- /**
- * Outputs all data to whatever location the user specified
- * via sun.perflog command-line parameter.
- */
- public static void outputLog() {
- outputLog(logWriter);
- }
-}
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -967,12 +967,6 @@
return "";
}
- @Override
- protected void finalize() throws Throwable {
- // This should do nothing. The stream finalizer will
- // close the fd.
- }
-
public void setDoNotRetry(boolean value) {
// failedOnce is used to determine if a request should be retried.
failedOnce = value;
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -108,13 +108,6 @@
return false;
}
- /*
- * close the jar file.
- */
- protected void finalize() throws IOException {
- close();
- }
-
/**
* Returns the <code>ZipEntry</code> for the given entry name or
* <code>null</code> if not found.
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -2211,7 +2211,7 @@
@Override
public synchronized String getHandshakeApplicationProtocol() {
- if ((handshaker != null) && !handshaker.started()) {
+ if ((handshaker != null) && handshaker.started()) {
return handshaker.getHandshakeApplicationProtocol();
}
return null;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -2598,7 +2598,7 @@
@Override
public synchronized String getHandshakeApplicationProtocol() {
- if ((handshaker != null) && !handshaker.started()) {
+ if ((handshaker != null) && handshaker.started()) {
return handshaker.getHandshakeApplicationProtocol();
}
return null;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -153,13 +153,11 @@
getSupportedAlgorithms(AlgorithmConstraints constraints) {
Collection<SignatureAndHashAlgorithm> supported = new ArrayList<>();
- synchronized (priorityMap) {
- for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) {
- if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM &&
- constraints.permits(SIGNATURE_PRIMITIVE_SET,
- sigAlg.algorithm, null)) {
- supported.add(sigAlg);
- }
+ for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) {
+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM &&
+ constraints.permits(SIGNATURE_PRIMITIVE_SET,
+ sigAlg.algorithm, null)) {
+ supported.add(sigAlg);
}
}
--- a/jdk/src/java.base/share/conf/security/java.policy Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/share/conf/security/java.policy Sat Jan 16 00:28:28 2016 +0000
@@ -98,17 +98,6 @@
// default permissions granted to all domains
grant {
- // Allows any thread to stop itself using the java.lang.Thread.stop()
- // method that takes no argument.
- // Note that this permission is granted by default only to remain
- // backwards compatible.
- // It is strongly recommended that you either remove this permission
- // from this policy file or further restrict it to code sources
- // that you specify, because Thread.stop() is potentially unsafe.
- // See the API specification of java.lang.Thread.stop() for more
- // information.
- permission java.lang.RuntimePermission "stopThread";
-
// allows anyone to listen on dynamic ports
permission java.net.SocketPermission "localhost:0", "listen";
--- a/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -47,6 +47,9 @@
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
super.setOption(name, value);
} else {
+ if (!flowSupported()) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
if (isClosed()) {
throw new SocketException("Socket closed");
}
@@ -61,6 +64,9 @@
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
return super.getOption(name);
}
+ if (!flowSupported()) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
if (isClosed()) {
throw new SocketException("Socket closed");
}
--- a/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/unix/classes/java/net/PlainSocketImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -61,6 +61,9 @@
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
super.setOption(name, value);
} else {
+ if (getSocket() == null || !flowSupported()) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
if (isClosedOrPending()) {
throw new SocketException("Socket closed");
}
@@ -75,6 +78,9 @@
if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
return super.getOption(name);
}
+ if (getSocket() == null || !flowSupported()) {
+ throw new UnsupportedOperationException("unsupported option");
+ }
if (isClosedOrPending()) {
throw new SocketException("Socket closed");
}
--- a/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/windows/classes/java/lang/ProcessImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -42,8 +42,10 @@
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.ref.CleanerFactory;
/* This class is for the exclusive use of ProcessBuilder.start() to
* create new processes.
@@ -417,6 +419,10 @@
handle = create(cmdstr, envblock, path,
stdHandles, redirectErrorStream);
+ // Register a cleaning function to close the handle
+ final long local_handle = handle; // local to prevent capture of this
+ CleanerFactory.cleaner().register(this, () -> closeHandle(local_handle));
+
processHandle = ProcessHandleImpl.getInternal(getProcessId0(handle));
java.security.AccessController.doPrivileged(
@@ -463,10 +469,6 @@
return stderr_stream;
}
- protected void finalize() {
- closeHandle(handle);
- }
-
private static final int STILL_ACTIVE = getStillActive();
private static native int getStillActive();
--- a/jdk/src/java.base/windows/native/libjli/java_md.c Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c Sat Jan 16 00:28:28 2016 +0000
@@ -337,6 +337,15 @@
}
}
+ /* Try getting path to JRE from path to JLI.DLL */
+ if (GetApplicationHomeFromDll(path, pathsize)) {
+ JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path);
+ if (stat(javadll, &s) == 0) {
+ JLI_TraceLauncher("JRE path is %s\n", path);
+ return JNI_TRUE;
+ }
+ }
+
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
@@ -404,17 +413,17 @@
}
/*
- * If app is "c:\foo\bin\javac", then put "c:\foo" into buf.
+ * Removes the trailing file name and one sub-folder from a path.
+ * If buf is "c:\foo\bin\javac", then put "c:\foo" into buf.
*/
jboolean
-GetApplicationHome(char *buf, jint bufsize)
+TruncatePath(char *buf)
{
char *cp;
- GetModuleFileName(0, buf, bufsize);
*JLI_StrRChr(buf, '\\') = '\0'; /* remove .exe file name */
if ((cp = JLI_StrRChr(buf, '\\')) == 0) {
/* This happens if the application is in a drive root, and
- * there is no bin directory. */
+ * there is no bin directory. */
buf[0] = '\0';
return JNI_FALSE;
}
@@ -423,6 +432,36 @@
}
/*
+ * Retrieves the path to the JRE home by locating the executable file
+ * of the current process and then truncating the path to the executable
+ */
+jboolean
+GetApplicationHome(char *buf, jint bufsize)
+{
+ GetModuleFileName(NULL, buf, bufsize);
+ return TruncatePath(buf);
+}
+
+/*
+ * Retrieves the path to the JRE home by locating JLI.DLL and
+ * then truncating the path to JLI.DLL
+ */
+jboolean
+GetApplicationHomeFromDll(char *buf, jint bufsize)
+{
+ HMODULE hModule;
+ DWORD dwFlags =
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+ GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
+
+ if (GetModuleHandleEx(dwFlags, (LPCSTR)&GetJREPath, &hModule) == 0) {
+ return JNI_FALSE;
+ };
+ GetModuleFileName(hModule, buf, bufsize);
+ return TruncatePath(buf);
+}
+
+/*
* Support for doing cheap, accurate interval timing.
*/
static jboolean counterAvailable = JNI_FALSE;
--- a/jdk/src/java.base/windows/native/libjli/java_md.h Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.base/windows/native/libjli/java_md.h Sat Jan 16 00:28:28 2016 +0000
@@ -54,4 +54,7 @@
int UnsetEnv(char *name);
+jboolean
+GetApplicationHomeFromDll(char *buf, jint bufsize);
+
#endif /* JAVA_MD_H */
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletPanel.java Sat Jan 16 00:28:28 2016 +0000
@@ -43,8 +43,8 @@
import sun.awt.AppContext;
import sun.awt.EmbeddedFrame;
import sun.awt.SunToolkit;
+import sun.awt.util.PerformanceLogger;
import sun.misc.ManagedLocalsThread;
-import sun.misc.PerformanceLogger;
import sun.security.util.SecurityConstants;
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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 sun.awt.util;
+
+import java.util.Vector;
+import java.io.FileWriter;
+import java.io.File;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+/**
+ * This class is intended to be a central place for the jdk to
+ * log timing events of interest. There is pre-defined event
+ * of startTime, as well as a general
+ * mechanism of setting arbitrary times in an array.
+ * All unreserved times in the array can be used by callers
+ * in application-defined situations. The caller is responsible
+ * for setting and getting all times and for doing whatever
+ * analysis is interesting; this class is merely a central container
+ * for those timing values.
+ * Note that, due to the variables in this class being static,
+ * use of particular time values by multiple applets will cause
+ * confusing results. For example, if plugin runs two applets
+ * simultaneously, the initTime for those applets will collide
+ * and the results may be undefined.
+ * <P>
+ * To automatically track startup performance in an app or applet,
+ * use the command-line parameter sun.perflog as follows:<BR>
+ * <pre>{@code
+ * -Dsun.perflog[=file:<filename>]
+ * }</pre>
+ * <BR>
+ * where simply using the parameter with no value will enable output
+ * to the console and a value of "{@code file:<filename>}" will cause
+ * that given filename to be created and used for all output.
+ * <P>
+ * By default, times are measured using System.currentTimeMillis(). To use
+ * System.nanoTime() instead, add the command-line parameter:<BR>
+ -Dsun.perflog.nano=true
+ * <BR>
+ * <P>
+ * <B>Warning: Use at your own risk!</B>
+ * This class is intended for internal testing
+ * purposes only and may be removed at any time. More
+ * permanent monitoring and profiling APIs are expected to be
+ * developed for future releases and this class will cease to
+ * exist once those APIs are in place.
+ * @author Chet Haase
+ */
+public class PerformanceLogger {
+
+ // Timing values of global interest
+ private static final int START_INDEX = 0; // VM start
+ private static final int LAST_RESERVED = START_INDEX;
+
+ private static boolean perfLoggingOn = false;
+ private static boolean useNanoTime = false;
+ private static Vector<TimeData> times;
+ private static String logFileName = null;
+ private static Writer logWriter = null;
+ private static long baseTime;
+
+ static {
+ String perfLoggingProp =
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("sun.perflog"));
+ if (perfLoggingProp != null) {
+ perfLoggingOn = true;
+
+ // Check if we should use nanoTime
+ String perfNanoProp =
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("sun.perflog.nano"));
+ if (perfNanoProp != null) {
+ useNanoTime = true;
+ }
+
+ // Now, figure out what the user wants to do with the data
+ if (perfLoggingProp.regionMatches(true, 0, "file:", 0, 5)) {
+ logFileName = perfLoggingProp.substring(5);
+ }
+ if (logFileName != null) {
+ if (logWriter == null) {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ try {
+ File logFile = new File(logFileName);
+ logFile.createNewFile();
+ logWriter = new FileWriter(logFile);
+ } catch (Exception e) {
+ System.out.println(e + ": Creating logfile " +
+ logFileName +
+ ". Log to console");
+ }
+ return null;
+ }
+ });
+ }
+ }
+ if (logWriter == null) {
+ logWriter = new OutputStreamWriter(System.out);
+ }
+ }
+ times = new Vector<TimeData>(10);
+ // Reserve predefined slots
+ for (int i = 0; i <= LAST_RESERVED; ++i) {
+ times.add(new TimeData("Time " + i + " not set", 0));
+ }
+ }
+
+ /**
+ * Returns status of whether logging is enabled or not. This is
+ * provided as a convenience method so that users do not have to
+ * perform the same GetPropertyAction check as above to determine whether
+ * to enable performance logging.
+ */
+ public static boolean loggingEnabled() {
+ return perfLoggingOn;
+ }
+
+
+ /**
+ * Internal class used to store time/message data together.
+ */
+ static class TimeData {
+ String message;
+ long time;
+
+ TimeData(String message, long time) {
+ this.message = message;
+ this.time = time;
+ }
+
+ String getMessage() {
+ return message;
+ }
+
+ long getTime() {
+ return time;
+ }
+ }
+
+ /**
+ * Return the current time, in millis or nanos as appropriate
+ */
+ private static long getCurrentTime() {
+ if (useNanoTime) {
+ return System.nanoTime();
+ } else {
+ return System.currentTimeMillis();
+ }
+ }
+
+ /**
+ * Sets the start time. Ideally, this is the earliest time available
+ * during the startup of a Java applet or application. This time is
+ * later used to analyze the difference between the initial startup
+ * time and other events in the system (such as an applet's init time).
+ */
+ public static void setStartTime(String message) {
+ if (loggingEnabled()) {
+ long nowTime = getCurrentTime();
+ setStartTime(message, nowTime);
+ }
+ }
+
+ /**
+ * Sets the base time, output can then
+ * be displayed as offsets from the base time;.
+ */
+ public static void setBaseTime(long time) {
+ if (loggingEnabled()) {
+ baseTime = time;
+ }
+ }
+
+ /**
+ * Sets the start time.
+ * This version of the method is
+ * given the time to log, instead of expecting this method to
+ * get the time itself. This is done in case the time was
+ * recorded much earlier than this method was called.
+ */
+ public static void setStartTime(String message, long time) {
+ if (loggingEnabled()) {
+ times.set(START_INDEX, new TimeData(message, time));
+ }
+ }
+
+ /**
+ * Gets the start time, which should be the time when
+ * the java process started, prior to the VM actually being
+ * loaded.
+ */
+ public static long getStartTime() {
+ if (loggingEnabled()) {
+ return times.get(START_INDEX).getTime();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Sets the value of a given time and returns the index of the
+ * slot that that time was stored in.
+ */
+ public static int setTime(String message) {
+ if (loggingEnabled()) {
+ long nowTime = getCurrentTime();
+ return setTime(message, nowTime);
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Sets the value of a given time and returns the index of the
+ * slot that that time was stored in.
+ * This version of the method is
+ * given the time to log, instead of expecting this method to
+ * get the time itself. This is done in case the time was
+ * recorded much earlier than this method was called.
+ */
+ public static int setTime(String message, long time) {
+ if (loggingEnabled()) {
+ // times is already synchronized, but we need to ensure that
+ // the size used in times.set() is the same used when returning
+ // the index of that operation.
+ synchronized (times) {
+ times.add(new TimeData(message, time));
+ return (times.size() - 1);
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns time at given index.
+ */
+ public static long getTimeAtIndex(int index) {
+ if (loggingEnabled()) {
+ return times.get(index).getTime();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns message at given index.
+ */
+ public static String getMessageAtIndex(int index) {
+ if (loggingEnabled()) {
+ return times.get(index).getMessage();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Outputs all data to parameter-specified Writer object
+ */
+ public static void outputLog(Writer writer) {
+ if (loggingEnabled()) {
+ try {
+ synchronized(times) {
+ for (int i = 0; i < times.size(); ++i) {
+ TimeData td = times.get(i);
+ if (td != null) {
+ writer.write(i + " " + td.getMessage() + ": " +
+ (td.getTime() - baseTime) + "\n");
+
+ }
+ }
+ }
+ writer.flush();
+ } catch (Exception e) {
+ System.out.println(e + ": Writing performance log to " +
+ writer);
+ }
+ }
+ }
+
+ /**
+ * Outputs all data to whatever location the user specified
+ * via sun.perflog command-line parameter.
+ */
+ public static void outputLog() {
+ outputLog(logWriter);
+ }
+}
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Sat Jan 16 00:28:28 2016 +0000
@@ -88,9 +88,9 @@
import sun.java2d.loops.XORComposite;
import sun.awt.ConstrainableGraphics;
import sun.awt.SunHints;
+import sun.awt.util.PerformanceLogger;
import java.util.Map;
import java.util.Iterator;
-import sun.misc.PerformanceLogger;
import java.lang.annotation.Native;
import java.awt.image.MultiResolutionImage;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Sat Jan 16 00:28:28 2016 +0000
@@ -52,6 +52,7 @@
import sun.font.FontConfigManager;
import sun.java2d.SunGraphicsEnvironment;
import sun.misc.*;
+import sun.awt.util.PerformanceLogger;
import sun.awt.util.ThreadGroupUtils;
import sun.print.PrintJob2D;
import sun.security.action.GetPropertyAction;
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Sat Jan 16 00:28:28 2016 +0000
@@ -67,10 +67,10 @@
import java.util.Map;
import java.util.Properties;
+import sun.awt.util.PerformanceLogger;
import sun.font.FontManager;
import sun.font.FontManagerFactory;
import sun.font.SunFontManager;
-import sun.misc.PerformanceLogger;
import sun.util.logging.PlatformLogger;
public final class WToolkit extends SunToolkit implements Runnable {
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Sat Jan 16 00:28:28 2016 +0000
@@ -38,6 +38,7 @@
import java.awt.peer.WindowPeer;
import java.util.ArrayList;
+import jdk.internal.perf.PerfCounter;
import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.Win32GraphicsDevice;
@@ -69,9 +70,9 @@
if (d3dAvailable) {
// we don't use pixel formats for the d3d pipeline
pfDisabled = true;
- sun.misc.PerfCounter.getD3DAvailable().set(1);
+ PerfCounter.getD3DAvailable().set(1);
} else {
- sun.misc.PerfCounter.getD3DAvailable().set(0);
+ PerfCounter.getD3DAvailable().set(0);
}
}
--- a/jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java Sat Jan 16 00:28:28 2016 +0000
@@ -34,7 +34,7 @@
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import sun.misc.Perf;
+import jdk.internal.perf.Perf;
import sun.management.counter.Units;
import sun.management.counter.Counter;
import sun.management.counter.perf.PerfInstrumentation;
--- a/jdk/src/java.management/share/classes/sun/management/VMManagementImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.management/share/classes/sun/management/VMManagementImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,7 +25,7 @@
package sun.management;
-import sun.misc.Perf;
+import jdk.internal.perf.Perf;
import sun.management.counter.*;
import sun.management.counter.perf.*;
import java.nio.ByteBuffer;
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Sat Jan 16 00:28:28 2016 +0000
@@ -31,12 +31,14 @@
* <code>ScriptEngineFactory</code> is used to describe and instantiate
* <code>ScriptEngines</code>.
* <br><br>
- * Each class implementing <code>ScriptEngine</code> has a corresponding factory
- * that exposes metadata describing the engine class.
+ * Each class implementing <code>ScriptEngine</code> has a corresponding
+ * factory that exposes metadata describing the engine class.
* <br><br>The <code>ScriptEngineManager</code>
- * uses the service provider mechanism described in the <i>Jar File Specification</i> to obtain
- * instances of all <code>ScriptEngineFactories</code> available in
- * the current ClassLoader.
+ * uses the service-provider loader mechanism described in the
+ * {@link java.util.ServiceLoader} class to obtain
+ * instances of {@code ScriptEngineFactory} instances.
+ * See {@link ScriptEngineManager#ScriptEngineManager()} and
+ * {@link ScriptEngineManager#ScriptEngineManager(java.lang.ClassLoader)}.
*
* @since 1.6
*/
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java Sat Jan 16 00:28:28 2016 +0000
@@ -33,7 +33,8 @@
* The <code>ScriptEngineManager</code> implements a discovery and instantiation
* mechanism for <code>ScriptEngine</code> classes and also maintains a
* collection of key/value pairs storing state shared by all engines created
- * by the Manager. This class uses the <a href="../../../technotes/guides/jar/jar.html#Service%20Provider">service provider</a> mechanism to enumerate all the
+ * by the Manager. This class uses the service provider mechanism described in the
+ * {@link java.util.ServiceLoader} class to enumerate all the
* implementations of <code>ScriptEngineFactory</code>. <br><br>
* The <code>ScriptEngineManager</code> provides a method to return a list of all these factories
* as well as utility methods which look up factories on the basis of language name, file extension
@@ -64,7 +65,7 @@
/**
* This constructor loads the implementations of
* <code>ScriptEngineFactory</code> visible to the given
- * <code>ClassLoader</code> using the <a href="../../../technotes/guides/jar/jar.html#Service%20Provider">service provider</a> mechanism.<br><br>
+ * <code>ClassLoader</code> using the service provider mechanism.<br><br>
* If loader is <code>null</code>, the script engine factories that are
* bundled with the platform are loaded. <br>
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/package-info.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2005, 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.
+ */
+
+/**
+
+<p>The scripting API consists of interfaces and classes that define
+Java™ Scripting Engines and provides
+a framework for their use in Java applications. This API is intended
+for use by application programmers who wish to execute programs
+written in scripting languages in their Java applications. The
+scripting language programs are usually provided by the end-users of
+the applications.
+</p>
+<p>The main areas of functionality of <code>javax.script</code>
+package include
+</p>
+<ol>
+<li><p><b>Script execution</b>: Scripts
+are streams of characters used as sources for programs executed by
+script engines. Script execution uses
+{@link javax.script.ScriptEngine#eval eval} methods of
+{@link javax.script.ScriptEngine ScriptEngine} and methods of the
+{@link javax.script.Invocable Invocable} interface.
+</p>
+<li><p><b>Binding</b>: This facility
+allows Java objects to be exposed to script programs as named
+variables. {@link javax.script.Bindings Bindings} and
+{@link javax.script.ScriptContext ScriptContext}
+classes are used for this purpose.
+</p>
+<li><p><b>Compilation</b>: This
+functionality allows the intermediate code generated by the
+front-end of a script engine to be stored and executed repeatedly.
+This benefits applications that execute the same script multiple
+times. These applications can gain efficiency since the engines'
+front-ends only need to execute once per script rather than once per
+script execution. Note that this functionality is optional and
+script engines may choose not to implement it. Callers need to check
+for availability of the {@link javax.script.Compilable Compilable}
+interface using an <I>instanceof</I> check.
+</p>
+<li><p><b>Invocation</b>: This
+functionality allows the reuse of intermediate code generated by a
+script engine's front-end. Whereas Compilation allows entire scripts
+represented by intermediate code to be re-executed, Invocation
+functionality allows individual procedures/methods in the scripts to
+be re-executed. As in the case with compilation, not all script
+engines are required to provide this facility. Caller has to check
+for {@link javax.script.Invocable Invocable} availability.
+</p>
+<li><p><b>Script engine discovery</b>: Applications
+written to the Scripting API might have specific requirements on
+script engines. Some may require a specific scripting language
+and/or version while others may require a specific implementation
+engine and/or version. Script engines are packaged in a specified
+way so that engines can be discovered at runtime and queried for
+attributes. The Engine discovery mechanism is based on the service-provider
+loading facility described in the {@link java.util.ServiceLoader} class.
+{@link javax.script.ScriptEngineManager ScriptEngineManager}
+includes
+{@link javax.script.ScriptEngineManager#getEngineFactories getEngineFactories} method to get all
+{@link javax.script.ScriptEngineFactory ScriptEngineFactory} instances
+discovered using this mechanism. <code>ScriptEngineFactory</code> has
+methods to query attributes about script engine.
+</p>
+</ol>
+
+@since 1.6
+*/
+
+package javax.script;
+
--- a/jdk/src/java.scripting/share/classes/javax/script/package.html Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-Copyright (c) 2005, 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.
--->
-
-</head>
-<body bgcolor="white">
-<p>The scripting API consists of interfaces and classes that define
-Java™ Scripting Engines and provides
-a framework for their use in Java applications. This API is intended
-for use by application programmers who wish to execute programs
-written in scripting languages in their Java applications. The
-scripting language programs are usually provided by the end-users of
-the applications.
-</p>
-<p>The main areas of functionality of <code>javax.script</code>
-package include
-</p>
-<ol>
- <li><p><b>Script execution</b>: Scripts
- are streams of characters used as sources for programs executed by
- script engines. Script execution uses
- {@link javax.script.ScriptEngine#eval eval} methods of
- {@link javax.script.ScriptEngine ScriptEngine} and methods of the
- {@link javax.script.Invocable Invocable} interface.
- </p>
- <li><p><b>Binding</b>: This facility
- allows Java objects to be exposed to script programs as named
- variables. {@link javax.script.Bindings Bindings} and
- {@link javax.script.ScriptContext ScriptContext}
- classes are used for this purpose.
- </p>
- <li><p><b>Compilation</b>: This
- functionality allows the intermediate code generated by the
- front-end of a script engine to be stored and executed repeatedly.
- This benefits applications that execute the same script multiple
- times. These applications can gain efficiency since the engines'
- front-ends only need to execute once per script rather than once per
- script execution. Note that this functionality is optional and
- script engines may choose not to implement it. Callers need to check
- for availability of the {@link javax.script.Compilable Compilable}
- interface using an <I>instanceof</I> check.
- </p>
- <li><p><b>Invocation</b>: This
- functionality allows the reuse of intermediate code generated by a
- script engine's front-end. Whereas Compilation allows entire scripts
- represented by intermediate code to be re-executed, Invocation
- functionality allows individual procedures/methods in the scripts to
- be re-executed. As in the case with compilation, not all script
- engines are required to provide this facility. Caller has to check
- for {@link javax.script.Invocable Invocable} availability.
- </p>
- <li><p><b>Script engine discovery and Metadata</b>: Applications
- written to the Scripting API might have specific requirements on
- script engines. Some may require a specific scripting language
- and/or version while others may require a specific implementation
- engine and/or version. Script engines are packaged in a specified
- way so that engines can be discovered at runtime and queried for
- attributes. The Engine discovery mechanism is based on the Service
- discovery mechanism described in the <b>Jar File Specification</b>.
- Script engine implementing classes are packaged in jar files that
- include a text resource named
- <b>META-INF/services/javax.script.ScriptEngineFactory</b>. This
- resource must include a line for each
- {@link javax.script.ScriptEngineFactory ScriptEngineFactory}
- that is packaged in the jar file.
- {@link javax.script.ScriptEngineManager ScriptEngineManager}
- includes
- {@link javax.script.ScriptEngineManager#getEngineFactories getEngineFactories} method to get all
- {@link javax.script.ScriptEngineFactory ScriptEngineFactory} instances
- discovered using this mechanism. <code>ScriptEngineFactory</code> has
- methods to query attributes about script engine.
- </p>
-</ol>
-
-@since 1.6
-
-</body>
-</html>
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractMonitoredVm.java Sat Jan 16 00:28:28 2016 +0000
@@ -95,7 +95,7 @@
public void detach() {
/*
* no default action required because the detach operation for the
- * native byte buffer is managed by the sun.misc.Perf class.
+ * native byte buffer is managed by the Perf class.
*/
}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AbstractPerfDataBuffer.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,7 +25,6 @@
package sun.jvmstat.perfdata.monitor;
-import sun.misc.Perf;
import sun.jvmstat.monitor.*;
import java.util.*;
import java.io.*;
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataBuffer.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,7 +25,7 @@
package sun.jvmstat.perfdata.monitor.protocol.local;
-import sun.misc.Perf;
+import jdk.internal.perf.Perf;
import sun.jvmstat.monitor.*;
import sun.jvmstat.perfdata.monitor.*;
import java.util.*;
--- a/jdk/test/ProblemList.txt Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/ProblemList.txt Sat Jan 16 00:28:28 2016 +0000
@@ -1,6 +1,6 @@
###########################################################################
#
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, 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
@@ -299,6 +299,9 @@
# 8074580
sun/security/pkcs11/rsa/TestKeyPairGenerator.java generic-all
+# 8146387
+javax/net/ssl/SSLSession/SessionCacheSizeTests.java windows-all,solaris-all
+
############################################################################
# jdk_sound
--- a/jdk/test/TEST.groups Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/TEST.groups Sat Jan 16 00:28:28 2016 +0000
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2016, 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,8 +31,8 @@
-java/util/zip/TestLocalTime.java \
:jdk_util \
-java/util/WeakHashMap/GCDuringIteration.java \
- -java/util/concurrent/Phaser/Basic.java \
-java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java
+ -java/util/concurrent/forkjoin/FJExceptionTableLeak.java
sun/nio/cs/ISO8859x.java \
java/nio/Buffer \
com/sun/crypto/provider/Cipher \
@@ -41,9 +41,9 @@
tier2 = \
java/lang/ProcessHandle/TreeTest.java \
java/util/zip/TestLocalTime.java \
- java/util/concurrent/Phaser/Basic.java \
java/util/WeakHashMap/GCDuringIteration.java \
java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
+ java/util/concurrent/forkjoin/FJExceptionTableLeak.java
:jdk_io \
:jdk_nio \
-sun/nio/cs/ISO8859x.java \
@@ -77,7 +77,6 @@
sun/misc \
sun/reflect \
jdk/lambda \
- jdk/internal/jimage \
vm
# All of the java.util package
--- a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Sat Jan 16 00:28:28 2016 +0000
@@ -86,29 +86,43 @@
System.out.println("frame: " + f);
Object[] locals = (Object[]) getLocals.invoke(f);
for (int i = 0; i < locals.length; i++) {
- System.out.format("local %d: %s type %s%n", i, locals[i], type(locals[i]));
+ System.out.format(" local %d: %s type %s\n", i, locals[i], type(locals[i]));
+
+ // check for non-null locals in LocalsAndOperands.test()
+ if (f.getClassName().equals("LocalsAndOperands") &&
+ f.getMethodName().equals("test")) {
+ if (locals[i] == null) {
+ throw new RuntimeException("kept-alive locals should not be null");
+ }
+ }
}
Object[] operands = (Object[]) getOperands.invoke(f);
for (int i = 0; i < operands.length; i++) {
- System.out.format("operand %d: %s type %s%n", i, operands[i], type(operands[i]));
+ System.out.format(" operand %d: %s type %s%n", i, operands[i],
+ type(operands[i]));
}
Object[] monitors = (Object[]) getMonitors.invoke(f);
for (int i = 0; i < monitors.length; i++) {
- System.out.format("monitor %d: %s%n", i, monitors[i]);
+ System.out.format(" monitor %d: %s%n", i, monitors[i]);
}
}
} else {
for (StackFrame f : frames) {
- if (liveStackFrameClass.isInstance(f))
+ if (liveStackFrameClass.isInstance(f)) {
throw new RuntimeException("should not be LiveStackFrame");
+ }
}
}
+ // Use local variables so they stay alive
+ System.out.println("Stayin' alive: "+x+" "+c+" "+hi+" "+l+" "+d);
}
String type(Object o) throws Exception {
- if (primitiveValueClass.isInstance(o)) {
+ if (o == null) {
+ return "null";
+ } else if (primitiveValueClass.isInstance(o)) {
char c = (char)primitiveType.invoke(o);
return String.valueOf(c);
} else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/8076596/Test8076596.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8076596
+ * @run main/othervm/policy=Test8076596.security.policy/secure=Test8076596 -ea -esa Test8076596
+ */
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class Test8076596 extends SecurityManager {
+ public Test8076596() {
+ // 1. Using lambda
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> null);
+ // 2. Using inner class
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ return null;
+ }
+ });
+ }
+
+ public static void main(String[] args) {
+ // empty
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/8076596/Test8076596.security.policy Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,8 @@
+/*
+ * Security policy used by the Test8076596.
+ * Must allow file reads so that jtreg itself can run.
+ */
+
+grant {
+ permission java.io.FilePermission "*", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/8147078/Test8147078.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8147078
+ * @run testng/othervm -ea -esa Test8147078
+ */
+
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+public class Test8147078 {
+
+ static int target(int x) {
+ throw new RuntimeException("ieps");
+ }
+
+ static int handler(String s, int x) {
+ return 4*x;
+ }
+
+ static final MethodHandle MH_target;
+ static final MethodHandle MH_handler;
+ static final MethodHandle MH_catchException;
+
+ static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+ static {
+ try {
+ Class<Test8147078> C = Test8147078.class;
+ MH_target = LOOKUP.findStatic(C, "target", methodType(int.class, int.class));
+ MH_handler = LOOKUP.findStatic(C, "handler", methodType(int.class, String.class, int.class));
+ MH_catchException = LOOKUP.findStatic(MethodHandles.class, "catchException",
+ methodType(MethodHandle.class, MethodHandle.class, Class.class, MethodHandle.class));
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ @Test
+ public void testNoExceptionType() {
+ boolean caught = false;
+ try {
+ MethodHandle eek = (MethodHandle) MH_catchException.invoke(MH_target, String.class, MH_handler);
+ } catch (ClassCastException cce) {
+ assertEquals("java.lang.String", cce.getMessage());
+ caught = true;
+ } catch (Throwable t) {
+ fail("unexpected exception caught: " + t);
+ }
+ assertTrue(caught);
+ }
+
+}
\ No newline at end of file
--- a/jdk/test/java/lang/invoke/FindClassSecurityManager.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/lang/invoke/FindClassSecurityManager.java Sat Jan 16 00:28:28 2016 +0000
@@ -24,6 +24,7 @@
*/
/* @test
+ * @bug 8139885
* @run main/othervm/policy=findclass.security.policy/secure=java.lang.SecurityManager -ea -esa test.java.lang.invoke.FindClassSecurityManager
*/
--- a/jdk/test/java/lang/invoke/T8139885.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/lang/invoke/T8139885.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -24,6 +24,8 @@
*/
/* @test
+ * @bug 8139885
+ * @bug 8143798
* @run testng/othervm -ea -esa test.java.lang.invoke.T8139885
*/
--- a/jdk/test/java/lang/ref/CleanerTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/lang/ref/CleanerTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,9 +34,10 @@
import java.util.function.Consumer;
import java.util.function.Supplier;
-import jdk.internal.misc.CleanerImpl.PhantomCleanable;
-import jdk.internal.misc.CleanerImpl.WeakCleanable;
-import jdk.internal.misc.CleanerImpl.SoftCleanable;
+import jdk.internal.ref.PhantomCleanable;
+import jdk.internal.ref.WeakCleanable;
+import jdk.internal.ref.SoftCleanable;
+import jdk.internal.ref.CleanerFactory;
import sun.hotspot.WhiteBox;
@@ -48,17 +49,17 @@
* @test
* @library /lib/testlibrary /test/lib
* @build sun.hotspot.WhiteBox
- * @modules java.base/jdk.internal.misc
+ * @modules java.base/jdk.internal.misc java.base/jdk.internal.ref
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run testng/othervm
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
- * -verbose:gc -Xmx4m CleanerTest
+ * -verbose:gc CleanerTest
*/
@Test
public class CleanerTest {
// A common CleaningService used by the test for notifications
- static final Cleaner COMMON = Cleaner.create();
+ static final Cleaner COMMON = CleanerFactory.cleaner();
// Access to WhiteBox utilities
static final WhiteBox whitebox = WhiteBox.getWhiteBox();
@@ -702,4 +703,17 @@
cleaner = null;
}
+ /**
+ * Test the Cleaner from the CleanerFactory.
+ */
+ @Test
+ void testCleanerFactory() {
+ Cleaner cleaner = CleanerFactory.cleaner();
+
+ Object obj = new Object();
+ CleanableCase s = setupPhantom(cleaner, obj);
+ obj = null;
+ Assert.assertTrue(checkCleaned(s.getSemaphore()),
+ "Object cleaning should have occurred using CleanerFactor.cleaner()");
+ }
}
--- a/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/net/DatagramSocket/SetDatagramSocketImplFactory/ADatagramSocket.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -41,7 +41,11 @@
} catch (Exception ex) {
throw new RuntimeException("Setting DatagramSocketImplFactory failed!");
}
- new QuoteServerThread().start();
+
+ QuoteServerThread server = new QuoteServerThread();
+ int port = server.getPort();
+ System.out.println("Server port is " + port);
+ server.start();
// get a datagram socket
DatagramSocket socket = new DatagramSocket();
@@ -49,7 +53,7 @@
// send request
byte[] buf = new byte[256];
InetAddress address = InetAddress.getLocalHost();
- DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445);
+ DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
// get response
@@ -67,6 +71,7 @@
class QuoteServerThread extends Thread {
protected DatagramSocket socket = null;
+ private final int port;
public QuoteServerThread() throws IOException {
this("QuoteServerThread");
@@ -74,7 +79,11 @@
public QuoteServerThread(String name) throws IOException {
super(name);
- socket = new DatagramSocket(4445);
+ socket = new DatagramSocket(0);
+ port = socket.getLocalPort();
+ }
+ public int getPort(){
+ return port;
}
public void run() {
@@ -101,3 +110,4 @@
socket.close();
}
}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016, 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 jdk.net.ExtendedSocketOptions;
+
+import java.io.IOException;
+import java.net.*;
+
+/*
+ * @test
+ * @bug 8143554
+ * @run main UnsupportedOptionsTest
+ * @summary Test checks that UnsupportedOperationException for unsupported
+ * SOCKET_OPTIONS is thrown by both getOption() and setOption() methods.
+ */
+public class UnsupportedOptionsTest {
+
+ private static final SocketOption[] SOCKET_OPTIONS = {
+ StandardSocketOptions.IP_MULTICAST_IF,
+ StandardSocketOptions.IP_MULTICAST_LOOP,
+ StandardSocketOptions.IP_MULTICAST_TTL,
+ StandardSocketOptions.IP_TOS,
+ StandardSocketOptions.SO_BROADCAST,
+ StandardSocketOptions.SO_KEEPALIVE,
+ StandardSocketOptions.SO_LINGER,
+ StandardSocketOptions.SO_RCVBUF,
+ StandardSocketOptions.SO_REUSEADDR,
+ StandardSocketOptions.SO_SNDBUF,
+ StandardSocketOptions.TCP_NODELAY,
+ ExtendedSocketOptions.SO_FLOW_SLA
+ };
+
+ public static void main(String[] args) throws IOException {
+ Socket s = new Socket();
+ ServerSocket ss = new ServerSocket();
+ DatagramSocket ds = new DatagramSocket();
+ MulticastSocket ms = new MulticastSocket();
+
+ for (SocketOption option : SOCKET_OPTIONS) {
+ if (!s.supportedOptions().contains(option)) {
+ testUnsupportedSocketOption(s, option);
+ }
+
+ if (!ss.supportedOptions().contains(option)) {
+ testUnsupportedSocketOption(ss, option);
+ }
+
+ if (!ms.supportedOptions().contains(option)) {
+ testUnsupportedSocketOption(ms, option);
+ }
+
+ if (!ds.supportedOptions().contains(option)) {
+ testUnsupportedSocketOption(ds, option);
+ }
+ }
+ }
+
+ /*
+ * Check that UnsupportedOperationException for unsupported option is
+ * thrown from both getOption() and setOption() methods.
+ */
+ private static void testUnsupportedSocketOption(Object socket,
+ SocketOption option) {
+ testSet(socket, option);
+ testGet(socket, option);
+ }
+
+ private static void testSet(Object socket, SocketOption option) {
+ try {
+ setOption(socket, option);
+ } catch (UnsupportedOperationException e) {
+ System.out.println("UnsupportedOperationException was throw " +
+ "as expected. Socket: " + socket + " Option: " + option);
+ return;
+ } catch (Exception e) {
+ throw new RuntimeException("FAIL. Unexpected exception.", e);
+ }
+ throw new RuntimeException("FAIL. UnsupportedOperationException " +
+ "hasn't been thrown. Socket: " + socket + " Option: " + option);
+ }
+
+ private static void testGet(Object socket, SocketOption option) {
+ try {
+ getOption(socket, option);
+ } catch (UnsupportedOperationException e) {
+ System.out.println("UnsupportedOperationException was throw " +
+ "as expected. Socket: " + socket + " Option: " + option);
+ return;
+ } catch (Exception e) {
+ throw new RuntimeException("FAIL. Unexpected exception.", e);
+ }
+ throw new RuntimeException("FAIL. UnsupportedOperationException " +
+ "hasn't been thrown. Socket: " + socket + " Option: " + option);
+ }
+
+ private static void getOption(Object socket,
+ SocketOption option) throws IOException {
+ if (socket instanceof Socket) {
+ ((Socket) socket).getOption(option);
+ } else if (socket instanceof ServerSocket) {
+ ((ServerSocket) socket).getOption(option);
+ } else if (socket instanceof DatagramSocket) {
+ ((DatagramSocket) socket).getOption(option);
+ } else {
+ throw new RuntimeException("Unsupported socket type");
+ }
+ }
+
+ private static void setOption(Object socket,
+ SocketOption option) throws IOException {
+ if (socket instanceof Socket) {
+ ((Socket) socket).setOption(option, null);
+ } else if (socket instanceof ServerSocket) {
+ ((ServerSocket) socket).setOption(option, null);
+ } else if (socket instanceof DatagramSocket) {
+ ((DatagramSocket) socket).setOption(option, null);
+ } else {
+ throw new RuntimeException("Unsupported socket type");
+ }
+ }
+}
--- a/jdk/test/java/nio/channels/ServerSocketChannel/Basic.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/Basic.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -22,6 +22,7 @@
*/
/* @test
+ * @bug 4286936 8143100
* @summary Unit test for server-socket channels
* @library ..
*/
@@ -130,7 +131,7 @@
Client client = new Client(port, block);
server.start();
client.start();
- if ((server.finish(2000) & client.finish(100)) == 0)
+ if ((server.finish(0) & client.finish(0)) == 0)
throw new Exception("Failure");
log.println();
}
--- a/jdk/test/java/nio/channels/ServerSocketChannel/NonBlockingAccept.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/NonBlockingAccept.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4801882 5046333
+ * @bug 4801882 5046333 8141595
* @summary test ServerSocketAdaptor.accept on nonblocking channel
* @library ..
* @build TestUtil
@@ -57,8 +57,17 @@
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(isa);
- Thread.sleep(100);
- ss.accept();
+
+ // loop until accepted
+ while (true) {
+ try {
+ ss.accept();
+ break;
+ } catch (IllegalBlockingModeException ex) {
+ System.out.println(ex + ", sleeping ...");
+ Thread.sleep(100);
+ }
+ }
}
--- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -1285,12 +1285,36 @@
public void test_plusWeeks_invalidMaxMinusMin() {
LocalDate.of(Year.MAX_VALUE, 12, 25).plusWeeks(Long.MIN_VALUE);
}
+ //-----------------------------------------------------------------------
+ @DataProvider(name="PlusDays")
+ Object[][] provider_plusDays() {
+ return new Object[][] {
+ {LocalDate.of(2007, 7, 15), 1, LocalDate.of(2007, 7, 16)},
+ {LocalDate.of(2007, 7, 15), 17, LocalDate.of(2007, 8, 1)},
+ {LocalDate.of(2007, 12, 31), 1, LocalDate.of(2008, 1, 1)},
+ {LocalDate.of(2007, 1, 1), 58, LocalDate.of(2007, 2, 28)},
+ {LocalDate.of(2007, 1, 1), 59, LocalDate.of(2007, 3, 1)},
+ {LocalDate.of(2008, 1, 1), 60, LocalDate.of(2008, 3, 1)},
+ {LocalDate.of(2007, 2, 1), 27, LocalDate.of(2007, 2, 28)},
+ {LocalDate.of(2007, 2, 1), 28, LocalDate.of(2007, 3, 1)},
+ {LocalDate.of(2007, 1, 1), 29, LocalDate.of(2007, 1, 30)},
+ {LocalDate.of(2007, 1, 1), 30, LocalDate.of(2007, 1, 31)},
+ {LocalDate.of(2007, 1, 15), 13, LocalDate.of(2007, 1, 28)},
+ {LocalDate.of(2007, 1, 15), 14, LocalDate.of(2007, 1, 29)},
+ {LocalDate.of(2007, 1, 15), 15, LocalDate.of(2007, 1, 30)},
+ {LocalDate.of(2007, 1, 15), 16, LocalDate.of(2007, 1, 31)},
+ {LocalDate.of(2007, 2, 15), 13, LocalDate.of(2007, 2, 28)},
+ {LocalDate.of(2007, 2, 15), 14, LocalDate.of(2007, 3, 1)},
+ {LocalDate.of(2007, 2, 15), 15, LocalDate.of(2007, 3, 2)},
+ {LocalDate.of(2007, 2, 15), 16, LocalDate.of(2007, 3, 3)},
+ };
+ }
- @Test
- public void test_plusDays_normal() {
- LocalDate t = TEST_2007_07_15.plusDays(1);
- assertEquals(t, LocalDate.of(2007, 7, 16));
- }
+ @Test(dataProvider="PlusDays")
+ public void test_plusDays_normal(LocalDate input, int amountsToAdd, LocalDate expected) {
+ LocalDate actual = input.plusDays(amountsToAdd);
+ assertEquals(actual, expected);
+ }
@Test
public void test_plusDays_overMonths() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Locale/Bug8026766.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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 8026766
+ * @summary Confirm that LanguageRange.toString() returns an expected result.
+ * @run main Bug8026766
+ */
+
+import java.util.Locale.LanguageRange;
+
+public class Bug8026766 {
+
+ public static void main(String[] args) {
+ LanguageRange lr1 = new LanguageRange("ja", 1.0);
+ LanguageRange lr2 = new LanguageRange("fr", 0.0);
+
+ if (!lr1.toString().equals("ja") ||
+ !lr2.toString().equals("fr;q=0.0")) {
+ throw new RuntimeException("LanguageRange.toString() returned an unexpected result.");
+ }
+ }
+
+}
--- a/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/util/concurrent/forkjoin/FJExceptionTableLeak.java Sat Jan 16 00:28:28 2016 +0000
@@ -37,6 +37,7 @@
* @bug 8004138
* @summary Check if ForkJoinPool table leaks thrown exceptions.
* @run main/othervm -Xmx2200k FJExceptionTableLeak
+ * @key intermittent
*/
import java.util.concurrent.ForkJoinPool;
--- a/jdk/test/java/util/logging/LogManager/Configuration/updateConfiguration/UpdateConfigurationTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/java/util/logging/LogManager/Configuration/updateConfiguration/UpdateConfigurationTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -209,8 +209,9 @@
+ barChild.getParent() +"\n\texpected: " + barRef.get());
}
Reference<? extends Logger> ref2;
- int max = 3;
+ int max = 10;
barChild = null;
+ System.gc();
while ((ref2 = queue.poll()) == null) {
System.gc();
Thread.sleep(100);
@@ -276,24 +277,27 @@
}
});
- // Now we need to forget the child, so that loggers are released,
- // and so that we can run the test with the next configuration...
-
- fooChild = null;
- System.out.println("Setting fooChild to: " + fooChild);
- while ((ref2 = queue.poll()) == null) {
- System.gc();
- Thread.sleep(1000);
+ if (suppressed == null) {
+ // Now we need to forget the child, so that loggers are released,
+ // and so that we can run the test with the next configuration...
+ // No need to do that if failed!=null however, as the first
+ // ref might not have been cleared yet and failing here would
+ // hide the original failure.
+ fooChild = null;
+ System.out.println("Setting fooChild to: " + fooChild);
+ while ((ref2 = queue.poll()) == null) {
+ System.gc();
+ Thread.sleep(1000);
+ }
+ if (ref2 != fooRef) {
+ throw new RuntimeException("Unexpected reference: "
+ + ref2 +"\n\texpected: " + fooRef);
+ }
+ if (ref2.get() != null) {
+ throw new RuntimeException("Referent not cleared: " + ref2.get());
+ }
+ System.out.println("Got fooRef after reset(), fooChild is " + fooChild);
}
- if (ref2 != fooRef) {
- throw new RuntimeException("Unexpected reference: "
- + ref2 +"\n\texpected: " + fooRef);
- }
- if (ref2.get() != null) {
- throw new RuntimeException("Referent not cleared: " + ref2.get());
- }
- System.out.println("Got fooRef after reset(), fooChild is " + fooChild);
-
}
}
if (failed != null) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016, 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.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509ExtendedKeyManager;
+
+public class MyX509ExtendedKeyManager extends X509ExtendedKeyManager {
+
+ static final String ERROR = "ERROR";
+ X509ExtendedKeyManager akm;
+ String expectedAP;
+
+ MyX509ExtendedKeyManager(X509ExtendedKeyManager akm) {
+ this.akm = akm;
+ }
+
+ public MyX509ExtendedKeyManager(
+ X509ExtendedKeyManager akm, String expectedAP) {
+ this.akm = akm;
+ this.expectedAP = expectedAP;
+
+ }
+
+ @Override
+ public String[] getClientAliases(String keyType, Principal[] issuers) {
+ return akm.getClientAliases(keyType, issuers);
+ }
+
+ @Override
+ public String chooseClientAlias(String[] keyType, Principal[] issuers,
+ Socket socket) {
+ String nap = ((SSLSocket) socket).getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseClientAlias(keyType, issuers, socket);
+ }
+
+ @Override
+ public String[] getServerAliases(String keyType, Principal[] issuers) {
+ return akm.getServerAliases(keyType, issuers);
+ }
+
+ @Override
+ public String chooseServerAlias(String keyType, Principal[] issuers,
+ Socket socket) {
+ String nap = ((SSLSocket) socket).getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseServerAlias(keyType, issuers, socket);
+ }
+
+ @Override
+ public X509Certificate[] getCertificateChain(String alias) {
+ return akm.getCertificateChain(alias);
+ }
+
+ @Override
+ public PrivateKey getPrivateKey(String alias) {
+ return akm.getPrivateKey(alias);
+ }
+
+ @Override
+ public String chooseEngineClientAlias(String[] keyType, Principal[] issuers,
+ SSLEngine engine) {
+ String nap = engine.getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseEngineClientAlias(keyType, issuers, engine);
+ }
+
+ @Override
+ public String chooseEngineServerAlias(String keyType, Principal[] issuers,
+ SSLEngine engine) {
+ String nap = engine.getHandshakeApplicationProtocol();
+ checkALPN(nap);
+
+ return akm.chooseEngineServerAlias(keyType, issuers, engine);
+ }
+
+ private void checkALPN(String ap) {
+
+ if (ERROR.equals(expectedAP)) {
+ throw new RuntimeException("Should not reach here");
+ }
+
+ System.out.println("Expected ALPN value: " + expectedAP
+ + " Got: " + ap);
+
+ if (ap == null) {
+ throw new RuntimeException(
+ "ALPN should be negotiated, but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new RuntimeException("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new RuntimeException(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ }
+}
--- a/jdk/test/javax/net/ssl/ALPN/SSLEngineAlpnTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/SSLEngineAlpnTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,9 @@
/*
* @test
- * @bug 8051498
+ * @bug 8051498 8145849
* @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
* @run main/othervm SSLEngineAlpnTest h2 h2 h2
* @run main/othervm SSLEngineAlpnTest h2 h2,http/1.1 h2
* @run main/othervm SSLEngineAlpnTest h2,http/1.1 h2,http/1.1 h2
@@ -162,7 +163,7 @@
throw new Exception("Invalid number of test parameters");
}
- SSLEngineAlpnTest test = new SSLEngineAlpnTest();
+ SSLEngineAlpnTest test = new SSLEngineAlpnTest(args[2]);
try {
test.runTest(convert(args[0]), convert(args[1]), args[2]);
} catch (SSLHandshakeException she) {
@@ -179,7 +180,7 @@
/*
* Create an initialized SSLContext to use for these tests.
*/
- public SSLEngineAlpnTest() throws Exception {
+ public SSLEngineAlpnTest(String expectedAP) throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
@@ -192,12 +193,20 @@
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, passphrase);
+ KeyManager [] kms = kmf.getKeyManagers();
+ if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+ throw new Exception("kms[0] not X509ExtendedKeyManager");
+ }
+
+ kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+ (X509ExtendedKeyManager) kms[0], expectedAP) };
+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslCtx = SSLContext.getInstance("TLS");
- sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ sslCtx.init(kms, tmf.getTrustManagers(), null);
sslc = sslCtx;
}
@@ -327,6 +336,11 @@
return;
}
+ if (engine.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
String ap = engine.getApplicationProtocol();
System.out.println("Application Protocol: \"" + ap + "\"");
@@ -384,6 +398,12 @@
sslp = clientEngine.getSSLParameters();
sslp.setApplicationProtocols(clientAPs);
clientEngine.setSSLParameters(sslp);
+
+ if ((clientEngine.getHandshakeApplicationProtocol() != null) ||
+ (serverEngine.getHandshakeApplicationProtocol() != null)) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
}
/*
--- a/jdk/test/javax/net/ssl/ALPN/SSLSocketAlpnTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/SSLSocketAlpnTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,9 @@
/*
* @test
- * @bug 8051498
+ * @bug 8051498 8145849
* @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
* @run main/othervm SSLSocketAlpnTest h2 h2 h2
* @run main/othervm SSLSocketAlpnTest h2 h2,http/1.1 h2
* @run main/othervm SSLSocketAlpnTest h2,http/1.1 h2,http/1.1 h2
@@ -40,6 +41,8 @@
* @author Brad Wetmore
*/
import java.io.*;
+import java.security.KeyStore;
+
import javax.net.ssl.*;
public class SSLSocketAlpnTest {
@@ -65,6 +68,16 @@
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
+ static String keyFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + keyStoreFile;
+ static String trustFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + trustStoreFile;
+
+ /*
+ * SSLContext
+ */
+ SSLContext mySSLContext = null;
+
/*
* Is the server ready to serve?
*/
@@ -82,7 +95,7 @@
/*
* If the client or server is doing some kind of object creation
* that the other side depends on, and that thread prematurely
- * exits, you may experience a hang. The test harness will
+ * exits, you may experience a hang. The test harness will
* terminate all hung threads after its timeout has expired,
* currently 3 minutes by default, but you might try to be
* smart about it....
@@ -95,10 +108,11 @@
* to avoid infinite hangs.
*/
void doServerSide() throws Exception {
- SSLServerSocketFactory sslssf
- = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ SSLServerSocketFactory sslssf = mySSLContext.getServerSocketFactory();
SSLServerSocket sslServerSocket
= (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ // for both client/server to call into X509KM
+ sslServerSocket.setNeedClientAuth(true);
serverPort = sslServerSocket.getLocalPort();
@@ -119,20 +133,30 @@
*/
String[] suites = sslp.getCipherSuites();
sslp.setCipherSuites(suites);
- sslp.setUseCipherSuitesOrder(true); // Set server side order
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
// Set the ALPN selection.
sslp.setApplicationProtocols(serverAPs);
sslSocket.setSSLParameters(sslp);
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
sslSocket.startHandshake();
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
String ap = sslSocket.getApplicationProtocol();
System.out.println("Application Protocol: \"" + ap + "\"");
if (ap == null) {
throw new Exception(
- "Handshake was completed but null was received");
+ "Handshake was completed but null was received");
}
if (expectedAP.equals("NONE")) {
if (!ap.isEmpty()) {
@@ -141,8 +165,8 @@
System.out.println("No ALPN value negotiated, as expected");
}
} else if (!expectedAP.equals(ap)) {
- throw new Exception(expectedAP +
- " ALPN value not available on negotiated connection");
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
}
InputStream sslIS = sslSocket.getInputStream();
@@ -170,8 +194,7 @@
Thread.sleep(50);
}
- SSLSocketFactory sslsf
- = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
SSLSocket sslSocket
= (SSLSocket) sslsf.createSocket("localhost", serverPort);
@@ -185,28 +208,35 @@
*/
String[] suites = sslp.getCipherSuites();
sslp.setCipherSuites(suites);
- sslp.setUseCipherSuitesOrder(true); // Set server side order
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
// Set the ALPN selection.
sslp.setApplicationProtocols(clientAPs);
sslSocket.setSSLParameters(sslp);
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
sslSocket.startHandshake();
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
/*
* Check that the resulting connection meets our defined ALPN
* criteria. If we were connecting to a non-JSSE implementation,
* the server might have negotiated something we shouldn't accept.
- *
- * We were expecting H2 from server, let's make sure the
- * conditions match.
*/
String ap = sslSocket.getApplicationProtocol();
System.out.println("Application Protocol: \"" + ap + "\"");
if (ap == null) {
throw new Exception(
- "Handshake was completed but null was received");
+ "Handshake was completed but null was received");
}
if (expectedAP.equals("NONE")) {
if (!ap.isEmpty()) {
@@ -215,8 +245,8 @@
System.out.println("No ALPN value negotiated, as expected");
}
} else if (!expectedAP.equals(ap)) {
- throw new Exception(expectedAP +
- " ALPN value not available on negotiated connection");
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
}
InputStream sslIS = sslSocket.getInputStream();
@@ -240,17 +270,6 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
- String keyFilename
- = System.getProperty("test.src", ".") + "/" + pathToStores
- + "/" + keyStoreFile;
- String trustFilename
- = System.getProperty("test.src", ".") + "/" + pathToStores
- + "/" + trustStoreFile;
-
- System.setProperty("javax.net.ssl.keyStore", keyFilename);
- System.setProperty("javax.net.ssl.keyStorePassword", passwd);
- System.setProperty("javax.net.ssl.trustStore", trustFilename);
- System.setProperty("javax.net.ssl.trustStorePassword", passwd);
if (debug) {
System.setProperty("javax.net.debug", "all");
@@ -280,6 +299,39 @@
System.out.println("Test Passed.");
}
+ SSLContext getSSLContext(String keyFilename, String trustFilename)
+ throws Exception {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ // Keystores
+ KeyStore keyKS = KeyStore.getInstance("JKS");
+ keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray());
+
+ KeyStore trustKS = KeyStore.getInstance("JKS");
+ trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray());
+
+ // Generate KeyManager and TrustManager
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(keyKS, passwd.toCharArray());
+
+ KeyManager[] kms = kmf.getKeyManagers();
+ if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+ throw new Exception("kms[0] not X509ExtendedKeyManager");
+ }
+
+ kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+ (X509ExtendedKeyManager) kms[0], expectedAP) };
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(trustKS);
+ TrustManager[] tms = tmf.getTrustManagers();
+
+ // initial SSLContext
+ ctx.init(kms, tms, null);
+
+ return ctx;
+ }
+
/*
* Convert a comma-separated list into an array of strings.
*/
@@ -309,6 +361,7 @@
*/
SSLSocketAlpnTest() throws Exception {
Exception startException = null;
+ mySSLContext = getSSLContext(keyFilename, trustFilename);
try {
if (separateServerThread) {
startServer(true);
--- a/jdk/test/javax/net/ssl/SSLSession/SessionCacheSizeTests.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/javax/net/ssl/SSLSession/SessionCacheSizeTests.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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,6 +31,7 @@
* @bug 4366807
* @summary Need new APIs to get/set session timeout and session cache size.
* @run main/othervm SessionCacheSizeTests
+ * @key intermittent
*/
import java.io.*;
@@ -108,28 +109,34 @@
void doServerSide(int serverPort, int serverConns) throws Exception {
- SSLServerSocket sslServerSocket =
- (SSLServerSocket) sslssf.createServerSocket(serverPort);
- sslServerSocket.setSoTimeout(45000); // timeout to accept a connection
- serverPorts[createdPorts++] = sslServerSocket.getLocalPort();
+ try (SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
+
+ // timeout to accept a connection
+ sslServerSocket.setSoTimeout(45000);
+
+ // make sure createdPorts++ is atomic
+ synchronized(serverPorts) {
+ serverPorts[createdPorts++] = sslServerSocket.getLocalPort();
- /*
- * Signal Client, we're ready for his connect.
- */
- if (createdPorts == serverPorts.length) {
- serverReady = true;
- }
- int read = 0;
- int nConnections = 0;
- /*
- * Divide the max connections among the available server ports.
- * The use of more than one server port ensures creation of more
- * than one session.
- */
- SSLSession sessions [] = new SSLSession [serverConns];
- SSLSessionContext sessCtx = sslctx.getServerSessionContext();
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ if (createdPorts == serverPorts.length) {
+ serverReady = true;
+ }
+ }
+ int read = 0;
+ int nConnections = 0;
- try {
+ /*
+ * Divide the max connections among the available server ports.
+ * The use of more than one server port ensures creation of more
+ * than one session.
+ */
+ SSLSession sessions [] = new SSLSession [serverConns];
+ SSLSessionContext sessCtx = sslctx.getServerSessionContext();
+
while (nConnections < serverConns) {
try (SSLSocket sslSocket =
(SSLSocket)sslServerSocket.accept()) {
@@ -143,8 +150,6 @@
nConnections++;
}
}
- } finally {
- sslServerSocket.close();
}
}
@@ -270,8 +275,8 @@
* Using four ports (one per each connection), we are able to create
* alteast four sessions.
*/
- volatile int serverPorts[] = new int[]{0, 0, 0, 0};
- volatile int createdPorts = 0;
+ int serverPorts[] = new int[]{0, 0, 0, 0}; // MAX_ACTIVE_CONNECTIONS: 4
+ int createdPorts = 0;
static SSLServerSocketFactory sslssf;
static SSLSocketFactory sslsf;
static SSLContext sslctx;
--- a/jdk/test/javax/security/auth/SubjectDomainCombiner/Optimize.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/javax/security/auth/SubjectDomainCombiner/Optimize.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -37,13 +37,16 @@
ProtectionDomain pd1 = new ProtectionDomain(
new CodeSource(null, (java.security.cert.Certificate[]) null),
- new Permissions());
+ new Permissions(),
+ null, null);
ProtectionDomain pd2 = new ProtectionDomain(
new CodeSource(null, (java.security.cert.Certificate[]) null),
- new Permissions());
+ new Permissions(),
+ null, null);
ProtectionDomain pd3 = new ProtectionDomain(
new CodeSource(null, (java.security.cert.Certificate[]) null),
- new Permissions());
+ new Permissions(),
+ null, null);
ProtectionDomain[] current = new ProtectionDomain[] {pd1, pd2};
ProtectionDomain[] assigned = new ProtectionDomain[] {pd3, pd2};
--- a/jdk/test/jdk/internal/jimage/JImageReadTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/jdk/test/jdk/internal/jimage/JImageReadTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -313,7 +313,7 @@
static boolean isMetaName(String name) {
return name.startsWith("/modules")
|| name.startsWith("/packages")
- || name.startsWith("META-INF/services")
+ || name.startsWith("META-INF")
|| name.equals("bootmodules.jdata");
}
--- a/langtools/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -343,3 +343,4 @@
345520da2ec17100cb512a53d541a307a195305e jdk-9+98
cb73b474703e2de266542b505cffd658bcc052da jdk-9+99
51136404ee5e6cd5868b60d66ebd55a02170b508 jdk-9+100
+3b3bea483542bc08278af529fb25f2e5930da945 jdk-9+101
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Sat Jan 16 00:28:28 2016 +0000
@@ -1146,14 +1146,21 @@
if (!visit(supertype(t), supertype(s)))
return false;
- HashSet<UniqueType> set = new HashSet<>();
- for (Type x : interfaces(t))
- set.add(new UniqueType(x, Types.this));
- for (Type x : interfaces(s)) {
- if (!set.remove(new UniqueType(x, Types.this)))
+ Map<Symbol,Type> tMap = new HashMap<>();
+ for (Type ti : interfaces(t)) {
+ if (tMap.containsKey(ti)) {
+ throw new AssertionError("Malformed intersection");
+ }
+ tMap.put(ti.tsym, ti);
+ }
+ for (Type si : interfaces(s)) {
+ if (!tMap.containsKey(si.tsym))
+ return false;
+ Type ti = tMap.remove(si.tsym);
+ if (!visit(ti, si))
return false;
}
- return (set.isEmpty());
+ return tMap.isEmpty();
}
return t.tsym == s.tsym
&& visit(t.getEnclosingType(), s.getEnclosingType())
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Jan 16 00:28:28 2016 +0000
@@ -1137,7 +1137,56 @@
/** Parameters {@code t} and {@code s} are unrelated functional interface types. */
private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
- FunctionalInterfaceMostSpecificChecker msc = new FunctionalInterfaceMostSpecificChecker(t, s);
+ Type tDesc = types.findDescriptorType(t);
+ Type sDesc = types.findDescriptorType(s);
+
+ // compare type parameters -- can't use Types.hasSameBounds because bounds may have ivars
+ final List<Type> tTypeParams = tDesc.getTypeArguments();
+ final List<Type> sTypeParams = sDesc.getTypeArguments();
+ List<Type> tIter = tTypeParams;
+ List<Type> sIter = sTypeParams;
+ while (tIter.nonEmpty() && sIter.nonEmpty()) {
+ Type tBound = tIter.head.getUpperBound();
+ Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
+ if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
+ return false;
+ }
+ if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
+ return false;
+ }
+ tIter = tIter.tail;
+ sIter = sIter.tail;
+ }
+ if (!tIter.isEmpty() || !sIter.isEmpty()) {
+ return false;
+ }
+
+ // compare parameters
+ List<Type> tParams = tDesc.getParameterTypes();
+ List<Type> sParams = sDesc.getParameterTypes();
+ while (tParams.nonEmpty() && sParams.nonEmpty()) {
+ Type tParam = tParams.head;
+ Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
+ if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
+ return false;
+ }
+ if (!types.isSameType(tParam, inferenceContext().asUndetVar(sParam))) {
+ return false;
+ }
+ tParams = tParams.tail;
+ sParams = sParams.tail;
+ }
+ if (!tParams.isEmpty() || !sParams.isEmpty()) {
+ return false;
+ }
+
+ // compare returns
+ Type tRet = tDesc.getReturnType();
+ Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
+ if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
+ return false;
+ }
+ MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
msc.scan(tree);
return msc.result;
}
@@ -1146,16 +1195,16 @@
* Tests whether one functional interface type can be considered more specific
* than another unrelated functional interface type for the scanned expression.
*/
- class FunctionalInterfaceMostSpecificChecker extends DeferredAttr.PolyScanner {
-
- final Type t;
- final Type s;
+ class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
+
+ final Type tRet;
+ final Type sRet;
boolean result;
/** Parameters {@code t} and {@code s} are unrelated functional interface types. */
- FunctionalInterfaceMostSpecificChecker(Type t, Type s) {
- this.t = t;
- this.s = s;
+ MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
+ this.tRet = tRet;
+ this.sRet = sRet;
result = true;
}
@@ -1172,29 +1221,18 @@
@Override
public void visitReference(JCMemberReference tree) {
- Type desc_t = types.findDescriptorType(t);
- Type desc_s = types.findDescriptorType(s);
- // use inference variables here for more-specific inference (18.5.4)
- if (!types.isSameTypes(desc_t.getParameterTypes(),
- inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
+ if (sRet.hasTag(VOID)) {
+ result &= true;
+ } else if (tRet.hasTag(VOID)) {
result &= false;
+ } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
+ boolean retValIsPrimitive =
+ tree.refPolyKind == PolyKind.STANDALONE &&
+ tree.sym.type.getReturnType().isPrimitive();
+ result &= (retValIsPrimitive == tRet.isPrimitive()) &&
+ (retValIsPrimitive != sRet.isPrimitive());
} else {
- // compare return types
- Type ret_t = desc_t.getReturnType();
- Type ret_s = desc_s.getReturnType();
- if (ret_s.hasTag(VOID)) {
- result &= true;
- } else if (ret_t.hasTag(VOID)) {
- result &= false;
- } else if (ret_t.isPrimitive() != ret_s.isPrimitive()) {
- boolean retValIsPrimitive =
- tree.refPolyKind == PolyKind.STANDALONE &&
- tree.sym.type.getReturnType().isPrimitive();
- result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
- (retValIsPrimitive != ret_s.isPrimitive());
- } else {
- result &= compatibleBySubtyping(ret_t, ret_s);
- }
+ result &= compatibleBySubtyping(tRet, sRet);
}
}
@@ -1205,32 +1243,24 @@
@Override
public void visitLambda(JCLambda tree) {
- Type desc_t = types.findDescriptorType(t);
- Type desc_s = types.findDescriptorType(s);
- // use inference variables here for more-specific inference (18.5.4)
- if (!types.isSameTypes(desc_t.getParameterTypes(),
- inferenceContext().asUndetVars(desc_s.getParameterTypes()))) {
+ if (sRet.hasTag(VOID)) {
+ result &= true;
+ } else if (tRet.hasTag(VOID)) {
result &= false;
} else {
- // compare return types
- Type ret_t = desc_t.getReturnType();
- Type ret_s = desc_s.getReturnType();
- if (ret_s.hasTag(VOID)) {
- result &= true;
- } else if (ret_t.hasTag(VOID)) {
- result &= false;
- } else if (unrelatedFunctionalInterfaces(ret_t, ret_s)) {
- for (JCExpression expr : lambdaResults(tree)) {
- result &= functionalInterfaceMostSpecific(ret_t, ret_s, expr);
+ List<JCExpression> lambdaResults = lambdaResults(tree);
+ if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
+ for (JCExpression expr : lambdaResults) {
+ result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
}
- } else if (ret_t.isPrimitive() != ret_s.isPrimitive()) {
- for (JCExpression expr : lambdaResults(tree)) {
+ } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
+ for (JCExpression expr : lambdaResults) {
boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
- result &= (retValIsPrimitive == ret_t.isPrimitive()) &&
- (retValIsPrimitive != ret_s.isPrimitive());
+ result &= (retValIsPrimitive == tRet.isPrimitive()) &&
+ (retValIsPrimitive != sRet.isPrimitive());
}
} else {
- result &= compatibleBySubtyping(ret_t, ret_s);
+ result &= compatibleBySubtyping(tRet, sRet);
}
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -301,15 +301,16 @@
}
/** Read a number.
- * @param radix The radix of the number; one of 2, j8, 10, 16.
+ * @param radix The radix of the number; one of 2, 8, 10, 16.
*/
private void scanNumber(int pos, int radix) {
// for octal, allow base-10 digit in case it's a float literal
this.radix = radix;
int digitRadix = (radix == 8 ? 10 : radix);
- boolean seendigit = false;
- if (reader.digit(pos, digitRadix) >= 0) {
- seendigit = true;
+ int firstDigit = reader.digit(pos, Math.max(10, digitRadix));
+ boolean seendigit = firstDigit >= 0;
+ boolean seenValidDigit = firstDigit >= 0 && firstDigit < digitRadix;
+ if (seendigit) {
scanDigits(pos, digitRadix);
}
if (radix == 16 && reader.ch == '.') {
@@ -325,6 +326,16 @@
reader.ch == 'd' || reader.ch == 'D')) {
scanFractionAndSuffix(pos);
} else {
+ if (!seenValidDigit) {
+ switch (radix) {
+ case 2:
+ lexError(pos, "invalid.binary.number");
+ break;
+ case 16:
+ lexError(pos, "invalid.hex.number");
+ break;
+ }
+ }
if (reader.ch == 'l' || reader.ch == 'L') {
reader.scanChar();
tk = TokenKind.LONGLITERAL;
@@ -491,13 +502,7 @@
if (reader.ch == 'x' || reader.ch == 'X') {
reader.scanChar();
skipIllegalUnderscores();
- if (reader.ch == '.') {
- scanHexFractionAndSuffix(pos, false);
- } else if (reader.digit(pos, 16) < 0) {
- lexError(pos, "invalid.hex.number");
- } else {
- scanNumber(pos, 16);
- }
+ scanNumber(pos, 16);
} else if (reader.ch == 'b' || reader.ch == 'B') {
if (!allowBinaryLiterals) {
lexError(pos, "unsupported.binary.lit", source.name);
@@ -505,11 +510,7 @@
}
reader.scanChar();
skipIllegalUnderscores();
- if (reader.digit(pos, 2) < 0) {
- lexError(pos, "invalid.binary.number");
- } else {
- scanNumber(pos, 2);
- }
+ scanNumber(pos, 2);
} else {
reader.putChar('0');
if (reader.ch == '_') {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java Sat Jan 16 00:28:28 2016 +0000
@@ -26,11 +26,20 @@
package com.sun.tools.sjavac;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
import java.util.Set;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
+import java.util.regex.PatternSyntaxException;
/** A Source object maintains information about a source file.
* For example which package it belongs to and kind of source it is.
@@ -56,8 +65,6 @@
private long lastModified;
// The source File.
private File file;
- // The source root under which file resides.
- private File root;
// If the source is generated.
private boolean isGenerated;
// If the source is only linked to, not compiled.
@@ -78,7 +85,7 @@
return name.hashCode();
}
- public Source(Module m, String n, File f, File r) {
+ public Source(Module m, String n, File f) {
name = n;
int dp = n.lastIndexOf(".");
if (dp != -1) {
@@ -87,7 +94,6 @@
suffix = "";
}
file = f;
- root = r;
lastModified = f.lastModified();
linkedOnly = false;
}
@@ -102,7 +108,6 @@
suffix = "";
}
file = null;
- root = null;
lastModified = lm;
linkedOnly = false;
int ls = n.lastIndexOf('/');
@@ -112,7 +117,6 @@
public String suffix() { return suffix; }
public Package pkg() { return pkg; }
public File file() { return file; }
- public File root() { return root; }
public long lastModified() {
return lastModified;
}
@@ -183,225 +187,122 @@
*/
static public void scanRoot(File root,
Set<String> suffixes,
- List<String> excludes, List<String> includes,
- List<String> excludeFiles, List<String> includeFiles,
+ List<String> excludes,
+ List<String> includes,
Map<String,Source> foundFiles,
Map<String,Module> foundModules,
- Module currentModule,
+ final Module currentModule,
boolean permitSourcesWithoutPackage,
boolean inGensrc,
boolean inLinksrc)
- throws ProblemException {
+ throws IOException, ProblemException {
+
+ if (root == null)
+ return;
+
+ FileSystem fs = root.toPath().getFileSystem();
+
+ if (includes.isEmpty()) {
+ includes = Collections.singletonList("**");
+ }
+
+ List<PathMatcher> includeMatchers = createPathMatchers(fs, includes);
+ List<PathMatcher> excludeMatchers = createPathMatchers(fs, excludes);
- if (root == null) return;
- int root_prefix = root.getPath().length()+1;
- // This is the root source directory, it must not contain any Java sources files
- // because we do not allow Java source files without a package.
- // (Unless of course --permit-sources-without-package has been specified.)
- // It might contain other source files however, (for -tr and -copy) these will
- // always be included, since no package pattern can match the root directory.
- currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
- excludeFiles, includeFiles,
- foundFiles, foundModules, currentModule,
- inGensrc, inLinksrc);
+ Files.walkFileTree(root.toPath(), new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+
+ Path relToRoot = root.toPath().relativize(file);
- File[] dirfiles = root.listFiles();
- for (File d : dirfiles) {
- if (d.isDirectory()) {
- // Descend into the directory structure.
- scanDirectory(d, root_prefix, root, suffixes,
- excludes, includes, excludeFiles, includeFiles,
- foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
- }
- }
- }
+ if (includeMatchers.stream().anyMatch(im -> im.matches(relToRoot))
+ && excludeMatchers.stream().noneMatch(em -> em.matches(relToRoot))
+ && suffixes.contains(Util.fileSuffix(file))) {
+
+ // TODO: Test this.
+ Source existing = foundFiles.get(file);
+ if (existing != null) {
+ throw new IOException("You have already added the file "+file+" from "+existing.file().getPath());
+ }
+ existing = currentModule.lookupSource(file.toString());
+ if (existing != null) {
- /**
- * Test if a path matches any of the patterns given.
- * The pattern foo/bar matches only foo/bar
- * The pattern foo/* matches foo/bar and foo/bar/zoo etc
- */
- static private boolean hasMatch(String path, List<String> patterns) {
-
- // Convert Windows '\' to '/' for the sake of comparing with the patterns
- path = path.replace(File.separatorChar, '/');
+ // Oups, the source is already added, could be ok, could be not, lets check.
+ if (inLinksrc) {
+ // So we are collecting sources for linking only.
+ if (existing.isLinkedOnly()) {
+ // Ouch, this one is also for linking only. Bad.
+ throw new IOException("You have already added the link only file " + file + " from " + existing.file().getPath());
+ }
+ // Ok, the existing source is to be compiled. Thus this link only is redundant
+ // since all compiled are also linked to. Continue to the next source.
+ // But we need to add the source, so that it will be visible to linking,
+ // if not the multi core compile will fail because a JavaCompiler cannot
+ // find the necessary dependencies for its part of the source.
+ foundFiles.put(file.toString(), existing);
+ } else {
+ // We are looking for sources to compile, if we find an existing to be compiled
+ // source with the same name, it is an internal error, since we must
+ // find the sources to be compiled before we find the sources to be linked to.
+ throw new IOException("Internal error: Double add of file " + file + " from " + existing.file().getPath());
+ }
- for (String p : patterns) {
- // Exact match
- if (p.equals(path))
- return true;
+ } else {
- // Single dot the end matches this package and all its subpackages.
- if (p.endsWith("/*")) {
- // Remove the wildcard
- String patprefix = p.substring(0,p.length()-2);
- // Does the path start with the pattern prefix?
- if (path.startsWith(patprefix)) {
- // If the path has the same length as the pattern prefix, then it is a match.
- // If the path is longer, then make sure that
- // the next part of the path starts with a dot (.) to prevent
- // wildcard matching in the middle of a package name.
- if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='/') {
- return true;
+ //////////////////////////////////////////////////////////////
+ // Add source
+ Source s = new Source(currentModule, file.toString(), file.toFile());
+ if (inGensrc) {
+ s.markAsGenerated();
+ }
+ if (inLinksrc) {
+ s.markAsLinkedOnly();
+ }
+ String pkg = packageOfJavaFile(root.toPath(), file);
+ pkg = currentModule.name() + ":" + pkg;
+ foundFiles.put(file.toString(), s);
+ currentModule.addSource(pkg, s);
+ //////////////////////////////////////////////////////////////
}
}
+
+ return FileVisitResult.CONTINUE;
}
- }
- return false;
- }
-
- /**
- * Matches patterns with the asterisk first. */
- // The pattern foo/bar.java only matches foo/bar.java
- // The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
- static private boolean hasFileMatch(String path, List<String> patterns) {
- // Convert Windows '\' to '/' for the sake of comparing with the patterns
- path = path.replace(File.separatorChar, '/');
-
- path = Util.normalizeDriveLetter(path);
- for (String p : patterns) {
- // Exact match
- if (p.equals(path)) {
- return true;
- }
- // Single dot the end matches this package and all its subpackages.
- if (p.startsWith("*")) {
- // Remove the wildcard
- String patsuffix = p.substring(1);
- // Does the path start with the pattern prefix?
- if (path.endsWith(patsuffix)) {
- return true;
- }
- }
- }
- return false;
+ });
}
- /**
- * Add the files in the directory, assuming that the file has not been excluded.
- * Returns a fresh Module object, if this was a dir with a module-info.java file.
- */
- static private Module addFilesInDir(File dir, int rootPrefix, File root,
- Set<String> suffixes, boolean allow_javas,
- List<String> excludeFiles, List<String> includeFiles,
- Map<String,Source> foundFiles,
- Map<String,Module> foundModules,
- Module currentModule,
- boolean inGensrc,
- boolean inLinksrc)
- throws ProblemException
- {
- for (File f : dir.listFiles()) {
-
- if (!f.isFile())
- continue;
-
- boolean should_add =
- (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
- && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
-
- if (!should_add)
- continue;
-
- if (!allow_javas && f.getName().endsWith(".java")) {
- throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
- ", please remove "+f.getName());
- }
- // Extract the file name relative the root.
- String fn = f.getPath().substring(rootPrefix);
- // Extract the package name.
- int sp = fn.lastIndexOf(File.separatorChar);
- String pkg = "";
- if (sp != -1) {
- pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
- }
- // Is this a module-info.java file?
- if (fn.endsWith("module-info.java")) {
- // Aha! We have recursed into a module!
- if (!currentModule.name().equals("")) {
- throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
- }
- String module_name = fn.substring(0,fn.length()-16);
- currentModule = new Module(module_name, f.getPath());
- foundModules.put(module_name, currentModule);
- }
- // Extract the suffix.
- int dp = fn.lastIndexOf(".");
- String suffix = "";
- if (dp > 0) {
- suffix = fn.substring(dp);
- }
- // Should the file be added?
- if (suffixes.contains(suffix)) {
- Source of = foundFiles.get(f.getPath());
- if (of != null) {
- throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
- }
- of = currentModule.lookupSource(f.getPath());
- if (of != null) {
- // Oups, the source is already added, could be ok, could be not, lets check.
- if (inLinksrc) {
- // So we are collecting sources for linking only.
- if (of.isLinkedOnly()) {
- // Ouch, this one is also for linking only. Bad.
- throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
- }
- // Ok, the existing source is to be compiled. Thus this link only is redundant
- // since all compiled are also linked to. Continue to the next source.
- // But we need to add the source, so that it will be visible to linking,
- // if not the multi core compile will fail because a JavaCompiler cannot
- // find the necessary dependencies for its part of the source.
- foundFiles.put(f.getPath(), of);
- continue;
- } else {
- // We are looking for sources to compile, if we find an existing to be compiled
- // source with the same name, it is an internal error, since we must
- // find the sources to be compiled before we find the sources to be linked to.
- throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
- }
- }
- Source s = new Source(currentModule, f.getPath(), f, root);
- if (inGensrc) s.markAsGenerated();
- if (inLinksrc) {
- s.markAsLinkedOnly();
- }
- pkg = currentModule.name()+":"+pkg;
- foundFiles.put(f.getPath(), s);
- currentModule.addSource(pkg, s);
+ private static List<PathMatcher> createPathMatchers(FileSystem fs, List<String> patterns) {
+ List<PathMatcher> matchers = new ArrayList<>();
+ for (String pattern : patterns) {
+ try {
+ matchers.add(fs.getPathMatcher("glob:" + pattern));
+ } catch (PatternSyntaxException e) {
+ Log.error("Invalid pattern: " + pattern);
+ throw e;
}
}
- return currentModule;
+ return matchers;
+ }
+
+ private static String packageOfJavaFile(Path sourceRoot, Path javaFile) {
+ Path javaFileDir = javaFile.getParent();
+ Path packageDir = sourceRoot.relativize(javaFileDir);
+ List<String> separateDirs = new ArrayList<>();
+ for (Path pathElement : packageDir) {
+ separateDirs.add(pathElement.getFileName().toString());
+ }
+ return String.join(".", separateDirs);
}
- static private void scanDirectory(File dir, int rootPrefix, File root,
- Set<String> suffixes,
- List<String> excludes, List<String> includes,
- List<String> excludeFiles, List<String> includeFiles,
- Map<String,Source> foundFiles,
- Map<String,Module> foundModules,
- Module currentModule, boolean inGensrc, boolean inLinksrc)
- throws ProblemException {
-
- String path = "";
- // Remove the root prefix from the dir path
- if (dir.getPath().length() > rootPrefix) {
- path = dir.getPath().substring(rootPrefix);
- }
- // Should this package directory be included and not excluded?
- if ((includes==null || includes.isEmpty() || hasMatch(path, includes)) &&
- (excludes==null || excludes.isEmpty() || !hasMatch(path, excludes))) {
- // Add the source files.
- currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles,
- foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
- }
-
- for (File d : dir.listFiles()) {
- if (d.isDirectory()) {
- // Descend into the directory structure.
- scanDirectory(d, rootPrefix, root, suffixes,
- excludes, includes, excludeFiles, includeFiles,
- foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
- }
- }
+ @Override
+ public String toString() {
+ return String.format("%s[pkg: %s, name: %s, suffix: %s, file: %s, isGenerated: %b, linkedOnly: %b]",
+ getClass().getSimpleName(),
+ pkg,
+ name,
+ suffix,
+ file,
+ isGenerated,
+ linkedOnly);
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Util.java Sat Jan 16 00:28:28 2016 +0000
@@ -230,4 +230,10 @@
Function<? super T, ? extends I> indexFunction) {
return c.stream().collect(Collectors.<T, I, T>toMap(indexFunction, o -> o));
}
+
+ public static String fileSuffix(Path file) {
+ String fileNameStr = file.getFileName().toString();
+ int dotIndex = fileNameStr.indexOf('.');
+ return dotIndex == -1 ? "" : fileNameStr.substring(dotIndex);
+ }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SjavacImpl.java Sat Jan 16 00:28:28 2016 +0000
@@ -144,77 +144,77 @@
Module current_module = new Module("", "");
modules.put("", current_module);
- // Find all sources, use the suffix rules to know which files are sources.
- Map<String,Source> sources = new HashMap<>();
+ try {
+ // Find all sources, use the suffix rules to know which files are sources.
+ Map<String,Source> sources = new HashMap<>();
- // Find the files, this will automatically populate the found modules
- // with found packages where the sources are found!
- findSourceFiles(options.getSources(),
- suffixRules.keySet(),
- sources,
- modules,
- current_module,
- options.isDefaultPackagePermitted(),
- false);
+ // Find the files, this will automatically populate the found modules
+ // with found packages where the sources are found!
+ findSourceFiles(options.getSources(),
+ suffixRules.keySet(),
+ sources,
+ modules,
+ current_module,
+ options.isDefaultPackagePermitted(),
+ false);
- if (sources.isEmpty()) {
- Log.error("Found nothing to compile!");
- return RC_FATAL;
- }
+ if (sources.isEmpty()) {
+ Log.error("Found nothing to compile!");
+ return RC_FATAL;
+ }
- // Create a map of all source files that are available for linking. Both -src and
- // -sourcepath point to such files. It is possible to specify multiple
- // -sourcepath options to enable different filtering rules. If the
- // filters are the same for multiple sourcepaths, they may be concatenated
- // using :(;). Before sending the list of sourcepaths to javac, they are
- // all concatenated. The list created here is used by the SmartFileWrapper to
- // make sure only the correct sources are actually available.
- // We might find more modules here as well.
- Map<String,Source> sources_to_link_to = new HashMap<>();
+ // Create a map of all source files that are available for linking. Both -src and
+ // -sourcepath point to such files. It is possible to specify multiple
+ // -sourcepath options to enable different filtering rules. If the
+ // filters are the same for multiple sourcepaths, they may be concatenated
+ // using :(;). Before sending the list of sourcepaths to javac, they are
+ // all concatenated. The list created here is used by the SmartFileWrapper to
+ // make sure only the correct sources are actually available.
+ // We might find more modules here as well.
+ Map<String,Source> sources_to_link_to = new HashMap<>();
- List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
- sourceResolutionLocations.addAll(options.getSources());
- sourceResolutionLocations.addAll(options.getSourceSearchPaths());
- findSourceFiles(sourceResolutionLocations,
- Collections.singleton(".java"),
- sources_to_link_to,
- modules,
- current_module,
- options.isDefaultPackagePermitted(),
- true);
+ List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
+ sourceResolutionLocations.addAll(options.getSources());
+ sourceResolutionLocations.addAll(options.getSourceSearchPaths());
+ findSourceFiles(sourceResolutionLocations,
+ Collections.singleton(".java"),
+ sources_to_link_to,
+ modules,
+ current_module,
+ options.isDefaultPackagePermitted(),
+ true);
- // Add the set of sources to the build database.
- javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
- javac_state.now().checkInternalState("checking sources", false, sources);
- javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
- javac_state.setVisibleSources(sources_to_link_to);
+ // Add the set of sources to the build database.
+ javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
+ javac_state.now().checkInternalState("checking sources", false, sources);
+ javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
+ javac_state.setVisibleSources(sources_to_link_to);
- int round = 0;
- printRound(round);
+ int round = 0;
+ printRound(round);
- // If there is any change in the source files, taint packages
- // and mark the database in need of saving.
- javac_state.checkSourceStatus(false);
+ // If there is any change in the source files, taint packages
+ // and mark the database in need of saving.
+ javac_state.checkSourceStatus(false);
- // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
- // in javac_state, simply because loading of the JavacState will clean out all artifacts
- // that do not match the javac_state database.
- javac_state.findAllArtifacts();
+ // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
+ // in javac_state, simply because loading of the JavacState will clean out all artifacts
+ // that do not match the javac_state database.
+ javac_state.findAllArtifacts();
- // Remove unidentified artifacts from the bin, gensrc and header dirs.
- // (Unless we allow them to be there.)
- // I.e. artifacts that are not known according to the build database (javac_state).
- // For examples, files that have been manually copied into these dirs.
- // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
- // in javac_state) have already been removed when the javac_state was loaded.
- if (!options.areUnidentifiedArtifactsPermitted()) {
- javac_state.removeUnidentifiedArtifacts();
- }
- // Go through all sources and taint all packages that miss artifacts.
- javac_state.taintPackagesThatMissArtifacts();
+ // Remove unidentified artifacts from the bin, gensrc and header dirs.
+ // (Unless we allow them to be there.)
+ // I.e. artifacts that are not known according to the build database (javac_state).
+ // For examples, files that have been manually copied into these dirs.
+ // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
+ // in javac_state) have already been removed when the javac_state was loaded.
+ if (!options.areUnidentifiedArtifactsPermitted()) {
+ javac_state.removeUnidentifiedArtifacts();
+ }
+ // Go through all sources and taint all packages that miss artifacts.
+ javac_state.taintPackagesThatMissArtifacts();
- try {
// Check recorded classpath public apis. Taint packages that depend on
// classpath classes whose public apis have changed.
javac_state.taintPackagesDependingOnChangedClasspathPackages();
@@ -229,8 +229,16 @@
// (Generated sources must always have a package.)
Map<String,Source> generated_sources = new HashMap<>();
- Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null,
- generated_sources, modules, current_module, false, true, false);
+ Source.scanRoot(Util.pathToFile(options.getGenSrcDir()),
+ Util.set(".java"),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ generated_sources,
+ modules,
+ current_module,
+ false,
+ true,
+ false);
javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
// Recheck the the source files and their timestamps again.
javac_state.checkSourceStatus(true);
@@ -254,7 +262,10 @@
printRound(round);
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
- again = javac_state.performJavaCompilations(compilationService, options, recently_compiled, rc);
+ again = javac_state.performJavaCompilations(compilationService,
+ options,
+ recently_compiled,
+ rc);
if (!rc[0]) {
Log.debug("Compilation failed.");
break;
@@ -344,7 +355,8 @@
Map<String, Module> foundModules,
Module currentModule,
boolean permitSourcesInDefaultPackage,
- boolean inLinksrc) {
+ boolean inLinksrc)
+ throws IOException {
for (SourceLocation source : sourceLocations) {
source.findSourceFiles(sourceTypes,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Option.java Sat Jan 16 00:28:28 2016 +0000
@@ -93,7 +93,7 @@
CLASSPATH.processMatching(iter, helper);
}
},
- X("-x", "Exclude directory from the subsequent source directory") {
+ X("-x", "Exclude files matching the given pattern") {
@Override
protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
String pattern = getFilePatternArg(iter, helper);
@@ -101,7 +101,7 @@
helper.exclude(pattern);
}
},
- I("-i", "Include only the given directory from the subsequent source directory") {
+ I("-i", "Include only files matching the given pattern") {
@Override
protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
String pattern = getFilePatternArg(iter, helper);
@@ -109,22 +109,6 @@
helper.include(pattern);
}
},
- XF("-xf", "Exclude a given file") {
- @Override
- protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
- String pattern = getFilePatternArg(iter, helper);
- if (pattern != null)
- helper.excludeFile(pattern);
- }
- },
- IF("-if", "Include only the given file") {
- @Override
- protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
- String pattern = getFilePatternArg(iter, helper);
- if (pattern != null)
- helper.includeFile(pattern);
- }
- },
TR("-tr", "Translate resources") {
@Override
protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
@@ -338,7 +322,7 @@
String getFilePatternArg(ArgumentIterator iter, OptionHelper helper) {
if (!iter.hasNext()) {
- helper.reportError(arg + " must be followed by a file or directory pattern.");
+ helper.reportError(arg + " must be followed by a glob pattern.");
return null;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/OptionHelper.java Sat Jan 16 00:28:28 2016 +0000
@@ -53,12 +53,6 @@
/** Record a package inclusion pattern */
public abstract void include(String incl);
- /** Record a file exclusion */
- public abstract void excludeFile(String exclFile);
-
- /** Record a file inclusion */
- public abstract void includeFile(String inclFile);
-
/** Record a root of sources to be compiled */
public abstract void sourceRoots(List<Path> path);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/Options.java Sat Jan 16 00:28:28 2016 +0000
@@ -220,8 +220,6 @@
for (SourceLocation sl : locs) {
for (String pkg : sl.includes) addArg(Option.I, pkg);
for (String pkg : sl.excludes) addArg(Option.X, pkg);
- for (String f : sl.excludedFiles) addArg(Option.XF, f);
- for (String f : sl.includedFiles) addArg(Option.IF, f);
addArg(opt, sl.getPath());
}
}
@@ -380,18 +378,6 @@
}
@Override
- public void excludeFile(String exclFilePattern) {
- exclFilePattern = Util.normalizeDriveLetter(exclFilePattern);
- excludeFiles.add(exclFilePattern);
- }
-
- @Override
- public void includeFile(String inclFilePattern) {
- inclFilePattern = Util.normalizeDriveLetter(inclFilePattern);
- includeFiles.add(inclFilePattern);
- }
-
- @Override
public void addTransformer(String suffix, Transformer tr) {
if (trRules.containsKey(suffix)) {
reportError("More than one transformer specified for " +
@@ -519,9 +505,7 @@
result.add(new SourceLocation(
path,
includes,
- excludes,
- includeFiles,
- excludeFiles));
+ excludes));
}
resetFilters();
return result;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/options/SourceLocation.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,11 +25,13 @@
package com.sun.tools.sjavac.options;
+import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.sun.tools.sjavac.Log;
import com.sun.tools.sjavac.Module;
import com.sun.tools.sjavac.ProblemException;
import com.sun.tools.sjavac.Source;
@@ -49,18 +51,14 @@
private Path path;
// Package include / exclude patterns and file includes / excludes.
- List<String> includes, excludes, includedFiles, excludedFiles;
+ List<String> includes, excludes;
public SourceLocation(Path path,
List<String> includes,
- List<String> excludes,
- List<String> includedFiles,
- List<String> excludedFiles) {
+ List<String> excludes) {
this.path = path;
this.includes = includes;
this.excludes = excludes;
- this.includedFiles = includedFiles;
- this.excludedFiles = excludedFiles;
}
@@ -81,17 +79,23 @@
Map<String, Module> foundModules,
Module currentModule,
boolean permitSourcesInDefaultPackage,
- boolean inLinksrc) {
+ boolean inLinksrc)
+ throws IOException {
try {
- Source.scanRoot(path.toFile(), suffixes, excludes, includes,
- excludedFiles, includedFiles, foundFiles, foundModules,
- currentModule, permitSourcesInDefaultPackage, false,
- inLinksrc);
+ Source.scanRoot(path.toFile(),
+ suffixes,
+ excludes,
+ includes,
+ foundFiles,
+ foundModules,
+ currentModule,
+ permitSourcesInDefaultPackage,
+ false,
+ inLinksrc);
} catch (ProblemException e) {
e.printStackTrace();
}
}
-
/** Get the root directory of this source location */
public Path getPath() {
return path;
@@ -107,14 +111,9 @@
return excludes;
}
- /** Get the file include patterns */
- public List<String> getIncludedFiles() {
- return includedFiles;
+ @Override
+ public String toString() {
+ return String.format("%s[\"%s\", includes: %s, excludes: %s]",
+ getClass().getSimpleName(), path, includes, excludes);
}
-
- /** Get the file exclude patterns */
- public List<String> getExcludedFiles() {
- return excludedFiles;
- }
-
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFile.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/PortFile.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -174,11 +174,20 @@
/**
* Delete the port file.
*/
- public void delete() throws IOException {
+ public void delete() throws IOException, InterruptedException {
// Access to file must be closed before deleting.
rwfile.close();
- // Now delete.
+
file.delete();
+
+ // Wait until file has been deleted (deletes are asynchronous on Windows!) otherwise we
+ // might shutdown the server and prevent another one from starting.
+ for (int i = 0; i < 10 && file.exists(); i++) {
+ Thread.sleep(1000);
+ }
+ if (file.exists()) {
+ throw new IOException("Failed to delete file.");
+ }
}
/**
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/server/SjavacServer.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -279,7 +279,7 @@
// failed connection attempts
try {
portFile.delete();
- } catch (IOException e) {
+ } catch (IOException | InterruptedException e) {
e.printStackTrace(theLog);
}
try {
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/util/VisibleMemberMap.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -248,7 +248,7 @@
for (ProgramElementDoc element : list) {
Object key = getMemberKey(element);
Map<ProgramElementDoc, String> memberLevelMap = memberNameMap.get(key);
- if (level.equals(memberLevelMap.get(element)))
+ if (memberLevelMap != null && level.equals(memberLevelMap.get(element)))
memberLevelMap.remove(element);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/remote/RemoteAgent.java Sat Jan 16 00:28:28 2016 +0000
@@ -28,6 +28,9 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -35,7 +38,9 @@
import java.util.ArrayList;
import java.util.List;
+
import static jdk.internal.jshell.remote.RemoteCodes.*;
+
import java.util.Map;
import java.util.TreeMap;
@@ -59,7 +64,10 @@
void commandLoop(Socket socket) throws IOException {
// in before out -- so we don't hang the controlling process
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
- ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
+ OutputStream socketOut = socket.getOutputStream();
+ System.setOut(new PrintStream(new MultiplexingOutputStream("out", socketOut), true));
+ System.setErr(new PrintStream(new MultiplexingOutputStream("err", socketOut), true));
+ ObjectOutputStream out = new ObjectOutputStream(new MultiplexingOutputStream("command", socketOut));
while (true) {
int cmd = in.readInt();
switch (cmd) {
@@ -260,4 +268,64 @@
}
return sb.toString();
}
+
+ private static final class MultiplexingOutputStream extends OutputStream {
+
+ private static final int PACKET_SIZE = 127;
+
+ private final byte[] name;
+ private final OutputStream delegate;
+
+ public MultiplexingOutputStream(String name, OutputStream delegate) {
+ try {
+ this.name = name.getBytes("UTF-8");
+ this.delegate = delegate;
+ } catch (UnsupportedEncodingException ex) {
+ throw new IllegalStateException(ex); //should not happen
+ }
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ synchronized (delegate) {
+ delegate.write(name.length); //assuming the len is small enough to fit into byte
+ delegate.write(name);
+ delegate.write(1);
+ delegate.write(b);
+ delegate.flush();
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ synchronized (delegate) {
+ int i = 0;
+ while (len > 0) {
+ int size = Math.min(PACKET_SIZE, len);
+
+ delegate.write(name.length); //assuming the len is small enough to fit into byte
+ delegate.write(name);
+ delegate.write(size);
+ delegate.write(b, off + i, size);
+ i += size;
+ len -= size;
+ }
+
+ delegate.flush();
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ super.flush();
+ delegate.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ delegate.close();
+ }
+
+ }
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,3 +1,4 @@
+
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -90,8 +91,10 @@
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Spliterators;
+import java.util.function.Function;
import java.util.function.Supplier;
import static java.util.stream.Collectors.toList;
+import static jdk.jshell.Snippet.SubKind.VAR_VALUE_SUBKIND;
/**
* Command line REPL tool for Java using the JShell API.
@@ -102,6 +105,7 @@
private static final Pattern LINEBREAK = Pattern.compile("\\R");
private static final Pattern HISTORY_ALL_START_FILENAME = Pattern.compile(
"((?<cmd>(all|history|start))(\\z|\\p{javaWhitespace}+))?(?<filename>.*)");
+ private static final String RECORD_SEPARATOR = "\u241E";
final InputStream cmdin;
final PrintStream cmdout;
@@ -150,9 +154,14 @@
private String cmdlineStartup = null;
private String editor = null;
- static final Preferences PREFS = Preferences.userRoot().node("tool/REPL");
+ // Commands and snippets which should be replayed
+ private List<String> replayableHistory;
+ private List<String> replayableHistoryPrevious;
+
+ static final Preferences PREFS = Preferences.userRoot().node("tool/JShell");
static final String STARTUP_KEY = "STARTUP";
+ static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE";
static final String DEFAULT_STARTUP =
"\n" +
@@ -165,11 +174,14 @@
"import java.util.regex.*;\n" +
"void printf(String format, Object... args) { System.out.printf(format, args); }\n";
- // Tool id (tid) mapping
+ // Tool id (tid) mapping: the three name spaces
NameSpace mainNamespace;
NameSpace startNamespace;
NameSpace errorNamespace;
+
+ // Tool id (tid) mapping: the current name spaces
NameSpace currentNameSpace;
+
Map<Snippet,SnippetInfo> mapSnippet;
void debug(String format, Object... args) {
@@ -252,6 +264,12 @@
private void start(IOContext in, List<String> loadList) {
resetState(); // Initialize
+ // Read replay history from last jshell session into previous history
+ String prevReplay = PREFS.get(REPLAY_RESTORE_KEY, null);
+ if (prevReplay != null) {
+ replayableHistoryPrevious = Arrays.asList(prevReplay.split(RECORD_SEPARATOR));
+ }
+
for (String loadFile : loadList) {
cmdOpen(loadFile);
}
@@ -370,6 +388,10 @@
mapSnippet = new LinkedHashMap<>();
currentNameSpace = startNamespace;
+ // Reset the replayable history, saving the old for restore
+ replayableHistoryPrevious = replayableHistory;
+ replayableHistory = new ArrayList<>();
+
state = JShell.builder()
.in(userin)
.out(userout)
@@ -382,7 +404,8 @@
analysis = state.sourceCodeAnalysis();
shutdownSubscription = state.onShutdown((JShell deadState) -> {
if (deadState == state) {
- hard("State engine terminated. See /history");
+ hard("State engine terminated.");
+ hard("Restore definitions with: /reload restore");
live = false;
}
});
@@ -392,7 +415,6 @@
state.addToClasspath(cmdlineClasspath);
}
-
String start;
if (cmdlineStartup == null) {
start = PREFS.get(STARTUP_KEY, "<nada>");
@@ -431,7 +453,7 @@
String incomplete = "";
while (live) {
String prompt;
- if (in.interactiveOutput() && displayPrompt) {
+ if (displayPrompt) {
prompt = testPrompt
? incomplete.isEmpty()
? "\u0005" //ENQ
@@ -480,6 +502,12 @@
}
}
+ private void addToReplayHistory(String s) {
+ if (currentNameSpace == mainNamespace) {
+ replayableHistory.add(s);
+ }
+ }
+
private String processSourceCatchingReset(String src) {
try {
input.beforeUserCode();
@@ -516,7 +544,12 @@
fluff("Type /help for help.");
}
} else if (candidates.length == 1) {
- candidates[0].run.accept(arg);
+ Command command = candidates[0];
+
+ // If comand was successful and is of a replayable kind, add it the replayable history
+ if (command.run.apply(arg) && command.kind == CommandKind.REPLAY) {
+ addToReplayHistory((command.command + " " + arg).trim());
+ }
} else {
hard("Command: %s is ambiguous: %s", cmd, Arrays.stream(candidates).map(c -> c.command).collect(Collectors.joining(", ")));
fluff("Type /help for help.");
@@ -546,15 +579,15 @@
public final String command;
public final String params;
public final String description;
- public final Consumer<String> run;
+ public final Function<String,Boolean> run;
public final CompletionProvider completions;
public final CommandKind kind;
- public Command(String command, String params, String description, Consumer<String> run, CompletionProvider completions) {
+ public Command(String command, String params, String description, Function<String,Boolean> run, CompletionProvider completions) {
this(command, params, description, run, completions, CommandKind.NORMAL);
}
- public Command(String command, String params, String description, Consumer<String> run, CompletionProvider completions, CommandKind kind) {
+ public Command(String command, String params, String description, Function<String,Boolean> run, CompletionProvider completions, CommandKind kind) {
this.command = command;
this.params = params;
this.description = description;
@@ -571,6 +604,7 @@
enum CommandKind {
NORMAL,
+ REPLAY,
HIDDEN,
HELP_ONLY;
}
@@ -602,6 +636,7 @@
private static final CompletionProvider EMPTY_COMPLETION_PROVIDER = new FixedCompletionProvider();
private static final CompletionProvider KEYWORD_COMPLETION_PROVIDER = new FixedCompletionProvider("all ", "start ", "history ");
+ private static final CompletionProvider RELOAD_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("restore", "quiet");
private static final CompletionProvider FILE_COMPLETION_PROVIDER = fileCompletions(p -> true);
private final Map<String, Command> commands = new LinkedHashMap<>();
private void registerCommand(Command cmd) {
@@ -674,6 +709,16 @@
};
}
+ private static CompletionProvider reloadCompletion() {
+ return (code, cursor, anchor) -> {
+ List<Suggestion> result = new ArrayList<>();
+ int pastSpace = code.indexOf(' ') + 1; // zero if no space
+ result.addAll(RELOAD_OPTIONS_COMPLETION_PROVIDER.completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor));
+ anchor[0] += pastSpace;
+ return result;
+ };
+ }
+
// Table of commands -- with command forms, argument kinds, help message, implementation, ...
{
@@ -688,7 +733,8 @@
editCompletion()));
registerCommand(new Command("/drop", "<name or id>", "delete a source entry referenced by name or id",
arg -> cmdDrop(arg),
- editCompletion()));
+ editCompletion(),
+ CommandKind.REPLAY));
registerCommand(new Command("/save", "[all|history|start] <file>", "save: <none> - current source;\n" +
" all - source including overwritten, failed, and start-up code;\n" +
" history - editing history;\n" +
@@ -716,6 +762,9 @@
registerCommand(new Command("/reset", null, "reset everything in the REPL",
arg -> cmdReset(),
EMPTY_COMPLETION_PROVIDER));
+ registerCommand(new Command("/reload", "[restore] [quiet]", "reset and replay relevant history -- current or previous (restore)",
+ arg -> cmdReload(arg),
+ reloadCompletion()));
registerCommand(new Command("/feedback", "<level>", "feedback information: off, concise, normal, verbose, default, or ?",
arg -> cmdFeedback(arg),
new FixedCompletionProvider("off", "concise", "normal", "verbose", "default", "?")));
@@ -724,7 +773,8 @@
EMPTY_COMPLETION_PROVIDER));
registerCommand(new Command("/classpath", "<path>", "add a path to the classpath",
arg -> cmdClasspath(arg),
- classPathCompletion()));
+ classPathCompletion(),
+ CommandKind.REPLAY));
registerCommand(new Command("/history", null, "history of what you have typed",
arg -> cmdHistory(),
EMPTY_COMPLETION_PROVIDER));
@@ -801,25 +851,29 @@
// --- Command implementations ---
- void cmdSetEditor(String arg) {
+ boolean cmdSetEditor(String arg) {
if (arg.isEmpty()) {
hard("/seteditor requires a path argument");
+ return false;
} else {
editor = arg;
fluff("Editor set to: %s", arg);
+ return true;
}
}
- void cmdClasspath(String arg) {
+ boolean cmdClasspath(String arg) {
if (arg.isEmpty()) {
hard("/classpath requires a path argument");
+ return false;
} else {
state.addToClasspath(toPathResolvingUserHome(arg).toString());
fluff("Path %s added to classpath", arg);
+ return true;
}
}
- void cmdDebug(String arg) {
+ boolean cmdDebug(String arg) {
if (arg.isEmpty()) {
debug = !debug;
InternalDebugControl.setDebugFlags(state, debug ? InternalDebugControl.DBG_GEN : 0);
@@ -860,20 +914,26 @@
default:
hard("Unknown debugging option: %c", ch);
fluff("Use: 0 r g f c d");
- break;
+ return false;
}
}
InternalDebugControl.setDebugFlags(state, flags);
}
+ return true;
}
- private void cmdExit() {
+ private boolean cmdExit() {
regenerateOnDeath = false;
live = false;
+ if (!replayableHistory.isEmpty()) {
+ PREFS.put(REPLAY_RESTORE_KEY, replayableHistory.stream().reduce(
+ (a, b) -> a + RECORD_SEPARATOR + b).get());
+ }
fluff("Goodbye\n");
+ return true;
}
- private void cmdFeedback(String arg) {
+ private boolean cmdFeedback(String arg) {
switch (arg) {
case "":
case "d":
@@ -905,12 +965,13 @@
hard(" default");
hard("You may also use just the first letter, for example: /f c");
hard("In interactive mode 'default' is the same as 'normal', from a file it is the same as 'off'");
- return;
+ return false;
}
fluff("Feedback mode: %s", feedback.name().toLowerCase());
+ return true;
}
- void cmdHelp() {
+ boolean cmdHelp() {
int synopsisLen = 0;
Map<String, String> synopsis2Description = new LinkedHashMap<>();
for (Command cmd : new LinkedHashSet<>(commands.values())) {
@@ -936,14 +997,16 @@
cmdout.println("Supported shortcuts include:");
cmdout.println("<tab> -- show possible completions for the current text");
cmdout.println("Shift-<tab> -- for current method or constructor invocation, show a synopsis of the method/constructor");
+ return true;
}
- private void cmdHistory() {
+ private boolean cmdHistory() {
cmdout.println();
for (String s : input.currentSessionHistory()) {
// No number prefix, confusing with snippet ids
cmdout.printf("%s\n", s);
}
+ return true;
}
/**
@@ -1010,23 +1073,23 @@
}
}
- private void cmdDrop(String arg) {
+ private boolean cmdDrop(String arg) {
if (arg.isEmpty()) {
hard("In the /drop argument, please specify an import, variable, method, or class to drop.");
hard("Specify by id or name. Use /list to see ids. Use /reset to reset all state.");
- return;
+ return false;
}
Stream<Snippet> stream = argToSnippets(arg, false);
if (stream == null) {
hard("No definition or id named %s found. See /classes, /methods, /vars, or /list", arg);
- return;
+ return false;
}
List<Snippet> snippets = stream
.filter(sn -> state.status(sn).isActive && sn instanceof PersistentSnippet)
.collect(toList());
if (snippets.isEmpty()) {
hard("The argument did not specify an active import, variable, method, or class to drop.");
- return;
+ return false;
}
if (snippets.size() > 1) {
hard("The argument references more than one import, variable, method, or class.");
@@ -1034,17 +1097,18 @@
for (Snippet sn : snippets) {
cmdout.printf("%4s : %s\n", sn.id(), sn.source().replace("\n", "\n "));
}
- return;
+ return false;
}
PersistentSnippet psn = (PersistentSnippet) snippets.get(0);
state.drop(psn).forEach(this::handleEvent);
+ return true;
}
- private void cmdEdit(String arg) {
+ private boolean cmdEdit(String arg) {
Stream<Snippet> stream = argToSnippets(arg, true);
if (stream == null) {
hard("No definition or id named %s found. See /classes, /methods, /vars, or /list", arg);
- return;
+ return false;
}
Set<String> srcSet = new LinkedHashSet<>();
stream.forEachOrdered(sn -> {
@@ -1078,6 +1142,7 @@
} else {
ExternalEditor.edit(editor, errorHandler, src, saveHandler, input);
}
+ return true;
}
//where
// receives editor requests to save
@@ -1135,10 +1200,9 @@
}
}
- private void cmdList(String arg) {
+ private boolean cmdList(String arg) {
if (arg.equals("history")) {
- cmdHistory();
- return;
+ return cmdHistory();
}
Stream<Snippet> stream = argToSnippets(arg, true);
if (stream == null) {
@@ -1148,7 +1212,7 @@
} else {
hard("No definition or id named %s found. There are no active definitions.", arg);
}
- return;
+ return false;
}
// prevent double newline on empty list
@@ -1160,38 +1224,72 @@
}
cmdout.printf("%4s : %s\n", sn.id(), sn.source().replace("\n", "\n "));
});
+ return true;
}
- private void cmdOpen(String filename) {
+ private boolean cmdOpen(String filename) {
if (filename.isEmpty()) {
hard("The /open command requires a filename argument.");
+ return false;
} else {
try {
run(new FileScannerIOContext(toPathResolvingUserHome(filename).toString()));
} catch (FileNotFoundException e) {
hard("File '%s' is not found: %s", filename, e.getMessage());
+ return false;
} catch (Exception e) {
hard("Exception while reading file: %s", e);
+ return false;
}
}
+ return true;
}
- private void cmdPrompt() {
+ private boolean cmdPrompt() {
displayPrompt = !displayPrompt;
fluff("Prompt will %sdisplay. Use /prompt to toggle.", displayPrompt ? "" : "NOT ");
concise("Prompt: %s", displayPrompt ? "on" : "off");
+ return true;
+ }
+
+ private boolean cmdReset() {
+ live = false;
+ fluff("Resetting state.");
+ return true;
}
- private void cmdReset() {
- live = false;
- fluff("Resetting state.");
+ private boolean cmdReload(String arg) {
+ Iterable<String> history = replayableHistory;
+ boolean echo = true;
+ if (arg.length() > 0) {
+ if ("restore".startsWith(arg)) {
+ if (replayableHistoryPrevious == null) {
+ hard("No previous history to restore\n", arg);
+ return false;
+ }
+ history = replayableHistoryPrevious;
+ } else if ("quiet".startsWith(arg)) {
+ echo = false;
+ } else {
+ hard("Invalid argument to reload command: %s\nUse 'restore', 'quiet', or no argument\n", arg);
+ return false;
+ }
+ }
+ fluff("Restarting and restoring %s.",
+ history == replayableHistoryPrevious
+ ? "from previous state"
+ : "state");
+ resetState();
+ run(new ReloadIOContext(history,
+ echo? cmdout : null));
+ return true;
}
- private void cmdSave(String arg_filename) {
+ private boolean cmdSave(String arg_filename) {
Matcher mat = HISTORY_ALL_START_FILENAME.matcher(arg_filename);
if (!mat.find()) {
hard("Malformed argument to the /save command: %s", arg_filename);
- return;
+ return false;
}
boolean useHistory = false;
String saveAll = "";
@@ -1211,7 +1309,7 @@
String filename = mat.group("filename");
if (filename == null ||filename.isEmpty()) {
hard("The /save command requires a filename argument.");
- return;
+ return false;
}
try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename),
Charset.defaultCharset(),
@@ -1234,12 +1332,15 @@
}
} catch (FileNotFoundException e) {
hard("File '%s' for save is not accessible: %s", filename, e.getMessage());
+ return false;
} catch (Exception e) {
hard("Exception while saving: %s", e);
+ return false;
}
+ return true;
}
- private void cmdSetStart(String filename) {
+ private boolean cmdSetStart(String filename) {
if (filename.isEmpty()) {
hard("The /setstart command requires a filename argument.");
} else {
@@ -1249,30 +1350,36 @@
PREFS.put(STARTUP_KEY, init);
} catch (AccessDeniedException e) {
hard("File '%s' for /setstart is not accessible.", filename);
+ return false;
} catch (NoSuchFileException e) {
hard("File '%s' for /setstart is not found.", filename);
+ return false;
} catch (Exception e) {
hard("Exception while reading start set file: %s", e);
+ return false;
}
}
+ return true;
}
- private void cmdVars() {
+ private boolean cmdVars() {
for (VarSnippet vk : state.variables()) {
String val = state.status(vk) == Status.VALID
? state.varValue(vk)
: "(not-active)";
hard(" %s %s = %s", vk.typeName(), vk.name(), val);
}
+ return true;
}
- private void cmdMethods() {
+ private boolean cmdMethods() {
for (MethodSnippet mk : state.methods()) {
hard(" %s %s", mk.name(), mk.signature());
}
+ return true;
}
- private void cmdClasses() {
+ private boolean cmdClasses() {
for (TypeDeclSnippet ck : state.types()) {
String kind;
switch (ck.subKind()) {
@@ -1295,15 +1402,17 @@
}
hard(" %s %s", kind, ck.name());
}
+ return true;
}
- private void cmdImports() {
+ private boolean cmdImports() {
state.imports().forEach(ik -> {
hard(" import %s%s", ik.isStatic() ? "static " : "", ik.fullname());
});
+ return true;
}
- private void cmdUseHistoryEntry(int index) {
+ private boolean cmdUseHistoryEntry(int index) {
List<Snippet> keys = state.snippets();
if (index < 0)
index += keys.size();
@@ -1313,7 +1422,9 @@
rerunSnippet(keys.get(index));
} else {
hard("Cannot find snippet %d", index + 1);
+ return false;
}
+ return true;
}
private boolean rerunHistoryEntryById(String id) {
@@ -1357,7 +1468,7 @@
}
}
- for (String line : diag.getMessage(null).split("\\r?\\n")) {
+ for (String line : diag.getMessage(null).split("\\r?\\n")) { // TODO: Internationalize
if (!line.trim().startsWith("location:")) {
hard("%s%s", padding, line);
}
@@ -1425,10 +1536,24 @@
private boolean processCompleteSource(String source) throws IllegalStateException {
debug("Compiling: %s", source);
boolean failed = false;
+ boolean isActive = false;
List<SnippetEvent> events = state.eval(source);
for (SnippetEvent e : events) {
+ // Report the event, recording failure
failed |= handleEvent(e);
+
+ // If any main snippet is active, this should be replayable
+ // also ignore var value queries
+ isActive |= e.causeSnippet() == null &&
+ e.status().isActive &&
+ e.snippet().subKind() != VAR_VALUE_SUBKIND;
}
+ // If this is an active snippet and it didn't cause the backend to die,
+ // add it to the replayable history
+ if (isActive && live) {
+ addToReplayHistory(source);
+ }
+
return failed;
}
@@ -1784,31 +1909,11 @@
}
}
-class ScannerIOContext extends IOContext {
-
- private final Scanner scannerIn;
- private final PrintStream pStream;
-
- public ScannerIOContext(Scanner scannerIn, PrintStream pStream) {
- this.scannerIn = scannerIn;
- this.pStream = pStream;
- }
-
- @Override
- public String readLine(String prompt, String prefix) {
- if (pStream != null && prompt != null) {
- pStream.print(prompt);
- }
- if (scannerIn.hasNextLine()) {
- return scannerIn.nextLine();
- } else {
- return null;
- }
- }
+abstract class NonInteractiveIOContext extends IOContext {
@Override
public boolean interactiveOutput() {
- return true;
+ return false;
}
@Override
@@ -1817,11 +1922,6 @@
}
@Override
- public void close() {
- scannerIn.close();
- }
-
- @Override
public boolean terminalEditorRunning() {
return false;
}
@@ -1847,19 +1947,62 @@
}
}
+class ScannerIOContext extends NonInteractiveIOContext {
+ private final Scanner scannerIn;
+
+ ScannerIOContext(Scanner scannerIn) {
+ this.scannerIn = scannerIn;
+ }
+
+ @Override
+ public String readLine(String prompt, String prefix) {
+ if (scannerIn.hasNextLine()) {
+ return scannerIn.nextLine();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void close() {
+ scannerIn.close();
+ }
+}
+
class FileScannerIOContext extends ScannerIOContext {
- public FileScannerIOContext(String fn) throws FileNotFoundException {
+ FileScannerIOContext(String fn) throws FileNotFoundException {
this(new FileReader(fn));
}
- public FileScannerIOContext(Reader rdr) throws FileNotFoundException {
- super(new Scanner(rdr), null);
+ FileScannerIOContext(Reader rdr) throws FileNotFoundException {
+ super(new Scanner(rdr));
+ }
+}
+
+class ReloadIOContext extends NonInteractiveIOContext {
+ private final Iterator<String> it;
+ private final PrintStream echoStream;
+
+ ReloadIOContext(Iterable<String> history, PrintStream echoStream) {
+ this.it = history.iterator();
+ this.echoStream = echoStream;
}
@Override
- public boolean interactiveOutput() {
- return false;
+ public String readLine(String prompt, String prefix) {
+ String s = it.hasNext()
+ ? it.next()
+ : null;
+ if (echoStream != null && s != null) {
+ String p = "-: ";
+ String p2 = "\n ";
+ echoStream.printf("%s%s\n", p, s.replace("\n", p2));
+ }
+ return s;
+ }
+
+ @Override
+ public void close() {
}
}
-
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExecutionControl.java Sat Jan 16 00:28:28 2016 +0000
@@ -26,9 +26,12 @@
package jdk.jshell;
import static jdk.internal.jshell.remote.RemoteCodes.*;
+import java.io.DataInputStream;
+import java.io.InputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import com.sun.jdi.*;
@@ -69,7 +72,9 @@
socket = listener.accept();
// out before in -- match remote creation so we don't hang
out = new ObjectOutputStream(socket.getOutputStream());
- in = new ObjectInputStream(socket.getInputStream());
+ PipeInputStream commandIn = new PipeInputStream();
+ new DemultiplexInput(socket.getInputStream(), commandIn, proc.out, proc.err).start();
+ in = new ObjectInputStream(commandIn);
}
}
@@ -117,11 +122,13 @@
String result = in.readUTF();
return result;
}
- } catch (EOFException ex) {
- env.shutdown();
} catch (IOException | ClassNotFoundException ex) {
- proc.debug(DBG_GEN, "Exception on remote invoke: %s\n", ex);
- return "Execution failure: " + ex.getMessage();
+ if (!env.connection().isRunning()) {
+ env.shutdown();
+ } else {
+ proc.debug(DBG_GEN, "Exception on remote invoke: %s\n", ex);
+ return "Execution failure: " + ex.getMessage();
+ }
} finally {
synchronized (STOP_LOCK) {
userCodeRunning = false;
@@ -310,4 +317,112 @@
}
}
}
+
+ private final class DemultiplexInput extends Thread {
+
+ private final DataInputStream delegate;
+ private final PipeInputStream command;
+ private final PrintStream out;
+ private final PrintStream err;
+
+ public DemultiplexInput(InputStream input,
+ PipeInputStream command,
+ PrintStream out,
+ PrintStream err) {
+ super("output reader");
+ this.delegate = new DataInputStream(input);
+ this.command = command;
+ this.out = out;
+ this.err = err;
+ }
+
+ public void run() {
+ try {
+ while (true) {
+ int nameLen = delegate.read();
+ if (nameLen == (-1))
+ break;
+ byte[] name = new byte[nameLen];
+ DemultiplexInput.this.delegate.readFully(name);
+ int dataLen = delegate.read();
+ byte[] data = new byte[dataLen];
+ DemultiplexInput.this.delegate.readFully(data);
+ switch (new String(name, "UTF-8")) {
+ case "err":
+ err.write(data);
+ break;
+ case "out":
+ out.write(data);
+ break;
+ case "command":
+ for (byte b : data) {
+ command.write(Byte.toUnsignedInt(b));
+ }
+ break;
+ }
+ }
+ } catch (IOException ex) {
+ proc.debug(ex, "Failed reading output");
+ } finally {
+ command.close();
+ }
+ }
+
+ }
+
+ public static final class PipeInputStream extends InputStream {
+ public static final int INITIAL_SIZE = 128;
+
+ private int[] buffer = new int[INITIAL_SIZE];
+ private int start;
+ private int end;
+ private boolean closed;
+
+ @Override
+ public synchronized int read() {
+ while (start == end) {
+ if (closed) {
+ return -1;
+ }
+ try {
+ wait();
+ } catch (InterruptedException ex) {
+ //ignore
+ }
+ }
+ try {
+ return buffer[start];
+ } finally {
+ start = (start + 1) % buffer.length;
+ }
+ }
+
+ public synchronized void write(int b) {
+ if (closed)
+ throw new IllegalStateException("Already closed.");
+ int newEnd = (end + 1) % buffer.length;
+ if (newEnd == start) {
+ //overflow:
+ int[] newBuffer = new int[buffer.length * 2];
+ int rightPart = (end > start ? end : buffer.length) - start;
+ int leftPart = end > start ? 0 : start - 1;
+ System.arraycopy(buffer, start, newBuffer, 0, rightPart);
+ System.arraycopy(buffer, 0, newBuffer, rightPart, leftPart);
+ buffer = newBuffer;
+ start = 0;
+ end = rightPart + leftPart;
+ newEnd = end + 1;
+ }
+ buffer[end] = b;
+ end = newEnd;
+ notifyAll();
+ }
+
+ @Override
+ public synchronized void close() {
+ closed = true;
+ notifyAll();
+ }
+
+ }
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIConnection.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JDIConnection.java Sat Jan 16 00:28:28 2016 +0000
@@ -133,7 +133,7 @@
return vm;
}
- boolean setConnectorArg(String name, String value) {
+ synchronized boolean setConnectorArg(String name, String value) {
/*
* Too late if the connection already made
*/
@@ -165,7 +165,7 @@
}
}
- boolean isOpen() {
+ synchronized boolean isOpen() {
return (vm != null);
}
@@ -173,13 +173,17 @@
return (connector instanceof LaunchingConnector);
}
- public void disposeVM() {
+ synchronized boolean isRunning() {
+ return process != null && process.isAlive();
+ }
+
+ public synchronized void disposeVM() {
try {
if (vm != null) {
vm.dispose(); // This could NPE, so it is caught below
vm = null;
}
- } catch (VMDisconnectedException | NullPointerException ex) {
+ } catch (VMDisconnectedException ex) {
// Ignore if already closed
} finally {
if (process != null) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrap.java Sat Jan 16 00:28:28 2016 +0000
@@ -182,9 +182,9 @@
return null;
}
- @Override
- public String toString() {
- return "WrappedDiagnostic(" + getMessage(null) + ":" + getPosition() + ")";
- }
+ @Override
+ public String toString() {
+ return "WrappedDiagnostic(" + getMessage(null) + ":" + getPosition() + ")";
+ }
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java Sat Jan 16 00:28:28 2016 +0000
@@ -33,7 +33,6 @@
import com.sun.tools.javac.util.Context;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
@@ -395,7 +394,7 @@
LinkedHashMap<String, Diag> diagMap = new LinkedHashMap<>();
for (Diagnostic<? extends JavaFileObject> in : diagnostics.getDiagnostics()) {
Diag d = diag(in);
- String uniqueKey = d.getCode() + ":" + d.getPosition() + ":" + d.getMessage(null);
+ String uniqueKey = d.getCode() + ":" + d.getPosition() + ":" + d.getMessage(PARSED_LOCALE);
diagMap.put(uniqueKey, d);
}
diags = new DiagList(diagMap.values());
@@ -410,7 +409,7 @@
String shortErrorMessage() {
StringBuilder sb = new StringBuilder();
for (Diag diag : getDiagnostics()) {
- for (String line : diag.getMessage(null).split("\\r?\\n")) {
+ for (String line : diag.getMessage(PARSED_LOCALE).split("\\r?\\n")) {
if (!line.trim().startsWith("location:")) {
sb.append(line);
}
@@ -422,7 +421,7 @@
void debugPrintDiagnostics(String src) {
for (Diag diag : getDiagnostics()) {
state.debug(DBG_GEN, "ERROR --\n");
- for (String line : diag.getMessage(null).split("\\r?\\n")) {
+ for (String line : diag.getMessage(PARSED_LOCALE).split("\\r?\\n")) {
if (!line.trim().startsWith("location:")) {
state.debug(DBG_GEN, "%s\n", line);
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Unit.java Sat Jan 16 00:28:28 2016 +0000
@@ -50,6 +50,7 @@
import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
import static jdk.jshell.Snippet.Status.REJECTED;
import static jdk.jshell.Snippet.Status.VALID;
+import static jdk.jshell.Util.PARSED_LOCALE;
import static jdk.jshell.Util.expunge;
/**
@@ -456,7 +457,7 @@
for (Diag diag : diags) {
if (diag.isError()) {
if (diag.isResolutionError()) {
- String m = diag.getMessage(null);
+ String m = diag.getMessage(PARSED_LOCALE);
int symPos = m.indexOf(RESOLVE_ERROR_SYMBOL);
if (symPos >= 0) {
m = m.substring(symPos + RESOLVE_ERROR_SYMBOL.length());
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,6 +25,7 @@
package jdk.jshell;
+import java.util.Locale;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import javax.lang.model.element.Name;
@@ -40,6 +41,8 @@
static final String REPL_CLASS_PREFIX = "$REPL";
static final String REPL_DOESNOTMATTER_CLASS_NAME = REPL_CLASS_PREFIX+"00DOESNOTMATTER";
+ static final Locale PARSED_LOCALE = Locale.ROOT;
+
static boolean isDoIt(Name name) {
return isDoIt(name.toString());
}
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Sat Jan 16 00:28:28 2016 +0000
@@ -152,13 +152,13 @@
}
public String getCommandOutput() {
- String s = cmdout.toString();
+ String s = normalizeLineEndings(cmdout.toString());
cmdout.reset();
return s;
}
public String getCommandErrorOutput() {
- String s = cmderr.toString();
+ String s = normalizeLineEndings(cmderr.toString());
cmderr.reset();
return s;
}
@@ -168,13 +168,13 @@
}
public String getUserOutput() {
- String s = userout.toString();
+ String s = normalizeLineEndings(userout.toString());
userout.reset();
return s;
}
public String getUserErrorOutput() {
- String s = usererr.toString();
+ String s = normalizeLineEndings(usererr.toString());
usererr.reset();
return s;
}
@@ -461,6 +461,10 @@
}
}
+ private String normalizeLineEndings(String text) {
+ return text.replace(System.getProperty("line.separator"), "\n");
+ }
+
public static abstract class MemberInfo {
public final String source;
public final String type;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/T8146368/JShellTest8146368.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, 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 8146368
+ * @summary Test Smashing Error when user language is Japanese
+ * @library /tools/lib /jdk/jshell
+ * @build KullaTesting
+ * @run testng/othervm -Duser.language=ja JShellTest8146368
+ */
+
+import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
+import org.testng.annotations.Test;
+
+@Test
+public class JShellTest8146368 extends KullaTesting {
+ public void test() {
+ assertEval("class A extends B {}", added(RECOVERABLE_NOT_DEFINED));
+ assertEval("und m() { return new und(); }", added(RECOVERABLE_NOT_DEFINED));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/T8146368/JShellToolTest8146368.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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 8146368
+ * @summary Test Smashing Error when user language is Japanese
+ * @library /tools/lib /jdk/jshell
+ * @build ReplToolTesting
+ * @run testng/othervm -Duser.language=ja JShellToolTest8146368
+ */
+
+import org.testng.annotations.Test;
+
+@Test
+public class JShellToolTest8146368 extends ReplToolTesting {
+ public void test() {
+ test(
+ a -> assertCommand(a, "class A extends B {}", "| Added class A, however, it cannot be referenced until class B is declared\n"),
+ a -> assertCommand(a, "und m() { return new und(); }", "| Added method m(), however, it cannot be referenced until class und is declared\n")
+ );
+ }
+}
--- a/langtools/test/jdk/jshell/ToolBasicTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -23,14 +23,16 @@
/*
* @test
- * @bug 8143037 8142447 8144095 8140265
+ * @bug 8143037 8142447 8144095 8140265 8144906
+ * @requires os.family != "solaris"
* @summary Tests for Basic tests for REPL tool
* @library /tools/lib
* @ignore 8139873
* @build KullaTesting TestingInputStream ToolBox Compiler
- * @run testng ToolBasicTest
+ * @run testng/timeout=600 ToolBasicTest
*/
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -460,8 +462,7 @@
Path unknown = compiler.getPath("UNKNOWN.jar");
test(true, new String[]{unknown.toString()},
"| File '" + unknown
- + "' is not found: " + unknown
- + " (No such file or directory)\n");
+ + "' is not found: " + unresolvableMessage(unknown) + "\n");
}
public void testReset() {
@@ -514,8 +515,7 @@
test(
(a) -> assertCommand(a, s + " " + unknown,
"| File '" + unknown
- + "' is not found: " + unknown
- + " (No such file or directory)\n")
+ + "' is not found: " + unresolvableMessage(unknown) + "\n")
);
}
}
@@ -874,6 +874,15 @@
);
}
+ private String unresolvableMessage(Path p) {
+ try {
+ new FileInputStream(p.toFile());
+ throw new AssertionError("Expected exception did not occur.");
+ } catch (IOException ex) {
+ return ex.getMessage();
+ }
+ }
+
public void testCommandPrefix() {
test(a -> assertCommandCheckOutput(a, "/s",
assertStartsWith("| Command: /s is ambiguous: /seteditor, /save, /setstart")),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/ToolReloadTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2015, 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 8081845
+ * @summary Tests for /reload in JShell tool
+ * @library /tools/lib
+ * @build KullaTesting TestingInputStream ToolBox Compiler
+ * @run testng ToolReloadTest
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.function.Function;
+
+import org.testng.annotations.Test;
+
+
+@Test
+public class ToolReloadTest extends ReplToolTesting {
+
+ public void testReloadSnippets() {
+ test(
+ (a) -> assertVariable(a, "int", "x", "5", "5"),
+ (a) -> assertMethod(a, "int m(int z) { return z * z; }",
+ "(int)int", "m"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25"),
+ (a) -> assertCommand(a, "/reload",
+ "| Restarting and restoring state.\n" +
+ "-: int x = 5;\n" +
+ "-: int m(int z) { return z * z; }\n" +
+ "-: m(x)\n"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25"),
+ (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+ (a) -> assertCommandCheckOutput(a, "/methods", assertMethods())
+ );
+ }
+
+ public void testReloadClasspath() {
+ Function<String,String> prog = (s) -> String.format(
+ "package pkg; public class A { public String toString() { return \"%s\"; } }\n", s);
+ Compiler compiler = new Compiler();
+ Path outDir = Paths.get("testClasspathDirectory");
+ compiler.compile(outDir, prog.apply("A"));
+ Path classpath = compiler.getPath(outDir);
+ test(
+ (a) -> assertCommand(a, "/classpath " + classpath,
+ String.format("| Path %s added to classpath\n", classpath)),
+ (a) -> assertMethod(a, "String foo() { return (new pkg.A()).toString(); }",
+ "()String", "foo"),
+ (a) -> assertVariable(a, "String", "v", "foo()", "\"A\""),
+ (a) -> {
+ if (!a) compiler.compile(outDir, prog.apply("Aprime"));
+ assertCommand(a, "/reload",
+ "| Restarting and restoring state.\n" +
+ "-: /classpath " + classpath + "\n" +
+ "-: String foo() { return (new pkg.A()).toString(); }\n" +
+ "-: String v = foo();\n");
+ },
+ (a) -> assertCommand(a, "v", "| Variable v of type String has value \"Aprime\"\n"),
+ (a) -> evaluateExpression(a, "String", "foo()", "\"Aprime\""),
+ (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "\"Aprime\"")
+ );
+ }
+
+ public void testReloadDrop() {
+ test(false, new String[]{"-nostartup"},
+ a -> assertVariable(a, "int", "a"),
+ a -> dropVariable(a, "/dr 1", "int a = 0"),
+ a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
+ a -> dropMethod(a, "/drop b", "b ()I"),
+ a -> assertClass(a, "class A {}", "class", "A"),
+ a -> dropClass(a, "/dr A", "class A"),
+ a -> assertCommand(a, "/reload",
+ "| Restarting and restoring state.\n" +
+ "-: int a;\n" +
+ "-: /drop 1\n" +
+ "-: int b() { return 0; }\n" +
+ "-: /drop b\n" +
+ "-: class A {}\n" +
+ "-: /drop A\n"),
+ a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+ a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
+ a -> assertCommandCheckOutput(a, "/classes", assertClasses()),
+ a -> assertCommandCheckOutput(a, "/imports", assertImports())
+ );
+ }
+
+ public void testReloadRepeat() {
+ test(false, new String[]{"-nostartup"},
+ (a) -> assertVariable(a, "int", "c", "7", "7"),
+ (a) -> assertCommand(a, "++c", null),
+ (a) -> assertCommand(a, "/!", null),
+ (a) -> assertCommand(a, "/2", null),
+ (a) -> assertCommand(a, "/-1", null),
+ (a) -> assertCommand(a, "/reload",
+ "| Restarting and restoring state.\n" +
+ "-: int c = 7;\n" +
+ "-: ++c\n" +
+ "-: ++c\n" +
+ "-: ++c\n" +
+ "-: ++c\n"
+ ),
+ (a) -> assertCommand(a, "c", "| Variable c of type int has value 11\n"),
+ (a) -> assertCommand(a, "$4", "| Variable $4 of type int has value 10\n")
+ );
+ }
+
+ public void testReloadIgnore() {
+ test(false, new String[]{"-nostartup"},
+ (a) -> assertCommand(a, "(-)", null),
+ (a) -> assertCommand(a, "/list", null),
+ (a) -> assertCommand(a, "/history", null),
+ (a) -> assertCommand(a, "/help", null),
+ (a) -> assertCommand(a, "/vars", null),
+ (a) -> assertCommand(a, "/save abcd", null),
+ (a) -> assertCommand(a, "/reload",
+ "| Restarting and restoring state.\n")
+ );
+ }
+
+ public void testReloadResetRestore() {
+ test(
+ (a) -> assertVariable(a, "int", "x", "5", "5"),
+ (a) -> assertMethod(a, "int m(int z) { return z * z; }",
+ "(int)int", "m"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25"),
+ (a) -> assertCommand(a, "/reset", "| Resetting state.\n"),
+ (a) -> assertCommand(a, "/reload restore",
+ "| Restarting and restoring from previous state.\n" +
+ "-: int x = 5;\n" +
+ "-: int m(int z) { return z * z; }\n" +
+ "-: m(x)\n"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25"),
+ (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+ (a) -> assertCommandCheckOutput(a, "/methods", assertMethods())
+ );
+ }
+
+ public void testReloadCrashRestore() {
+ test(
+ (a) -> assertVariable(a, "int", "x", "5", "5"),
+ (a) -> assertMethod(a, "int m(int z) { return z * z; }",
+ "(int)int", "m"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25"),
+ (a) -> assertCommand(a, "System.exit(1);",
+ "| State engine terminated.\n" +
+ "| Restore definitions with: /reload restore\n"),
+ (a) -> assertCommand(a, "/reload restore",
+ "| Restarting and restoring from previous state.\n" +
+ "-: int x = 5;\n" +
+ "-: int m(int z) { return z * z; }\n" +
+ "-: m(x)\n"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25"),
+ (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
+ (a) -> assertCommandCheckOutput(a, "/methods", assertMethods())
+ );
+ }
+
+ public void testReloadExitRestore() {
+ test(false, new String[]{"-nostartup"},
+ (a) -> assertVariable(a, "int", "x", "5", "5"),
+ (a) -> assertMethod(a, "int m(int z) { return z * z; }",
+ "(int)int", "m"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25")
+ );
+ test(false, new String[]{"-nostartup"},
+ (a) -> assertCommand(a, "/reload restore",
+ "| Restarting and restoring from previous state.\n" +
+ "-: int x = 5;\n" +
+ "-: int m(int z) { return z * z; }\n" +
+ "-: m(x)\n"),
+ (a) -> evaluateExpression(a, "int", "m(x)", "25")
+ );
+ }
+}
--- a/langtools/test/tools/javac/BadHexConstant.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/javac/BadHexConstant.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 4049982
+ * @bug 4049982 8056897
* @summary Compiler permitted invalid hex literal.
* @author turnidge
*
--- a/langtools/test/tools/javac/BadHexConstant.out Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/javac/BadHexConstant.out Sat Jan 16 00:28:28 2016 +0000
@@ -1,3 +1,2 @@
BadHexConstant.java:12:14: compiler.err.invalid.hex.number
-BadHexConstant.java:12:17: compiler.err.expected: token.identifier
-2 errors
+1 error
--- a/langtools/test/tools/javac/api/T6430241.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, 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 6430241
- * @summary Hard to disable symbol file feature through API
- * @library /tools/lib
- * @modules jdk.compiler/com.sun.tools.javac.api
- * jdk.compiler/com.sun.tools.javac.file
- * jdk.compiler/com.sun.tools.javac.main
- * jdk.compiler/com.sun.tools.javac.util
- * @build ToolBox
- * @run main T6430241
- */
-
-import java.io.*;
-import java.util.*;
-
-import javax.tools.*;
-
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.Context;
-
-public class T6430241 {
- public static void main(String... args) throws Exception {
- new T6430241().run();
- }
-
- void run() throws Exception {
- setup();
- testCommandLine();
- testSimpleAPI();
- testTaskAPI();
-
- if (errors > 0)
- throw new Exception(errors + " errors found");
- }
-
- void setup() throws Exception {
- classesDir = new File("classes");
- classesDir.mkdirs();
-
- emptyDir = new File("empty");
- emptyDir.mkdirs();
-
- bootClassPath = createJar().getPath();
-
- File srcDir = new File("src");
- String test = "import sun.misc.Unsafe; class Test { }";
- testFile = writeFile(srcDir, "Test.java", test);
- }
-
- //----- tests for command line invocation
-
- void testCommandLine() throws Exception {
- testCommandLine(true);
- testCommandLine(false, "-Xbootclasspath/p:" + emptyDir);
- testCommandLine(false, "-Xbootclasspath:" + bootClassPath);
- testCommandLine(false, "-Xbootclasspath/a:" + emptyDir);
- testCommandLine(false, "-XDignore.symbol.file");
- System.err.println();
- }
-
- void testCommandLine(boolean expectWarnings, String... opts) throws Exception {
- System.err.println("test command line: " + Arrays.asList(opts));
-
- String[] args = initArgs(opts);
-
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- int rc = com.sun.tools.javac.Main.compile(args, pw);
- String out = showOutput(sw.toString());
-
- checkCompilationOK(rc);
- checkOutput(out, expectWarnings);
- }
-
- //----- tests for simple API invocation
-
- void testSimpleAPI() {
- testSimpleAPI(true);
- testSimpleAPI(false, "-Xbootclasspath/p:" + emptyDir);
- testSimpleAPI(false, "-Xbootclasspath:" + bootClassPath);
- testSimpleAPI(false, "-Xbootclasspath/a:" + emptyDir);
- testSimpleAPI(false, "-XDignore.symbol.file");
- System.err.println();
- }
-
- void testSimpleAPI(boolean expectWarnings, String... opts) {
- System.err.println("test simple API: " + Arrays.asList(opts));
-
- String[] args = initArgs(opts);
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos);
-
- JavacTool tool = JavacTool.create();
- int rc = tool.run(null, null, ps, args);
-
- String out = showOutput(baos.toString());
-
- checkCompilationOK(rc);
- checkOutput(out, expectWarnings);
- }
-
- //----- tests for CompilationTask API invocation
-
- void testTaskAPI() throws Exception {
- List<File> bcp = new ArrayList<File>();
- for (String f: bootClassPath.split(File.pathSeparator)) {
- if (!f.isEmpty())
- bcp.add(new File(f));
- }
-
- testTaskAPI(true, null);
- testTaskAPI(false, bcp);
- System.err.println();
- }
-
- void testTaskAPI(boolean expectWarnings, Iterable<? extends File> pcp) throws Exception {
- System.err.println("test task API: " + pcp);
-
- JavacTool tool = JavacTool.create();
- try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
-
- if (pcp != null)
- fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, pcp);
-
- Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(testFile);
-
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- JavacTask task = tool.getTask(pw, fm, null, null, null, files);
- boolean ok = task.call();
- String out = showOutput(sw.toString());
-
- checkCompilationOK(ok);
- checkOutput(out, expectWarnings);
- }
- }
-
- //----- utility methods
-
- File createJar() throws IOException {
- File f = new File("test.jar");
- try (JavaFileManager fm = new JavacFileManager(new Context(), false, null)) {
- ToolBox tb = new ToolBox();
- tb.new JarTask(f.getPath())
- .files(fm, StandardLocation.PLATFORM_CLASS_PATH, "java.lang.*", "sun.misc.*")
- .run();
- }
- return f;
- }
-
- /**
- * Create a file with given content.
- */
- File writeFile(File dir, String path, String content) throws IOException {
- File f = new File(dir, path);
- f.getParentFile().mkdirs();
- FileWriter out = new FileWriter(f);
- try {
- out.write(content);
- } finally {
- out.close();
- }
- return f;
- }
-
- /**
- * Initialize args for compilation with given opts.
- * @return opts -d classesDir testFile
- */
- String[] initArgs(String[] opts) {
- List<String> args = new ArrayList<String>();
- args.addAll(Arrays.asList(opts));
- args.add("-d");
- args.add(classesDir.getPath());
- args.add(testFile.getPath());
- return args.toArray(new String[args.size()]);
- }
-
- /**
- * Show output from compilation if non empty.
- */
- String showOutput(String out) {
- if (!out.isEmpty())
- System.err.println(out);
- return out;
- }
-
- /**
- * Verify compilation succeeded.
- */
- void checkCompilationOK(boolean ok) {
- if (!ok)
- error("compilation failed");
- }
-
- /**
- * Verify compilation succeeded.
- */
- void checkCompilationOK(int rc) {
- if (rc != 0)
- error("compilation failed, rc: " + rc);
- }
-
- /**
- * Check whether output contains warnings if and only if warnings
- * are expected.
- */
- void checkOutput(String out, boolean expectWarnings) {
- boolean foundWarnings = out.contains("warning");
- if (foundWarnings) {
- if (!expectWarnings)
- error("unexpected warnings found");
- } else {
- if (expectWarnings)
- error("expected warnings not found");
- }
- }
-
- /**
- * Report an error.
- */
- void error(String msg) {
- System.err.println("error: " + msg);
- errors++;
- }
-
- String bootClassPath;
- File classesDir;
- File emptyDir;
- File testFile;
- int errors;
-}
--- a/langtools/test/tools/javac/diags/examples/IdentifierExpected.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/javac/diags/examples/IdentifierExpected.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,9 @@
// key: compiler.misc.token.identifier
// key: compiler.err.expected
-// key: compiler.err.invalid.binary.number
-// key: compiler.misc.count.error.plural
+// key: compiler.misc.count.error
// key: compiler.err.error
// run: backdoor
-class IdentifierExpected {
- long bl = 0BL;
+class {
}
--- a/langtools/test/tools/javac/file/BootClassPathPrepend.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, 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 8067445
- * @summary Verify that file.Locations analyze sun.boot.class.path for BCP prepends/appends
- * @library /tools/lib
- * @modules jdk.compiler/com.sun.tools.javac.api
- * jdk.compiler/com.sun.tools.javac.file
- * jdk.compiler/com.sun.tools.javac.main
- */
-
-import java.io.IOException;
-import java.util.EnumSet;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.StandardLocation;
-import javax.tools.ToolProvider;
-
-public class BootClassPathPrepend {
- public static void main(String... args) throws IOException {
- if (args.length == 0) {
- new BootClassPathPrepend().reRun();
- } else {
- new BootClassPathPrepend().run();
- }
- }
-
- void reRun() {
- String testClasses = System.getProperty("test.classes");
- ToolBox tb = new ToolBox();
- tb.new JavaTask().vmOptions("-Xbootclasspath/p:" + testClasses)
- .classArgs("real-run")
- .className("BootClassPathPrepend")
- .run()
- .writeAll();
- }
-
- EnumSet<Kind> classKind = EnumSet.of(JavaFileObject.Kind.CLASS);
-
- void run() throws IOException {
- JavaCompiler toolProvider = ToolProvider.getSystemJavaCompiler();
- try (JavaFileManager fm = toolProvider.getStandardFileManager(null, null, null)) {
- Iterable<JavaFileObject> files =
- fm.list(StandardLocation.PLATFORM_CLASS_PATH, "", classKind, false);
- for (JavaFileObject fo : files) {
- if (fo.isNameCompatible("BootClassPathPrepend", JavaFileObject.Kind.CLASS)) {
- System.err.println("Found BootClassPathPrepend on bootclasspath");
- return ;//found
- }
- }
-
- throw new AssertionError("Cannot find class that was prepended on BCP");
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific15.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 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 8143852
+ * @summary Rename functional interface method type parameters during most specific test
+ * @compile MostSpecific15.java
+ */
+class MostSpecific15 {
+ interface F1 { <X> Object apply(X arg); }
+ interface F2 { <Y> String apply(Y arg); }
+
+ static void m1(F1 f) {}
+ static void m1(F2 f) {}
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific15::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific16.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Rename functional interface method type parameters during most specific test
+ * @compile/fail/ref=MostSpecific16.out -XDrawDiagnostics MostSpecific16.java
+ */
+class MostSpecific16 {
+ interface F1 { <X> Object apply(Object arg); }
+ interface F2 { String apply(Object arg); }
+
+ static void m1(F1 f) {}
+ static void m1(F2 f) {}
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific16::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific16.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific16.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific16.F1), MostSpecific16, kindname.method, m1(MostSpecific16.F2), MostSpecific16
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific17.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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 8143852
+ * @summary Rename functional interface method type parameters during most specific test
+ * @compile MostSpecific17.java
+ */
+class MostSpecific17 {
+
+ interface A<T> {}
+ interface B<T> extends A<T> {}
+
+ interface F1 { <X> A<? super X> apply(Object arg); }
+ interface F2 { <Y> B<? super Y> apply(Object arg); }
+
+ static void m1(F1 f) {}
+ static void m1(F2 f) {}
+
+ static B<Object> foo(Object in) { return null; }
+
+ void test() {
+ m1(MostSpecific17::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific18.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 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 8143852
+ * @summary Test that generic function interface method bounds are the same
+ * @compile MostSpecific18.java
+ */
+class MostSpecific18 {
+ interface F1 { <X extends Number> Object apply(X arg); }
+ interface F2 { <Y extends Number> String apply(Y arg); }
+
+ static void m1(F1 f) {}
+ static void m1(F2 f) {}
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific18::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific19.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Test that generic function interface method bounds are the same
+ * @compile/fail/ref=MostSpecific19.out -XDrawDiagnostics MostSpecific19.java
+ */
+class MostSpecific19 {
+ interface F1 { <X extends Number> Object apply(X arg); }
+ interface F2 { <Y extends Integer> String apply(Y arg); }
+
+ static void m1(F1 f) {}
+ static void m1(F2 f) {}
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific19::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific19.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific19.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific19.F1), MostSpecific19, kindname.method, m1(MostSpecific19.F2), MostSpecific19
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific20.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 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 8143852
+ * @summary Test that generic function interface method bounds are the same
+ * @compile MostSpecific20.java
+ */
+class MostSpecific20 {
+ interface F1 { <X extends Iterable<X>> Object apply(X arg); }
+ interface F2 { <Y extends Iterable<Y>> String apply(Y arg); }
+
+ static void m1(F1 f) {}
+ static void m1(F2 f) {}
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific20::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific21.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific inference constraints derived from both functional interface method parameters and tparam bounds
+ * @compile/fail/ref=MostSpecific21.out -XDrawDiagnostics MostSpecific21.java
+ */
+class MostSpecific21 {
+ interface F1<T> { <X extends T> Object apply(T arg); }
+ interface F2 { <Y extends Number> String apply(Integer arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific21::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific21.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific21.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific21.F1<T>), MostSpecific21, kindname.method, m1(MostSpecific21.F2), MostSpecific21
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific22.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 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 8143852
+ * @summary Most specific inference constraints derived from both functional interface method parameters and tparam bounds
+ * @compile MostSpecific22.java
+ */
+class MostSpecific22 {
+ interface F1<T> { <X extends T> Object apply(T arg); }
+ interface F2 { <Y extends Number> String apply(Number arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific22::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific23.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific failure if ivar can be bounded by functional interface method tparam
+ * @compile/fail/ref=MostSpecific23.out -XDrawDiagnostics MostSpecific23.java
+ */
+class MostSpecific23 {
+ interface F1<T> { <X extends T> Object apply(Integer arg); }
+ interface F2 { <Y extends Class<Y>> String apply(Integer arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific23::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific23.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific23.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific23.F1<T>), MostSpecific23, kindname.method, m1(MostSpecific23.F2), MostSpecific23
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific24.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific failure if ivar can be bounded by functional interface method tparam
+ * @compile/fail/ref=MostSpecific24.out -XDrawDiagnostics MostSpecific24.java
+ */
+class MostSpecific24 {
+ interface F1<T> { <X> Object apply(Class<T> arg); }
+ interface F2 { <Y> String apply(Class<Y> arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific24::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific24.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific24.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific24.F1<T>), MostSpecific24, kindname.method, m1(MostSpecific24.F2), MostSpecific24
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific25.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific failure if ivar can be bounded by functional interface method tparam
+ * @compile/fail/ref=MostSpecific25.out -XDrawDiagnostics MostSpecific25.java
+ */
+class MostSpecific25 {
+ interface F1<T> { <X> T apply(Integer arg); }
+ interface F2 { <Y> Class<? super Y> apply(Integer arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static Class<Object> foo(Object in) { return Object.class; }
+
+ void test() {
+ m1(MostSpecific25::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific25.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific25.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific25.F1<T>), MostSpecific25, kindname.method, m1(MostSpecific25.F2), MostSpecific25
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific26.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Most specific inference constraints derived from intersection bound
+ * @compile/fail/ref=MostSpecific26.out -XDrawDiagnostics MostSpecific26.java
+ */
+class MostSpecific26 {
+ interface F1<T> { <X extends Iterable<T> & Runnable> Object apply(T arg); }
+ interface F2 { <Y extends Iterable<Number> & Runnable> String apply(Integer arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific26::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific26.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific26.java:17:9: compiler.err.ref.ambiguous: m1, kindname.method, <T>m1(MostSpecific26.F1<T>), MostSpecific26, kindname.method, m1(MostSpecific26.F2), MostSpecific26
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific27.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, 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 8143852
+ * @summary Most specific inference constraints derived from intersection bound
+ * @compile MostSpecific27.java
+ */
+class MostSpecific27 {
+ interface F1<T> { <X extends Iterable<T> & Runnable> Object apply(T arg); }
+ interface F2 { <Y extends Iterable<Number> & Runnable> String apply(Number arg); }
+
+ static <T> T m1(F1<T> f) { return null; }
+ static Object m1(F2 f) { return null; }
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1(MostSpecific27::foo);
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific28.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8143852
+ * @summary Test that functional interface method parameter types are equal, even for an explicit lambda
+ * @compile/fail/ref=MostSpecific28.out -XDrawDiagnostics MostSpecific28.java
+ */
+class MostSpecific28 {
+
+ interface Pred<T> { boolean test(T arg); }
+ interface Fun<T,R> { R apply(T arg); }
+
+ static void m1(Pred<? super Integer> f) {}
+ static void m1(Fun<Number, Boolean> f) {}
+
+ static String foo(Object in) { return "a"; }
+
+ void test() {
+ m1((Number n) -> true);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific28.out Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,2 @@
+MostSpecific28.java:18:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific28.Pred<? super java.lang.Integer>), MostSpecific28, kindname.method, m1(MostSpecific28.Fun<java.lang.Number,java.lang.Boolean>), MostSpecific28
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lexer/JavaLexerTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, 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 8056897
+ * @summary Proper lexing of integer literals.
+ */
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Objects;
+
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+import com.sun.tools.javac.parser.JavaTokenizer;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.parser.Tokens.Token;
+import com.sun.tools.javac.parser.Tokens.TokenKind;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+
+public class JavaLexerTest {
+ public static void main(String... args) throws Exception {
+ new JavaLexerTest().run();
+ }
+
+ void run() throws Exception {
+ Context ctx = new Context();
+ Log log = Log.instance(ctx);
+ String input = "0bL 0b20L 0xL ";
+ log.useSource(new SimpleJavaFileObject(new URI("mem://Test.java"), JavaFileObject.Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return input;
+ }
+ });
+ char[] inputArr = input.toCharArray();
+ JavaTokenizer tokenizer = new JavaTokenizer(ScannerFactory.instance(ctx), inputArr, inputArr.length) {
+ };
+
+ assertKind(input, tokenizer, TokenKind.LONGLITERAL, "0bL");
+ assertKind(input, tokenizer, TokenKind.LONGLITERAL, "0b20L");
+ assertKind(input, tokenizer, TokenKind.LONGLITERAL, "0xL");
+ }
+
+ void assertKind(String input, JavaTokenizer tokenizer, TokenKind kind, String expectedText) {
+ Token token = tokenizer.readToken();
+
+ if (token.kind != kind) {
+ throw new AssertionError("Unexpected token kind: " + token.kind);
+ }
+
+ String actualText = input.substring(token.pos, token.endPos);
+
+ if (!Objects.equals(actualText, expectedText)) {
+ throw new AssertionError("Unexpected token text: " + actualText);
+ }
+ }
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/literals/T6891079.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/javac/literals/T6891079.java Sat Jan 16 00:28:28 2016 +0000
@@ -1,5 +1,5 @@
/* @test /nodynamiccopyright/
- * @bug 6891079
+ * @bug 6891079 8056897
* @summary Compiler allows invalid binary literals 0b and oBL
* @compile/fail/ref=T6891079.out -XDrawDiagnostics T6891079.java
*/
--- a/langtools/test/tools/javac/literals/T6891079.out Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/javac/literals/T6891079.out Sat Jan 16 00:28:28 2016 +0000
@@ -1,7 +1,5 @@
T6891079.java:8:14: compiler.err.invalid.binary.number
T6891079.java:9:15: compiler.err.invalid.binary.number
-T6891079.java:9:18: compiler.err.expected: token.identifier
T6891079.java:10:14: compiler.err.invalid.hex.number
T6891079.java:11:15: compiler.err.invalid.hex.number
-T6891079.java:11:18: compiler.err.expected: token.identifier
-6 errors
+4 errors
--- a/langtools/test/tools/sjavac/CompileExcludingDependency.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/CompileExcludingDependency.java Sat Jan 16 00:28:28 2016 +0000
@@ -55,9 +55,9 @@
tb.writeFile(GENSRC.resolve("beta/B.java"),
"package beta; public class B { }");
- compile("-x", "beta",
+ compile("-x", "beta/*",
"-src", GENSRC.toString(),
- "-x", "alfa/omega",
+ "-x", "alfa/omega/*",
"-sourcepath", GENSRC.toString(),
"-d", BIN.toString(),
"--state-dir=" + BIN,
--- a/langtools/test/tools/sjavac/CompileWithAtFile.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/CompileWithAtFile.java Sat Jan 16 00:28:28 2016 +0000
@@ -47,8 +47,8 @@
void test() throws Exception {
tb.writeFile(GENSRC.resolve("list.txt"),
- "-if */alfa/omega/A.java\n" +
- "-if */beta/B.java\n" +
+ "-i alfa/omega/A.java\n" +
+ "-i beta/B.java\n" +
GENSRC + "\n" +
"-d " + BIN + "\n" +
"--state-dir=" + BIN + "\n");
--- a/langtools/test/tools/sjavac/CompileWithInvisibleSources.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/CompileWithInvisibleSources.java Sat Jan 16 00:28:28 2016 +0000
@@ -64,7 +64,7 @@
"package beta; public class B { }");
compile(GENSRC.toString(),
- "-x", "beta",
+ "-x", "beta/*",
"-sourcepath", GENSRC2.toString(),
"-sourcepath", GENSRC3.toString(),
"-d", BIN.toString(),
--- a/langtools/test/tools/sjavac/CompileWithOverrideSources.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/CompileWithOverrideSources.java Sat Jan 16 00:28:28 2016 +0000
@@ -62,7 +62,7 @@
tb.writeFile(GENSRC2.resolve("beta/B.java"),
"package beta; public class B { }");
- compile("-x", "beta",
+ compile("-x", "beta/*",
GENSRC.toString(),
GENSRC2.toString(),
"-d", BIN.toString(),
--- a/langtools/test/tools/sjavac/ExclPattern.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, 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 8037085
- * @summary Ensures that sjavac can handle various exclusion patterns.
- *
- * @modules jdk.compiler/com.sun.tools.sjavac
- * @build Wrapper
- * @run main Wrapper ExclPattern
- */
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-public class ExclPattern {
-
- public static void main(String[] ignore) throws IOException {
-
- String toBeExcluded = "pkg/excl-dir/excluded.txt";
- String toBeIncluded = "pkg/incl-dir/included.txt";
-
- // Set up source directory with directory to be excluded
- populate(Paths.get("srcdir"),
- "pkg/SomeClass.java",
- "package pkg; public class SomeClass { }",
-
- toBeExcluded,
- "This file should not end up in the dest directory.",
-
- toBeIncluded,
- "This file should end up in the dest directory.");
-
- String[] args = {
- "-x", "pkg/excl-dir/*",
- "-src", "srcdir",
- "-d", "dest",
- "--state-dir=dest",
- "-j", "1",
- "-copy", ".txt",
- "--server:portfile=testserver,background=false",
- "--log=debug"
- };
-
- int rc = com.sun.tools.sjavac.Main.go(args);
- if (rc != 0) throw new RuntimeException("Error during compile!");
-
- if (!Files.exists(Paths.get("dest/" + toBeIncluded)))
- throw new AssertionError("File missing: " + toBeIncluded);
-
- if (Files.exists(Paths.get("dest/" + toBeExcluded)))
- throw new AssertionError("File present: " + toBeExcluded);
- }
-
- static void populate(Path root, String... args) throws IOException {
- if (!Files.exists(root))
- Files.createDirectory(root);
- for (int i = 0; i < args.length; i += 2) {
- String filename = args[i];
- String content = args[i+1];
- Path p = root.resolve(filename);
- Files.createDirectories(p.getParent());
- try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(p,
- Charset.defaultCharset()))) {
- out.println(content);
- }
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/HiddenFiles.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8144226
+ * @summary Ensures that excluded files are inaccessible (even for implicit
+ * compilation)
+ *
+ * @modules jdk.compiler/com.sun.tools.sjavac
+ * @library /tools/lib
+ * @build Wrapper ToolBox
+ * @run main Wrapper HiddenFiles
+ */
+
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.sjavac.server.Sjavac;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class HiddenFiles extends SjavacBase {
+
+ public static void main(String[] ignore) throws Exception {
+ Path BIN = Paths.get("bin");
+ Path STATE_DIR = Paths.get("state-dir");
+ Path SRC = Paths.get("src");
+
+ Files.createDirectories(BIN);
+ Files.createDirectories(STATE_DIR);
+
+ toolbox.writeJavaFiles(SRC, "package pkg; class A { B b; }");
+ toolbox.writeJavaFiles(SRC, "package pkg; class B { }");
+
+ // This compilation should fail (return RC_FATAL) since A.java refers to B.java and B.java
+ // is excluded.
+ int rc = compile("-x", "pkg/B.java", SRC.toString(),
+ "--server:portfile=testportfile,background=false",
+ "-d", BIN.toString(),
+ "--state-dir=" + STATE_DIR);
+
+ Assert.check(rc == Sjavac.RC_FATAL, "Compilation succeeded unexpectedly.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/IncludeExcludePatterns.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, 2016, 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 8037085
+ * @summary Ensures that sjavac can handle various exclusion patterns.
+ *
+ * @modules jdk.compiler/com.sun.tools.sjavac
+ * @library /tools/lib
+ * @build Wrapper ToolBox
+ * @run main Wrapper IncludeExcludePatterns
+ */
+
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.sjavac.server.Sjavac;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class IncludeExcludePatterns extends SjavacBase {
+
+ final Path SRC = Paths.get("src");
+ final Path BIN = Paths.get("bin");
+ final Path STATE_DIR = Paths.get("state-dir");
+
+ // An arbitrarily but sufficiently complicated source tree.
+ final Path A = Paths.get("pkga/A.java");
+ final Path X1 = Paths.get("pkga/subpkg/Xx.java");
+ final Path Y = Paths.get("pkga/subpkg/subsubpkg/Y.java");
+ final Path B = Paths.get("pkgb/B.java");
+ final Path C = Paths.get("pkgc/C.java");
+ final Path X2 = Paths.get("pkgc/Xx.java");
+
+ final Path[] ALL_PATHS = {A, X1, Y, B, C, X2};
+
+ public static void main(String[] ignore) throws Exception {
+ new IncludeExcludePatterns().runTest();
+ }
+
+ public void runTest() throws IOException, ReflectiveOperationException {
+ Files.createDirectories(BIN);
+ Files.createDirectories(STATE_DIR);
+ for (Path p : ALL_PATHS) {
+ writeDummyClass(p);
+ }
+
+ // Single file
+ testPattern("pkga/A.java", A);
+
+ // Leading wild cards
+ testPattern("*/A.java", A);
+ testPattern("**/Xx.java", X1, X2);
+ testPattern("**x.java", X1, X2);
+
+ // Wild card in middle of path
+ testPattern("pkga/*/Xx.java", X1);
+ testPattern("pkga/**/Y.java", Y);
+
+ // Trailing wild cards
+ testPattern("pkga/*", A);
+ testPattern("pkga/**", A, X1, Y);
+
+ // Multiple wildcards
+ testPattern("pkga/*/*/Y.java", Y);
+ testPattern("**/*/**", X1, Y);
+
+ }
+
+ // Given "src/pkg/subpkg/A.java" this method returns "A"
+ String classNameOf(Path javaFile) {
+ return javaFile.getFileName()
+ .toString()
+ .replace(".java", "");
+ }
+
+ // Puts an empty (dummy) class definition in the given path.
+ void writeDummyClass(Path javaFile) throws IOException {
+ String pkg = javaFile.getParent().toString().replace(File.separatorChar, '.');
+ String cls = javaFile.getFileName().toString().replace(".java", "");
+ toolbox.writeFile(SRC.resolve(javaFile), "package " + pkg + "; class " + cls + " {}");
+ }
+
+ void testPattern(String filterArgs, Path... sourcesExpectedToBeVisible)
+ throws ReflectiveOperationException, IOException {
+ testFilter("-i " + filterArgs, Arrays.asList(sourcesExpectedToBeVisible));
+
+ Set<Path> complement = new HashSet<>(Arrays.asList(ALL_PATHS));
+ complement.removeAll(Arrays.asList(sourcesExpectedToBeVisible));
+ testFilter("-x " + filterArgs, complement);
+ }
+
+ void testFilter(String filterArgs, Collection<Path> sourcesExpectedToBeVisible)
+ throws IOException, ReflectiveOperationException {
+ System.out.println("Testing filter: " + filterArgs);
+ toolbox.cleanDirectory(BIN);
+ toolbox.cleanDirectory(STATE_DIR);
+ String args = filterArgs + " " + SRC
+ + " --server:portfile=testportfile,background=false"
+ + " -d " + BIN
+ + " --state-dir=" + STATE_DIR;
+ int rc = compile((Object[]) args.split(" "));
+
+ // Compilation should always pass in these tests
+ Assert.check(rc == Sjavac.RC_OK, "Compilation failed unexpectedly.");
+
+ // The resulting .class files should correspond to the visible source files
+ Set<Path> result = allFilesInDir(BIN);
+ Set<Path> expected = correspondingClassFiles(sourcesExpectedToBeVisible);
+ if (!result.equals(expected)) {
+ System.out.println("Result:");
+ printPaths(result);
+ System.out.println("Expected:");
+ printPaths(expected);
+ Assert.error("Test case failed: " + filterArgs);
+ }
+ }
+
+ void printPaths(Collection<Path> paths) {
+ paths.stream()
+ .sorted()
+ .forEachOrdered(p -> System.out.println(" " + p));
+ }
+
+ // Given "pkg/A.java, pkg/B.java" this method returns "bin/pkg/A.class, bin/pkg/B.class"
+ Set<Path> correspondingClassFiles(Collection<Path> javaFiles) {
+ return javaFiles.stream()
+ .map(javaFile -> javaFile.resolveSibling(classNameOf(javaFile) + ".class"))
+ .map(BIN::resolve)
+ .collect(Collectors.toSet());
+ }
+
+ Set<Path> allFilesInDir(Path p) throws IOException {
+ try (Stream<Path> files = Files.walk(p).filter(Files::isRegularFile)) {
+ return files.collect(Collectors.toSet());
+ }
+ }
+}
--- a/langtools/test/tools/sjavac/OptionDecoding.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/OptionDecoding.java Sat Jan 16 00:28:28 2016 +0000
@@ -61,7 +61,6 @@
public static void main(String[] args) throws IOException {
testPaths();
testDupPaths();
- testSourceLocations();
testSimpleOptions();
testServerConf();
testSearchPaths();
@@ -110,78 +109,6 @@
}
}
- // Test source locations and -x, -i, -xf, -if filters
- static void testSourceLocations() throws IOException {
- Path a1 = Paths.get("root/pkg1/ClassA1.java");
- Path a2 = Paths.get("root/pkg1/ClassA2.java");
- Path b1 = Paths.get("root/pkg1/pkg2/ClassB1.java");
- Path b2 = Paths.get("root/pkg1/pkg2/ClassB2.java");
- Path c1 = Paths.get("root/pkg3/ClassC1.java");
- Path c2 = Paths.get("root/pkg3/ClassC2.java");
-
- for (Path p : Arrays.asList(a1, a2, b1, b2, c1, c2)) {
- Files.createDirectories(p.getParent());
- Files.createFile(p);
- }
-
- // Test -if
- {
- Options options = Options.parseArgs("-if", "root/pkg1/ClassA1.java", "root");
-
- Map<String, Source> foundFiles = new HashMap<>();
- SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
- new HashMap<String, Module>(), new Module("", ""), false, true);
-
- checkFilesFound(foundFiles.keySet(), a1);
- }
-
- // Test -i
- System.out.println("--------------------------- CHECKING -i ----------------");
- {
- Options options = Options.parseArgs("-i", "pkg1/*", "root");
-
- Map<String, Source> foundFiles = new HashMap<>();
- SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
- new HashMap<String, Module>(), new Module("", ""), false, true);
-
- checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
- }
- System.out.println("--------------------------------------------------------");
-
- // Test -xf
- {
- Options options = Options.parseArgs("-xf", "root/pkg1/ClassA1.java", "root");
-
- Map<String, Source> foundFiles = new HashMap<>();
- SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
- new HashMap<String, Module>(), new Module("", ""), false, true);
-
- checkFilesFound(foundFiles.keySet(), a2, b1, b2, c1, c2);
- }
-
- // Test -x
- {
- Options options = Options.parseArgs("-i", "pkg1/*", "root");
-
- Map<String, Source> foundFiles = new HashMap<>();
- SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
- new HashMap<String, Module>(), new Module("", ""), false, true);
-
- checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
- }
-
- // Test -x and -i
- {
- Options options = Options.parseArgs("-i", "pkg1/*", "-x", "pkg1/pkg2/*", "root");
-
- Map<String, Source> foundFiles = new HashMap<>();
- SjavacImpl.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
- new HashMap<String, Module>(), new Module("", ""), false, true);
-
- checkFilesFound(foundFiles.keySet(), a1, a2);
- }
- }
-
// Test basic options
static void testSimpleOptions() {
Options options = Options.parseArgs("-j", "17", "--log=debug");
@@ -216,8 +143,8 @@
List<String> i, x, iF, xF;
i = x = iF = xF = new ArrayList<>();
- SourceLocation dir1 = new SourceLocation(Paths.get("dir1"), i, x, iF, xF);
- SourceLocation dir2 = new SourceLocation(Paths.get("dir2"), i, x, iF, xF);
+ SourceLocation dir1 = new SourceLocation(Paths.get("dir1"), i, x);
+ SourceLocation dir2 = new SourceLocation(Paths.get("dir2"), i, x);
String dir1_PS_dir2 = "dir1" + File.pathSeparator + "dir2";
Options options = Options.parseArgs("-sourcepath", dir1_PS_dir2);
--- a/langtools/test/tools/sjavac/Serialization.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/Serialization.java Sat Jan 16 00:28:28 2016 +0000
@@ -58,8 +58,6 @@
Option.D.arg, "dest",
Option.I.arg, "pkg/*",
Option.X.arg, "pkg/pkg/*",
- Option.IF.arg, "root/pkg/MyClass1.java",
- Option.XF.arg, "root/pkg/MyClass2.java",
Option.SRC.arg, "root",
Option.SOURCEPATH.arg, "sourcepath",
Option.CLASSPATH.arg, "classpath",
@@ -87,8 +85,6 @@
assertEquals(sl1.getPath(), sl2.getPath());
assertEquals(sl1.getIncludes(), sl2.getIncludes());
assertEquals(sl1.getExcludes(), sl2.getExcludes());
- assertEquals(sl1.getIncludedFiles(), sl2.getIncludedFiles());
- assertEquals(sl1.getExcludedFiles(), sl2.getExcludedFiles());
assertEquals(options1.getClassSearchPath(), options2.getClassSearchPath());
assertEquals(options1.getSourceSearchPaths(), options2.getSourceSearchPaths());
--- a/langtools/test/tools/sjavac/util/OptionTestUtil.java Fri Jan 15 23:38:25 2016 +0000
+++ b/langtools/test/tools/sjavac/util/OptionTestUtil.java Sat Jan 16 00:28:28 2016 +0000
@@ -62,9 +62,7 @@
if (!sl1.getPath().equals(sl2.getPath()) ||
!sl1.getIncludes().equals(sl2.getIncludes()) ||
- !sl1.getExcludes().equals(sl2.getExcludes()) ||
- !sl1.getIncludedFiles().equals(sl2.getIncludedFiles()) ||
- !sl1.getExcludedFiles().equals(sl2.getExcludedFiles()))
+ !sl1.getExcludes().equals(sl2.getExcludes()))
throw new AssertionError("Expected " + sl1 + " but got " + sl2);
}
}
--- a/make/common/JavaCompilation.gmk Fri Jan 15 23:38:25 2016 +0000
+++ b/make/common/JavaCompilation.gmk Sat Jan 16 00:28:28 2016 +0000
@@ -202,23 +202,28 @@
# CacheFind does not preserve order so need to call it for each root.
$1_ALL_SRCS += $$(foreach s, $$($1_SRC), $$(call CacheFind, $$(s)))
# Extract the java files.
- ifneq ($$($1_EXCLUDE_FILES),)
- $1_EXCLUDE_FILES_PATTERN:=$$(addprefix %,$$($1_EXCLUDE_FILES))
+ $1_SRCS := $$(filter %.java, $$($1_ALL_SRCS))
+
+ # Translate include/exclude into patterns
+ ifneq ($$($1_EXCLUDE_FILES), )
+ $1_EXCLUDE_PATTERN := $$(addprefix %, $$($1_EXCLUDE_FILES))
endif
- $1_SRCS := $$(filter-out $$($1_EXCLUDE_FILES_PATTERN),$$(filter %.java,$$($1_ALL_SRCS)))
- ifneq ($$($1_INCLUDE_FILES),)
- $1_INCLUDE_FILES:=$$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$($1_INCLUDE_FILES)))
- $1_SRCS := $$(filter $$($1_INCLUDE_FILES), $$($1_SRCS))
+ ifneq ($$($1_INCLUDE_FILES), )
+ $1_INCLUDE_PATTERN := $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$($1_INCLUDE_FILES)))
+ endif
+ ifneq ($$($1_EXCLUDES), )
+ $1_EXCLUDE_PATTERN += $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_EXCLUDES))))
+ endif
+ ifneq ($$($1_INCLUDES), )
+ $1_INCLUDE_PATTERN += $$(foreach i, $$($1_SRC), $$(addprefix $$i/, $$(addsuffix /%, $$($1_INCLUDES))))
endif
- # Prepend the source/bin path to the filter expressions.
- ifneq ($$($1_INCLUDES),)
- $1_SRC_INCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_INCLUDES))))
- $1_SRCS := $$(filter $$($1_SRC_INCLUDES),$$($1_SRCS))
+ # Apply include/exclude patterns to java sources
+ ifneq ($$($1_EXCLUDE_PATTERN), )
+ $1_SRCS := $$(filter-out $$($1_EXCLUDE_PATTERN), $$($1_SRCS))
endif
- ifneq ($$($1_EXCLUDES),)
- $1_SRC_EXCLUDES := $$(foreach i,$$($1_SRC),$$(addprefix $$i/,$$(addsuffix /%,$$($1_EXCLUDES))))
- $1_SRCS := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_SRCS))
+ ifneq ($$($1_INCLUDE_PATTERN), )
+ $1_SRCS := $$(filter $$($1_INCLUDE_PATTERN), $$($1_SRCS))
endif
ifneq ($$($1_KEEP_DUPS), true)
@@ -242,10 +247,10 @@
$1_SAFE_NAME := $$(strip $$(subst /,_, $1))
# Create the corresponding smart javac wrapper command line.
- $1_SJAVAC_ARGS:=$$(addprefix -x ,$$(addsuffix /*,$$($1_EXCLUDES))) \
- $$(addprefix -i ,$$(addsuffix /*,$$($1_INCLUDES))) \
- $$(addprefix -xf *,$$(strip $$($1_EXCLUDE_FILES) $$($1_SJAVAC_EXCLUDE_FILES))) \
- $$(addprefix -if *,$$(strip $$($1_INCLUDE_FILES))) \
+ $1_SJAVAC_ARGS:=$$(addprefix -x ,$$(addsuffix /**,$$($1_EXCLUDES))) \
+ $$(addprefix -i ,$$(addsuffix /**,$$($1_INCLUDES))) \
+ $$(addprefix -x **,$$(strip $$($1_EXCLUDE_FILES) $$($1_SJAVAC_EXCLUDE_FILES))) \
+ $$(addprefix -i **,$$(strip $$($1_INCLUDE_FILES))) \
-src $$(call PathList, $$($1_SRC))
# All files below META-INF are always copied.
@@ -258,14 +263,11 @@
$1_ALL_COPIES += $$($1_COPY_FILES)
endif
# Copy must also respect filters.
- ifneq (,$$($1_INCLUDES))
- $1_ALL_COPIES := $$(filter $$($1_SRC_INCLUDES),$$($1_ALL_COPIES))
+ ifneq (,$$($1_INCLUDE_PATTERN))
+ $1_ALL_COPIES := $$(filter $$($1_INCLUDE_PATTERN),$$($1_ALL_COPIES))
endif
- ifneq (,$$($1_EXCLUDES))
- $1_ALL_COPIES := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_ALL_COPIES))
- endif
- ifneq (,$$($1_EXCLUDE_FILES))
- $1_ALL_COPIES := $$(filter-out $$($1_EXCLUDE_FILES_PATTERN),$$($1_ALL_COPIES))
+ ifneq (,$$($1_EXCLUDE_PATTERN))
+ $1_ALL_COPIES := $$(filter-out $$($1_EXCLUDE_PATTERN),$$($1_ALL_COPIES))
endif
ifneq (,$$($1_ALL_COPIES))
# Yep, there are files to be copied!
@@ -281,14 +283,11 @@
# Clean these explicitly
$1_ALL_CLEANS += $$($1_CLEAN_FILES)
# Copy and clean must also respect filters.
- ifneq (,$$($1_INCLUDES))
- $1_ALL_CLEANS := $$(filter $$($1_SRC_INCLUDES),$$($1_ALL_CLEANS))
+ ifneq (,$$($1_INCLUDE_PATTERN))
+ $1_ALL_CLEANS := $$(filter $$($1_INCLUDE_PATTERN),$$($1_ALL_CLEANS))
endif
- ifneq (,$$($1_EXCLUDES))
- $1_ALL_CLEANS := $$(filter-out $$($1_SRC_EXCLUDES),$$($1_ALL_CLEANS))
- endif
- ifneq (,$$($1_EXCLUDE_FILES))
- $1_ALL_CLEANS := $$(filter-out $$($1_EXCLUDE_FILES_PATTERN),$$($1_ALL_CLEANS))
+ ifneq (,$$($1_EXCLUDE_PATTERN))
+ $1_ALL_CLEANS := $$(filter-out $$($1_EXCLUDE_PATTERN),$$($1_ALL_CLEANS))
endif
ifneq (,$$($1_ALL_CLEANS))
# Yep, there are files to be copied and cleaned!
--- a/modules.xml Fri Jan 15 23:38:25 2016 +0000
+++ b/modules.xml Sat Jan 16 00:28:28 2016 +0000
@@ -239,6 +239,12 @@
<to>jdk.scripting.nashorn</to>
</export>
<export>
+ <name>jdk.internal.perf</name>
+ <to>java.desktop</to>
+ <to>java.management</to>
+ <to>jdk.jvmstat</to>
+ </export>
+ <export>
<name>jdk.internal.org.objectweb.asm</name>
<to>java.instrument</to>
<to>jdk.jfr</to>
--- a/nashorn/.hgtags Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/.hgtags Sat Jan 16 00:28:28 2016 +0000
@@ -334,3 +334,4 @@
68a36216f70c0de4c7e36f8978995934fc72ec03 jdk-9+98
74ddd1339c57cf2c2a13e34e1760006c2e54d1fc jdk-9+99
da397aea8adad7e6f743b60bfe0c415fc8508df5 jdk-9+100
+1916a2c680d8c33b59943dbb6dc2dd2000ec821a jdk-9+101
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AbstractJavaLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AbstractJavaLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -349,55 +349,121 @@
throws Exception {
final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();
+ final MissingMemberHandlerFactory missingMemberHandlerFactory;
+ final LinkerServices directLinkerServices;
+ if (linkerServices instanceof LinkerServicesWithMissingMemberHandlerFactory) {
+ final LinkerServicesWithMissingMemberHandlerFactory lswmmhf = ((LinkerServicesWithMissingMemberHandlerFactory)linkerServices);
+ missingMemberHandlerFactory = lswmmhf.missingMemberHandlerFactory;
+ directLinkerServices = lswmmhf.linkerServices;
+ } else {
+ missingMemberHandlerFactory = null;
+ directLinkerServices = linkerServices;
+ }
+
// Handle NamedOperation(CALL_METHOD, name) separately
final Operation operation = callSiteDescriptor.getOperation();
if (operation instanceof NamedOperation) {
final NamedOperation namedOperation = (NamedOperation)operation;
if (namedOperation.getBaseOperation() == StandardOperation.CALL_METHOD) {
- return createGuardedDynamicMethodInvocation(callSiteDescriptor,
- linkerServices, namedOperation.getName().toString(), methods);
+ final GuardedInvocation inv =
+ createGuardedDynamicMethodInvocation(callSiteDescriptor,
+ directLinkerServices, namedOperation.getName().toString(), methods);
+ if (inv == null) {
+ return createNoSuchMemberHandler(missingMemberHandlerFactory,
+ request, directLinkerServices).getGuardedInvocation();
+ }
+ return inv;
}
}
- List<Operation> operations = Arrays.asList(
- CompositeOperation.getOperations(
- NamedOperation.getBaseOperation(operation)));
- final Object name = NamedOperation.getName(operation);
+ final GuardedInvocationComponent gic = getGuardedInvocationComponent(
+ new ComponentLinkRequest(request, directLinkerServices,
+ missingMemberHandlerFactory));
+ return gic != null ? gic.getGuardedInvocation() : null;
+ }
+
+ static final class ComponentLinkRequest {
+ final LinkRequest linkRequest;
+ final LinkerServices linkerServices;
+ final MissingMemberHandlerFactory missingMemberHandlerFactory;
+ final List<Operation> operations;
+ final Object name;
+
+ ComponentLinkRequest(final LinkRequest linkRequest,
+ final LinkerServices linkerServices,
+ final MissingMemberHandlerFactory missingMemberHandlerFactory) {
+ this.linkRequest = linkRequest;
+ this.linkerServices = linkerServices;
+ this.missingMemberHandlerFactory = missingMemberHandlerFactory;
+ final Operation operation = linkRequest.getCallSiteDescriptor().getOperation();
+ this.operations = Arrays.asList(
+ CompositeOperation.getOperations(
+ NamedOperation.getBaseOperation(operation)));
+ this.name = NamedOperation.getName(operation);
+ }
- while(!operations.isEmpty()) {
- final GuardedInvocationComponent gic =
- getGuardedInvocationComponent(callSiteDescriptor,
- linkerServices, operations, name);
- if(gic != null) {
- return gic.getGuardedInvocation();
+ private ComponentLinkRequest(final LinkRequest linkRequest,
+ final LinkerServices linkerServices,
+ final MissingMemberHandlerFactory missingMemberHandlerFactory,
+ final List<Operation> operations, final Object name) {
+ this.linkRequest = linkRequest;
+ this.linkerServices = linkerServices;
+ this.missingMemberHandlerFactory = missingMemberHandlerFactory;
+ this.operations = operations;
+ this.name = name;
+ }
+
+ CallSiteDescriptor getDescriptor() {
+ return linkRequest.getCallSiteDescriptor();
+ }
+
+ ComponentLinkRequest popOperations() {
+ return new ComponentLinkRequest(linkRequest, linkerServices,
+ missingMemberHandlerFactory,
+ operations.subList(1, operations.size()), name);
+ }
+ }
+
+ protected GuardedInvocationComponent getGuardedInvocationComponent(final ComponentLinkRequest req)
+ throws Exception {
+ final Operation op = req.operations.get(0);
+ if (op instanceof StandardOperation) {
+ switch((StandardOperation)op) {
+ case GET_PROPERTY: return getPropertyGetter(req.popOperations());
+ case SET_PROPERTY: return getPropertySetter(req.popOperations());
+ case GET_METHOD: return getMethodGetter(req.popOperations());
+ default:
}
- operations = pop(operations);
}
return null;
}
- protected GuardedInvocationComponent getGuardedInvocationComponent(
- final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices,
- final List<Operation> operations, final Object name)
- throws Exception {
- if(operations.isEmpty()) {
+ GuardedInvocationComponent getNextComponent(final ComponentLinkRequest req) throws Exception {
+ if (req.operations.isEmpty()) {
+ return createNoSuchMemberHandler(req.missingMemberHandlerFactory,
+ req.linkRequest, req.linkerServices);
+ }
+ final GuardedInvocationComponent gic = getGuardedInvocationComponent(req);
+ if (gic != null) {
+ return gic;
+ }
+ return getNextComponent(req.popOperations());
+ }
+
+ private GuardedInvocationComponent createNoSuchMemberHandler(
+ final MissingMemberHandlerFactory missingMemberHandlerFactory,
+ final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ if (missingMemberHandlerFactory == null) {
return null;
}
- final Operation op = operations.get(0);
- // Either GET_PROPERTY:name(this) or GET_PROPERTY(this, name)
- if(op == StandardOperation.GET_PROPERTY) {
- return getPropertyGetter(callSiteDescriptor, linkerServices, pop(operations), name);
+ final MethodHandle handler = missingMemberHandlerFactory.createMissingMemberHandler(linkRequest, linkerServices);
+ if (handler == null) {
+ return null;
}
- // Either SET_PROPERTY:name(this, value) or SET_PROPERTY(this, name, value)
- if(op == StandardOperation.SET_PROPERTY) {
- return getPropertySetter(callSiteDescriptor, linkerServices, pop(operations), name);
- }
- // Either GET_METHOD:name(this), or GET_METHOD(this, name)
- if(op == StandardOperation.GET_METHOD) {
- return getMethodGetter(callSiteDescriptor, linkerServices, pop(operations), name);
- }
- return null;
+ final MethodType type = linkRequest.getCallSiteDescriptor().getMethodType();
+ // The returned handler is allowed to differ in return type.
+ assert handler.type().changeReturnType(type.returnType()).equals(type);
+ return getClassGuardedInvocationComponent(handler, type);
}
static final <T> List<T> pop(final List<T> l) {
@@ -483,16 +549,15 @@
private static final MethodHandle CONSTANT_NULL_DROP_METHOD_HANDLE = MethodHandles.dropArguments(
MethodHandles.constant(Object.class, null), 0, MethodHandle.class);
- private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> operations, final Object name) throws Exception {
- if (name == null) {
- return getUnnamedPropertySetter(callSiteDescriptor, linkerServices, operations);
+ private GuardedInvocationComponent getPropertySetter(final ComponentLinkRequest req) throws Exception {
+ if (req.name == null) {
+ return getUnnamedPropertySetter(req);
}
- return getNamedPropertySetter(callSiteDescriptor, linkerServices, operations, name);
+ return getNamedPropertySetter(req);
}
- private GuardedInvocationComponent getUnnamedPropertySetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> operations) throws Exception {
+ private GuardedInvocationComponent getUnnamedPropertySetter(final ComponentLinkRequest req) throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
// Must have three arguments: target object, property name, and property value.
assertParameterCount(callSiteDescriptor, 3);
@@ -501,6 +566,7 @@
// invoked, we'll conservatively presume Object return type. The one exception is void return.
final MethodType origType = callSiteDescriptor.getMethodType();
final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class);
+ final LinkerServices linkerServices = req.linkerServices;
// What's below is basically:
// foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
@@ -527,11 +593,10 @@
// Handle to invoke the setter, dropping unnecessary fold arguments R(MethodHandle, O, N, V)
final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandle, 2, type.parameterType(
1));
- final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
- linkerServices, operations, null);
+ final GuardedInvocationComponent nextComponent = getNextComponent(req);
final MethodHandle fallbackFolded;
- if(nextComponent == null) {
+ if (nextComponent == null) {
// Object(MethodHandle)->Object(MethodHandle, O, N, V); returns constant null
fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_METHOD_HANDLE, 1,
type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class));
@@ -551,19 +616,19 @@
return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
}
- private GuardedInvocationComponent getNamedPropertySetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> operations, final Object name) throws Exception {
+ private GuardedInvocationComponent getNamedPropertySetter(final ComponentLinkRequest req) throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
// Must have two arguments: target object and property value
assertParameterCount(callSiteDescriptor, 2);
- final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
- name.toString(), propertySetters);
+ final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, req.linkerServices,
+ req.name.toString(), propertySetters);
// If we have a property setter with this name, this composite operation will always stop here
if(gi != null) {
return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
}
// If we don't have a property setter with this name, always fall back to the next operation in the
// composite (if any)
- return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations, name);
+ return getNextComponent(req);
}
private static final Lookup privateLookup = new Lookup(MethodHandles.lookup());
@@ -576,20 +641,18 @@
"getTarget", MethodType.methodType(MethodHandle.class, CallSiteDescriptor.class, LinkerServices.class));
private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class));
- private GuardedInvocationComponent getPropertyGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> ops, final Object name) throws Exception {
- if (name == null) {
- return getUnnamedPropertyGetter(callSiteDescriptor, linkerServices, ops);
+ private GuardedInvocationComponent getPropertyGetter(final ComponentLinkRequest req) throws Exception {
+ if (req.name == null) {
+ return getUnnamedPropertyGetter(req);
}
-
- return getNamedPropertyGetter(callSiteDescriptor, linkerServices, ops, name);
+ return getNamedPropertyGetter(req);
}
- private GuardedInvocationComponent getUnnamedPropertyGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> ops) throws Exception {
+ private GuardedInvocationComponent getUnnamedPropertyGetter(final ComponentLinkRequest req) throws Exception {
// Since we can't know what kind of a getter we'll get back on different invocations, we'll just
// conservatively presume Object. Note we can't just coerce to a narrower call site type as the linking
// runtime might not allow coercing at that call site.
+ final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
// Must have exactly two arguments: receiver and name
assertParameterCount(callSiteDescriptor, 2);
@@ -600,6 +663,7 @@
// AnnotatedDynamicMethod; if it is non-null, invoke its "handle" field, otherwise either return null,
// or delegate to next component's invocation.
+ final LinkerServices linkerServices = req.linkerServices;
final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
AnnotatedDynamicMethod.class));
final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments(
@@ -613,8 +677,7 @@
// Object(AnnotatedDynamicMethod, T0)->Object(AnnotatedDynamicMethod, T0, T1)
final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
type.parameterType(1));
- final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
- linkerServices, ops, null);
+ final GuardedInvocationComponent nextComponent = getNextComponent(req);
final MethodHandle fallbackFolded;
if(nextComponent == null) {
@@ -639,17 +702,17 @@
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
}
- private GuardedInvocationComponent getNamedPropertyGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> ops, final Object name) throws Exception {
+ private GuardedInvocationComponent getNamedPropertyGetter(final ComponentLinkRequest req) throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
// Must have exactly one argument: receiver
assertParameterCount(callSiteDescriptor, 1);
// Fixed name
- final AnnotatedDynamicMethod annGetter = propertyGetters.get(name.toString());
+ final AnnotatedDynamicMethod annGetter = propertyGetters.get(req.name.toString());
if(annGetter == null) {
// We have no such property, always delegate to the next component operation
- return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops, name);
+ return getNextComponent(req);
}
- final MethodHandle getter = annGetter.getInvocation(callSiteDescriptor, linkerServices);
+ final MethodHandle getter = annGetter.getInvocation(req);
// NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being
// overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the
// method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If
@@ -686,28 +749,27 @@
MethodType.methodType(boolean.class, Object.class));
private static final MethodHandle OBJECT_IDENTITY = MethodHandles.identity(Object.class);
- private GuardedInvocationComponent getMethodGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> ops, final Object name) throws Exception {
+ private GuardedInvocationComponent getMethodGetter(final ComponentLinkRequest req) throws Exception {
+ if (req.name == null) {
+ return getUnnamedMethodGetter(req);
+ }
+ return getNamedMethodGetter(req);
+ }
+
+ private static MethodType getMethodGetterType(final ComponentLinkRequest req) {
// The created method handle will always return a DynamicMethod (or null), but since we don't want that type to
// be visible outside of this linker, declare it to return Object.
- final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
- if (name == null) {
- return getUnnamedMethodGetter(callSiteDescriptor, linkerServices, ops, type);
- }
-
- return getNamedMethodGetter(callSiteDescriptor, linkerServices, ops, name, type);
+ return req.getDescriptor().getMethodType().changeReturnType(Object.class);
}
- private GuardedInvocationComponent getUnnamedMethodGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> ops, final MethodType type) throws Exception {
+ private GuardedInvocationComponent getUnnamedMethodGetter(final ComponentLinkRequest req) throws Exception {
// Must have exactly two arguments: receiver and name
- assertParameterCount(callSiteDescriptor, 2);
- final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
- linkerServices, ops, null);
- if(nextComponent == null || !InternalTypeUtilities.areAssignable(DynamicMethod.class,
- nextComponent.getGuardedInvocation().getInvocation().type().returnType())) {
- // No next component operation, or it can never produce a dynamic method; just return a component
- // for this operation.
+ assertParameterCount(req.getDescriptor(), 2);
+ final GuardedInvocationComponent nextComponent = getNextComponent(req);
+ final LinkerServices linkerServices = req.linkerServices;
+ final MethodType type = getMethodGetterType(req);
+ if(nextComponent == null) {
+ // No next component operation; just return a component for this operation.
return getClassGuardedInvocationComponent(linkerServices.asType(getDynamicMethod, type), type);
}
@@ -728,25 +790,28 @@
final MethodHandle nextCombinedInvocation = MethodHandles.dropArguments(nextComponentInvocation, 0,
Object.class);
// Assemble it all into a fold(guard(isNotNull, identity, nextInvocation), get)
+ // Note that nextCombinedInvocation needs to have its return type changed to Object
final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
- IS_DYNAMIC_METHOD, returnMethodHandle, nextCombinedInvocation), typedGetter);
+ IS_DYNAMIC_METHOD, returnMethodHandle,
+ nextCombinedInvocation.asType(nextCombinedInvocation.type().changeReturnType(Object.class))),
+ typedGetter);
return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
}
- private GuardedInvocationComponent getNamedMethodGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> ops, final Object name, final MethodType type)
+ private GuardedInvocationComponent getNamedMethodGetter(final ComponentLinkRequest req)
throws Exception {
// Must have exactly one argument: receiver
- assertParameterCount(callSiteDescriptor, 1);
- final DynamicMethod method = getDynamicMethod(name.toString());
+ assertParameterCount(req.getDescriptor(), 1);
+ final DynamicMethod method = getDynamicMethod(req.name.toString());
if(method == null) {
// We have no such method, always delegate to the next component
- return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops, name);
+ return getNextComponent(req);
}
// No delegation to the next component of the composite operation; if we have a method with that name,
// we'll always return it at this point.
- return getClassGuardedInvocationComponent(linkerServices.asType(MethodHandles.dropArguments(
+ final MethodType type = getMethodGetterType(req);
+ return getClassGuardedInvocationComponent(req.linkerServices.asType(MethodHandles.dropArguments(
MethodHandles.constant(Object.class, method), 0, type.parameterType(0)), type), type);
}
@@ -876,8 +941,8 @@
this.validationType = validationType;
}
- MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
- return method.getInvocation(callSiteDescriptor, linkerServices);
+ MethodHandle getInvocation(final ComponentLinkRequest req) {
+ return method.getInvocation(req.getDescriptor(), req.linkerServices);
}
@SuppressWarnings("unused")
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -88,6 +88,7 @@
import java.lang.invoke.MethodType;
import java.lang.reflect.Array;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import jdk.dynalink.CallSiteDescriptor;
@@ -129,25 +130,21 @@
}
@Override
- protected GuardedInvocationComponent getGuardedInvocationComponent(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> operations, final Object name) throws Exception {
- final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(callSiteDescriptor,
- linkerServices, operations, name);
+ protected GuardedInvocationComponent getGuardedInvocationComponent(final ComponentLinkRequest req) throws Exception {
+ final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(req);
if(superGic != null) {
return superGic;
}
- if(operations.isEmpty()) {
- return null;
- }
- final Operation op = operations.get(0);
- if(op == StandardOperation.GET_ELEMENT) {
- return getElementGetter(callSiteDescriptor, linkerServices, pop(operations), name);
- }
- if(op == StandardOperation.SET_ELEMENT) {
- return getElementSetter(callSiteDescriptor, linkerServices, pop(operations), name);
- }
- if(op == StandardOperation.GET_LENGTH) {
- return getLengthGetter(callSiteDescriptor);
+ if (!req.operations.isEmpty()) {
+ final Operation op = req.operations.get(0);
+ if (op instanceof StandardOperation) {
+ switch ((StandardOperation)op) {
+ case GET_ELEMENT: return getElementGetter(req.popOperations());
+ case SET_ELEMENT: return getElementSetter(req.popOperations());
+ case GET_LENGTH: return getLengthGetter(req.getDescriptor());
+ default:
+ }
+ }
}
return null;
}
@@ -166,16 +163,31 @@
private static final MethodHandle LIST_GUARD = Guards.getInstanceOfGuard(List.class);
private static final MethodHandle MAP_GUARD = Guards.getInstanceOfGuard(Map.class);
+ private static final MethodHandle NULL_GETTER_1;
+ private static final MethodHandle NULL_GETTER_2;
+ static {
+ final MethodHandle constantNull = MethodHandles.constant(Object.class, null);
+ NULL_GETTER_1 = dropObjectArguments(constantNull, 1);
+ NULL_GETTER_2 = dropObjectArguments(constantNull, 2);
+ }
+
+ private static MethodHandle dropObjectArguments(final MethodHandle m, final int n) {
+ return MethodHandles.dropArguments(m, 0, Collections.nCopies(n, Object.class));
+ }
+
private enum CollectionType {
ARRAY, LIST, MAP
};
- private GuardedInvocationComponent getElementGetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> operations, final Object name) throws Exception {
+ private GuardedInvocationComponent getElementGetter(final ComponentLinkRequest req) throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
+ final Object name = req.name;
+ final boolean isFixedKey = name != null;
+ assertParameterCount(callSiteDescriptor, isFixedKey ? 1 : 2);
+ final LinkerServices linkerServices = req.linkerServices;
final MethodType callSiteType = callSiteDescriptor.getMethodType();
final Class<?> declaredType = callSiteType.parameterType(0);
- final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
- linkerServices, operations, name);
+ final GuardedInvocationComponent nextComponent = getNextComponent(req);
// If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing
// is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're
@@ -211,12 +223,14 @@
// Convert the key to a number if we're working with a list or array
final Object typedName;
- if(collectionType != CollectionType.MAP && name != null) {
- typedName = convertKeyToInteger(name, linkerServices);
- if(typedName == null) {
- // key is not numeric, it can never succeed
+ if (collectionType != CollectionType.MAP && isFixedKey) {
+ final Integer integer = convertKeyToInteger(name, linkerServices);
+ if (integer == null || integer.intValue() < 0) {
+ // key is not a non-negative integer, it can never address an
+ // array or list element
return nextComponent;
}
+ typedName = integer;
} else {
typedName = name;
}
@@ -225,30 +239,33 @@
final Binder binder = new Binder(linkerServices, callSiteType, typedName);
final MethodHandle invocation = gi.getInvocation();
- if(nextComponent == null) {
- return gic.replaceInvocation(binder.bind(invocation));
- }
-
final MethodHandle checkGuard;
switch(collectionType) {
case LIST:
- checkGuard = convertArgToInt(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
+ checkGuard = convertArgToNumber(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
break;
case MAP:
- // TODO: A more complex solution could be devised for maps, one where we do a get() first, and fold it
- // into a GWT that tests if it returned null, and if it did, do another GWT with containsKey()
- // that returns constant null (on true), or falls back to next component (on false)
checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP);
break;
case ARRAY:
- checkGuard = convertArgToInt(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+ checkGuard = convertArgToNumber(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
break;
default:
throw new AssertionError();
}
+
+ // If there's no next component, produce a fixed null-returning one
+ final GuardedInvocationComponent finalNextComponent;
+ if (nextComponent != null) {
+ finalNextComponent = nextComponent;
+ } else {
+ final MethodHandle nullGetterHandle = isFixedKey ? NULL_GETTER_1 : NULL_GETTER_2;
+ finalNextComponent = createGuardedInvocationComponentAsType(nullGetterHandle, callSiteType, linkerServices);
+ }
+
final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
- nextComponent.getGuardedInvocation().getInvocation());
- return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
+ finalNextComponent.getGuardedInvocation().getInvocation());
+ return finalNextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
gic.getValidatorClass(), gic.getValidationType());
}
@@ -257,6 +274,11 @@
return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
+ private static GuardedInvocationComponent createGuardedInvocationComponentAsType(
+ final MethodHandle invocation, final MethodType fromType, final LinkerServices linkerServices) {
+ return new GuardedInvocationComponent(linkerServices.asType(invocation, fromType));
+ }
+
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
final ValidationType validationType, final LinkerServices linkerServices) {
@@ -310,7 +332,7 @@
return intIndex;
}
- private static MethodHandle convertArgToInt(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) {
+ private static MethodHandle convertArgToNumber(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) {
final Class<?> sourceType = desc.getMethodType().parameterType(1);
if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
return mh;
@@ -366,14 +388,10 @@
}
final Number n = (Number)index;
final int intIndex = n.intValue();
- final double doubleValue = n.doubleValue();
- if(intIndex != doubleValue && !Double.isInfinite(doubleValue)) { // let infinite trigger IOOBE
+ if (intIndex != n.doubleValue()) {
return false;
}
- if(0 <= intIndex && intIndex < Array.getLength(array)) {
- return true;
- }
- throw new ArrayIndexOutOfBoundsException("Array index out of range: " + n);
+ return 0 <= intIndex && intIndex < Array.getLength(array);
}
@SuppressWarnings("unused")
@@ -383,14 +401,14 @@
}
final Number n = (Number)index;
final int intIndex = n.intValue();
- final double doubleValue = n.doubleValue();
- if(intIndex != doubleValue && !Double.isInfinite(doubleValue)) { // let infinite trigger IOOBE
+ if (intIndex != n.doubleValue()) {
return false;
}
- if(0 <= intIndex && intIndex < list.size()) {
- return true;
- }
- throw new IndexOutOfBoundsException("Index: " + n + ", Size: " + list.size());
+ return 0 <= intIndex && intIndex < list.size();
+ }
+
+ @SuppressWarnings("unused")
+ private static void noOpSetter() {
}
private static final MethodHandle SET_LIST_ELEMENT = Lookup.PUBLIC.findVirtual(List.class, "set",
@@ -399,8 +417,20 @@
private static final MethodHandle PUT_MAP_ELEMENT = Lookup.PUBLIC.findVirtual(Map.class, "put",
MethodType.methodType(Object.class, Object.class, Object.class));
- private GuardedInvocationComponent getElementSetter(final CallSiteDescriptor callSiteDescriptor,
- final LinkerServices linkerServices, final List<Operation> operations, final Object name) throws Exception {
+ private static final MethodHandle NO_OP_SETTER_2;
+ private static final MethodHandle NO_OP_SETTER_3;
+ static {
+ final MethodHandle noOpSetter = Lookup.findOwnStatic(MethodHandles.lookup(), "noOpSetter", void.class);
+ NO_OP_SETTER_2 = dropObjectArguments(noOpSetter, 2);
+ NO_OP_SETTER_3 = dropObjectArguments(noOpSetter, 3);
+ }
+
+ private GuardedInvocationComponent getElementSetter(final ComponentLinkRequest req) throws Exception {
+ final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
+ final Object name = req.name;
+ final boolean isFixedKey = name != null;
+ assertParameterCount(callSiteDescriptor, isFixedKey ? 2 : 3);
+ final LinkerServices linkerServices = req.linkerServices;
final MethodType callSiteType = callSiteDescriptor.getMethodType();
final Class<?> declaredType = callSiteType.parameterType(0);
@@ -441,20 +471,21 @@
// In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map,
// as maps will always succeed in setting the element and will never need to fall back to the next component
// operation.
- final GuardedInvocationComponent nextComponent = collectionType == CollectionType.MAP ? null : getGuardedInvocationComponent(
- callSiteDescriptor, linkerServices, operations, name);
+ final GuardedInvocationComponent nextComponent = collectionType == CollectionType.MAP ? null : getNextComponent(req);
if(gic == null) {
return nextComponent;
}
// Convert the key to a number if we're working with a list or array
final Object typedName;
- if(collectionType != CollectionType.MAP && name != null) {
- typedName = convertKeyToInteger(name, linkerServices);
- if(typedName == null) {
- // key is not numeric, it can never succeed
+ if (collectionType != CollectionType.MAP && isFixedKey) {
+ final Integer integer = convertKeyToInteger(name, linkerServices);
+ if (integer == null || integer.intValue() < 0) {
+ // key is not a non-negative integer, it can never address an
+ // array or list element
return nextComponent;
}
+ typedName = integer;
} else {
typedName = name;
}
@@ -463,16 +494,27 @@
final Binder binder = new Binder(linkerServices, callSiteType, typedName);
final MethodHandle invocation = gi.getInvocation();
- if(nextComponent == null) {
+ if (collectionType == CollectionType.MAP) {
+ assert nextComponent == null;
return gic.replaceInvocation(binder.bind(invocation));
}
assert collectionType == CollectionType.LIST || collectionType == CollectionType.ARRAY;
- final MethodHandle checkGuard = convertArgToInt(collectionType == CollectionType.LIST ? RANGE_CHECK_LIST :
+ final MethodHandle checkGuard = convertArgToNumber(collectionType == CollectionType.LIST ? RANGE_CHECK_LIST :
RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+
+ // If there's no next component, produce a no-op one.
+ final GuardedInvocationComponent finalNextComponent;
+ if (nextComponent != null) {
+ finalNextComponent = nextComponent;
+ } else {
+ final MethodHandle noOpSetterHandle = isFixedKey ? NO_OP_SETTER_2 : NO_OP_SETTER_3;
+ finalNextComponent = createGuardedInvocationComponentAsType(noOpSetterHandle, callSiteType, linkerServices);
+ }
+
final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
- nextComponent.getGuardedInvocation().getInvocation());
- return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
+ finalNextComponent.getGuardedInvocation().getInvocation());
+ return finalNextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
gic.getValidatorClass(), gic.getValidationType());
}
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeansLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -146,7 +146,11 @@
* are otherwise public and link requests have call site descriptors carrying
* full-strength {@link Lookup} objects and not weakened lookups or the public
* lookup.</p>
- * <p>The class also exposes various static methods for discovery of available
+ * <p><strong>The behavior for handling missing members</strong> can be
+ * customized by passing a {@link MissingMemberHandlerFactory} to the
+ * {@link BeansLinker#BeansLinker(MissingMemberHandlerFactory) constructor}.
+ * </p>
+ * <p>The class also exposes various methods for discovery of available
* property and method names on classes and class instances, as well as access
* to per-class linkers using the {@link #getLinkerForClass(Class)}
* method.</p>
@@ -164,10 +168,27 @@
}
};
+ private final MissingMemberHandlerFactory missingMemberHandlerFactory;
+
/**
- * Creates a new beans linker.
+ * Creates a new beans linker. Equivalent to
+ * {@link BeansLinker#BeansLinker(MissingMemberHandlerFactory)} with
+ * {@code null} passed as the missing member handler factory, resulting in
+ * the default behavior for linking and evaluating missing members.
*/
public BeansLinker() {
+ this(null);
+ }
+
+ /**
+ * Creates a new beans linker with the specified factory for creating
+ * missing member handlers. The passed factory can be null if the default
+ * behavior is adequate. See {@link MissingMemberHandlerFactory} for details.
+ * @param missingMemberHandlerFactory a factory for creating handlers for
+ * operations on missing members.
+ */
+ public BeansLinker(final MissingMemberHandlerFactory missingMemberHandlerFactory) {
+ this.missingMemberHandlerFactory = missingMemberHandlerFactory;
}
/**
@@ -178,7 +199,37 @@
* @param clazz the class
* @return a bean linker for that class
*/
- public static TypeBasedGuardingDynamicLinker getLinkerForClass(final Class<?> clazz) {
+ public TypeBasedGuardingDynamicLinker getLinkerForClass(final Class<?> clazz) {
+ final TypeBasedGuardingDynamicLinker staticLinker = getStaticLinkerForClass(clazz);
+ if (missingMemberHandlerFactory == null) {
+ return staticLinker;
+ }
+ return new NoSuchMemberHandlerBindingLinker(staticLinker, missingMemberHandlerFactory);
+ }
+
+ private static class NoSuchMemberHandlerBindingLinker implements TypeBasedGuardingDynamicLinker {
+ private final TypeBasedGuardingDynamicLinker linker;
+ private final MissingMemberHandlerFactory missingMemberHandlerFactory;
+
+ NoSuchMemberHandlerBindingLinker(final TypeBasedGuardingDynamicLinker linker, final MissingMemberHandlerFactory missingMemberHandlerFactory) {
+ this.linker = linker;
+ this.missingMemberHandlerFactory = missingMemberHandlerFactory;
+ }
+
+ @Override
+ public boolean canLinkType(final Class<?> type) {
+ return linker.canLinkType(type);
+ }
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ return linker.getGuardedInvocation(linkRequest,
+ LinkerServicesWithMissingMemberHandlerFactory.get(
+ linkerServices, missingMemberHandlerFactory));
+ }
+ }
+
+ static TypeBasedGuardingDynamicLinker getStaticLinkerForClass(final Class<?> clazz) {
return linkers.get(clazz);
}
@@ -234,7 +285,7 @@
* @return a set of names of all readable instance properties of a class.
*/
public static Set<String> getReadableInstancePropertyNames(final Class<?> clazz) {
- final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+ final TypeBasedGuardingDynamicLinker linker = getStaticLinkerForClass(clazz);
if(linker instanceof BeanLinker) {
return ((BeanLinker)linker).getReadablePropertyNames();
}
@@ -247,7 +298,7 @@
* @return a set of names of all writable instance properties of a class.
*/
public static Set<String> getWritableInstancePropertyNames(final Class<?> clazz) {
- final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+ final TypeBasedGuardingDynamicLinker linker = getStaticLinkerForClass(clazz);
if(linker instanceof BeanLinker) {
return ((BeanLinker)linker).getWritablePropertyNames();
}
@@ -260,7 +311,7 @@
* @return a set of names of all instance methods of a class.
*/
public static Set<String> getInstanceMethodNames(final Class<?> clazz) {
- final TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+ final TypeBasedGuardingDynamicLinker linker = getStaticLinkerForClass(clazz);
if(linker instanceof BeanLinker) {
return ((BeanLinker)linker).getMethodNames();
}
@@ -302,6 +353,8 @@
// Can't operate on null
return null;
}
- return getLinkerForClass(receiver.getClass()).getGuardedInvocation(request, linkerServices);
+ return getLinkerForClass(receiver.getClass()).getGuardedInvocation(request,
+ LinkerServicesWithMissingMemberHandlerFactory.get(linkerServices,
+ missingMemberHandlerFactory));
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/LinkerServicesWithMissingMemberHandlerFactory.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, 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.dynalink.beans;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import jdk.dynalink.linker.ConversionComparator.Comparison;
+import jdk.dynalink.linker.GuardedInvocation;
+import jdk.dynalink.linker.LinkRequest;
+import jdk.dynalink.linker.LinkerServices;
+
+final class LinkerServicesWithMissingMemberHandlerFactory implements LinkerServices {
+ final LinkerServices linkerServices;
+ final MissingMemberHandlerFactory missingMemberHandlerFactory;
+
+ static LinkerServices get(final LinkerServices linkerServices, final MissingMemberHandlerFactory missingMemberHandlerFactory) {
+ if (missingMemberHandlerFactory == null) {
+ return linkerServices;
+ }
+ return new LinkerServicesWithMissingMemberHandlerFactory(linkerServices, missingMemberHandlerFactory);
+ }
+
+ private LinkerServicesWithMissingMemberHandlerFactory(final LinkerServices linkerServices, final MissingMemberHandlerFactory missingMemberHandlerFactory) {
+ this.linkerServices = linkerServices;
+ this.missingMemberHandlerFactory = missingMemberHandlerFactory;
+ }
+
+ @Override
+ public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
+ return linkerServices.asType(handle, fromType);
+ }
+
+ @Override
+ public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
+ return linkerServices.getTypeConverter(sourceType, targetType);
+ }
+
+ @Override
+ public boolean canConvert(final Class<?> from, final Class<?> to) {
+ return linkerServices.canConvert(from, to);
+ }
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
+ return linkerServices.getGuardedInvocation(linkRequest);
+ }
+
+ @Override
+ public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+ return linkerServices.compareConversion(sourceType, targetType1, targetType2);
+ }
+
+ @Override
+ public MethodHandle filterInternalObjects(final MethodHandle target) {
+ return linkerServices.filterInternalObjects(target);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/MissingMemberHandlerFactory.java Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, 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.dynalink.beans;
+
+import java.lang.invoke.MethodHandle;
+import jdk.dynalink.DynamicLinkerFactory;
+import jdk.dynalink.NamedOperation;
+import jdk.dynalink.NoSuchDynamicMethodException;
+import jdk.dynalink.StandardOperation;
+import jdk.dynalink.linker.LinkRequest;
+import jdk.dynalink.linker.LinkerServices;
+
+/**
+ * A factory for creating method handles for linking missing member behavior
+ * in {@link BeansLinker}. BeansLinker links these method handles into guarded
+ * invocations for link requests specifying {@code GET_*} and {@code SET_*}
+ * {@link StandardOperation}s when it is either certain or possible that the
+ * requested member (property, method, or element) is missing. They will be
+ * linked both for {@link NamedOperation named} and unnamed operations. The
+ * implementer must ensure that the parameter types of the returned method
+ * handle match the parameter types of the call site described in the link
+ * request. The return types can differ, though, to allow
+ * {@link DynamicLinkerFactory#setPrelinkTransformer(jdk.dynalink.linker.GuardedInvocationTransformer)}
+ * late return type transformations}. It is allowed to return {@code null} for a
+ * method handle if the default behavior is sufficient.
+ * <h2>Default missing member behavior</h2>
+ * When a {@link BeansLinker} is configured without a missing member handler
+ * factory, or the factory returns {@code null} for a particular handler
+ * creation invocation, the default behavior is used. The default behavior is to
+ * return {@code null} from
+ * {@link BeansLinker#getGuardedInvocation(LinkRequest, LinkerServices)} when it
+ * can be determined at link time that the linked operation will never address
+ * an existing member. This lets the {@code DynamicLinker} attempt the next
+ * linker if there is one, or ultimately fail the link request with
+ * {@link NoSuchDynamicMethodException}. For other cases (typically all unnamed
+ * member operations as well as most named operations on collection elements)
+ * {@code BeansLinker} will produce a conditional linkage that will return
+ * {@code null} when invoked at runtime with a name that does not match any
+ * member for getters and silently ignore the passed values for setters.
+ * <h2>Implementing exception-throwing behavior</h2>
+ * Note that if the language-specific behavior for an operation on a missing
+ * member is to throw an exception then the factory should produce a method
+ * handle that throws the exception when invoked, and must not throw an
+ * exception itself, as the linkage for the missing member is often conditional.
+ *
+ * @see BeansLinker#BeansLinker(MissingMemberHandlerFactory)
+ */
+@FunctionalInterface
+public interface MissingMemberHandlerFactory {
+ /**
+ * Returns a method handle suitable for implementing missing member behavior
+ * for a particular link request. See the class description for details.
+ * @param linkRequest the current link request
+ * @param linkerServices the current link services
+ * @return a method handle that can be invoked if the property, element, or
+ * method being addressed by an operation is missing. The return value can
+ * be null.
+ * @throws Exception if the operation fails for any reason. Please observe
+ * the class documentation notes for implementing exception-throwing
+ * missing member behavior.
+ */
+ public MethodHandle createMissingMemberHandler(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception;
+}
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClassLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/StaticClassLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -91,6 +91,7 @@
import java.util.Set;
import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.NamedOperation;
+import jdk.dynalink.Operation;
import jdk.dynalink.StandardOperation;
import jdk.dynalink.beans.GuardedInvocationComponent.ValidationType;
import jdk.dynalink.linker.GuardedInvocation;
@@ -162,6 +163,27 @@
}
@Override
+ protected GuardedInvocationComponent getGuardedInvocationComponent(final ComponentLinkRequest req) throws Exception {
+ final GuardedInvocationComponent superGic = super.getGuardedInvocationComponent(req);
+ if (superGic != null) {
+ return superGic;
+ }
+ if (!req.operations.isEmpty()) {
+ final Operation op = req.operations.get(0);
+ if (op instanceof StandardOperation) {
+ switch ((StandardOperation)op) {
+ case GET_ELEMENT:
+ case SET_ELEMENT:
+ // StaticClass doesn't behave as a collection
+ return getNextComponent(req.popOperations());
+ default:
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
SingleDynamicMethod getConstructorMethod(final String signature) {
return constructor != null? constructor.getMethodForExactParamTypes(signature) : null;
}
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java Sat Jan 16 00:28:28 2016 +0000
@@ -202,6 +202,9 @@
this.invocation = Objects.requireNonNull(invocation);
this.guard = guard;
this.switchPoints = switchPoint == null ? null : new SwitchPoint[] { switchPoint };
+ if (exception != null && !Throwable.class.isAssignableFrom(exception)) {
+ throw new IllegalArgumentException(exception.getName() + " is not assignable from Throwable");
+ }
this.exception = exception;
}
@@ -228,6 +231,9 @@
this.invocation = Objects.requireNonNull(invocation);
this.guard = guard;
this.switchPoints = switchPoints == null ? null : switchPoints.clone();
+ if (exception != null && !Throwable.class.isAssignableFrom(exception)) {
+ throw new IllegalArgumentException(exception.getName() + " is not assignable from Throwable");
+ }
this.exception = exception;
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java Sat Jan 16 00:28:28 2016 +0000
@@ -1133,6 +1133,8 @@
return NativeNumber.lookupPrimitive(request, self);
} else if (self instanceof Boolean) {
return NativeBoolean.lookupPrimitive(request, self);
+ } else if (self instanceof Symbol) {
+ return NativeSymbol.lookupPrimitive(request, self);
}
throw new IllegalArgumentException("Unsupported primitive: " + self);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Sat Jan 16 00:28:28 2016 +0000
@@ -284,8 +284,8 @@
// Step 3c and 3d - get new length and convert to long
final long newLen = NativeArray.validLength(newLenDesc.getValue());
- // Step 3e
- newLenDesc.setValue(newLen);
+ // Step 3e - note that we need to convert to int or double as long is not considered a JS number type anymore
+ newLenDesc.setValue(JSType.isRepresentableAsInt(newLen) ? Integer.valueOf((int) newLen) : Double.valueOf((double) newLen));
// Step 3f
// increasing array length - just need to set new length value (and attributes if any) and return
@@ -918,21 +918,6 @@
* @throws ClassCastException if array is empty, facilitating Undefined return value
*/
@SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
- public static long popLong(final Object self) {
- //must be non empty Int or LongArrayData
- return getContinuousNonEmptyArrayDataCCE(self, IntOrLongElements.class).fastPopLong();
- }
-
- /**
- * Specialization of pop for ContinuousArrayData
- *
- * Primitive specialization, {@link LinkLogic}
- *
- * @param self self reference
- * @return element popped
- * @throws ClassCastException if array is empty, facilitating Undefined return value
- */
- @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
public static double popDouble(final Object self) {
//must be non empty int long or double array data
return getContinuousNonEmptyArrayDataCCE(self, NumericElements.class).fastPopDouble();
@@ -997,7 +982,7 @@
* @return array length after push
*/
@SpecializedFunction(linkLogic=PushLinkLogic.class)
- public static long push(final Object self, final int arg) {
+ public static double push(final Object self, final int arg) {
return getContinuousArrayDataCCE(self, Integer.class).fastPush(arg);
}
@@ -1011,7 +996,7 @@
* @return array length after push
*/
@SpecializedFunction(linkLogic=PushLinkLogic.class)
- public static long push(final Object self, final long arg) {
+ public static double push(final Object self, final long arg) {
return getContinuousArrayDataCCE(self, Long.class).fastPush(arg);
}
@@ -1025,7 +1010,7 @@
* @return array length after push
*/
@SpecializedFunction(linkLogic=PushLinkLogic.class)
- public static long push(final Object self, final double arg) {
+ public static double push(final Object self, final double arg) {
return getContinuousArrayDataCCE(self, Double.class).fastPush(arg);
}
@@ -1039,7 +1024,7 @@
* @return array length after push
*/
@SpecializedFunction(name="push", linkLogic=PushLinkLogic.class)
- public static long pushObject(final Object self, final Object arg) {
+ public static double pushObject(final Object self, final Object arg) {
return getContinuousArrayDataCCE(self, Object.class).fastPush(arg);
}
@@ -1081,7 +1066,7 @@
* @return array after pushes
*/
@SpecializedFunction
- public static long push(final Object self, final Object arg) {
+ public static double push(final Object self, final Object arg) {
try {
final ScriptObject sobj = (ScriptObject)self;
final ArrayData arrayData = sobj.getArray();
@@ -1498,7 +1483,7 @@
* @return index of element, or -1 if not found
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
- public static long indexOf(final Object self, final Object searchElement, final Object fromIndex) {
+ public static double indexOf(final Object self, final Object searchElement, final Object fromIndex) {
try {
final ScriptObject sobj = (ScriptObject)Global.toObject(self);
final long len = JSType.toUint32(sobj.getLength());
@@ -1534,7 +1519,7 @@
* @return index of element, or -1 if not found
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
- public static long lastIndexOf(final Object self, final Object... args) {
+ public static double lastIndexOf(final Object self, final Object... args) {
try {
final ScriptObject sobj = (ScriptObject)Global.toObject(self);
final long len = JSType.toUint32(sobj.getLength());
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeBoolean.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeBoolean.java Sat Jan 16 00:28:28 2016 +0000
@@ -168,9 +168,9 @@
}
/**
- * Wrap a native string in a NativeString object.
+ * Wrap a native boolean in a NativeBoolean object.
*
- * @param receiver Native string.
+ * @param receiver Native boolean.
* @return Wrapped object.
*/
@SuppressWarnings("unused")
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeDate.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeDate.java Sat Jan 16 00:28:28 2016 +0000
@@ -256,8 +256,9 @@
* @return a Date that points to the current moment in time
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
- public static long now(final Object self) {
- return System.currentTimeMillis();
+ public static double now(final Object self) {
+ // convert to double as long does not represent the primitive JS number type
+ return (double) System.currentTimeMillis();
}
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeNumber.java Sat Jan 16 00:28:28 2016 +0000
@@ -48,6 +48,7 @@
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.doubleconv.DoubleConversion;
+import jdk.nashorn.internal.runtime.linker.NashornGuards;
import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
/**
@@ -315,7 +316,7 @@
* @return Link to be invoked at call site.
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
- return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER, PROTOFILTER);
+ return PrimitiveLookup.lookupPrimitive(request, NashornGuards.getNumberGuard(), new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER, PROTOFILTER);
}
@SuppressWarnings("unused")
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeObject.java Sat Jan 16 00:28:28 2016 +0000
@@ -776,7 +776,7 @@
final MethodType getterType = MethodType.methodType(Object.class, clazz);
final MethodType setterType = MethodType.methodType(Object.class, clazz, Object.class);
- final GuardingDynamicLinker linker = BeansLinker.getLinkerForClass(clazz);
+ final GuardingDynamicLinker linker = Bootstrap.getBeanLinkerForClass(clazz);
final List<AccessorProperty> properties = new ArrayList<>(propertyNames.size() + methodNames.size());
for(final String methodName: methodNames) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Sat Jan 16 00:28:28 2016 +0000
@@ -74,7 +74,7 @@
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
public static Object length(final Object self) {
if (self instanceof ScriptObject) {
- return JSType.toUint32(((ScriptObject)self).getArray().length());
+ return (double) JSType.toUint32(((ScriptObject)self).getArray().length());
}
return 0;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java Sat Jan 16 00:28:28 2016 +0000
@@ -146,7 +146,7 @@
if (returnType == Object.class && JSType.isString(self)) {
try {
- return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
+ return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getStringGuard());
} catch (final LookupException e) {
//empty. Shouldn't happen. Fall back to super
}
@@ -1235,8 +1235,8 @@
* @return Link to be invoked at call site.
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
- final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
- return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
+ return PrimitiveLookup.lookupPrimitive(request, NashornGuards.getStringGuard(),
+ new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
}
@SuppressWarnings("unused")
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeSymbol.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeSymbol.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,8 +25,14 @@
package jdk.nashorn.internal.objects;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.dynalink.linker.GuardedInvocation;
+import jdk.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.WeakValueCache;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -39,6 +45,7 @@
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.Symbol;
import jdk.nashorn.internal.runtime.Undefined;
+import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
/**
* ECMAScript 6 - 19.4 Symbol Objects
@@ -48,12 +55,21 @@
private final Symbol symbol;
+ /** Method handle to create an object wrapper for a primitive symbol. */
+ static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeSymbol.class, Object.class));
+ /** Method handle to retrieve the Symbol prototype object. */
+ private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
+
// initialized by nasgen
private static PropertyMap $nasgenmap$;
/** See ES6 19.4.2.1 */
private static WeakValueCache<String, Symbol> globalSymbolRegistry = new WeakValueCache<>();
+ NativeSymbol(final Symbol symbol) {
+ this(symbol, Global.instance());
+ }
+
NativeSymbol(final Symbol symbol, final Global global) {
this(symbol, global.getSymbolPrototype(), $nasgenmap$);
}
@@ -73,6 +89,17 @@
}
}
+ /**
+ * Lookup the appropriate method for an invoke dynamic call.
+ *
+ * @param request The link request
+ * @param receiver The receiver for the call
+ * @return Link to be invoked at call site.
+ */
+ public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
+ return PrimitiveLookup.lookupPrimitive(request, Symbol.class, new NativeSymbol((Symbol)receiver), WRAPFILTER, PROTOFILTER);
+ }
+
// ECMA 6 19.4.3.4 Symbol.prototype [ @@toPrimitive ] ( hint )
@Override
public Object getDefaultValue(final Class<?> typeHint) {
@@ -149,4 +176,19 @@
final String name = ((Symbol) arg).getName();
return globalSymbolRegistry.get(name) == arg ? name : Undefined.getUndefined();
}
+
+ @SuppressWarnings("unused")
+ private static NativeSymbol wrapFilter(final Object receiver) {
+ return new NativeSymbol((Symbol)receiver);
+ }
+
+ @SuppressWarnings("unused")
+ private static Object protoFilter(final Object object) {
+ return Global.instance().getSymbolPrototype();
+ }
+
+ private static MethodHandle findOwnMH(final String name, final MethodType type) {
+ return MH.findStatic(MethodHandles.lookup(), NativeSymbol.class, name, type);
+ }
+
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java Sat Jan 16 00:28:28 2016 +0000
@@ -178,6 +178,12 @@
/** Method handle for void returns. */
public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);
+ /** Method handle for isString method */
+ public static final Call IS_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "isString", boolean.class, Object.class);
+
+ /** Method handle for isNumber method */
+ public static final Call IS_NUMBER = staticCall(JSTYPE_LOOKUP, JSType.class, "isNumber", boolean.class, Object.class);
+
/**
* The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
* in the dual--fields world
@@ -280,7 +286,7 @@
return JSType.STRING;
}
- if (obj instanceof Number) {
+ if (isNumber(obj)) {
return JSType.NUMBER;
}
@@ -322,7 +328,7 @@
return JSType.STRING;
}
- if (obj instanceof Number) {
+ if (isNumber(obj)) {
return JSType.NUMBER;
}
@@ -434,7 +440,7 @@
return obj == null ||
obj == ScriptRuntime.UNDEFINED ||
isString(obj) ||
- obj instanceof Number ||
+ isNumber(obj) ||
obj instanceof Boolean ||
obj instanceof Symbol;
}
@@ -610,6 +616,24 @@
}
/**
+ * Returns true if object represents a primitive JavaScript number value. Note that we only
+ * treat wrapper objects of Java primitive number types as objects that can be fully represented
+ * as JavaScript numbers (doubles). This means we exclude {@code long} and special purpose Number
+ * instances such as {@link java.util.concurrent.atomic.AtomicInteger}, as well as arbitrary precision
+ * numbers such as {@link java.math.BigInteger}.
+ *
+ * @param obj the object
+ * @return true if the object represents a primitive JavaScript number value.
+ */
+ public static boolean isNumber(final Object obj) {
+ if (obj != null) {
+ final Class<?> c = obj.getClass();
+ return c == Integer.class || c == Double.class || c == Float.class || c == Short.class || c == Byte.class;
+ }
+ return false;
+ }
+
+ /**
* JavaScript compliant conversion of integer to String
*
* @param num an integer
@@ -761,7 +785,7 @@
if (obj instanceof Double) {
return (Double)obj;
}
- if (obj instanceof Number) {
+ if (isNumber(obj)) {
return ((Number)obj).doubleValue();
}
return Double.NaN;
@@ -1337,7 +1361,7 @@
return obj.toString();
}
- if (obj instanceof Number) {
+ if (isNumber(obj)) {
return toString(((Number)obj).doubleValue());
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Undefined.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Undefined.java Sat Jan 16 00:28:28 2016 +0000
@@ -94,6 +94,9 @@
*/
public static GuardedInvocation lookup(final CallSiteDescriptor desc) {
final StandardOperation op = NashornCallSiteDescriptor.getFirstStandardOperation(desc);
+ if (op == null) {
+ return null;
+ }
switch (op) {
case CALL:
case NEW:
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java Sat Jan 16 00:28:28 2016 +0000
@@ -287,7 +287,7 @@
* @param arg argument
* @return new array length
*/
- public long fastPush(final int arg) {
+ public double fastPush(final int arg) {
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
}
@@ -296,7 +296,7 @@
* @param arg argument
* @return new array length
*/
- public long fastPush(final long arg) {
+ public double fastPush(final long arg) {
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
}
@@ -305,7 +305,7 @@
* @param arg argument
* @return new array length
*/
- public long fastPush(final double arg) {
+ public double fastPush(final double arg) {
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
}
@@ -314,7 +314,7 @@
* @param arg argument
* @return new array length
*/
- public long fastPush(final Object arg) {
+ public double fastPush(final Object arg) {
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
}
@@ -330,14 +330,6 @@
* Specialization - fast pop implementation
* @return element value
*/
- public long fastPopLong() {
- throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
- }
-
- /**
- * Specialization - fast pop implementation
- * @return element value
- */
public double fastPopDouble() {
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Sat Jan 16 00:28:28 2016 +0000
@@ -340,7 +340,7 @@
}
@Override
- public long fastPush(final int arg) {
+ public double fastPush(final int arg) {
final int len = (int)length();
if (len == array.length) {
array = Arrays.copyOf(array, nextSize(len));
@@ -362,11 +362,6 @@
}
@Override
- public long fastPopLong() {
- return fastPopInt();
- }
-
- @Override
public double fastPopDouble() {
return fastPopInt();
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Sat Jan 16 00:28:28 2016 +0000
@@ -303,17 +303,17 @@
}
@Override
- public long fastPush(final int arg) {
+ public double fastPush(final int arg) {
return fastPush((double)arg);
}
@Override
- public long fastPush(final long arg) {
+ public double fastPush(final long arg) {
return fastPush((double)arg);
}
@Override
- public long fastPush(final double arg) {
+ public double fastPush(final double arg) {
final int len = (int)length();
if (len == array.length) {
//note that fastpush never creates spares arrays, there is nothing to gain by that - it will just use even more memory
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java Sat Jan 16 00:28:28 2016 +0000
@@ -236,22 +236,22 @@
}
@Override
- public long fastPush(final int arg) {
+ public double fastPush(final int arg) {
return fastPush((Object)arg);
}
@Override
- public long fastPush(final long arg) {
+ public double fastPush(final long arg) {
return fastPush((Object)arg);
}
@Override
- public long fastPush(final double arg) {
+ public double fastPush(final double arg) {
return fastPush((Object)arg);
}
@Override
- public long fastPush(final Object arg) {
+ public double fastPush(final Object arg) {
final int len = (int)length();
if (len == array.length) {
array = Arrays.copyOf(array, nextSize(len));
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Sat Jan 16 00:28:28 2016 +0000
@@ -40,10 +40,11 @@
import jdk.dynalink.beans.BeansLinker;
import jdk.dynalink.beans.StaticClass;
import jdk.dynalink.linker.GuardedInvocation;
-import jdk.dynalink.linker.GuardedInvocationTransformer;
+import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.LinkRequest;
import jdk.dynalink.linker.LinkerServices;
import jdk.dynalink.linker.MethodTypeConversionStrategy;
+import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
import jdk.dynalink.linker.support.TypeUtilities;
import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
@@ -67,6 +68,24 @@
private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED);
+ private static final BeansLinker beansLinker = new BeansLinker(Bootstrap::createMissingMemberHandler);
+ private static final GuardingDynamicLinker[] prioritizedLinkers;
+ private static final GuardingDynamicLinker[] fallbackLinkers;
+ static {
+ final NashornBeansLinker nashornBeansLinker = new NashornBeansLinker(beansLinker);
+ prioritizedLinkers = new GuardingDynamicLinker[] {
+ new NashornLinker(),
+ new NashornPrimitiveLinker(),
+ new NashornStaticClassLinker(beansLinker),
+ new BoundCallableLinker(),
+ new JavaSuperAdapterLinker(beansLinker),
+ new JSObjectLinker(nashornBeansLinker),
+ new BrowserJSObjectLinker(nashornBeansLinker),
+ new ReflectionCheckLinker()
+ };
+ fallbackLinkers = new GuardingDynamicLinker[] {nashornBeansLinker, new NashornBottomLinker() };
+ }
+
// do not create me!!
private Bootstrap() {
}
@@ -81,31 +100,14 @@
public static DynamicLinker createDynamicLinker(final ClassLoader appLoader,
final int unstableRelinkThreshold) {
final DynamicLinkerFactory factory = new DynamicLinkerFactory();
- final NashornBeansLinker nashornBeansLinker = new NashornBeansLinker();
- factory.setPrioritizedLinkers(
- new NashornLinker(),
- new NashornPrimitiveLinker(),
- new NashornStaticClassLinker(),
- new BoundCallableLinker(),
- new JavaSuperAdapterLinker(),
- new JSObjectLinker(nashornBeansLinker),
- new BrowserJSObjectLinker(nashornBeansLinker),
- new ReflectionCheckLinker());
- factory.setFallbackLinkers(nashornBeansLinker, new NashornBottomLinker());
+ factory.setPrioritizedLinkers(prioritizedLinkers);
+ factory.setFallbackLinkers(fallbackLinkers);
factory.setSyncOnRelink(true);
- factory.setPrelinkTransformer(new GuardedInvocationTransformer() {
- @Override
- public GuardedInvocation filter(final GuardedInvocation inv, final LinkRequest request, final LinkerServices linkerServices) {
- final CallSiteDescriptor desc = request.getCallSiteDescriptor();
- return OptimisticReturnFilters.filterOptimisticReturnValue(inv, desc).asType(linkerServices, desc.getMethodType());
- }
+ factory.setPrelinkTransformer((inv, request, linkerServices) -> {
+ final CallSiteDescriptor desc = request.getCallSiteDescriptor();
+ return OptimisticReturnFilters.filterOptimisticReturnValue(inv, desc).asType(linkerServices, desc.getMethodType());
});
- factory.setAutoConversionStrategy(new MethodTypeConversionStrategy() {
- @Override
- public MethodHandle asType(final MethodHandle target, final MethodType newType) {
- return unboxReturnType(target, newType);
- }
- });
+ factory.setAutoConversionStrategy(Bootstrap::unboxReturnType);
factory.setInternalObjectsFilter(NashornBeansLinker.createHiddenObjectFilter());
factory.setUnstableRelinkThreshold(unstableRelinkThreshold);
@@ -115,6 +117,15 @@
}
/**
+ * Returns a dynamic linker for the specific Java class using beans semantics.
+ * @param clazz the Java class
+ * @return a dynamic linker for the specific Java class using beans semantics.
+ */
+ public static TypeBasedGuardingDynamicLinker getBeanLinkerForClass(final Class<?> clazz) {
+ return beansLinker.getLinkerForClass(clazz);
+ }
+
+ /**
* Returns if the given object is a "callable"
* @param obj object to be checked for callability
* @return true if the obj is callable
@@ -475,4 +486,14 @@
}
return target;
}
+
+ private static MethodHandle createMissingMemberHandler(
+ final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ if (BrowserJSObjectLinker.canLinkTypeStatic(linkRequest.getReceiver().getClass())) {
+ // Don't create missing member handlers for the browser JS objects as they
+ // have their own logic.
+ return null;
+ }
+ return NashornBottomLinker.linkMissingBeanMember(linkRequest, linkerServices);
+ }
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -25,7 +25,6 @@
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;
@@ -62,6 +61,12 @@
IS_ADAPTER_OF_CLASS = lookup.findOwnStatic("isAdapterOfClass", boolean.class, Class.class, Object.class);
}
+ private final BeansLinker beansLinker;
+
+ JavaSuperAdapterLinker(final BeansLinker beansLinker) {
+ this.beansLinker = beansLinker;
+ }
+
@Override
public boolean canLinkType(final Class<?> type) {
return type == JavaSuperAdapter.class;
@@ -101,17 +106,13 @@
// Delegate to BeansLinker
final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
- BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
+ beansLinker, linkRequest.replaceArguments(newDescriptor, args),
linkerServices);
+ // Even for non-existent methods, Bootstrap's BeansLinker will link a
+ // noSuchMember handler.
+ assert guardedInv != null;
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();
@@ -165,7 +166,7 @@
*/
@SuppressWarnings("unused")
private static Object bindDynamicMethod(final Object dynamicMethod, final Object boundThis) {
- return dynamicMethod == null ? ScriptRuntime.UNDEFINED : Bootstrap.bindCallable(dynamicMethod, boundThis, null);
+ return dynamicMethod == ScriptRuntime.UNDEFINED ? ScriptRuntime.UNDEFINED : Bootstrap.bindCallable(dynamicMethod, boundThis, null);
}
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -85,7 +85,11 @@
}
};
- private final BeansLinker beansLinker = new BeansLinker();
+ private final BeansLinker beansLinker;
+
+ NashornBeansLinker(final BeansLinker beansLinker) {
+ this.beansLinker = beansLinker;
+ }
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -27,26 +27,27 @@
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.JSType.GET_UNDEFINED;
-import static jdk.nashorn.internal.runtime.JSType.TYPE_OBJECT_INDEX;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.NamedOperation;
import jdk.dynalink.Operation;
+import jdk.dynalink.StandardOperation;
import jdk.dynalink.beans.BeansLinker;
import jdk.dynalink.linker.GuardedInvocation;
import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.GuardingTypeConverterFactory;
import jdk.dynalink.linker.LinkRequest;
import jdk.dynalink.linker.LinkerServices;
-import jdk.dynalink.linker.support.Guards;
+import jdk.dynalink.linker.support.Lookup;
import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
@@ -73,7 +74,7 @@
// this point is a generic Java bean. Therefore, reaching here with a ScriptObject is a Nashorn bug.
assert isExpectedObject(self) : "Couldn't link " + linkRequest.getCallSiteDescriptor() + " for " + self.getClass().getName();
- return linkBean(linkRequest, linkerServices);
+ return linkBean(linkRequest);
}
private static final MethodHandle EMPTY_PROP_GETTER =
@@ -85,7 +86,18 @@
private static final MethodHandle EMPTY_ELEM_SETTER =
MH.dropArguments(EMPTY_PROP_SETTER, 0, Object.class);
- private static GuardedInvocation linkBean(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ private static final MethodHandle THROW_NO_SUCH_FUNCTION;
+ private static final MethodHandle THROW_STRICT_PROPERTY_SETTER;
+ private static final MethodHandle THROW_OPTIMISTIC_UNDEFINED;
+
+ static {
+ final Lookup lookup = new Lookup(MethodHandles.lookup());
+ THROW_NO_SUCH_FUNCTION = lookup.findOwnStatic("throwNoSuchFunction", Object.class, Object.class, Object.class);
+ THROW_STRICT_PROPERTY_SETTER = lookup.findOwnStatic("throwStrictPropertySetter", void.class, Object.class, Object.class);
+ THROW_OPTIMISTIC_UNDEFINED = lookup.findOwnStatic("throwOptimisticUndefined", Object.class, int.class);
+ }
+
+ private static GuardedInvocation linkBean(final LinkRequest linkRequest) throws Exception {
final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
final Object self = linkRequest.getReceiver();
switch (NashornCallSiteDescriptor.getFirstStandardOperation(desc)) {
@@ -105,35 +117,79 @@
throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
}
throw typeError("not.a.function", NashornCallSiteDescriptor.getFunctionErrorMessage(desc, self));
- case CALL_METHOD:
- throw typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
- case GET_METHOD:
- // evaluate to undefined, later on Undefined will take care of throwing TypeError
- return getInvocation(MH.dropArguments(GET_UNDEFINED.get(TYPE_OBJECT_INDEX), 0, Object.class), self, linkerServices, desc);
- case GET_PROPERTY:
- case GET_ELEMENT:
- if(NashornCallSiteDescriptor.isOptimistic(desc)) {
- throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT);
- }
- if (NashornCallSiteDescriptor.getOperand(desc) != null) {
- return getInvocation(EMPTY_PROP_GETTER, self, linkerServices, desc);
- }
- return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
- case SET_PROPERTY:
- case SET_ELEMENT:
- final boolean strict = NashornCallSiteDescriptor.isStrict(desc);
- if (strict) {
- throw typeError("cant.set.property", getArgument(linkRequest), ScriptRuntime.safeToString(self));
- }
- if (NashornCallSiteDescriptor.getOperand(desc) != null) {
- return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
- }
- return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
default:
+ // Everything else is supposed to have been already handled by Bootstrap.beansLinker
+ // delegating to linkNoSuchBeanMember
throw new AssertionError("unknown call type " + desc);
}
}
+ static MethodHandle linkMissingBeanMember(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
+ final StandardOperation op = NashornCallSiteDescriptor.getFirstStandardOperation(desc);
+ if (op != null) {
+ final String operand = NashornCallSiteDescriptor.getOperand(desc);
+ switch (op) {
+ case CALL_METHOD:
+ return adaptThrower(bindOperand(THROW_NO_SUCH_FUNCTION, operand), desc);
+ case GET_METHOD:
+ case GET_PROPERTY:
+ case GET_ELEMENT: {
+ if (NashornCallSiteDescriptor.isOptimistic(desc)) {
+ return adaptThrower(MethodHandles.insertArguments(THROW_OPTIMISTIC_UNDEFINED, 0, NashornCallSiteDescriptor.getProgramPoint(desc)), desc);
+ }
+ if (NashornCallSiteDescriptor.getOperand(desc) != null) {
+ return getInvocation(EMPTY_PROP_GETTER, linkerServices, desc);
+ }
+ return getInvocation(EMPTY_ELEM_GETTER, linkerServices, desc);
+ }
+ case SET_PROPERTY:
+ case SET_ELEMENT:
+ final boolean strict = NashornCallSiteDescriptor.isStrict(desc);
+ if (strict) {
+ return adaptThrower(bindOperand(THROW_STRICT_PROPERTY_SETTER, operand), desc);
+ }
+ if (NashornCallSiteDescriptor.getOperand(desc) != null) {
+ return getInvocation(EMPTY_PROP_SETTER, linkerServices, desc);
+ }
+ return getInvocation(EMPTY_ELEM_SETTER, linkerServices, desc);
+ default:
+ }
+ }
+ throw new AssertionError("unknown call type " + desc);
+ }
+
+ private static MethodHandle bindOperand(final MethodHandle handle, final String operand) {
+ return operand == null ? handle : MethodHandles.insertArguments(handle, 1, operand);
+ }
+
+ private static MethodHandle adaptThrower(final MethodHandle handle, final CallSiteDescriptor desc) {
+ final MethodType targetType = desc.getMethodType();
+ final int paramCount = handle.type().parameterCount();
+ return MethodHandles
+ .dropArguments(handle, paramCount, targetType.parameterList().subList(paramCount, targetType.parameterCount()))
+ .asType(targetType);
+ }
+
+ @SuppressWarnings("unused")
+ private static Object throwNoSuchFunction(final Object self, final Object name) {
+ throw createTypeError(self, name, "no.such.function");
+ }
+
+ @SuppressWarnings("unused")
+ private static void throwStrictPropertySetter(final Object self, final Object name) {
+ throw createTypeError(self, name, "cant.set.property");
+ }
+
+ private static ECMAException createTypeError(final Object self, final Object name, final String msg) {
+ return typeError(msg, String.valueOf(name), ScriptRuntime.safeToString(self));
+ }
+
+ @SuppressWarnings("unused")
+ private static Object throwOptimisticUndefined(final int programPoint) {
+ throw new UnwarrantedOptimismException(UNDEFINED, programPoint, Type.OBJECT);
+ }
+
@Override
public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType, final Supplier<MethodHandles.Lookup> lookupSupplier) throws Exception {
final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
@@ -158,8 +214,8 @@
return null;
}
- private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
- return Bootstrap.asTypeSafeReturn(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
+ private static MethodHandle getInvocation(final MethodHandle handle, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
+ return linkerServices.asTypeLosslessReturn(handle, desc.getMethodType());
}
// Used solely in an assertion to figure out if the object we get here is something we in fact expect. Objects
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornGuards.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornGuards.java Sat Jan 16 00:28:28 2016 +0000
@@ -34,6 +34,7 @@
import jdk.dynalink.linker.LinkRequest;
import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -46,10 +47,9 @@
public final class NashornGuards {
private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, ScriptObject.class, PropertyMap.class);
private static final MethodHandle IS_MAP_SCRIPTOBJECT = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
- private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
private static final MethodHandle IS_NOT_JSOBJECT = findOwnMH("isNotJSObject", boolean.class, Object.class);
- private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
+ private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
//TODO - maybe put this back in ScriptFunction instead of the ClassCastException.class relinkage
//private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
@@ -165,14 +165,21 @@
}
/**
- * Get a guard that checks if in item is an instance of either of two classes.
+ * Get a guard that checks if in item is a JS string.
*
- * @param class1 the first class
- * @param class2 the second class
* @return method handle for guard
*/
- public static MethodHandle getInstanceOf2Guard(final Class<?> class1, final Class<?> class2) {
- return MH.insertArguments(IS_INSTANCEOF_2, 1, class1, class2);
+ public static MethodHandle getStringGuard() {
+ return JSType.IS_STRING.methodHandle();
+ }
+
+ /**
+ * Get a guard that checks if in item is a JS number.
+ *
+ * @return method handle for guard
+ */
+ public static MethodHandle getNumberGuard() {
+ return JSType.IS_NUMBER.methodHandle();
}
/**
@@ -224,11 +231,6 @@
}
@SuppressWarnings("unused")
- private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) {
- return class1.isInstance(self) || class2.isInstance(self);
- }
-
- @SuppressWarnings("unused")
private static boolean isScriptFunction(final Object self) {
return self instanceof ScriptFunction;
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -41,6 +41,7 @@
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.Symbol;
/**
* Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
@@ -57,7 +58,9 @@
}
private static boolean canLinkTypeStatic(final Class<?> type) {
- return type == String.class || type == Boolean.class || type == ConsString.class || Number.class.isAssignableFrom(type);
+ return type == String.class || type == Boolean.class || type == ConsString.class || type == Integer.class
+ || type == Double.class || type == Float.class || type == Short.class || type == Byte.class
+ || type == Symbol.class;
}
@Override
@@ -167,7 +170,7 @@
@SuppressWarnings("unused")
private static boolean isJavaScriptPrimitive(final Object o) {
- return JSType.isString(o) || o instanceof Boolean || o instanceof Number || o == null;
+ return JSType.isString(o) || o instanceof Boolean || JSType.isNumber(o) || o == null || o instanceof Symbol;
}
private static final MethodHandle GUARD_PRIMITIVE = findOwnMH("isJavaScriptPrimitive", boolean.class, Object.class);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Sat Jan 16 00:28:28 2016 +0000
@@ -53,7 +53,11 @@
* </pre>
*/
final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
- private static final GuardingDynamicLinker staticClassLinker = BeansLinker.getLinkerForClass(StaticClass.class);
+ private final GuardingDynamicLinker staticClassLinker;
+
+ NashornStaticClassLinker(final BeansLinker beansLinker) {
+ this.staticClassLinker = beansLinker.getLinkerForClass(StaticClass.class);
+ }
@Override
public boolean canLinkType(final Class<?> type) {
@@ -100,7 +104,7 @@
return delegate(linkerServices, request);
}
- private static GuardedInvocation delegate(final LinkerServices linkerServices, final LinkRequest request) throws Exception {
+ private GuardedInvocation delegate(final LinkerServices linkerServices, final LinkRequest request) throws Exception {
return NashornBeansLinker.getGuardedInvocation(staticClassLinker, request, linkerServices);
}
--- a/nashorn/test/script/basic/JDK-8030200.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/JDK-8030200.js Sat Jan 16 00:28:28 2016 +0000
@@ -33,4 +33,4 @@
var s = n.toString(5);
var m = parseInt(s, 5);
print(m === n);
-print(n);
+print(m);
--- a/nashorn/test/script/basic/JDK-8049242.js.EXPECTED Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/JDK-8049242.js.EXPECTED Sat Jan 16 00:28:28 2016 +0000
@@ -1,10 +1,10 @@
abc
[jdk.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)]
ava
-TypeError: null is not a function
-TypeError: null is not a function
-TypeError: null is not a function
+TypeError: Java.type("java.lang.Object")["()xxxxx"] is not a function
+TypeError: Java.type("java.lang.Object")["("] is not a function
+TypeError: Java.type("java.lang.Object")[")"] is not a function
TypeError: Constructor [jdk.dynalink.beans.SimpleDynamicMethod java.lang.String(char[],int,int)] requires "new".
-TypeError: null is not a function
-TypeError: null is not a function
+TypeError: Java.type("java.lang.Runnable")["()"] is not a function
+TypeError: Java.type("java.lang.Runnable")["(int)"] is not a function
java.lang.InstantiationException: java.io.InputStream
--- a/nashorn/test/script/basic/JDK-8066669.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/JDK-8066669.js Sat Jan 16 00:28:28 2016 +0000
@@ -29,12 +29,13 @@
*/
// Make sure index access on Java objects is working as expected.
-var map = new java.util.HashMap();
+var map = new java.util.LinkedHashMap();
map["foo"] = "bar";
map[1] = 2;
map[false] = true;
map[null] = 0;
+map["a"] = null;
print(map);
@@ -49,10 +50,12 @@
print(typeof map[1], map[1]);
print(typeof map[false], map[false]);
print(typeof map[null], map[null]);
+print(typeof map["a"], map["a"]);
-print(map.foo);
-print(map.false);
-print(map.null);
+print("map.foo=" + map.foo);
+print("map.false=" + map.false);
+print("map.null=" + map.null);
+print("map.a=" + map.a);
map.foo = "baz";
print(map);
--- a/nashorn/test/script/basic/JDK-8066669.js.EXPECTED Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/JDK-8066669.js.EXPECTED Sat Jan 16 00:28:28 2016 +0000
@@ -1,13 +1,16 @@
-{null=0, 1=2, false=true, foo=bar}
-object null
+{foo=bar, 1=2, false=true, null=0, a=null}
+string foo
number 1
boolean false
-string foo
+object null
+string a
string bar
number 2
boolean true
number 0
-bar
-null
-null
-{null=0, 1=2, false=true, foo=baz}
+object null
+map.foo=bar
+map.false=undefined
+map.null=undefined
+map.a=null
+{foo=baz, 1=2, false=true, null=0, a=null}
--- a/nashorn/test/script/basic/JDK-8079145.js.EXPECTED Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/JDK-8079145.js.EXPECTED Sat Jan 16 00:28:28 2016 +0000
@@ -5,8 +5,8 @@
int array: check widen for true [class java.lang.Boolean]
int array: check widen for 34 [class java.lang.Byte]
int array: check widen for 344454 [class java.lang.Integer]
-int array: check widen for 454545 [class java.lang.Long]
-int array: check widen for 2147483648 [class java.lang.Long]
+int array: check widen for 454545
+int array: check widen for 2147483648
int array: check widen for 34.29999923706055 [class java.lang.Float]
int array: check widen for 3.141592653589793 [class java.lang.Double]
int array: check widen for s
@@ -17,8 +17,8 @@
long array: check widen for true [class java.lang.Boolean]
long array: check widen for 34 [class java.lang.Byte]
long array: check widen for 344454 [class java.lang.Integer]
-long array: check widen for 454545 [class java.lang.Long]
-long array: check widen for 2147483648 [class java.lang.Long]
+long array: check widen for 454545
+long array: check widen for 2147483648
long array: check widen for 34.29999923706055 [class java.lang.Float]
long array: check widen for 3.141592653589793 [class java.lang.Double]
long array: check widen for s
@@ -29,8 +29,8 @@
number array: check widen for true [class java.lang.Boolean]
number array: check widen for 34 [class java.lang.Byte]
number array: check widen for 344454 [class java.lang.Integer]
-number array: check widen for 454545 [class java.lang.Long]
-number array: check widen for 2147483648 [class java.lang.Long]
+number array: check widen for 454545
+number array: check widen for 2147483648
number array: check widen for 34.29999923706055 [class java.lang.Float]
number array: check widen for 3.141592653589793 [class java.lang.Double]
number array: check widen for s
@@ -41,8 +41,8 @@
object array: check widen for true [class java.lang.Boolean]
object array: check widen for 34 [class java.lang.Byte]
object array: check widen for 344454 [class java.lang.Integer]
-object array: check widen for 454545 [class java.lang.Long]
-object array: check widen for 2147483648 [class java.lang.Long]
+object array: check widen for 454545
+object array: check widen for 2147483648
object array: check widen for 34.29999923706055 [class java.lang.Float]
object array: check widen for 3.141592653589793 [class java.lang.Double]
object array: check widen for s
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8143896.js Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, 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-8143896: java.lang.Long is implicitly converted to double
+ *
+ * @test
+ * @run
+ */
+
+Assert.assertTrue(java.lang.Long.valueOf("301077366599181567").toString() === "301077366599181567");
+Assert.assertTrue(java.lang.Long.valueOf("-301077366599181567").toString() === "-301077366599181567");
+Assert.assertTrue(java.lang.Long.valueOf("301077366599181567") == 301077366599181567);
+Assert.assertFalse(java.lang.Long.valueOf("301077366599181567") === 301077366599181567);
+
+Assert.assertTrue(new java.math.BigInteger("301077366599181567").toString() === "301077366599181567");
+Assert.assertTrue(new java.math.BigInteger("-301077366599181567").toString() === "-301077366599181567");
+Assert.assertTrue(new java.math.BigInteger("301077366599181567") == 301077366599181567);
+Assert.assertFalse(new java.math.BigInteger("301077366599181567") === 301077366599181567);
+
+
+var n = new java.lang.Byte("123");
+Assert.assertTrue(typeof n === "number");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertTrue(n === 123);
+
+n = new java.lang.Short("123");
+Assert.assertTrue(typeof n === "number");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertTrue(n === 123);
+
+n = new java.lang.Integer("123");
+Assert.assertTrue(typeof n === "number");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertTrue(n === 123);
+
+n = new java.lang.Float("123");
+Assert.assertTrue(typeof n === "number");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertTrue(n === 123);
+
+n = new java.lang.Double("123");
+Assert.assertTrue(typeof n === "number");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertTrue(n === 123);
+
+n = new java.lang.Long("123");
+Assert.assertTrue(typeof n === "object");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertFalse(n === 123);
+
+n = new java.util.concurrent.atomic.DoubleAdder();
+n.add("123");
+Assert.assertTrue(typeof n === "object");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertFalse(n === 123);
+
+n = new java.util.concurrent.atomic.AtomicInteger(123);
+Assert.assertTrue(typeof n === "object");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertFalse(n === 123);
+
+n = new java.util.concurrent.atomic.AtomicLong(123);
+Assert.assertTrue(typeof n === "object");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertFalse(n === 123);
+
+n = new java.math.BigInteger("123");
+Assert.assertTrue(typeof n === "object");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertFalse(n === 123);
+
+n = new java.math.BigDecimal("123");
+Assert.assertTrue(typeof n === "object");
+Assert.assertTrue(n + 1 === 124);
+Assert.assertTrue(n == 123);
+Assert.assertFalse(n === 123);
--- a/nashorn/test/script/basic/es6/symbols.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/es6/symbols.js Sat Jan 16 00:28:28 2016 +0000
@@ -40,11 +40,11 @@
Assert.assertTrue(Symbol(null).toString() === 'Symbol(null)');
Assert.assertTrue(Symbol(undefined).toString() === 'Symbol()');
-var s1 = Symbol();
-var s2 = Symbol("s2");
+const s1 = Symbol();
+const s2 = Symbol("s2");
Assert.assertFalse(s1 instanceof Symbol); // not an object
-var obj = {};
+let obj = {};
obj['foo'] = 'foo';
obj[s1] = s1;
obj['bar'] = 'bar';
@@ -57,17 +57,17 @@
Assert.assertTrue(obj[1] === 1);
Assert.assertTrue(obj[s2] === s2);
-var expectedNames = ['1', 'foo', 'bar'];
-var expectedSymbols = [s1, s2];
-var actualNames = Object.getOwnPropertyNames(obj);
-var actualSymbols = Object.getOwnPropertySymbols(obj);
+const expectedNames = ['1', 'foo', 'bar'];
+const expectedSymbols = [s1, s2];
+const actualNames = Object.getOwnPropertyNames(obj);
+let actualSymbols = Object.getOwnPropertySymbols(obj);
Assert.assertTrue(expectedNames.length == actualNames.length);
Assert.assertTrue(expectedSymbols.length == actualSymbols.length);
-for (var key in expectedNames) {
+for (let key in expectedNames) {
Assert.assertTrue(expectedNames[key] === actualNames[key]);
}
-for (var key in expectedSymbols) {
+for (let key in expectedSymbols) {
Assert.assertTrue(expectedSymbols[key] === actualSymbols[key]);
}
@@ -114,8 +114,8 @@
// Symbol.for and Symbol.keyFor
-var uncached = Symbol('foo');
-var cached = Symbol.for('foo');
+const uncached = Symbol('foo');
+const cached = Symbol.for('foo');
Assert.assertTrue(uncached !== cached);
Assert.assertTrue(Symbol.keyFor(uncached) === undefined);
@@ -123,9 +123,15 @@
Assert.assertTrue(cached === Symbol.for('foo'));
Assert.assertTrue(cached === Symbol.for('f' + 'oo'));
+// JDK-8147008: Make sure symbols are handled by primitive linker
+Symbol.prototype.foo = 123;
+Symbol.prototype[s2] = s2;
+Assert.assertEquals(s1.foo, 123);
+Assert.assertEquals(s2[s2], s2);
+
// Object wrapper
-var o = Object(s1);
+const o = Object(s1);
obj = {};
obj[s1] = "s1";
Assert.assertTrue(o == s1);
@@ -134,6 +140,8 @@
Assert.assertTrue(o instanceof Symbol);
Assert.assertTrue(obj[o] == 's1');
Assert.assertTrue(o in obj);
+Assert.assertEquals(o.foo, 123);
+Assert.assertEquals(o[s2], s2);
// various non-strict comparisons that should fail
--- a/nashorn/test/script/basic/list.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/list.js Sat Jan 16 00:28:28 2016 +0000
@@ -54,15 +54,14 @@
var size_name = "size"
print("l[size_name]()=" + l[size_name]()) // ... but existing methods can be accessed with []
-expectException(2) // Java lists don't auto-expand to accommodate new indices
-expectException(java.lang.Double.POSITIVE_INFINITY) // Dynalink will throw IOOBE
-expectException(java.lang.Double.NEGATIVE_INFINITY) // Dynalink will throw IOOBE
+// All illegal indices, even those out of bounds, return undefined
+print("l[2]=" + l[2]);
+print("l[-1]=" + l[-1]);
+print("l[2.1]=" + l[2.1]);
+print("l[-1.1]=" + l[-1.1]);
+print("l[Infinity]=" + l[Infinity]);
+print("l[-Infinity]=" + l[-Infinity]);
+print("l[NaN]=" + l[NaN]);
-function expectException(index) {
- try {
- l[index] = "x"
- print("Not caught out-of-bounds assignment for " + index)
- } catch(e) {
- print(e)
- }
-}
+l[1.1]="b"; // should be no-op
+print("l[0]=" + l[0]);
--- a/nashorn/test/script/basic/list.js.EXPECTED Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/list.js.EXPECTED Sat Jan 16 00:28:28 2016 +0000
@@ -9,9 +9,14 @@
--for each end--
l[0]=foo
l[1]=a
-l[0.9]=null
+l[0.9]=undefined
l['blah']=undefined
l[size_name]()=2
-java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
-java.lang.IndexOutOfBoundsException: Index: Infinity, Size: 2
-java.lang.IndexOutOfBoundsException: Index: -Infinity, Size: 2
+l[2]=undefined
+l[-1]=undefined
+l[2.1]=undefined
+l[-1.1]=undefined
+l[Infinity]=undefined
+l[-Infinity]=undefined
+l[NaN]=undefined
+l[0]=foo
--- a/nashorn/test/script/basic/map.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/map.js Sat Jan 16 00:28:28 2016 +0000
@@ -44,8 +44,8 @@
print("m['empty'] = " + m['empty'])
print("m[empty_key] = " + m[empty_key]) // prints "foo"
-print("m.bwah = " + m.bwah) // prints "null"
-print("m['bwah'] = " + m['bwah']) // prints "null"
+print("m.bwah = " + m.bwah) // prints "undefined"
+print("m['bwah'] = " + m['bwah']) // prints "undefined"
m.put("twonk", "ding")
print("m.twonk = " + m.twonk) // prints "ding"
--- a/nashorn/test/script/basic/map.js.EXPECTED Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/basic/map.js.EXPECTED Sat Jan 16 00:28:28 2016 +0000
@@ -7,8 +7,8 @@
m.empty = false
m['empty'] = foo
m[empty_key] = foo
-m.bwah = null
-m['bwah'] = null
+m.bwah = undefined
+m['bwah'] = undefined
m.twonk = ding
m['twonk'] = ding
m.size()=2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/context-dependent-logging.js Sat Jan 16 00:28:28 2016 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Test that logging configuration is per engine, rather than per process.
+ *
+ * @test
+ * @bug 8036977
+ * @run/ignore-std-error
+ * @fork
+ * @option -scripting
+ */
+
+// To test, start another engine (testEngine) with a time logger and ensure the
+// logger exists.
+
+var NashornFactory = new (Java.type('jdk.nashorn.api.scripting.NashornScriptEngineFactory'))(),
+ testEngine = NashornFactory.getScriptEngine("-scripting", "--log=time")
+
+if (!testEngine.eval('$OPTIONS._loggers.time')) {
+ throw 'fresh testEngine does not have time logger'
+}
+
+// To test further, have the testEngine start yet another engine (e) without
+// time logging, but with compiler logging. Check the logging is as configured,
+// and verify the testEngine still has time logging, but no compiler logging.
+
+var script = <<EOS
+ var F = new (Java.type('jdk.nashorn.api.scripting.NashornScriptEngineFactory'))(),
+ e = F.getScriptEngine('-scripting', '--log=compiler')
+ if (!e.eval('$OPTIONS._loggers.compiler')) {
+ throw 'e does not have compiler logger'
+ }
+ if (e.eval('$OPTIONS._loggers.time')) {
+ throw 'e has time logger'
+ }
+EOS
+
+testEngine.eval(script)
+
+if (!testEngine.eval('$OPTIONS._loggers.time')) {
+ throw 'after-test testEngine does not have time logger'
+}
+if (testEngine.eval('$OPTIONS._loggers.compiler')) {
+ throw 'after-test testEngine has compiler logger'
+}
--- a/nashorn/test/script/nosecurity/parserapi.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/parserapi.js Sat Jan 16 00:28:28 2016 +0000
@@ -30,8 +30,8 @@
*/
function Parser() {
- // create nashorn parser
- this._parser = Parser.create();
+ // create nashorn parser
+ this._parser = Parser.create();
}
// Java types used
@@ -54,59 +54,60 @@
// convert Nashorn parser Tree, Diagnostic as a script friendly object
Parser.prototype.convert = function(tree) {
- if (!tree || typeof tree != 'object') {
+ if (!tree || typeof tree != 'object' || tree instanceof java.lang.Long) {
return tree;
}
var obj = Object.bindProperties({}, tree);
var result = {};
for (var i in obj) {
- var val = obj[i];
- if (val instanceof Parser.Tree) {
- result[i] = this.convert(val);
- } else if (val instanceof Parser.List) {
- var arr = new Array(val.size());
- for (var j in val) {
- arr[j] = this.convert(val[j]);
- }
-
- result[i] = arr;
- } else {
- switch (typeof val) {
- case 'number':
- case 'string':
- case 'boolean':
- result[i] = String(val);
- default:
- if (val instanceof Parser.Enum) {
- result[i] = String(val);
- }
- }
- }
- }
- return result;
+ var val = obj[i];
+ if (val instanceof Parser.Tree) {
+ result[i] = this.convert(val);
+ } else if (val instanceof Parser.List) {
+ var arr = new Array(val.size());
+ for (var j in val) {
+ arr[j] = this.convert(val[j]);
+ }
+
+ result[i] = arr;
+ } else {
+ switch (typeof val) {
+ case 'number':
+ case 'string':
+ case 'boolean':
+ result[i] = String(val);
+ break;
+ default:
+ if (val instanceof java.lang.Long || val instanceof Parser.Enum) {
+ result[i] = String(val);
+ }
+ }
+ }
+ }
+ return result;
}
function processFiles(subdir) {
- var File = Java.type("java.io.File");
- var files = new File(__DIR__ + subdir).listFiles();
- java.util.Arrays.sort(files);
- for each (var file in files) {
- if (file.name.endsWith(".js")) {
- var script = readFully(file);
- var parser = new Parser();
- var tree = parser.parse(subdir + "/" + file.name, script,
- function(diagnostic) {
- print(JSON.stringify(parser.convert(diagnostic), null, 2).replace(/\\r/g, ''));
- print(",");
- });
+ var File = Java.type("java.io.File");
+ var files = new File(__DIR__ + subdir).listFiles();
+ java.util.Arrays.sort(files);
+ for each (var file in files) {
+ if (file.name.endsWith(".js")) {
+ var script = readFully(file);
+ var parser = new Parser();
+ var tree = parser.parse(subdir + "/" + file.name, script,
+ function(diagnostic) {
+ print(JSON.stringify(parser.convert(diagnostic), null, 2).replace(/\\r/g, ''));
+ print(",");
+ });
- if (tree != null) {
- print(JSON.stringify(tree, null, 2));
- print(",");
- }
- }
- }
+ if (tree != null) {
+ print(JSON.stringify(tree, null, 2));
+ print(",");
+ }
+ }
+ }
}
// parse files in parsertests directory
--- a/nashorn/test/script/nosecurity/parserapi.js.EXPECTED Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/parserapi.js.EXPECTED Sat Jan 16 00:28:28 2016 +0000
@@ -1,4 +1,4 @@
-[
+[
{
"endPosition": "1113",
"kind": "COMPILATION_UNIT",
@@ -132,8 +132,8 @@
"sourceName": "parsertests/array_literal.js",
"strict": "false",
"startPosition": "1113"
-}
-,
+}
+,
{
"endPosition": "1126",
"kind": "COMPILATION_UNIT",
@@ -406,8 +406,8 @@
"sourceName": "parsertests/assignmentExpr.js",
"strict": "false",
"startPosition": "1126"
-}
-,
+}
+,
{
"endPosition": "1116",
"kind": "COMPILATION_UNIT",
@@ -912,8 +912,8 @@
"sourceName": "parsertests/binaryExpr.js",
"strict": "false",
"startPosition": "1116"
-}
-,
+}
+,
{
"endPosition": "1117",
"kind": "COMPILATION_UNIT",
@@ -959,8 +959,8 @@
"sourceName": "parsertests/block.js",
"strict": "false",
"startPosition": "1117"
-}
-,
+}
+,
{
"endPosition": "1117",
"kind": "COMPILATION_UNIT",
@@ -1060,8 +1060,8 @@
"sourceName": "parsertests/breakStat.js",
"strict": "false",
"startPosition": "1117"
-}
-,
+}
+,
{
"endPosition": "1117",
"kind": "COMPILATION_UNIT",
@@ -1098,8 +1098,8 @@
"sourceName": "parsertests/condExpr.js",
"strict": "false",
"startPosition": "1117"
-}
-,
+}
+,
{
"endPosition": "1120",
"kind": "COMPILATION_UNIT",
@@ -1199,8 +1199,8 @@
"sourceName": "parsertests/continueStat.js",
"strict": "false",
"startPosition": "1120"
-}
-,
+}
+,
{
"endPosition": "1118",
"kind": "COMPILATION_UNIT",
@@ -1214,8 +1214,8 @@
"sourceName": "parsertests/debuggerStat.js",
"strict": "false",
"startPosition": "1118"
-}
-,
+}
+,
{
"endPosition": "1137",
"kind": "COMPILATION_UNIT",
@@ -1500,8 +1500,8 @@
"sourceName": "parsertests/functions.js",
"strict": "false",
"startPosition": "1137"
-}
-,
+}
+,
{
"endPosition": "1114",
"kind": "COMPILATION_UNIT",
@@ -1604,8 +1604,8 @@
"sourceName": "parsertests/ifStat.js",
"strict": "false",
"startPosition": "1114"
-}
-,
+}
+,
{
"endPosition": "1113",
"kind": "COMPILATION_UNIT",
@@ -1668,8 +1668,8 @@
"sourceName": "parsertests/labelledStat.js",
"strict": "false",
"startPosition": "1113"
-}
-,
+}
+,
{
"endPosition": "1125",
"kind": "COMPILATION_UNIT",
@@ -2066,8 +2066,8 @@
"sourceName": "parsertests/lhsExpr.js",
"strict": "false",
"startPosition": "1125"
-}
-,
+}
+,
{
"endPosition": "1110",
"kind": "COMPILATION_UNIT",
@@ -2350,8 +2350,8 @@
"sourceName": "parsertests/loopStat.js",
"strict": "false",
"startPosition": "1110"
-}
-,
+}
+,
{
"endPosition": "1125",
"kind": "COMPILATION_UNIT",
@@ -2705,8 +2705,8 @@
"sourceName": "parsertests/objectLitExpr.js",
"strict": "false",
"startPosition": "1125"
-}
-,
+}
+,
{
"endPosition": "1118",
"kind": "COMPILATION_UNIT",
@@ -2781,8 +2781,8 @@
"sourceName": "parsertests/parenExpr.js",
"strict": "false",
"startPosition": "1118"
-}
-,
+}
+,
{
"endPosition": "1119",
"kind": "COMPILATION_UNIT",
@@ -2995,8 +2995,8 @@
"sourceName": "parsertests/primaryExpr.js",
"strict": "false",
"startPosition": "1119"
-}
-,
+}
+,
{
"endPosition": "1114",
"kind": "COMPILATION_UNIT",
@@ -3044,8 +3044,8 @@
"sourceName": "parsertests/regexp_literal.js",
"strict": "false",
"startPosition": "1114"
-}
-,
+}
+,
{
"endPosition": "1118",
"kind": "COMPILATION_UNIT",
@@ -3144,8 +3144,8 @@
"sourceName": "parsertests/returnStat.js",
"strict": "false",
"startPosition": "1118"
-}
-,
+}
+,
{
"endPosition": "1111",
"kind": "COMPILATION_UNIT",
@@ -3309,8 +3309,8 @@
"sourceName": "parsertests/switchStat.js",
"strict": "false",
"startPosition": "1111"
-}
-,
+}
+,
{
"endPosition": "1110",
"kind": "COMPILATION_UNIT",
@@ -3421,8 +3421,8 @@
"sourceName": "parsertests/throwStat.js",
"strict": "false",
"startPosition": "1110"
-}
-,
+}
+,
{
"endPosition": "1121",
"kind": "COMPILATION_UNIT",
@@ -3783,8 +3783,8 @@
"sourceName": "parsertests/tryCatchStat.js",
"strict": "false",
"startPosition": "1121"
-}
-,
+}
+,
{
"endPosition": "1115",
"kind": "COMPILATION_UNIT",
@@ -3969,8 +3969,8 @@
"sourceName": "parsertests/unaryExpr.js",
"strict": "false",
"startPosition": "1115"
-}
-,
+}
+,
{
"endPosition": "1122",
"kind": "COMPILATION_UNIT",
@@ -4016,8 +4016,8 @@
"sourceName": "parsertests/useStrict.js",
"strict": "true",
"startPosition": "1122"
-}
-,
+}
+,
{
"endPosition": "1143",
"kind": "COMPILATION_UNIT",
@@ -4092,8 +4092,8 @@
"sourceName": "parsertests/varDecl.js",
"strict": "false",
"startPosition": "1143"
-}
-,
+}
+,
{
"endPosition": "1111",
"kind": "COMPILATION_UNIT",
@@ -4142,8 +4142,8 @@
"sourceName": "parsertests/withStat.js",
"strict": "false",
"startPosition": "1111"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/caseoutofswitch.js",
"code": "case (1090, 4)",
@@ -4152,8 +4152,8 @@
"position": "1090",
"message": "parsernegativetests/caseoutofswitch.js:29:0 Expected an operand but found case\ncase 23:\n^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/caseoutofswitch.js",
"code": "default (1112, 7)",
@@ -4162,8 +4162,8 @@
"position": "1112",
"message": "parsernegativetests/caseoutofswitch.js:31:0 Expected an operand but found default\ndefault:\n^",
"lineNumber": "31"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4240,8 +4240,8 @@
"sourceName": "parsernegativetests/caseoutofswitch.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegalbreak.js",
"code": "break (1090, 5)",
@@ -4250,8 +4250,8 @@
"position": "1090",
"message": "parsernegativetests/illegalbreak.js:29:0 Illegal break statement\nbreak;\n^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegalbreak.js",
"code": "ident (1103, 3)",
@@ -4260,8 +4260,8 @@
"position": "1103",
"message": "parsernegativetests/illegalbreak.js:30:6 Undefined Label \"foo\"\nbreak foo;\n ^",
"lineNumber": "30"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4290,8 +4290,8 @@
"sourceName": "parsernegativetests/illegalbreak.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegalcontinue.js",
"code": "continue (1090, 8)",
@@ -4300,8 +4300,8 @@
"position": "1090",
"message": "parsernegativetests/illegalcontinue.js:29:0 Illegal continue statement\ncontinue;\n^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegalcontinue.js",
"code": "ident (1109, 3)",
@@ -4310,8 +4310,8 @@
"position": "1109",
"message": "parsernegativetests/illegalcontinue.js:30:9 Undefined Label \"foo\"\ncontinue foo;\n ^",
"lineNumber": "30"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4340,8 +4340,8 @@
"sourceName": "parsernegativetests/illegalcontinue.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegallvalue.js",
"code": "decimal (1090, 2)",
@@ -4350,8 +4350,8 @@
"position": "1090",
"message": "parsernegativetests/illegallvalue.js:29:0 Invalid left hand side for assignment\n44 = 54;\n^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegallvalue.js",
"code": "decimal (1099, 3)",
@@ -4360,8 +4360,8 @@
"position": "1099",
"message": "parsernegativetests/illegallvalue.js:30:0 Invalid left hand side for assignment\n233 += 33;\n^",
"lineNumber": "30"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegallvalue.js",
"code": "decimal (1110, 4)",
@@ -4370,8 +4370,8 @@
"position": "1110",
"message": "parsernegativetests/illegallvalue.js:31:0 Invalid left hand side for assignment\n3423 -= 234;\n^",
"lineNumber": "31"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4410,8 +4410,8 @@
"sourceName": "parsernegativetests/illegallvalue.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/illegaloperator.js",
"code": "* (1093, 1)",
@@ -4420,8 +4420,8 @@
"position": "1093",
"message": "parsernegativetests/illegaloperator.js:29:3 Expected an operand but found *\nx ** y\n ^",
"lineNumber": "29"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4440,8 +4440,8 @@
"sourceName": "parsernegativetests/illegaloperator.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/keywordident.js",
"code": "var (1094, 3)",
@@ -4450,8 +4450,8 @@
"position": "1094",
"message": "parsernegativetests/keywordident.js:29:4 Expected ident but found var\nvar var = 23;\n ^",
"lineNumber": "29"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4482,8 +4482,8 @@
"sourceName": "parsernegativetests/keywordident.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/parenmissing.js",
"code": "; (1096, 1)",
@@ -4492,8 +4492,8 @@
"position": "1096",
"message": "parsernegativetests/parenmissing.js:29:6 Expected ) but found ;\n(1 + 2;\n ^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/parenmissing.js",
"code": ") (1103, 1)",
@@ -4502,8 +4502,8 @@
"position": "1103",
"message": "parsernegativetests/parenmissing.js:30:5 Expected ; but found )\nx * y);\n ^",
"lineNumber": "30"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4554,8 +4554,8 @@
"sourceName": "parsernegativetests/parenmissing.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/repeatedproperty.js",
"code": "ident (1111, 3)",
@@ -4564,8 +4564,8 @@
"position": "1111",
"message": "parsernegativetests/repeatedproperty.js:29:21 Property \"foo\" already defined\nvar obj = { foo: 34, get foo() { return 'hello' } };\n ^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/repeatedproperty.js",
"code": "ident (1165, 3)",
@@ -4574,8 +4574,8 @@
"position": "1165",
"message": "parsernegativetests/repeatedproperty.js:30:22 Property \"foo\" already defined\nvar obj1 = { foo: 34, set foo(x) { } };\n ^",
"lineNumber": "30"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/repeatedproperty.js",
"code": "ident (1205, 3)",
@@ -4584,8 +4584,8 @@
"position": "1205",
"message": "parsernegativetests/repeatedproperty.js:31:22 Property \"foo\" already defined\nvar obj2 = { foo: 34, set foo(x) { } };\n ^",
"lineNumber": "31"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/repeatedproperty.js",
"code": "ident (1251, 3)",
@@ -4594,8 +4594,8 @@
"position": "1251",
"message": "parsernegativetests/repeatedproperty.js:32:28 Property \"bar\" already defined\nvar obj3 = { get bar() { }, get bar() {} };\n ^",
"lineNumber": "32"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/repeatedproperty.js",
"code": "ident (1296, 3)",
@@ -4604,8 +4604,8 @@
"position": "1296",
"message": "parsernegativetests/repeatedproperty.js:33:29 Property \"bar\" already defined\nvar obj4 = { set bar(x) { }, set bar(x) {} };\n ^",
"lineNumber": "33"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4664,8 +4664,8 @@
"sourceName": "parsernegativetests/repeatedproperty.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/strict_repeatedproperty.js",
"code": "ident (1126, 3)",
@@ -4674,8 +4674,8 @@
"position": "1126",
"message": "parsernegativetests/strict_repeatedproperty.js:31:21 Property \"foo\" already defined\nvar obj = { foo: 34, foo: 'hello' };\n ^",
"lineNumber": "31"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4705,8 +4705,8 @@
"sourceName": "parsernegativetests/strict_repeatedproperty.js",
"strict": "true",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/strict_repeatparam.js",
"code": "ident (1119, 1)",
@@ -4715,8 +4715,8 @@
"position": "1119",
"message": "parsernegativetests/strict_repeatparam.js:31:14 strict mode function cannot have duplicate parameter name \"x\"\nfunction func(x, x) {}\n ^",
"lineNumber": "31"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4746,8 +4746,8 @@
"sourceName": "parsernegativetests/strict_repeatparam.js",
"strict": "true",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/strict_with.js",
"code": "with (1105, 4)",
@@ -4756,8 +4756,8 @@
"position": "1105",
"message": "parsernegativetests/strict_with.js:31:0 \"with\" statement cannot be used in strict mode\nwith({}) {}\n^",
"lineNumber": "31"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/strict_with.js",
"code": ") (1112, 1)",
@@ -4766,8 +4766,8 @@
"position": "1112",
"message": "parsernegativetests/strict_with.js:31:7 Expected ; but found )\nwith({}) {}\n ^",
"lineNumber": "31"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4807,8 +4807,8 @@
"sourceName": "parsernegativetests/strict_with.js",
"strict": "true",
"startPosition": "1090"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/toplevelreturn.js",
"code": "return (1090, 6)",
@@ -4817,8 +4817,8 @@
"position": "1090",
"message": "parsernegativetests/toplevelreturn.js:29:0 Invalid return statement\nreturn;\n^",
"lineNumber": "29"
-}
-,
+}
+,
{
"fileName": "parsernegativetests/toplevelreturn.js",
"code": "return (1098, 6)",
@@ -4827,8 +4827,8 @@
"position": "1098",
"message": "parsernegativetests/toplevelreturn.js:30:0 Invalid return statement\nreturn 23;\n^",
"lineNumber": "30"
-}
-,
+}
+,
{
"endPosition": "1090",
"kind": "COMPILATION_UNIT",
@@ -4857,59 +4857,59 @@
"sourceName": "parsernegativetests/toplevelreturn.js",
"strict": "false",
"startPosition": "1090"
-}
-,
+}
+,
{
"endPosition": "1136",
"kind": "COMPILATION_UNIT",
"sourceElements": [
{
- "endPosition": "1240",
+ "endPosition": "1242",
"kind": "FUNCTION",
"name": "Parser",
"body": {
- "endPosition": "1218",
+ "endPosition": "1220",
"kind": "BLOCK",
"statements": [
{
"expression": {
"expression": {
- "endPosition": "1217",
+ "endPosition": "1219",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "create",
"expression": {
- "endPosition": "1208",
+ "endPosition": "1210",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1202"
+ "startPosition": "1204"
},
- "endPosition": "1215",
+ "endPosition": "1217",
"kind": "MEMBER_SELECT",
- "startPosition": "1202"
+ "startPosition": "1204"
},
"arguments": [],
- "startPosition": "1202"
+ "startPosition": "1204"
},
- "endPosition": "1217",
+ "endPosition": "1219",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "_parser",
"expression": {
- "endPosition": "1191",
+ "endPosition": "1193",
"kind": "IDENTIFIER",
"name": "this",
- "startPosition": "1187"
+ "startPosition": "1189"
},
- "endPosition": "1199",
+ "endPosition": "1201",
"kind": "MEMBER_SELECT",
- "startPosition": "1187"
+ "startPosition": "1189"
},
- "startPosition": "1187"
+ "startPosition": "1189"
},
- "endPosition": "1217",
+ "endPosition": "1219",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1187"
+ "startPosition": "1189"
}
],
"startPosition": "1154"
@@ -4921,1368 +4921,1489 @@
{
"expression": {
"expression": {
- "endPosition": "1305",
+ "endPosition": "1307",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "1265",
+ "endPosition": "1267",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "1261"
+ "startPosition": "1263"
},
- "endPosition": "1270",
+ "endPosition": "1272",
"kind": "MEMBER_SELECT",
- "startPosition": "1261"
+ "startPosition": "1263"
},
"arguments": [
{
- "endPosition": "1303",
+ "endPosition": "1305",
"kind": "STRING_LITERAL",
"value": "jdk.nashorn.api.tree.Diagnostic",
- "startPosition": "1272"
+ "startPosition": "1274"
}
],
- "startPosition": "1261"
- },
- "endPosition": "1305",
+ "startPosition": "1263"
+ },
+ "endPosition": "1307",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "Diagnostic",
"expression": {
- "endPosition": "1247",
+ "endPosition": "1249",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1241"
+ "startPosition": "1243"
},
- "endPosition": "1258",
+ "endPosition": "1260",
"kind": "MEMBER_SELECT",
- "startPosition": "1241"
- },
- "startPosition": "1241"
- },
- "endPosition": "1305",
+ "startPosition": "1243"
+ },
+ "startPosition": "1243"
+ },
+ "endPosition": "1307",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1241"
+ "startPosition": "1243"
},
{
"expression": {
"expression": {
- "endPosition": "1390",
+ "endPosition": "1392",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "1338",
+ "endPosition": "1340",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "1334"
+ "startPosition": "1336"
},
- "endPosition": "1343",
+ "endPosition": "1345",
"kind": "MEMBER_SELECT",
- "startPosition": "1334"
+ "startPosition": "1336"
},
"arguments": [
{
- "endPosition": "1388",
+ "endPosition": "1390",
"kind": "STRING_LITERAL",
"value": "jdk.nashorn.api.tree.SimpleTreeVisitorES5_1",
- "startPosition": "1345"
+ "startPosition": "1347"
}
],
- "startPosition": "1334"
- },
- "endPosition": "1390",
+ "startPosition": "1336"
+ },
+ "endPosition": "1392",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "SimpleTreeVisitor",
"expression": {
- "endPosition": "1313",
+ "endPosition": "1315",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1307"
+ "startPosition": "1309"
},
- "endPosition": "1331",
+ "endPosition": "1333",
"kind": "MEMBER_SELECT",
- "startPosition": "1307"
- },
- "startPosition": "1307"
- },
- "endPosition": "1390",
+ "startPosition": "1309"
+ },
+ "startPosition": "1309"
+ },
+ "endPosition": "1392",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1307"
+ "startPosition": "1309"
},
{
"expression": {
"expression": {
- "endPosition": "1444",
+ "endPosition": "1446",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "1410",
+ "endPosition": "1412",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "1406"
+ "startPosition": "1408"
},
- "endPosition": "1415",
+ "endPosition": "1417",
"kind": "MEMBER_SELECT",
- "startPosition": "1406"
+ "startPosition": "1408"
},
"arguments": [
{
- "endPosition": "1442",
+ "endPosition": "1444",
"kind": "STRING_LITERAL",
"value": "jdk.nashorn.api.tree.Tree",
- "startPosition": "1417"
+ "startPosition": "1419"
}
],
- "startPosition": "1406"
- },
- "endPosition": "1444",
+ "startPosition": "1408"
+ },
+ "endPosition": "1446",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "Tree",
"expression": {
- "endPosition": "1398",
+ "endPosition": "1400",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1392"
+ "startPosition": "1394"
},
- "endPosition": "1403",
+ "endPosition": "1405",
"kind": "MEMBER_SELECT",
- "startPosition": "1392"
- },
- "startPosition": "1392"
- },
- "endPosition": "1444",
+ "startPosition": "1394"
+ },
+ "startPosition": "1394"
+ },
+ "endPosition": "1446",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1392"
+ "startPosition": "1394"
},
{
"expression": {
"expression": {
- "endPosition": "1487",
+ "endPosition": "1489",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "1464",
+ "endPosition": "1466",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "1460"
+ "startPosition": "1462"
},
- "endPosition": "1469",
+ "endPosition": "1471",
"kind": "MEMBER_SELECT",
- "startPosition": "1460"
+ "startPosition": "1462"
},
"arguments": [
{
- "endPosition": "1485",
+ "endPosition": "1487",
"kind": "STRING_LITERAL",
"value": "java.util.List",
- "startPosition": "1471"
+ "startPosition": "1473"
}
],
- "startPosition": "1460"
- },
- "endPosition": "1487",
+ "startPosition": "1462"
+ },
+ "endPosition": "1489",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "List",
"expression": {
- "endPosition": "1452",
+ "endPosition": "1454",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1446"
+ "startPosition": "1448"
},
- "endPosition": "1457",
+ "endPosition": "1459",
"kind": "MEMBER_SELECT",
- "startPosition": "1446"
- },
- "startPosition": "1446"
- },
- "endPosition": "1487",
+ "startPosition": "1448"
+ },
+ "startPosition": "1448"
+ },
+ "endPosition": "1489",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1446"
+ "startPosition": "1448"
},
{
"expression": {
"expression": {
- "endPosition": "1530",
+ "endPosition": "1532",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "1507",
+ "endPosition": "1509",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "1503"
+ "startPosition": "1505"
},
- "endPosition": "1512",
+ "endPosition": "1514",
"kind": "MEMBER_SELECT",
- "startPosition": "1503"
+ "startPosition": "1505"
},
"arguments": [
{
- "endPosition": "1528",
+ "endPosition": "1530",
"kind": "STRING_LITERAL",
"value": "java.lang.Enum",
- "startPosition": "1514"
+ "startPosition": "1516"
}
],
- "startPosition": "1503"
- },
- "endPosition": "1530",
+ "startPosition": "1505"
+ },
+ "endPosition": "1532",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "Enum",
"expression": {
- "endPosition": "1495",
+ "endPosition": "1497",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1489"
+ "startPosition": "1491"
},
- "endPosition": "1500",
+ "endPosition": "1502",
"kind": "MEMBER_SELECT",
- "startPosition": "1489"
- },
- "startPosition": "1489"
- },
- "endPosition": "1530",
+ "startPosition": "1491"
+ },
+ "startPosition": "1491"
+ },
+ "endPosition": "1532",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1489"
+ "startPosition": "1491"
},
{
"expression": {
"expression": {
- "endPosition": "1657",
+ "endPosition": "1659",
"kind": "FUNCTION_EXPRESSION",
"body": {
- "endPosition": "1803",
+ "endPosition": "1805",
"kind": "BLOCK",
"statements": [
{
- "endPosition": "1716",
+ "endPosition": "1718",
"kind": "VARIABLE",
"name": "tree",
- "startPosition": "1667",
+ "startPosition": "1669",
"initializer": {
- "endPosition": "1716",
+ "endPosition": "1718",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "parse",
"expression": {
"identifier": "_parser",
"expression": {
- "endPosition": "1678",
+ "endPosition": "1680",
"kind": "IDENTIFIER",
"name": "this",
- "startPosition": "1674"
+ "startPosition": "1676"
},
- "endPosition": "1686",
+ "endPosition": "1688",
"kind": "MEMBER_SELECT",
- "startPosition": "1674"
+ "startPosition": "1676"
},
- "endPosition": "1692",
+ "endPosition": "1694",
"kind": "MEMBER_SELECT",
- "startPosition": "1674"
+ "startPosition": "1676"
},
"arguments": [
{
- "endPosition": "1697",
+ "endPosition": "1699",
"kind": "IDENTIFIER",
"name": "name",
- "startPosition": "1693"
+ "startPosition": "1695"
},
{
- "endPosition": "1705",
+ "endPosition": "1707",
"kind": "IDENTIFIER",
"name": "script",
- "startPosition": "1699"
+ "startPosition": "1701"
},
{
- "endPosition": "1715",
+ "endPosition": "1717",
"kind": "IDENTIFIER",
"name": "listener",
- "startPosition": "1707"
+ "startPosition": "1709"
}
],
- "startPosition": "1674"
+ "startPosition": "1676"
}
},
{
"expression": {
- "endPosition": "1771",
+ "endPosition": "1773",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "accept",
"expression": {
- "endPosition": "1726",
+ "endPosition": "1728",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "1722"
+ "startPosition": "1724"
},
- "endPosition": "1733",
+ "endPosition": "1735",
"kind": "MEMBER_SELECT",
- "startPosition": "1722"
+ "startPosition": "1724"
},
"arguments": [
{
"constructorExpression": {
- "endPosition": "1764",
+ "endPosition": "1766",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "SimpleTreeVisitor",
"expression": {
- "endPosition": "1744",
+ "endPosition": "1746",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1738"
+ "startPosition": "1740"
},
- "endPosition": "1762",
+ "endPosition": "1764",
"kind": "MEMBER_SELECT",
- "startPosition": "1738"
+ "startPosition": "1740"
},
"arguments": [],
- "startPosition": "1744"
+ "startPosition": "1746"
},
- "endPosition": "1764",
+ "endPosition": "1766",
"kind": "NEW",
- "startPosition": "1734"
+ "startPosition": "1736"
},
{
- "endPosition": "1770",
+ "endPosition": "1772",
"kind": "NULL_LITERAL",
- "startPosition": "1766"
+ "startPosition": "1768"
}
],
- "startPosition": "1722"
+ "startPosition": "1724"
},
- "endPosition": "1771",
+ "endPosition": "1773",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1722"
+ "startPosition": "1724"
},
{
"expression": {
- "endPosition": "1802",
+ "endPosition": "1804",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "convert",
"expression": {
- "endPosition": "1788",
+ "endPosition": "1790",
"kind": "IDENTIFIER",
"name": "this",
- "startPosition": "1784"
+ "startPosition": "1786"
},
- "endPosition": "1796",
+ "endPosition": "1798",
"kind": "MEMBER_SELECT",
- "startPosition": "1784"
+ "startPosition": "1786"
},
"arguments": [
{
- "endPosition": "1801",
+ "endPosition": "1803",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "1797"
+ "startPosition": "1799"
}
],
- "startPosition": "1784"
+ "startPosition": "1786"
},
- "endPosition": "1803",
+ "endPosition": "1805",
"kind": "RETURN",
- "startPosition": "1777"
+ "startPosition": "1779"
}
],
- "startPosition": "1657"
+ "startPosition": "1659"
},
"strict": "false",
- "startPosition": "1657",
+ "startPosition": "1659",
"parameters": [
{
- "endPosition": "1637",
+ "endPosition": "1639",
"kind": "IDENTIFIER",
"name": "name",
- "startPosition": "1633"
+ "startPosition": "1635"
},
{
- "endPosition": "1645",
+ "endPosition": "1647",
"kind": "IDENTIFIER",
"name": "script",
- "startPosition": "1639"
+ "startPosition": "1641"
},
{
- "endPosition": "1655",
+ "endPosition": "1657",
"kind": "IDENTIFIER",
"name": "listener",
- "startPosition": "1647"
+ "startPosition": "1649"
}
]
},
- "endPosition": "1657",
+ "endPosition": "1659",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "parse",
"expression": {
"identifier": "prototype",
"expression": {
- "endPosition": "1605",
+ "endPosition": "1607",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1599"
+ "startPosition": "1601"
},
- "endPosition": "1615",
+ "endPosition": "1617",
"kind": "MEMBER_SELECT",
- "startPosition": "1599"
+ "startPosition": "1601"
},
- "endPosition": "1621",
+ "endPosition": "1623",
"kind": "MEMBER_SELECT",
- "startPosition": "1599"
- },
- "startPosition": "1599"
- },
- "endPosition": "1805",
+ "startPosition": "1601"
+ },
+ "startPosition": "1601"
+ },
+ "endPosition": "1807",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1599"
+ "startPosition": "1601"
},
{
"expression": {
"expression": {
- "endPosition": "1834",
+ "endPosition": "1836",
"kind": "FUNCTION_EXPRESSION",
"body": {
- "endPosition": "1897",
+ "endPosition": "1899",
"kind": "BLOCK",
"statements": [
{
"expression": {
- "endPosition": "1896",
+ "endPosition": "1898",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "create",
"expression": {
- "endPosition": "1887",
+ "endPosition": "1889",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "1851",
+ "endPosition": "1853",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "1847"
+ "startPosition": "1849"
},
- "endPosition": "1856",
+ "endPosition": "1858",
"kind": "MEMBER_SELECT",
- "startPosition": "1847"
+ "startPosition": "1849"
},
"arguments": [
{
- "endPosition": "1885",
+ "endPosition": "1887",
"kind": "STRING_LITERAL",
"value": "jdk.nashorn.api.tree.Parser",
- "startPosition": "1858"
+ "startPosition": "1860"
}
],
- "startPosition": "1847"
+ "startPosition": "1849"
},
- "endPosition": "1894",
+ "endPosition": "1896",
"kind": "MEMBER_SELECT",
- "startPosition": "1847"
+ "startPosition": "1849"
},
"arguments": [],
- "startPosition": "1894"
+ "startPosition": "1896"
},
- "endPosition": "1897",
+ "endPosition": "1899",
"kind": "RETURN",
- "startPosition": "1840"
+ "startPosition": "1842"
}
],
- "startPosition": "1834"
+ "startPosition": "1836"
},
"strict": "false",
- "startPosition": "1834",
+ "startPosition": "1836",
"parameters": []
},
- "endPosition": "1834",
+ "endPosition": "1836",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "create",
"expression": {
- "endPosition": "1813",
+ "endPosition": "1815",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1807"
+ "startPosition": "1809"
},
- "endPosition": "1820",
+ "endPosition": "1822",
"kind": "MEMBER_SELECT",
- "startPosition": "1807"
- },
- "startPosition": "1807"
- },
- "endPosition": "1971",
+ "startPosition": "1809"
+ },
+ "startPosition": "1809"
+ },
+ "endPosition": "1973",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1807"
+ "startPosition": "1809"
},
{
"expression": {
"expression": {
- "endPosition": "2014",
+ "endPosition": "2016",
"kind": "FUNCTION_EXPRESSION",
"body": {
- "endPosition": "2863",
+ "endPosition": "2994",
"kind": "BLOCK",
"statements": [
{
"condition": {
"leftOperand": {
- "expression": {
- "endPosition": "2029",
- "kind": "IDENTIFIER",
- "name": "tree",
- "startPosition": "2025"
+ "leftOperand": {
+ "expression": {
+ "endPosition": "2031",
+ "kind": "IDENTIFIER",
+ "name": "tree",
+ "startPosition": "2027"
+ },
+ "endPosition": "2031",
+ "kind": "LOGICAL_COMPLEMENT",
+ "startPosition": "2026"
},
- "endPosition": "2029",
- "kind": "LOGICAL_COMPLEMENT",
- "startPosition": "2024"
+ "endPosition": "2057",
+ "kind": "CONDITIONAL_OR",
+ "rightOperand": {
+ "leftOperand": {
+ "expression": {
+ "endPosition": "2046",
+ "kind": "IDENTIFIER",
+ "name": "tree",
+ "startPosition": "2042"
+ },
+ "endPosition": "2046",
+ "kind": "TYPEOF",
+ "startPosition": "2035"
+ },
+ "endPosition": "2057",
+ "kind": "NOT_EQUAL_TO",
+ "rightOperand": {
+ "endPosition": "2057",
+ "kind": "STRING_LITERAL",
+ "value": "object",
+ "startPosition": "2051"
+ },
+ "startPosition": "2035"
+ },
+ "startPosition": "2026"
},
- "endPosition": "2055",
+ "endPosition": "2092",
"kind": "CONDITIONAL_OR",
"rightOperand": {
"leftOperand": {
- "expression": {
- "endPosition": "2044",
- "kind": "IDENTIFIER",
- "name": "tree",
- "startPosition": "2040"
- },
- "endPosition": "2044",
- "kind": "TYPEOF",
- "startPosition": "2033"
+ "endPosition": "2066",
+ "kind": "IDENTIFIER",
+ "name": "tree",
+ "startPosition": "2062"
},
- "endPosition": "2055",
- "kind": "NOT_EQUAL_TO",
+ "expression": {
+ "endPosition": "2066",
+ "kind": "IDENTIFIER",
+ "name": "tree",
+ "startPosition": "2062"
+ },
+ "endPosition": "2092",
+ "kind": "INSTANCE_OF",
"rightOperand": {
- "endPosition": "2055",
- "kind": "STRING_LITERAL",
- "value": "object",
- "startPosition": "2049"
+ "identifier": "Long",
+ "expression": {
+ "identifier": "lang",
+ "expression": {
+ "endPosition": "2082",
+ "kind": "IDENTIFIER",
+ "name": "java",
+ "startPosition": "2078"
+ },
+ "endPosition": "2087",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2078"
+ },
+ "endPosition": "2092",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2078"
},
- "startPosition": "2033"
+ "type": {
+ "identifier": "Long",
+ "expression": {
+ "identifier": "lang",
+ "expression": {
+ "endPosition": "2082",
+ "kind": "IDENTIFIER",
+ "name": "java",
+ "startPosition": "2078"
+ },
+ "endPosition": "2087",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2078"
+ },
+ "endPosition": "2092",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2078"
+ },
+ "startPosition": "2062"
},
- "startPosition": "2024"
+ "startPosition": "2026"
},
- "endPosition": "2086",
+ "endPosition": "2122",
"kind": "IF",
- "startPosition": "2020",
+ "startPosition": "2022",
"thenStatement": {
- "endPosition": "2086",
+ "endPosition": "2122",
"kind": "BLOCK",
"statements": [
{
"expression": {
- "endPosition": "2079",
+ "endPosition": "2115",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "2075"
+ "startPosition": "2111"
},
- "endPosition": "2080",
+ "endPosition": "2116",
"kind": "RETURN",
- "startPosition": "2068"
+ "startPosition": "2104"
}
],
- "startPosition": "2058"
+ "startPosition": "2094"
}
},
{
- "endPosition": "2133",
+ "endPosition": "2169",
"kind": "VARIABLE",
"name": "obj",
- "startPosition": "2096",
+ "startPosition": "2132",
"initializer": {
- "endPosition": "2133",
+ "endPosition": "2169",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "bindProperties",
"expression": {
- "endPosition": "2108",
+ "endPosition": "2144",
"kind": "IDENTIFIER",
"name": "Object",
- "startPosition": "2102"
+ "startPosition": "2138"
},
- "endPosition": "2123",
+ "endPosition": "2159",
"kind": "MEMBER_SELECT",
- "startPosition": "2102"
+ "startPosition": "2138"
},
"arguments": [
{
- "endPosition": "2126",
+ "endPosition": "2162",
"kind": "OBJECT_LITERAL",
- "startPosition": "2124",
+ "startPosition": "2160",
"properties": []
},
{
- "endPosition": "2132",
+ "endPosition": "2168",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "2128"
+ "startPosition": "2164"
}
],
- "startPosition": "2102"
+ "startPosition": "2138"
}
},
{
- "endPosition": "2154",
+ "endPosition": "2190",
"kind": "VARIABLE",
"name": "result",
- "startPosition": "2143",
+ "startPosition": "2179",
"initializer": {
- "endPosition": "2154",
+ "endPosition": "2190",
"kind": "OBJECT_LITERAL",
- "startPosition": "2152",
+ "startPosition": "2188",
"properties": []
}
},
{
- "endPosition": "2170",
+ "endPosition": "2206",
"kind": "VARIABLE",
"name": "i",
- "startPosition": "2169"
+ "startPosition": "2205"
},
{
"expression": {
- "endPosition": "2177",
+ "endPosition": "2213",
"kind": "IDENTIFIER",
"name": "obj",
- "startPosition": "2174"
+ "startPosition": "2210"
},
- "endPosition": "2845",
+ "endPosition": "2975",
"kind": "FOR_IN_LOOP",
"forEach": "false",
"variable": {
- "endPosition": "2170",
+ "endPosition": "2206",
"kind": "IDENTIFIER",
"name": "i",
- "startPosition": "2169"
+ "startPosition": "2205"
},
"statement": {
- "endPosition": "2845",
+ "endPosition": "2975",
"kind": "BLOCK",
"statements": [
{
- "endPosition": "2204",
+ "endPosition": "2241",
"kind": "VARIABLE",
"name": "val",
- "startPosition": "2192",
+ "startPosition": "2229",
"initializer": {
"expression": {
- "endPosition": "2201",
+ "endPosition": "2238",
"kind": "IDENTIFIER",
"name": "obj",
- "startPosition": "2198"
+ "startPosition": "2235"
},
- "endPosition": "2204",
+ "endPosition": "2241",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2203",
+ "endPosition": "2240",
"kind": "IDENTIFIER",
"name": "i",
- "startPosition": "2202"
+ "startPosition": "2239"
},
- "startPosition": "2198"
+ "startPosition": "2235"
}
},
{
"condition": {
"leftOperand": {
- "endPosition": "2220",
+ "endPosition": "2258",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2217"
+ "startPosition": "2255"
},
"expression": {
- "endPosition": "2220",
+ "endPosition": "2258",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2217"
+ "startPosition": "2255"
},
- "endPosition": "2243",
+ "endPosition": "2281",
"kind": "INSTANCE_OF",
"rightOperand": {
"identifier": "Tree",
"expression": {
- "endPosition": "2238",
+ "endPosition": "2276",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "2232"
+ "startPosition": "2270"
},
- "endPosition": "2243",
+ "endPosition": "2281",
"kind": "MEMBER_SELECT",
- "startPosition": "2232"
+ "startPosition": "2270"
},
"type": {
"identifier": "Tree",
"expression": {
- "endPosition": "2238",
+ "endPosition": "2276",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "2232"
+ "startPosition": "2270"
},
- "endPosition": "2243",
+ "endPosition": "2281",
"kind": "MEMBER_SELECT",
- "startPosition": "2232"
+ "startPosition": "2270"
},
- "startPosition": "2217"
+ "startPosition": "2255"
},
"elseStatement": {
"condition": {
"leftOperand": {
- "endPosition": "2309",
+ "endPosition": "2350",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2306"
+ "startPosition": "2347"
},
"expression": {
- "endPosition": "2309",
+ "endPosition": "2350",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2306"
+ "startPosition": "2347"
},
- "endPosition": "2332",
+ "endPosition": "2373",
"kind": "INSTANCE_OF",
"rightOperand": {
"identifier": "List",
"expression": {
- "endPosition": "2327",
+ "endPosition": "2368",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "2321"
+ "startPosition": "2362"
},
- "endPosition": "2332",
+ "endPosition": "2373",
"kind": "MEMBER_SELECT",
- "startPosition": "2321"
+ "startPosition": "2362"
},
"type": {
"identifier": "List",
"expression": {
- "endPosition": "2327",
+ "endPosition": "2368",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "2321"
+ "startPosition": "2362"
},
- "endPosition": "2332",
+ "endPosition": "2373",
"kind": "MEMBER_SELECT",
- "startPosition": "2321"
+ "startPosition": "2362"
},
- "startPosition": "2306"
+ "startPosition": "2347"
},
"elseStatement": {
- "endPosition": "2840",
+ "endPosition": "2969",
"kind": "BLOCK",
"statements": [
{
"cases": [
{
"expression": {
- "endPosition": "2574",
+ "endPosition": "2625",
"kind": "STRING_LITERAL",
"value": "number",
- "startPosition": "2568"
+ "startPosition": "2619"
},
- "endPosition": "2576",
+ "endPosition": "2627",
"kind": "CASE",
"statements": [],
- "startPosition": "2562"
+ "startPosition": "2613"
},
{
"expression": {
- "endPosition": "2603",
+ "endPosition": "2656",
"kind": "STRING_LITERAL",
"value": "string",
- "startPosition": "2597"
+ "startPosition": "2650"
},
- "endPosition": "2605",
+ "endPosition": "2658",
"kind": "CASE",
"statements": [],
- "startPosition": "2591"
+ "startPosition": "2644"
},
{
"expression": {
- "endPosition": "2633",
+ "endPosition": "2688",
"kind": "STRING_LITERAL",
"value": "boolean",
- "startPosition": "2626"
+ "startPosition": "2681"
},
- "endPosition": "2678",
+ "endPosition": "2762",
"kind": "CASE",
"statements": [
{
"expression": {
"expression": {
- "endPosition": "2677",
+ "endPosition": "2734",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "2672",
+ "endPosition": "2729",
"kind": "IDENTIFIER",
"name": "String",
- "startPosition": "2666"
+ "startPosition": "2723"
},
"arguments": [
{
- "endPosition": "2676",
+ "endPosition": "2733",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2673"
+ "startPosition": "2730"
}
],
- "startPosition": "2666"
+ "startPosition": "2723"
},
- "endPosition": "2677",
+ "endPosition": "2734",
"kind": "ASSIGNMENT",
"variable": {
"expression": {
- "endPosition": "2660",
+ "endPosition": "2717",
"kind": "IDENTIFIER",
"name": "result",
- "startPosition": "2654"
+ "startPosition": "2711"
},
- "endPosition": "2663",
+ "endPosition": "2720",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2662",
+ "endPosition": "2719",
"kind": "IDENTIFIER",
"name": "i",
- "startPosition": "2661"
+ "startPosition": "2718"
},
- "startPosition": "2654"
+ "startPosition": "2711"
},
- "startPosition": "2654"
+ "startPosition": "2711"
},
- "endPosition": "2677",
+ "endPosition": "2734",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "2654"
+ "startPosition": "2711"
+ },
+ {
+ "endPosition": "2762",
+ "kind": "BREAK",
+ "startPosition": "2756"
}
],
- "startPosition": "2620"
+ "startPosition": "2675"
},
{
- "endPosition": "2820",
+ "endPosition": "2945",
"kind": "CASE",
"statements": [
{
"condition": {
"leftOperand": {
- "endPosition": "2727",
- "kind": "IDENTIFIER",
- "name": "val",
- "startPosition": "2724"
- },
- "expression": {
- "endPosition": "2727",
- "kind": "IDENTIFIER",
- "name": "val",
- "startPosition": "2724"
- },
- "endPosition": "2750",
- "kind": "INSTANCE_OF",
- "rightOperand": {
- "identifier": "Enum",
+ "leftOperand": {
+ "endPosition": "2815",
+ "kind": "IDENTIFIER",
+ "name": "val",
+ "startPosition": "2812"
+ },
"expression": {
- "endPosition": "2745",
+ "endPosition": "2815",
"kind": "IDENTIFIER",
- "name": "Parser",
- "startPosition": "2739"
+ "name": "val",
+ "startPosition": "2812"
+ },
+ "endPosition": "2841",
+ "kind": "INSTANCE_OF",
+ "rightOperand": {
+ "identifier": "Long",
+ "expression": {
+ "identifier": "lang",
+ "expression": {
+ "endPosition": "2831",
+ "kind": "IDENTIFIER",
+ "name": "java",
+ "startPosition": "2827"
+ },
+ "endPosition": "2836",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2827"
+ },
+ "endPosition": "2841",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2827"
+ },
+ "type": {
+ "identifier": "Long",
+ "expression": {
+ "identifier": "lang",
+ "expression": {
+ "endPosition": "2831",
+ "kind": "IDENTIFIER",
+ "name": "java",
+ "startPosition": "2827"
+ },
+ "endPosition": "2836",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2827"
+ },
+ "endPosition": "2841",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2827"
},
- "endPosition": "2750",
- "kind": "MEMBER_SELECT",
- "startPosition": "2739"
+ "startPosition": "2812"
},
- "type": {
- "identifier": "Enum",
+ "endPosition": "2871",
+ "kind": "CONDITIONAL_OR",
+ "rightOperand": {
+ "leftOperand": {
+ "endPosition": "2848",
+ "kind": "IDENTIFIER",
+ "name": "val",
+ "startPosition": "2845"
+ },
"expression": {
- "endPosition": "2745",
+ "endPosition": "2848",
"kind": "IDENTIFIER",
- "name": "Parser",
- "startPosition": "2739"
+ "name": "val",
+ "startPosition": "2845"
},
- "endPosition": "2750",
- "kind": "MEMBER_SELECT",
- "startPosition": "2739"
+ "endPosition": "2871",
+ "kind": "INSTANCE_OF",
+ "rightOperand": {
+ "identifier": "Enum",
+ "expression": {
+ "endPosition": "2866",
+ "kind": "IDENTIFIER",
+ "name": "Parser",
+ "startPosition": "2860"
+ },
+ "endPosition": "2871",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2860"
+ },
+ "type": {
+ "identifier": "Enum",
+ "expression": {
+ "endPosition": "2866",
+ "kind": "IDENTIFIER",
+ "name": "Parser",
+ "startPosition": "2860"
+ },
+ "endPosition": "2871",
+ "kind": "MEMBER_SELECT",
+ "startPosition": "2860"
+ },
+ "startPosition": "2845"
},
- "startPosition": "2724"
+ "startPosition": "2812"
},
- "endPosition": "2820",
+ "endPosition": "2945",
"kind": "IF",
- "startPosition": "2720",
+ "startPosition": "2808",
"thenStatement": {
- "endPosition": "2820",
+ "endPosition": "2945",
"kind": "BLOCK",
"statements": [
{
"expression": {
"expression": {
- "endPosition": "2799",
+ "endPosition": "2922",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "2794",
+ "endPosition": "2917",
"kind": "IDENTIFIER",
"name": "String",
- "startPosition": "2788"
+ "startPosition": "2911"
},
"arguments": [
{
- "endPosition": "2798",
+ "endPosition": "2921",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2795"
+ "startPosition": "2918"
}
],
- "startPosition": "2788"
+ "startPosition": "2911"
},
- "endPosition": "2799",
+ "endPosition": "2922",
"kind": "ASSIGNMENT",
"variable": {
"expression": {
- "endPosition": "2782",
+ "endPosition": "2905",
"kind": "IDENTIFIER",
"name": "result",
- "startPosition": "2776"
+ "startPosition": "2899"
},
- "endPosition": "2785",
+ "endPosition": "2908",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2784",
+ "endPosition": "2907",
"kind": "IDENTIFIER",
"name": "i",
- "startPosition": "2783"
+ "startPosition": "2906"
},
- "startPosition": "2776"
+ "startPosition": "2899"
},
- "startPosition": "2776"
+ "startPosition": "2899"
},
- "endPosition": "2799",
+ "endPosition": "2922",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "2776"
+ "startPosition": "2899"
}
],
- "startPosition": "2752"
+ "startPosition": "2873"
}
}
],
- "startPosition": "2693"
+ "startPosition": "2779"
}
],
"expression": {
"expression": {
- "endPosition": "2544",
+ "endPosition": "2593",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2541"
+ "startPosition": "2590"
},
- "endPosition": "2544",
+ "endPosition": "2593",
"kind": "TYPEOF",
- "startPosition": "2534"
+ "startPosition": "2583"
},
- "endPosition": "2832",
+ "endPosition": "2959",
"kind": "SWITCH",
- "startPosition": "2526"
+ "startPosition": "2575"
}
],
- "startPosition": "2514"
+ "startPosition": "2561"
},
- "endPosition": "2840",
+ "endPosition": "2969",
"kind": "IF",
- "startPosition": "2302",
+ "startPosition": "2343",
"thenStatement": {
- "endPosition": "2508",
+ "endPosition": "2555",
"kind": "BLOCK",
"statements": [
{
- "endPosition": "2377",
+ "endPosition": "2420",
"kind": "VARIABLE",
"name": "arr",
- "startPosition": "2350",
+ "startPosition": "2393",
"initializer": {
"constructorExpression": {
- "endPosition": "2377",
+ "endPosition": "2420",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "2365",
+ "endPosition": "2408",
"kind": "IDENTIFIER",
"name": "Array",
- "startPosition": "2360"
+ "startPosition": "2403"
},
"arguments": [
{
- "endPosition": "2376",
+ "endPosition": "2419",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "size",
"expression": {
- "endPosition": "2369",
+ "endPosition": "2412",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2366"
+ "startPosition": "2409"
},
- "endPosition": "2374",
+ "endPosition": "2417",
"kind": "MEMBER_SELECT",
- "startPosition": "2366"
+ "startPosition": "2409"
},
"arguments": [],
- "startPosition": "2366"
+ "startPosition": "2409"
}
],
- "startPosition": "2360"
+ "startPosition": "2403"
},
- "endPosition": "2377",
+ "endPosition": "2420",
"kind": "NEW",
- "startPosition": "2356"
+ "startPosition": "2399"
}
},
{
- "endPosition": "2399",
+ "endPosition": "2444",
"kind": "VARIABLE",
"name": "j",
- "startPosition": "2398"
+ "startPosition": "2443"
},
{
"expression": {
- "endPosition": "2406",
+ "endPosition": "2451",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2403"
+ "startPosition": "2448"
},
- "endPosition": "2466",
+ "endPosition": "2515",
"kind": "FOR_IN_LOOP",
"forEach": "false",
"variable": {
- "endPosition": "2399",
+ "endPosition": "2444",
"kind": "IDENTIFIER",
"name": "j",
- "startPosition": "2398"
+ "startPosition": "2443"
},
"statement": {
- "endPosition": "2466",
+ "endPosition": "2515",
"kind": "BLOCK",
"statements": [
{
"expression": {
"expression": {
- "endPosition": "2453",
+ "endPosition": "2500",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "convert",
"expression": {
- "endPosition": "2437",
+ "endPosition": "2484",
"kind": "IDENTIFIER",
"name": "this",
- "startPosition": "2433"
+ "startPosition": "2480"
},
- "endPosition": "2445",
+ "endPosition": "2492",
"kind": "MEMBER_SELECT",
- "startPosition": "2433"
+ "startPosition": "2480"
},
"arguments": [
{
"expression": {
- "endPosition": "2449",
+ "endPosition": "2496",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2446"
+ "startPosition": "2493"
},
- "endPosition": "2452",
+ "endPosition": "2499",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2451",
+ "endPosition": "2498",
"kind": "IDENTIFIER",
"name": "j",
- "startPosition": "2450"
+ "startPosition": "2497"
},
- "startPosition": "2446"
+ "startPosition": "2493"
}
],
- "startPosition": "2433"
+ "startPosition": "2480"
},
- "endPosition": "2453",
+ "endPosition": "2500",
"kind": "ASSIGNMENT",
"variable": {
"expression": {
- "endPosition": "2427",
+ "endPosition": "2474",
"kind": "IDENTIFIER",
"name": "arr",
- "startPosition": "2424"
+ "startPosition": "2471"
},
- "endPosition": "2430",
+ "endPosition": "2477",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2429",
+ "endPosition": "2476",
"kind": "IDENTIFIER",
"name": "j",
- "startPosition": "2428"
+ "startPosition": "2475"
},
- "startPosition": "2424"
+ "startPosition": "2471"
},
- "startPosition": "2424"
+ "startPosition": "2471"
},
- "endPosition": "2453",
+ "endPosition": "2500",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "2424"
+ "startPosition": "2471"
}
],
- "startPosition": "2408"
+ "startPosition": "2453"
},
- "startPosition": "2389"
+ "startPosition": "2434"
},
{
"expression": {
"expression": {
- "endPosition": "2499",
+ "endPosition": "2544",
"kind": "IDENTIFIER",
"name": "arr",
- "startPosition": "2496"
+ "startPosition": "2541"
},
- "endPosition": "2499",
+ "endPosition": "2544",
"kind": "ASSIGNMENT",
"variable": {
"expression": {
- "endPosition": "2490",
+ "endPosition": "2535",
"kind": "IDENTIFIER",
"name": "result",
- "startPosition": "2484"
+ "startPosition": "2529"
},
- "endPosition": "2493",
+ "endPosition": "2538",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2492",
+ "endPosition": "2537",
"kind": "IDENTIFIER",
"name": "i",
- "startPosition": "2491"
+ "startPosition": "2536"
},
- "startPosition": "2484"
+ "startPosition": "2529"
},
- "startPosition": "2484"
+ "startPosition": "2529"
},
- "endPosition": "2499",
+ "endPosition": "2544",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "2484"
+ "startPosition": "2529"
}
],
- "startPosition": "2334"
+ "startPosition": "2375"
}
},
- "endPosition": "2840",
+ "endPosition": "2969",
"kind": "IF",
- "startPosition": "2213",
+ "startPosition": "2251",
"thenStatement": {
- "endPosition": "2296",
+ "endPosition": "2337",
"kind": "BLOCK",
"statements": [
{
"expression": {
"expression": {
- "endPosition": "2286",
+ "endPosition": "2326",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "convert",
"expression": {
- "endPosition": "2273",
+ "endPosition": "2313",
"kind": "IDENTIFIER",
"name": "this",
- "startPosition": "2269"
+ "startPosition": "2309"
},
- "endPosition": "2281",
+ "endPosition": "2321",
"kind": "MEMBER_SELECT",
- "startPosition": "2269"
+ "startPosition": "2309"
},
"arguments": [
{
- "endPosition": "2285",
+ "endPosition": "2325",
"kind": "IDENTIFIER",
"name": "val",
- "startPosition": "2282"
+ "startPosition": "2322"
}
],
- "startPosition": "2269"
+ "startPosition": "2309"
},
- "endPosition": "2286",
+ "endPosition": "2326",
"kind": "ASSIGNMENT",
"variable": {
"expression": {
- "endPosition": "2263",
+ "endPosition": "2303",
"kind": "IDENTIFIER",
"name": "result",
- "startPosition": "2257"
+ "startPosition": "2297"
},
- "endPosition": "2266",
+ "endPosition": "2306",
"kind": "ARRAY_ACCESS",
"index": {
- "endPosition": "2265",
+ "endPosition": "2305",
"kind": "IDENTIFIER",
"name": "i",
- "startPosition": "2264"
+ "startPosition": "2304"
},
- "startPosition": "2257"
+ "startPosition": "2297"
},
- "startPosition": "2257"
+ "startPosition": "2297"
},
- "endPosition": "2286",
+ "endPosition": "2326",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "2257"
+ "startPosition": "2297"
}
],
- "startPosition": "2245"
+ "startPosition": "2283"
}
}
],
- "startPosition": "2179"
+ "startPosition": "2215"
},
- "startPosition": "2160"
+ "startPosition": "2196"
},
{
"expression": {
- "endPosition": "2862",
+ "endPosition": "2993",
"kind": "IDENTIFIER",
"name": "result",
- "startPosition": "2856"
+ "startPosition": "2987"
},
- "endPosition": "2863",
+ "endPosition": "2994",
"kind": "RETURN",
- "startPosition": "2849"
+ "startPosition": "2980"
}
],
- "startPosition": "2014"
+ "startPosition": "2016"
},
"strict": "false",
- "startPosition": "2014",
+ "startPosition": "2016",
"parameters": [
{
- "endPosition": "2012",
+ "endPosition": "2014",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "2008"
+ "startPosition": "2010"
}
]
},
- "endPosition": "2014",
+ "endPosition": "2016",
"kind": "ASSIGNMENT",
"variable": {
"identifier": "convert",
"expression": {
"identifier": "prototype",
"expression": {
- "endPosition": "1978",
+ "endPosition": "1980",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "1972"
+ "startPosition": "1974"
},
- "endPosition": "1988",
+ "endPosition": "1990",
"kind": "MEMBER_SELECT",
- "startPosition": "1972"
+ "startPosition": "1974"
},
- "endPosition": "1996",
+ "endPosition": "1998",
"kind": "MEMBER_SELECT",
- "startPosition": "1972"
- },
- "startPosition": "1972"
- },
- "endPosition": "2865",
+ "startPosition": "1974"
+ },
+ "startPosition": "1974"
+ },
+ "endPosition": "2996",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "1972"
- },
- {
- "endPosition": "3618",
+ "startPosition": "1974"
+ },
+ {
+ "endPosition": "3767",
"kind": "FUNCTION",
"name": "processFiles",
"body": {
- "endPosition": "3575",
+ "endPosition": "3724",
"kind": "BLOCK",
"statements": [
{
- "endPosition": "2938",
+ "endPosition": "3070",
"kind": "VARIABLE",
"name": "File",
- "startPosition": "2906",
+ "startPosition": "3038",
"initializer": {
- "endPosition": "2938",
+ "endPosition": "3070",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "type",
"expression": {
- "endPosition": "2917",
+ "endPosition": "3049",
"kind": "IDENTIFIER",
"name": "Java",
- "startPosition": "2913"
+ "startPosition": "3045"
},
- "endPosition": "2922",
+ "endPosition": "3054",
"kind": "MEMBER_SELECT",
- "startPosition": "2913"
+ "startPosition": "3045"
},
"arguments": [
{
- "endPosition": "2936",
+ "endPosition": "3068",
"kind": "STRING_LITERAL",
"value": "java.io.File",
- "startPosition": "2924"
+ "startPosition": "3056"
}
],
- "startPosition": "2913"
+ "startPosition": "3045"
}
},
{
- "endPosition": "2993",
+ "endPosition": "3126",
"kind": "VARIABLE",
"name": "files",
- "startPosition": "2947",
+ "startPosition": "3080",
"initializer": {
- "endPosition": "2993",
+ "endPosition": "3126",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "listFiles",
"expression": {
"constructorExpression": {
- "endPosition": "2981",
+ "endPosition": "3114",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "2963",
+ "endPosition": "3096",
"kind": "IDENTIFIER",
"name": "File",
- "startPosition": "2959"
+ "startPosition": "3092"
},
"arguments": [
{
"leftOperand": {
- "endPosition": "2971",
+ "endPosition": "3104",
"kind": "IDENTIFIER",
"name": "__DIR__",
- "startPosition": "2964"
+ "startPosition": "3097"
},
- "endPosition": "2980",
+ "endPosition": "3113",
"kind": "PLUS",
"rightOperand": {
- "endPosition": "2980",
+ "endPosition": "3113",
"kind": "IDENTIFIER",
"name": "subdir",
- "startPosition": "2974"
+ "startPosition": "3107"
},
- "startPosition": "2964"
+ "startPosition": "3097"
}
],
- "startPosition": "2959"
+ "startPosition": "3092"
},
- "endPosition": "2981",
+ "endPosition": "3114",
"kind": "NEW",
- "startPosition": "2955"
+ "startPosition": "3088"
},
- "endPosition": "2991",
+ "endPosition": "3124",
"kind": "MEMBER_SELECT",
- "startPosition": "2955"
+ "startPosition": "3088"
},
"arguments": [],
- "startPosition": "2955"
+ "startPosition": "3088"
}
},
{
"expression": {
- "endPosition": "3026",
+ "endPosition": "3160",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "sort",
@@ -6291,751 +6412,751 @@
"expression": {
"identifier": "util",
"expression": {
- "endPosition": "3002",
+ "endPosition": "3136",
"kind": "IDENTIFIER",
"name": "java",
- "startPosition": "2998"
+ "startPosition": "3132"
},
- "endPosition": "3007",
+ "endPosition": "3141",
"kind": "MEMBER_SELECT",
- "startPosition": "2998"
+ "startPosition": "3132"
},
- "endPosition": "3014",
+ "endPosition": "3148",
"kind": "MEMBER_SELECT",
- "startPosition": "2998"
+ "startPosition": "3132"
},
- "endPosition": "3019",
+ "endPosition": "3153",
"kind": "MEMBER_SELECT",
- "startPosition": "2998"
+ "startPosition": "3132"
},
"arguments": [
{
- "endPosition": "3025",
+ "endPosition": "3159",
"kind": "IDENTIFIER",
"name": "files",
- "startPosition": "3020"
+ "startPosition": "3154"
}
],
- "startPosition": "2998"
+ "startPosition": "3132"
},
- "endPosition": "3026",
+ "endPosition": "3160",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "2998"
+ "startPosition": "3132"
},
{
- "endPosition": "3049",
+ "endPosition": "3184",
"kind": "VARIABLE",
"name": "file",
- "startPosition": "3045"
+ "startPosition": "3180"
},
{
"expression": {
- "endPosition": "3058",
+ "endPosition": "3193",
"kind": "IDENTIFIER",
"name": "files",
- "startPosition": "3053"
+ "startPosition": "3188"
},
- "endPosition": "3575",
+ "endPosition": "3724",
"kind": "FOR_IN_LOOP",
"forEach": "true",
"variable": {
- "endPosition": "3049",
+ "endPosition": "3184",
"kind": "IDENTIFIER",
"name": "file",
- "startPosition": "3045"
+ "startPosition": "3180"
},
"statement": {
- "endPosition": "3575",
+ "endPosition": "3724",
"kind": "BLOCK",
"statements": [
{
"condition": {
- "endPosition": "3098",
+ "endPosition": "3234",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "endsWith",
"expression": {
"identifier": "name",
"expression": {
- "endPosition": "3077",
+ "endPosition": "3213",
"kind": "IDENTIFIER",
"name": "file",
- "startPosition": "3073"
+ "startPosition": "3209"
},
- "endPosition": "3082",
+ "endPosition": "3218",
"kind": "MEMBER_SELECT",
- "startPosition": "3073"
+ "startPosition": "3209"
},
- "endPosition": "3091",
+ "endPosition": "3227",
"kind": "MEMBER_SELECT",
- "startPosition": "3073"
+ "startPosition": "3209"
},
"arguments": [
{
- "endPosition": "3096",
+ "endPosition": "3232",
"kind": "STRING_LITERAL",
"value": ".js",
- "startPosition": "3093"
+ "startPosition": "3229"
}
],
- "startPosition": "3073"
+ "startPosition": "3209"
},
- "endPosition": "3570",
+ "endPosition": "3718",
"kind": "IF",
- "startPosition": "3069",
+ "startPosition": "3205",
"thenStatement": {
- "endPosition": "3570",
+ "endPosition": "3718",
"kind": "BLOCK",
"statements": [
{
- "endPosition": "3141",
+ "endPosition": "3278",
"kind": "VARIABLE",
"name": "script",
- "startPosition": "3117",
+ "startPosition": "3254",
"initializer": {
- "endPosition": "3141",
+ "endPosition": "3278",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3135",
+ "endPosition": "3272",
"kind": "IDENTIFIER",
"name": "readFully",
- "startPosition": "3126"
+ "startPosition": "3263"
},
"arguments": [
{
- "endPosition": "3140",
+ "endPosition": "3277",
"kind": "IDENTIFIER",
"name": "file",
- "startPosition": "3136"
+ "startPosition": "3273"
}
],
- "startPosition": "3126"
+ "startPosition": "3263"
}
},
{
- "endPosition": "3179",
+ "endPosition": "3317",
"kind": "VARIABLE",
"name": "parser",
- "startPosition": "3158",
+ "startPosition": "3296",
"initializer": {
"constructorExpression": {
- "endPosition": "3179",
+ "endPosition": "3317",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3177",
+ "endPosition": "3315",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "3171"
+ "startPosition": "3309"
},
"arguments": [],
- "startPosition": "3171"
+ "startPosition": "3309"
},
- "endPosition": "3179",
+ "endPosition": "3317",
"kind": "NEW",
- "startPosition": "3167"
+ "startPosition": "3305"
}
},
{
- "endPosition": "3435",
+ "endPosition": "3578",
"kind": "VARIABLE",
"name": "tree",
- "startPosition": "3196",
+ "startPosition": "3335",
"initializer": {
- "endPosition": "3435",
+ "endPosition": "3578",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "parse",
"expression": {
- "endPosition": "3209",
+ "endPosition": "3348",
"kind": "IDENTIFIER",
"name": "parser",
- "startPosition": "3203"
+ "startPosition": "3342"
},
- "endPosition": "3215",
+ "endPosition": "3354",
"kind": "MEMBER_SELECT",
- "startPosition": "3203"
+ "startPosition": "3342"
},
"arguments": [
{
"leftOperand": {
"leftOperand": {
- "endPosition": "3222",
+ "endPosition": "3361",
"kind": "IDENTIFIER",
"name": "subdir",
- "startPosition": "3216"
+ "startPosition": "3355"
},
- "endPosition": "3227",
+ "endPosition": "3366",
"kind": "PLUS",
"rightOperand": {
- "endPosition": "3227",
+ "endPosition": "3366",
"kind": "STRING_LITERAL",
"value": "/",
- "startPosition": "3226"
+ "startPosition": "3365"
},
- "startPosition": "3216"
+ "startPosition": "3355"
},
- "endPosition": "3240",
+ "endPosition": "3379",
"kind": "PLUS",
"rightOperand": {
"identifier": "name",
"expression": {
- "endPosition": "3235",
+ "endPosition": "3374",
"kind": "IDENTIFIER",
"name": "file",
- "startPosition": "3231"
+ "startPosition": "3370"
},
- "endPosition": "3240",
+ "endPosition": "3379",
"kind": "MEMBER_SELECT",
- "startPosition": "3231"
+ "startPosition": "3370"
},
- "startPosition": "3216"
+ "startPosition": "3355"
},
{
- "endPosition": "3248",
+ "endPosition": "3387",
"kind": "IDENTIFIER",
"name": "script",
- "startPosition": "3242"
+ "startPosition": "3381"
},
{
- "endPosition": "3286",
+ "endPosition": "3426",
"kind": "FUNCTION_EXPRESSION",
"body": {
- "endPosition": "3417",
+ "endPosition": "3559",
"kind": "BLOCK",
"statements": [
{
"expression": {
- "endPosition": "3385",
+ "endPosition": "3526",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3312",
+ "endPosition": "3453",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3307"
+ "startPosition": "3448"
},
"arguments": [
{
- "endPosition": "3384",
+ "endPosition": "3525",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "replace",
"expression": {
- "endPosition": "3364",
+ "endPosition": "3505",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "stringify",
"expression": {
- "endPosition": "3317",
+ "endPosition": "3458",
"kind": "IDENTIFIER",
"name": "JSON",
- "startPosition": "3313"
+ "startPosition": "3454"
},
- "endPosition": "3327",
+ "endPosition": "3468",
"kind": "MEMBER_SELECT",
- "startPosition": "3313"
+ "startPosition": "3454"
},
"arguments": [
{
- "endPosition": "3354",
+ "endPosition": "3495",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "convert",
"expression": {
- "endPosition": "3334",
+ "endPosition": "3475",
"kind": "IDENTIFIER",
"name": "parser",
- "startPosition": "3328"
+ "startPosition": "3469"
},
- "endPosition": "3342",
+ "endPosition": "3483",
"kind": "MEMBER_SELECT",
- "startPosition": "3328"
+ "startPosition": "3469"
},
"arguments": [
{
- "endPosition": "3353",
+ "endPosition": "3494",
"kind": "IDENTIFIER",
"name": "diagnostic",
- "startPosition": "3343"
+ "startPosition": "3484"
}
],
- "startPosition": "3328"
+ "startPosition": "3469"
},
{
- "endPosition": "3360",
+ "endPosition": "3501",
"kind": "NULL_LITERAL",
- "startPosition": "3356"
+ "startPosition": "3497"
},
{
- "endPosition": "3363",
+ "endPosition": "3504",
"kind": "NUMBER_LITERAL",
"value": "2",
- "startPosition": "3362"
+ "startPosition": "3503"
}
],
- "startPosition": "3313"
+ "startPosition": "3454"
},
- "endPosition": "3372",
+ "endPosition": "3513",
"kind": "MEMBER_SELECT",
- "startPosition": "3313"
+ "startPosition": "3454"
},
"arguments": [
{
- "endPosition": "3379",
+ "endPosition": "3520",
"kind": "REGEXP_LITERAL",
"options": "g",
"pattern": "\\\\r",
- "startPosition": "3373"
+ "startPosition": "3514"
},
{
- "endPosition": "3382",
+ "endPosition": "3523",
"kind": "STRING_LITERAL",
"value": "",
- "startPosition": "3382"
+ "startPosition": "3523"
}
],
- "startPosition": "3372"
+ "startPosition": "3513"
}
],
- "startPosition": "3307"
+ "startPosition": "3448"
},
- "endPosition": "3385",
+ "endPosition": "3526",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3307"
+ "startPosition": "3448"
},
{
"expression": {
- "endPosition": "3416",
+ "endPosition": "3558",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3411",
+ "endPosition": "3553",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3406"
+ "startPosition": "3548"
},
"arguments": [
{
- "endPosition": "3414",
+ "endPosition": "3556",
"kind": "STRING_LITERAL",
"value": ",",
- "startPosition": "3413"
+ "startPosition": "3555"
}
],
- "startPosition": "3406"
+ "startPosition": "3548"
},
- "endPosition": "3416",
+ "endPosition": "3558",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3406"
+ "startPosition": "3548"
}
],
- "startPosition": "3286"
+ "startPosition": "3426"
},
"strict": "false",
- "startPosition": "3286",
+ "startPosition": "3426",
"parameters": [
{
- "endPosition": "3284",
+ "endPosition": "3424",
"kind": "IDENTIFIER",
"name": "diagnostic",
- "startPosition": "3274"
+ "startPosition": "3414"
}
]
}
],
- "startPosition": "3203"
+ "startPosition": "3342"
}
},
{
"condition": {
"leftOperand": {
- "endPosition": "3457",
+ "endPosition": "3601",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "3453"
+ "startPosition": "3597"
},
- "endPosition": "3465",
+ "endPosition": "3609",
"kind": "NOT_EQUAL_TO",
"rightOperand": {
- "endPosition": "3465",
+ "endPosition": "3609",
"kind": "NULL_LITERAL",
- "startPosition": "3461"
+ "startPosition": "3605"
},
- "startPosition": "3453"
+ "startPosition": "3597"
},
- "endPosition": "3561",
+ "endPosition": "3708",
"kind": "IF",
- "startPosition": "3449",
+ "startPosition": "3593",
"thenStatement": {
- "endPosition": "3561",
+ "endPosition": "3708",
"kind": "BLOCK",
"statements": [
{
"expression": {
- "endPosition": "3520",
+ "endPosition": "3665",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3489",
+ "endPosition": "3634",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3484"
+ "startPosition": "3629"
},
"arguments": [
{
- "endPosition": "3519",
+ "endPosition": "3664",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "stringify",
"expression": {
- "endPosition": "3494",
+ "endPosition": "3639",
"kind": "IDENTIFIER",
"name": "JSON",
- "startPosition": "3490"
+ "startPosition": "3635"
},
- "endPosition": "3504",
+ "endPosition": "3649",
"kind": "MEMBER_SELECT",
- "startPosition": "3490"
+ "startPosition": "3635"
},
"arguments": [
{
- "endPosition": "3509",
+ "endPosition": "3654",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "3505"
+ "startPosition": "3650"
},
{
- "endPosition": "3515",
+ "endPosition": "3660",
"kind": "NULL_LITERAL",
- "startPosition": "3511"
+ "startPosition": "3656"
},
{
- "endPosition": "3518",
+ "endPosition": "3663",
"kind": "NUMBER_LITERAL",
"value": "2",
- "startPosition": "3517"
+ "startPosition": "3662"
}
],
- "startPosition": "3490"
+ "startPosition": "3635"
}
],
- "startPosition": "3484"
+ "startPosition": "3629"
},
- "endPosition": "3520",
+ "endPosition": "3665",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3484"
+ "startPosition": "3629"
},
{
"expression": {
- "endPosition": "3547",
+ "endPosition": "3693",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3542",
+ "endPosition": "3688",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3537"
+ "startPosition": "3683"
},
"arguments": [
{
- "endPosition": "3545",
+ "endPosition": "3691",
"kind": "STRING_LITERAL",
"value": ",",
- "startPosition": "3544"
+ "startPosition": "3690"
}
],
- "startPosition": "3537"
+ "startPosition": "3683"
},
- "endPosition": "3547",
+ "endPosition": "3693",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3537"
+ "startPosition": "3683"
}
],
- "startPosition": "3467"
+ "startPosition": "3611"
}
}
],
- "startPosition": "3100"
+ "startPosition": "3236"
}
}
],
- "startPosition": "3060"
+ "startPosition": "3195"
},
- "startPosition": "3031"
+ "startPosition": "3166"
}
],
- "startPosition": "2897"
+ "startPosition": "3028"
},
"strict": "false",
- "startPosition": "2867",
+ "startPosition": "2998",
"parameters": [
{
- "endPosition": "2895",
+ "endPosition": "3026",
"kind": "IDENTIFIER",
"name": "subdir",
- "startPosition": "2889"
+ "startPosition": "3020"
}
]
},
{
- "endPosition": "3921",
+ "endPosition": "4070",
"kind": "FUNCTION",
"name": "main",
"body": {
- "endPosition": "3919",
+ "endPosition": "4068",
"kind": "BLOCK",
"statements": [
{
"expression": {
- "endPosition": "3651",
+ "endPosition": "3800",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3646",
+ "endPosition": "3795",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3641"
+ "startPosition": "3790"
},
"arguments": [
{
- "endPosition": "3649",
+ "endPosition": "3798",
"kind": "STRING_LITERAL",
"value": "[",
- "startPosition": "3648"
+ "startPosition": "3797"
}
],
- "startPosition": "3641"
+ "startPosition": "3790"
},
- "endPosition": "3651",
+ "endPosition": "3800",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3641"
+ "startPosition": "3790"
},
{
"expression": {
- "endPosition": "3685",
+ "endPosition": "3834",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3670",
+ "endPosition": "3819",
"kind": "IDENTIFIER",
"name": "processFiles",
- "startPosition": "3658"
+ "startPosition": "3807"
},
"arguments": [
{
- "endPosition": "3683",
+ "endPosition": "3832",
"kind": "STRING_LITERAL",
"value": "parsertests",
- "startPosition": "3672"
+ "startPosition": "3821"
}
],
- "startPosition": "3658"
+ "startPosition": "3807"
},
- "endPosition": "3685",
+ "endPosition": "3834",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3658"
+ "startPosition": "3807"
},
{
"expression": {
- "endPosition": "3726",
+ "endPosition": "3875",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3703",
+ "endPosition": "3852",
"kind": "IDENTIFIER",
"name": "processFiles",
- "startPosition": "3691"
+ "startPosition": "3840"
},
"arguments": [
{
- "endPosition": "3724",
+ "endPosition": "3873",
"kind": "STRING_LITERAL",
"value": "parsernegativetests",
- "startPosition": "3705"
+ "startPosition": "3854"
}
],
- "startPosition": "3691"
+ "startPosition": "3840"
},
- "endPosition": "3726",
+ "endPosition": "3875",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3691"
+ "startPosition": "3840"
},
{
- "endPosition": "3795",
+ "endPosition": "3944",
"kind": "VARIABLE",
"name": "script",
- "startPosition": "3767",
+ "startPosition": "3916",
"initializer": {
- "endPosition": "3795",
+ "endPosition": "3944",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3785",
+ "endPosition": "3934",
"kind": "IDENTIFIER",
"name": "readFully",
- "startPosition": "3776"
+ "startPosition": "3925"
},
"arguments": [
{
- "endPosition": "3794",
+ "endPosition": "3943",
"kind": "IDENTIFIER",
"name": "__FILE__",
- "startPosition": "3786"
+ "startPosition": "3935"
}
],
- "startPosition": "3776"
+ "startPosition": "3925"
}
},
{
- "endPosition": "3860",
+ "endPosition": "4009",
"kind": "VARIABLE",
"name": "tree",
- "startPosition": "3805",
+ "startPosition": "3954",
"initializer": {
- "endPosition": "3860",
+ "endPosition": "4009",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "parse",
"expression": {
"constructorExpression": {
- "endPosition": "3824",
+ "endPosition": "3973",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3822",
+ "endPosition": "3971",
"kind": "IDENTIFIER",
"name": "Parser",
- "startPosition": "3816"
+ "startPosition": "3965"
},
"arguments": [],
- "startPosition": "3816"
+ "startPosition": "3965"
},
- "endPosition": "3824",
+ "endPosition": "3973",
"kind": "NEW",
- "startPosition": "3812"
+ "startPosition": "3961"
},
- "endPosition": "3830",
+ "endPosition": "3979",
"kind": "MEMBER_SELECT",
- "startPosition": "3812"
+ "startPosition": "3961"
},
"arguments": [
{
- "endPosition": "3844",
+ "endPosition": "3993",
"kind": "STRING_LITERAL",
"value": "parserapi.js",
- "startPosition": "3832"
+ "startPosition": "3981"
},
{
- "endPosition": "3853",
+ "endPosition": "4002",
"kind": "IDENTIFIER",
"name": "script",
- "startPosition": "3847"
+ "startPosition": "3996"
},
{
- "endPosition": "3859",
+ "endPosition": "4008",
"kind": "NULL_LITERAL",
- "startPosition": "3855"
+ "startPosition": "4004"
}
],
- "startPosition": "3812"
+ "startPosition": "3961"
}
},
{
"expression": {
- "endPosition": "3902",
+ "endPosition": "4051",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3871",
+ "endPosition": "4020",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3866"
+ "startPosition": "4015"
},
"arguments": [
{
- "endPosition": "3901",
+ "endPosition": "4050",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
"identifier": "stringify",
"expression": {
- "endPosition": "3876",
+ "endPosition": "4025",
"kind": "IDENTIFIER",
"name": "JSON",
- "startPosition": "3872"
+ "startPosition": "4021"
},
- "endPosition": "3886",
+ "endPosition": "4035",
"kind": "MEMBER_SELECT",
- "startPosition": "3872"
+ "startPosition": "4021"
},
"arguments": [
{
- "endPosition": "3891",
+ "endPosition": "4040",
"kind": "IDENTIFIER",
"name": "tree",
- "startPosition": "3887"
+ "startPosition": "4036"
},
{
- "endPosition": "3897",
+ "endPosition": "4046",
"kind": "NULL_LITERAL",
- "startPosition": "3893"
+ "startPosition": "4042"
},
{
- "endPosition": "3900",
+ "endPosition": "4049",
"kind": "NUMBER_LITERAL",
"value": "2",
- "startPosition": "3899"
+ "startPosition": "4048"
}
],
- "startPosition": "3872"
+ "startPosition": "4021"
}
],
- "startPosition": "3866"
+ "startPosition": "4015"
},
- "endPosition": "3902",
+ "endPosition": "4051",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3866"
+ "startPosition": "4015"
},
{
"expression": {
- "endPosition": "3918",
+ "endPosition": "4067",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3913",
+ "endPosition": "4062",
"kind": "IDENTIFIER",
"name": "print",
- "startPosition": "3908"
+ "startPosition": "4057"
},
"arguments": [
{
- "endPosition": "3916",
+ "endPosition": "4065",
"kind": "STRING_LITERAL",
"value": "]",
- "startPosition": "3915"
+ "startPosition": "4064"
}
],
- "startPosition": "3908"
+ "startPosition": "4057"
},
- "endPosition": "3918",
+ "endPosition": "4067",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3908"
+ "startPosition": "4057"
}
],
- "startPosition": "3635"
+ "startPosition": "3784"
},
"strict": "false",
- "startPosition": "3619",
+ "startPosition": "3768",
"parameters": []
},
{
"expression": {
- "endPosition": "3929",
+ "endPosition": "4078",
"kind": "FUNCTION_INVOCATION",
"functionSelect": {
- "endPosition": "3927",
+ "endPosition": "4076",
"kind": "IDENTIFIER",
"name": "main",
- "startPosition": "3923"
+ "startPosition": "4072"
},
"arguments": [],
- "startPosition": "3923"
- },
- "endPosition": "3929",
+ "startPosition": "4072"
+ },
+ "endPosition": "4078",
"kind": "EXPRESSION_STATEMENT",
- "startPosition": "3923"
+ "startPosition": "4072"
}
],
"sourceName": "parserapi.js",
"strict": "false",
"startPosition": "1136"
-}
-]
+}
+]
--- a/nashorn/test/script/nosecurity/treeapi/for.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/for.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
@@ -47,4 +47,4 @@
visitForLoop : function (node, obj) {
obj.push(convert(node))
}
-})))
\ No newline at end of file
+})))
--- a/nashorn/test/script/nosecurity/treeapi/forin.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/forin.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
@@ -45,4 +45,4 @@
visitForInLoop : function (node, obj) {
obj.push(convert(node))
}
-})))
\ No newline at end of file
+})))
--- a/nashorn/test/script/nosecurity/treeapi/functionCall.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/functionCall.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
@@ -51,4 +51,4 @@
visitFunctionCall : function (node, obj) {
obj.push(convert(node))
}
-})))
\ No newline at end of file
+})))
--- a/nashorn/test/script/nosecurity/treeapi/functionDeclaration.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/functionDeclaration.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
--- a/nashorn/test/script/nosecurity/treeapi/functionExpr.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/functionExpr.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
--- a/nashorn/test/script/nosecurity/treeapi/identifier.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/identifier.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
--- a/nashorn/test/script/nosecurity/treeapi/if.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/if.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
--- a/nashorn/test/script/nosecurity/treeapi/instanceof.js Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/script/nosecurity/treeapi/instanceof.js Sat Jan 16 00:28:28 2016 +0000
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2014, Or1cle 1nd/or its 1ffili1tes. 1ll rights reserved.
- * DO NOT 1LTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HE1DER.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * This code is free softw1re; you c1n redistri2ute it 1nd/or modify it
- * under the terms of the GNU Gener1l Pu2lic License version 2 only, 1s
- * pu2lished 2y the Free Softw1re Found1tion.
+ * 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 distri2uted in the hope th1t it will 2e useful, 2ut WITHOUT
- * 1NY W1RR1NTY; without even the implied w1rr1nty of MERCH1NT12ILITY or
- * FITNESS FOR 1 P1RTICUL1R PURPOSE. See the GNU Gener1l Pu2lic License
- * version 2 for more det1ils (1 copy is included in the LICENSE file th1t
- * 1ccomp1nied 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 h1ve received 1 copy of the GNU Gener1l Pu2lic License version
- * 2 1long with this work; if not, write to the Free Softw1re Found1tion,
- * Inc., 51 Fr1nklin St, Fifth Floor, 2oston, M1 02110-1301 US1.
+ * 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.
*
- * Ple1se cont1ct Or1cle, 500 Or1cle P1rkw1y, Redwood Shores, C1 94065 US1
- * or visit www.or1cle.com if you need 1ddition1l inform1tion or h1ve 1ny
+ * 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.
*/
--- a/nashorn/test/src/jdk/dynalink/beans/test/BeanLinkerTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/src/jdk/dynalink/beans/test/BeanLinkerTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -24,7 +24,17 @@
*/
package jdk.dynalink.beans.test;
+import static jdk.dynalink.StandardOperation.CALL;
+import static jdk.dynalink.StandardOperation.CALL_METHOD;
+import static jdk.dynalink.StandardOperation.GET_ELEMENT;
+import static jdk.dynalink.StandardOperation.GET_LENGTH;
+import static jdk.dynalink.StandardOperation.GET_METHOD;
+import static jdk.dynalink.StandardOperation.GET_PROPERTY;
+import static jdk.dynalink.StandardOperation.NEW;
+import static jdk.dynalink.StandardOperation.SET_ELEMENT;
+
import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.security.AccessControlException;
@@ -38,7 +48,6 @@
import jdk.dynalink.NamedOperation;
import jdk.dynalink.NoSuchDynamicMethodException;
import jdk.dynalink.Operation;
-import jdk.dynalink.StandardOperation;
import jdk.dynalink.beans.BeansLinker;
import jdk.dynalink.beans.StaticClass;
import jdk.dynalink.support.SimpleRelinkableCallSite;
@@ -72,9 +81,80 @@
return createCallSite(publicLookup, new NamedOperation(op, name), mt);
}
+ private static final MethodHandle throwArrayIndexOutOfBounds = findThrower("throwArrayIndexOutOfBounds");
+ private static final MethodHandle throwIndexOutOfBounds = findThrower("throwIndexOutOfBounds");
+
+ private static final MethodHandle findThrower(final String name) {
+ try {
+ return MethodHandles.lookup().findStatic(BeanLinkerTest.class, name,
+ MethodType.methodType(Object.class, Object.class, Object.class));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ Assert.fail("Unexpected exception", e);
+ return null;
+ }
+ }
+
+ private static Object throwArrayIndexOutOfBounds(final Object receiver, final Object index) {
+ throw new ArrayIndexOutOfBoundsException(String.valueOf(index));
+ }
+
+ private static Object throwIndexOutOfBounds(final Object receiver, final Object index) {
+ throw new IndexOutOfBoundsException(String.valueOf(index));
+ }
+
@BeforeTest
public void initLinker() {
final DynamicLinkerFactory factory = new DynamicLinkerFactory();
+ factory.setFallbackLinkers(new BeansLinker((req, services) -> {
+ // This is a MissingMemberHandlerFactory that creates a missing
+ // member handler for element getters and setters that throw an
+ // ArrayIndexOutOfBoundsException when applied to an array and an
+ // IndexOutOfBoundsException when applied to a list.
+
+ final CallSiteDescriptor desc = req.getCallSiteDescriptor();
+ final Operation op = desc.getOperation();
+ final Operation baseOp = NamedOperation.getBaseOperation(op);
+ if (baseOp != GET_ELEMENT && baseOp != SET_ELEMENT) {
+ // We only handle GET_ELEMENT and SET_ELEMENT.
+ return null;
+ }
+
+ final Object receiver = req.getReceiver();
+ Assert.assertNotNull(receiver);
+
+ final Class<?> clazz = receiver.getClass();
+ final MethodHandle throwerHandle;
+ if (clazz.isArray()) {
+ throwerHandle = throwArrayIndexOutOfBounds;
+ } else if (List.class.isAssignableFrom(clazz)) {
+ throwerHandle = throwIndexOutOfBounds;
+ } else {
+ Assert.fail("Unexpected receiver type " + clazz.getName());
+ return null;
+ }
+
+ final Object name = NamedOperation.getName(op);
+ final MethodHandle nameBoundHandle;
+ if (name == null) {
+ nameBoundHandle = throwerHandle;
+ } else {
+ // If the operation is for a fixed index, bind it
+ nameBoundHandle = MethodHandles.insertArguments(throwerHandle, 1, name);
+ }
+
+ final MethodType callSiteType = desc.getMethodType();
+ final MethodHandle arityMatchedHandle;
+ if (baseOp == SET_ELEMENT) {
+ // Drop "value" parameter for a setter
+ final int handleArity = nameBoundHandle.type().parameterCount();
+ arityMatchedHandle = MethodHandles.dropArguments(nameBoundHandle,
+ handleArity, callSiteType.parameterType(handleArity));
+ } else {
+ arityMatchedHandle = nameBoundHandle;
+ }
+
+ return arityMatchedHandle.asType(callSiteType);
+ }));
this.linker = factory.createLinker();
}
@@ -86,7 +166,7 @@
@Test(dataProvider = "flags")
public void getPropertyTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_PROPERTY, mt);
+ final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, mt);
Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class);
Assert.assertEquals(cs.getTarget().invoke(new Date(), "class"), Date.class);
}
@@ -94,14 +174,14 @@
@Test(dataProvider = "flags")
public void getPropertyNegativeTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_PROPERTY, mt);
+ final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, mt);
Assert.assertNull(cs.getTarget().invoke(new Object(), "DOES_NOT_EXIST"));
}
@Test(dataProvider = "flags")
public void getPropertyTest2(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_PROPERTY, "class", mt);
+ final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, "class", mt);
Assert.assertEquals(cs.getTarget().invoke(new Object()), Object.class);
Assert.assertEquals(cs.getTarget().invoke(new Date()), Date.class);
}
@@ -109,12 +189,12 @@
@Test(dataProvider = "flags")
public void getPropertyNegativeTest2(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_PROPERTY, "DOES_NOT_EXIST", mt);
+ final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, "DOES_NOT_EXIST", mt);
try {
cs.getTarget().invoke(new Object());
throw new RuntimeException("Expected NoSuchDynamicMethodException");
- } catch (Throwable th) {
+ } catch (final Throwable th) {
Assert.assertTrue(th instanceof NoSuchDynamicMethodException);
}
}
@@ -122,7 +202,7 @@
@Test(dataProvider = "flags")
public void getLengthPropertyTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(int.class, Object.class, String.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_PROPERTY, mt);
+ final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, mt);
Assert.assertEquals((int) cs.getTarget().invoke(new int[10], "length"), 10);
Assert.assertEquals((int) cs.getTarget().invoke(new String[33], "length"), 33);
@@ -131,7 +211,7 @@
@Test(dataProvider = "flags")
public void getlengthTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(int.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_LENGTH, mt);
+ final CallSite cs = createCallSite(publicLookup, GET_LENGTH, mt);
final int[] arr = {23, 42};
Assert.assertEquals((int) cs.getTarget().invoke((Object) arr), 2);
@@ -151,21 +231,21 @@
@Test(dataProvider = "flags")
public void getElementTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(int.class, Object.class, int.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_ELEMENT, mt);
+ final CallSite cs = createCallSite(publicLookup, GET_ELEMENT, mt);
final int[] arr = {23, 42};
Assert.assertEquals((int) cs.getTarget().invoke(arr, 0), 23);
Assert.assertEquals((int) cs.getTarget().invoke(arr, 1), 42);
try {
- int x = (int) cs.getTarget().invoke(arr, -1);
+ final int x = (int) cs.getTarget().invoke(arr, -1);
throw new RuntimeException("expected ArrayIndexOutOfBoundsException");
- } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (final ArrayIndexOutOfBoundsException ex) {
}
try {
- int x = (int) cs.getTarget().invoke(arr, arr.length);
+ final int x = (int) cs.getTarget().invoke(arr, arr.length);
throw new RuntimeException("expected ArrayIndexOutOfBoundsException");
- } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (final ArrayIndexOutOfBoundsException ex) {
}
final List<Integer> list = new ArrayList<>();
@@ -176,22 +256,22 @@
Assert.assertEquals((int) cs.getTarget().invoke(list, 1), (int) list.get(1));
Assert.assertEquals((int) cs.getTarget().invoke(list, 2), (int) list.get(2));
try {
- int x = (int) cs.getTarget().invoke(list, -1);
+ final int x = (int) cs.getTarget().invoke(list, -1);
throw new RuntimeException("expected IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException ex) {
+ } catch (final IndexOutOfBoundsException ex) {
}
try {
- int x = (int) cs.getTarget().invoke(list, list.size());
+ final int x = (int) cs.getTarget().invoke(list, list.size());
throw new RuntimeException("expected IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException ex) {
+ } catch (final IndexOutOfBoundsException ex) {
}
}
@Test(dataProvider = "flags")
public void setElementTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(void.class, Object.class, int.class, int.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.SET_ELEMENT, mt);
+ final CallSite cs = createCallSite(publicLookup, SET_ELEMENT, mt);
final int[] arr = {23, 42};
cs.getTarget().invoke(arr, 0, 0);
@@ -202,13 +282,13 @@
try {
cs.getTarget().invoke(arr, -1, 12);
throw new RuntimeException("expected ArrayIndexOutOfBoundsException");
- } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (final ArrayIndexOutOfBoundsException ex) {
}
try {
cs.getTarget().invoke(arr, arr.length, 20);
throw new RuntimeException("expected ArrayIndexOutOfBoundsException");
- } catch (ArrayIndexOutOfBoundsException ex) {
+ } catch (final ArrayIndexOutOfBoundsException ex) {
}
final List<Integer> list = new ArrayList<>();
@@ -223,25 +303,25 @@
try {
cs.getTarget().invoke(list, -1, 343);
throw new RuntimeException("expected IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException ex) {
+ } catch (final IndexOutOfBoundsException ex) {
}
try {
cs.getTarget().invoke(list, list.size(), 43543);
throw new RuntimeException("expected IndexOutOfBoundsException");
- } catch (IndexOutOfBoundsException ex) {
+ } catch (final IndexOutOfBoundsException ex) {
}
}
@Test(dataProvider = "flags")
public void newObjectTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.NEW, mt);
+ final CallSite cs = createCallSite(publicLookup, NEW, mt);
Object obj = null;
try {
obj = cs.getTarget().invoke(StaticClass.forClass(Date.class));
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -251,12 +331,12 @@
@Test(dataProvider = "flags")
public void staticPropertyTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(Object.class, Class.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_PROPERTY, "static", mt);
+ final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, "static", mt);
Object obj = null;
try {
obj = cs.getTarget().invoke(Object.class);
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -265,7 +345,7 @@
try {
obj = cs.getTarget().invoke(Date.class);
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -274,7 +354,7 @@
try {
obj = cs.getTarget().invoke(Object[].class);
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -285,14 +365,14 @@
@Test(dataProvider = "flags")
public void instanceMethodCallTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_METHOD, "getClass", mt);
+ final CallSite cs = createCallSite(publicLookup, GET_METHOD, "getClass", mt);
final MethodType mt2 = MethodType.methodType(Class.class, Object.class, Object.class);
- final CallSite cs2 = createCallSite(publicLookup, StandardOperation.CALL, mt2);
+ final CallSite cs2 = createCallSite(publicLookup, CALL, mt2);
Object method = null;
try {
method = cs.getTarget().invoke(new Date());
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -301,7 +381,7 @@
Class clz = null;
try {
clz = (Class) cs2.getTarget().invoke(method, new Date());
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -311,11 +391,11 @@
@Test(dataProvider = "flags")
public void instanceMethodCallTest2(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(Class.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.CALL_METHOD, "getClass", mt);
+ final CallSite cs = createCallSite(publicLookup, CALL_METHOD, "getClass", mt);
Class clz = null;
try {
clz = (Class) cs.getTarget().invoke(new Date());
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -325,14 +405,14 @@
@Test(dataProvider = "flags")
public void staticMethodCallTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(Object.class, StaticClass.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.GET_METHOD, "getProperty", mt);
+ final CallSite cs = createCallSite(publicLookup, GET_METHOD, "getProperty", mt);
final MethodType mt2 = MethodType.methodType(String.class, Object.class, Object.class, String.class);
- final CallSite cs2 = createCallSite(publicLookup, StandardOperation.CALL, mt2);
+ final CallSite cs2 = createCallSite(publicLookup, CALL, mt2);
Object method = null;
try {
method = cs.getTarget().invoke(StaticClass.forClass(System.class));
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
@@ -342,7 +422,7 @@
String str = null;
try {
str = (String) cs2.getTarget().invoke(method, null, "os.name");
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
Assert.assertEquals(str, System.getProperty("os.name"));
@@ -351,12 +431,12 @@
@Test(dataProvider = "flags")
public void staticMethodCallTest2(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(String.class, Object.class, String.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.CALL_METHOD, "getProperty", mt);
+ final CallSite cs = createCallSite(publicLookup, CALL_METHOD, "getProperty", mt);
String str = null;
try {
str = (String) cs.getTarget().invoke(StaticClass.forClass(System.class), "os.name");
- } catch (Throwable th) {
+ } catch (final Throwable th) {
throw new RuntimeException(th);
}
Assert.assertEquals(str, System.getProperty("os.name"));
@@ -366,12 +446,12 @@
@Test(dataProvider = "flags")
public void systemGetenvTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.CALL_METHOD, "getenv", mt);
+ final CallSite cs = createCallSite(publicLookup, CALL_METHOD, "getenv", mt);
try {
cs.getTarget().invoke(StaticClass.forClass(System.class));
throw new RuntimeException("should not reach here in any case!");
- } catch (Throwable th) {
+ } catch (final Throwable th) {
Assert.assertTrue(th instanceof SecurityException);
}
}
@@ -380,12 +460,12 @@
@Test(dataProvider = "flags")
public void systemGetPropertyTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(String.class, Object.class, String.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.CALL_METHOD, "getProperty", mt);
+ final CallSite cs = createCallSite(publicLookup, CALL_METHOD, "getProperty", mt);
try {
cs.getTarget().invoke(StaticClass.forClass(System.class), "java.home");
throw new RuntimeException("should not reach here in any case!");
- } catch (Throwable th) {
+ } catch (final Throwable th) {
Assert.assertTrue(th instanceof SecurityException);
}
}
@@ -394,12 +474,12 @@
@Test(dataProvider = "flags")
public void systemLoadLibraryTest(final boolean publicLookup) {
final MethodType mt = MethodType.methodType(void.class, Object.class, String.class);
- final CallSite cs = createCallSite(publicLookup, StandardOperation.CALL_METHOD, "loadLibrary", mt);
+ final CallSite cs = createCallSite(publicLookup, CALL_METHOD, "loadLibrary", mt);
try {
cs.getTarget().invoke(StaticClass.forClass(System.class), "foo");
throw new RuntimeException("should not reach here in any case!");
- } catch (Throwable th) {
+ } catch (final Throwable th) {
if (publicLookup) {
Assert.assertTrue(th instanceof IllegalAccessError);
} else {
--- a/nashorn/test/src/jdk/dynalink/beans/test/BeansLinkerTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/src/jdk/dynalink/beans/test/BeansLinkerTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -33,6 +33,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -44,6 +45,7 @@
import jdk.dynalink.CompositeOperation;
import jdk.dynalink.DynamicLinkerFactory;
import jdk.dynalink.NamedOperation;
+import jdk.dynalink.NoSuchDynamicMethodException;
import jdk.dynalink.Operation;
import jdk.dynalink.StandardOperation;
import jdk.dynalink.support.SimpleRelinkableCallSite;
@@ -207,6 +209,30 @@
Assert.assertEquals("element2", map.get("name"));
}
+ @Test
+ public static void testMissingMembersAtLinkTime() {
+ testPermutations(GETTER_PERMUTATIONS, (op) -> expectNoSuchDynamicMethodException(()-> call(named("foo", op), new Object())));
+ testPermutations(SETTER_PERMUTATIONS, (op) -> expectNoSuchDynamicMethodException(()-> call(named("foo", op), new Object(), "newValue")));
+ }
+
+ @Test
+ public static void testMissingMembersAtRunTime() {
+ call(GET_ELEMENT, new ArrayList<>(), "foo");
+ Stream.of(new HashMap(), new ArrayList(), new Object[0]).forEach((receiver) -> {
+ testPermutations(GETTER_PERMUTATIONS, (op) -> { System.err.println(op + " " + receiver.getClass().getName()); Assert.assertNull(call(op, receiver, "foo"));});
+ // No assertion for the setter; we just expect it to silently succeed
+ testPermutations(SETTER_PERMUTATIONS, (op) -> call(op, receiver, "foo", "newValue"));
+ });
+ }
+
+ private static void expectNoSuchDynamicMethodException(final Runnable r) {
+ try {
+ r.run();
+ Assert.fail("Should've thrown NoSuchDynamicMethodException");
+ } catch(final NoSuchDynamicMethodException e) {
+ }
+ }
+
private static Operation[] GETTER_PERMUTATIONS = new Operation[] {
GET_PROPERTY,
GET_METHOD,
@@ -240,6 +266,10 @@
testPermutationsWithFilter(ops, (op)->regex.matcher(op.toString()).matches(), expectedCount, test);
}
+ private static void testPermutations(final Operation[] ops, final Consumer<Operation> test) {
+ testPermutationsWithFilter(ops, (op)->true, ops.length, test);
+ }
+
private static void testPermutationsWithFilter(final Operation[] ops, final Predicate<Operation> filter, final int expectedCount, final Consumer<Operation> test) {
final int[] counter = new int[1];
Stream.of(ops).filter(filter).forEach((op)-> { counter[0]++; test.accept(op); });
--- a/nashorn/test/src/jdk/dynalink/beans/test/CallerSensitiveTest.java Fri Jan 15 23:38:25 2016 +0000
+++ b/nashorn/test/src/jdk/dynalink/beans/test/CallerSensitiveTest.java Sat Jan 16 00:28:28 2016 +0000
@@ -33,6 +33,6 @@
public class CallerSensitiveTest {
@Test
public void testCallerSensitive() {
- BeansLinker.getLinkerForClass(ClassLoaderAware.class);
+ new BeansLinker().getLinkerForClass(ClassLoaderAware.class);
}
}
--- a/nashorn/test/src/jdk/internal/dynalink/beans/test/CallerSensitiveTest.java Fri Jan 15 23:38:25 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2014, 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.internal.dynalink.beans.test;
-
-import jdk.dynalink.beans.BeansLinker;
-import jdk.nashorn.test.models.ClassLoaderAware;
-import org.testng.annotations.Test;
-
-@SuppressWarnings("javadoc")
-public class CallerSensitiveTest {
- @Test
- public void testCallerSensitive() {
- BeansLinker.getLinkerForClass(ClassLoaderAware.class);
- }
-}
--- a/test/make/TestJavaCompilation.gmk Fri Jan 15 23:38:25 2016 +0000
+++ b/test/make/TestJavaCompilation.gmk Sat Jan 16 00:28:28 2016 +0000
@@ -239,6 +239,7 @@
$(eval $(call SetupJavaCompiler,BOOT_JAVAC, \
JAVAC := $(JAVAC), \
+ DISABLE_SJAVAC := true, \
))
JAVA_SRC_ROOT1 := $(OUTPUT_DIR)/javaroot1