Merge
This commit is contained in:
commit
8d15b19e9d
@ -343,3 +343,4 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
|
||||
48987460c7d49a29013963ee44d090194396bb61 jdk-9+98
|
||||
7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99
|
||||
c1f30ac14db0eaff398429c04cd9fab92e1b4b2a jdk-9+100
|
||||
c4d72a1620835b5d657b7b6792c2879367d0154f jdk-9+101
|
||||
|
@ -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 @@ AC_DEFUN_ONCE([BASIC_POST_CONFIG_OUTPUT],
|
||||
|
||||
# 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
|
||||
|
||||
|
@ -425,7 +425,7 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_OPTIMIZATION],
|
||||
# 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 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
|
||||
-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_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
|
||||
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 @@ AC_DEFUN([FLAGS_COMPILER_CHECK_ARGUMENTS],
|
||||
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_DEFUN([FLAGS_COMPILER_CHECK_ARGUMENTS],
|
||||
|
||||
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_DEFUN([FLAGS_LINKER_CHECK_ARGUMENTS],
|
||||
|
||||
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 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
|
||||
*)
|
||||
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 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
|
||||
;;
|
||||
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 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
|
||||
# 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-"
|
||||
|
@ -3451,6 +3451,31 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
|
||||
# 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 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
|
||||
|
||||
|
||||
|
||||
# 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 @@ VS_SDK_PLATFORM_NAME_2013=
|
||||
#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 @@ $as_echo "$as_me: Rewriting BUILD_AR to \"$new_complete\"" >&6;}
|
||||
# "-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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $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 @@ $as_echo "$ac_cv_c_bigendian" >&6; }
|
||||
# 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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
$as_echo "$supports" >&6; }
|
||||
if test "x$supports" = "xyes" ; then
|
||||
:
|
||||
|
||||
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 @@ $as_echo "$supports" >&6; }
|
||||
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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
$as_echo "$supports" >&6; }
|
||||
if test "x$supports" = "xyes" ; then
|
||||
:
|
||||
|
||||
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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $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 @@ $as_echo "yes (default)" >&6; }
|
||||
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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $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 @@ $as_echo "$supports" >&6; }
|
||||
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 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $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 @@ fi
|
||||
|
||||
# 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
|
||||
|
||||
|
@ -75,8 +75,8 @@ AC_DEFUN([TOOLCHAIN_SETUP_FILENAME_PATTERNS],
|
||||
# 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 @@ AC_DEFUN_ONCE([TOOLCHAIN_MISC_CHECKS],
|
||||
|
||||
# "-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
|
||||
|
@ -343,3 +343,4 @@ feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
|
||||
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
|
||||
180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
|
||||
791d0d3ac0138faeb6110bd840a4545bc1950df2 jdk-9+100
|
||||
30dfb3bd3d06b4bb80a087babc0d1841edba187b jdk-9+101
|
||||
|
@ -503,3 +503,4 @@ de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
|
||||
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
|
||||
f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
|
||||
bdb0acafc63c42e84d9d8195bf2e2b25ee9c3306 jdk-9+100
|
||||
9f45d3d57d6948cf526fbc2e2891a9a74ac6941a jdk-9+101
|
||||
|
@ -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
|
||||
@ -124,7 +124,7 @@ static JNINativeMethod lookup_special_native_methods[] = {
|
||||
{ CC"Java_jdk_internal_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
|
||||
{ CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
|
||||
{ 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) },
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
||||
|
@ -343,3 +343,4 @@ fdd84b2265ddce7f50e084b7c8635189bba6f012 jdk-9+97
|
||||
f86ee68d1107dad41a27efc34306e0e56244a12e jdk-9+98
|
||||
e1a789be1535741274c9779f4d4ca3495196b5c3 jdk-9+99
|
||||
3d452840f48299a36842760d17c0c8402f0e1266 jdk-9+100
|
||||
5e8370fb3ed925335164afe340d1e54beab2d4d5 jdk-9+101
|
||||
|
@ -48,7 +48,6 @@ BREAK_ITERATOR_CLASSES := $(BUILDTOOLS_OUTPUTDIR)/break_iterator_classes
|
||||
$(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := $(TEXT_SRCDIR), \
|
||||
INCLUDES := $(TEXT_PKG), \
|
||||
INCLUDE_FILES := $(TEXT_SOURCES), \
|
||||
BIN := $(BREAK_ITERATOR_CLASSES)))
|
||||
|
||||
|
@ -50,6 +50,8 @@ import java.util.Vector;
|
||||
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 @@ public abstract class ClassLoader {
|
||||
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) {
|
||||
|
@ -61,6 +61,9 @@ interface LiveStackFrame extends StackFrame {
|
||||
* 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();
|
||||
|
@ -1535,6 +1535,8 @@ public final class System {
|
||||
* @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 @@ public final class System {
|
||||
* 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) {
|
||||
|
@ -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 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
|
||||
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);
|
||||
|
@ -28,7 +28,7 @@ package java.lang.ref;
|
||||
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.
|
||||
|
@ -376,19 +376,23 @@ public abstract class SocketImpl implements SocketOptions {
|
||||
* @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 @@ public abstract class SocketImpl implements SocketOptions {
|
||||
*/
|
||||
@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");
|
||||
|
@ -1146,13 +1146,30 @@ public final class URI
|
||||
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 @@ public final class URI
|
||||
//
|
||||
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 @@ public final class URI
|
||||
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);
|
||||
|
@ -52,6 +52,7 @@ import java.util.jar.Manifest;
|
||||
|
||||
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 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ package java.security;
|
||||
|
||||
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 @@ public class ProtectionDomain {
|
||||
*
|
||||
* 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 @@ public class ProtectionDomain {
|
||||
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 @@ public class ProtectionDomain {
|
||||
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.
|
||||
*/
|
||||
|
@ -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 @@ public final class LocalDate
|
||||
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);
|
||||
}
|
||||
|
@ -3144,6 +3144,18 @@ public final class Locale implements Cloneable, Serializable {
|
||||
&& 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,6 +54,7 @@ import java.util.stream.Stream;
|
||||
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 @@ class ZipFile implements ZipConstants, Closeable {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -22,13 +22,14 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.misc;
|
||||
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
|
||||
@ -46,7 +47,7 @@ import java.io.UnsupportedEncodingException;
|
||||
* @author Brian Doherty
|
||||
* @since 1.4.2
|
||||
* @see #getPerf
|
||||
* @see sun.misc.Perf$GetPerfAction
|
||||
* @see jdk.internal.perf.Perf.GetPerfAction
|
||||
* @see java.nio.ByteBuffer
|
||||
*/
|
||||
public final class Perf {
|
||||
@ -123,10 +124,10 @@ public final class Perf {
|
||||
* 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.
|
||||
* @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
|
||||
*/
|
||||
@ -134,7 +135,7 @@ public final class Perf {
|
||||
{
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
Permission perm = new RuntimePermission("sun.misc.Perf.getPerf");
|
||||
Permission perm = new RuntimePermission("jdk.internal.perf.Perf.getPerf");
|
||||
security.checkPermission(perm);
|
||||
}
|
||||
|
||||
@ -277,27 +278,35 @@ public final class Perf {
|
||||
// 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.
|
||||
// with a Cleaner. When the duplicate becomes phantom 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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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>
|
||||
@ -341,7 +350,7 @@ public final class Perf {
|
||||
* 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
|
||||
* @param bb A direct allocated byte buffer created by the
|
||||
* <code>attach</code> method.
|
||||
* @see java.nio.ByteBuffer
|
||||
* @see #attach
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.misc;
|
||||
package jdk.internal.perf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
@ -23,16 +23,26 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.internal.dynalink.beans.test;
|
||||
package jdk.internal.ref;
|
||||
|
||||
import jdk.dynalink.beans.BeansLinker;
|
||||
import jdk.nashorn.test.models.ClassLoaderAware;
|
||||
import org.testng.annotations.Test;
|
||||
import java.lang.ref.Cleaner;
|
||||
|
||||
@SuppressWarnings("javadoc")
|
||||
public class CallerSensitiveTest {
|
||||
@Test
|
||||
public void testCallerSensitive() {
|
||||
BeansLinker.getLinkerForClass(ClassLoaderAware.class);
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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 @@ public class HttpClient extends NetworkClient {
|
||||
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;
|
||||
|
@ -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 @@ public class URLJarFile extends JarFile {
|
||||
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.
|
||||
|
@ -2211,7 +2211,7 @@ public final class SSLEngineImpl extends SSLEngine {
|
||||
|
||||
@Override
|
||||
public synchronized String getHandshakeApplicationProtocol() {
|
||||
if ((handshaker != null) && !handshaker.started()) {
|
||||
if ((handshaker != null) && handshaker.started()) {
|
||||
return handshaker.getHandshakeApplicationProtocol();
|
||||
}
|
||||
return null;
|
||||
|
@ -2598,7 +2598,7 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
|
||||
@Override
|
||||
public synchronized String getHandshakeApplicationProtocol() {
|
||||
if ((handshaker != null) && !handshaker.started()) {
|
||||
if ((handshaker != null) && handshaker.started()) {
|
||||
return handshaker.getHandshakeApplicationProtocol();
|
||||
}
|
||||
return null;
|
||||
|
@ -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 @@ final class SignatureAndHashAlgorithm {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,17 +98,6 @@ grant codeBase "jrt:/java.activation" {
|
||||
// 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";
|
||||
|
||||
|
@ -47,6 +47,9 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
||||
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 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
|
||||
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");
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
||||
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 @@ class PlainSocketImpl extends AbstractPlainSocketImpl
|
||||
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");
|
||||
}
|
||||
|
@ -42,8 +42,10 @@ import java.util.concurrent.CompletableFuture;
|
||||
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 @@ final class ProcessImpl extends Process {
|
||||
|
||||
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 @@ final class ProcessImpl extends Process {
|
||||
return stderr_stream;
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
closeHandle(handle);
|
||||
}
|
||||
|
||||
private static final int STILL_ACTIVE = getStillActive();
|
||||
private static native int getStillActive();
|
||||
|
||||
|
@ -337,6 +337,15 @@ GetJREPath(char *path, jint pathsize)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 @@ LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
@ -422,6 +431,36 @@ GetApplicationHome(char *buf, jint bufsize)
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
@ -54,4 +54,7 @@ extern jlong Counter2Micros(jlong counts);
|
||||
|
||||
int UnsetEnv(char *name);
|
||||
|
||||
jboolean
|
||||
GetApplicationHomeFromDll(char *buf, jint bufsize);
|
||||
|
||||
#endif /* JAVA_MD_H */
|
||||
|
@ -43,8 +43,8 @@ import sun.awt.AWTAccessor;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
|
||||
|
||||
package sun.misc;
|
||||
package sun.awt.util;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.io.FileWriter;
|
@ -88,9 +88,9 @@ import java.awt.font.FontRenderContext;
|
||||
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;
|
||||
|
@ -52,6 +52,7 @@ import sun.awt.datatransfer.DataTransferer;
|
||||
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;
|
||||
|
@ -67,10 +67,10 @@ import java.util.Locale;
|
||||
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 {
|
||||
|
@ -38,6 +38,7 @@ import java.awt.event.WindowListener;
|
||||
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 @@ public class D3DGraphicsDevice extends Win32GraphicsDevice {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ import java.util.List;
|
||||
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;
|
||||
|
@ -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;
|
||||
|
@ -31,12 +31,14 @@ import java.util.List;
|
||||
* <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
|
||||
*/
|
||||
|
@ -33,7 +33,8 @@ import java.util.ServiceConfigurationError;
|
||||
* 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 @@ public class ScriptEngineManager {
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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>
|
@ -95,7 +95,7 @@ public abstract class AbstractMonitoredVm implements BufferedMonitoredVm {
|
||||
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.
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package sun.jvmstat.perfdata.monitor;
|
||||
|
||||
import sun.misc.Perf;
|
||||
import sun.jvmstat.monitor.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
@ -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.*;
|
||||
|
@ -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 @@ sun/security/provider/SecureRandom/StrongSecureRandom.java macosx-10.10
|
||||
# 8074580
|
||||
sun/security/pkcs11/rsa/TestKeyPairGenerator.java generic-all
|
||||
|
||||
# 8146387
|
||||
javax/net/ssl/SSLSession/SessionCacheSizeTests.java windows-all,solaris-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_sound
|
||||
|
@ -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 @@ tier1 = \
|
||||
-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 @@ tier1 = \
|
||||
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 @@ jdk_lang = \
|
||||
sun/misc \
|
||||
sun/reflect \
|
||||
jdk/lambda \
|
||||
jdk/internal/jimage \
|
||||
vm
|
||||
|
||||
# All of the java.util package
|
||||
|
@ -86,29 +86,43 @@ public class LocalsAndOperands {
|
||||
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 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2006, 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
|
||||
@ -23,23 +23,28 @@
|
||||
* 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
|
||||
/* @test
|
||||
* @bug 8076596
|
||||
* @run main/othervm/policy=Test8076596.security.policy/secure=Test8076596 -ea -esa Test8076596
|
||||
*/
|
||||
@Deprecated
|
||||
public class JarFilter implements FilenameFilter {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
String lower = name.toLowerCase();
|
||||
return lower.endsWith(".jar") || lower.endsWith(".zip");
|
||||
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
|
||||
}
|
||||
}
|
@ -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";
|
||||
};
|
82
jdk/test/java/lang/invoke/8147078/Test8147078.java
Normal file
82
jdk/test/java/lang/invoke/8147078/Test8147078.java
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
*/
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
|
@ -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.concurrent.TimeUnit;
|
||||
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 @@ import org.testng.annotations.Test;
|
||||
* @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 @@ public class CleanerTest {
|
||||
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()");
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ public class ADatagramSocket {
|
||||
} 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 @@ public class ADatagramSocket {
|
||||
// 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 @@ public class ADatagramSocket {
|
||||
class QuoteServerThread extends Thread {
|
||||
|
||||
protected DatagramSocket socket = null;
|
||||
private final int port;
|
||||
|
||||
public QuoteServerThread() throws IOException {
|
||||
this("QuoteServerThread");
|
||||
@ -74,7 +79,11 @@ class QuoteServerThread extends Thread {
|
||||
|
||||
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 @@ class QuoteServerThread extends Thread {
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
141
jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java
Normal file
141
jdk/test/java/net/SocketOption/UnsupportedOptionsTest.java
Normal file
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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 @@ public class Basic {
|
||||
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();
|
||||
}
|
||||
|
@ -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 @@ public class NonBlockingAccept {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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,13 +1285,37 @@ public class TCKLocalDate extends AbstractDateTimeTest {
|
||||
public void test_plusWeeks_invalidMaxMinusMin() {
|
||||
LocalDate.of(Year.MAX_VALUE, 12, 25).plusWeeks(Long.MIN_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_plusDays_normal() {
|
||||
LocalDate t = TEST_2007_07_15.plusDays(1);
|
||||
assertEquals(t, LocalDate.of(2007, 7, 16));
|
||||
//-----------------------------------------------------------------------
|
||||
@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(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() {
|
||||
LocalDate t = TEST_2007_07_15.plusDays(62);
|
||||
|
@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2011, 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
|
||||
* 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.
|
||||
* 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
|
||||
@ -23,14 +21,25 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.misc;
|
||||
/*
|
||||
* @test
|
||||
* @bug 8026766
|
||||
* @summary Confirm that LanguageRange.toString() returns an expected result.
|
||||
* @run main Bug8026766
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale.LanguageRange;
|
||||
|
||||
public class CEFormatException extends IOException {
|
||||
static final long serialVersionUID = -7139121221067081482L;
|
||||
public CEFormatException(String s) {
|
||||
super(s);
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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 @@ public class UpdateConfigurationTest {
|
||||
+ 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 @@ public class UpdateConfigurationTest {
|
||||
}
|
||||
});
|
||||
|
||||
// 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) {
|
||||
|
130
jdk/test/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java
Normal file
130
jdk/test/javax/net/ssl/ALPN/MyX509ExtendedKeyManager.java
Normal file
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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 @@ public class SSLEngineAlpnTest {
|
||||
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 @@ public class SSLEngineAlpnTest {
|
||||
/*
|
||||
* 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 @@ public class SSLEngineAlpnTest {
|
||||
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 @@ public class SSLEngineAlpnTest {
|
||||
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 @@ public class SSLEngineAlpnTest {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 @@ public class SSLSocketAlpnTest {
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
/*
|
||||
* 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 @@ public class SSLSocketAlpnTest {
|
||||
* 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 @@ public class SSLSocketAlpnTest {
|
||||
*/
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
SSLSocketFactory sslsf
|
||||
= (SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
|
||||
SSLSocket sslSocket
|
||||
= (SSLSocket) sslsf.createSocket("localhost", serverPort);
|
||||
|
||||
@ -185,28 +208,35 @@ public class SSLSocketAlpnTest {
|
||||
*/
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
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 @@ public class SSLSocketAlpnTest {
|
||||
*/
|
||||
SSLSocketAlpnTest() throws Exception {
|
||||
Exception startException = null;
|
||||
mySSLContext = getSSLContext(keyFilename, trustFilename);
|
||||
try {
|
||||
if (separateServerThread) {
|
||||
startServer(true);
|
||||
|
@ -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 @@ public class SessionCacheSizeTests {
|
||||
|
||||
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)) {
|
||||
|
||||
/*
|
||||
* 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();
|
||||
// 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();
|
||||
|
||||
try {
|
||||
while (nConnections < serverConns) {
|
||||
try (SSLSocket sslSocket =
|
||||
(SSLSocket)sslServerSocket.accept()) {
|
||||
@ -143,8 +150,6 @@ public class SessionCacheSizeTests {
|
||||
nConnections++;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
sslServerSocket.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,8 +275,8 @@ public class SessionCacheSizeTests {
|
||||
* 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;
|
||||
|
@ -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 @@ public class Optimize {
|
||||
|
||||
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};
|
||||
|
@ -313,7 +313,7 @@ public class JImageReadTest {
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -202,23 +202,28 @@ define SetupJavaCompilationBody
|
||||
# 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 @@ define SetupJavaCompilationBody
|
||||
$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 @@ define SetupJavaCompilationBody
|
||||
$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 @@ define SetupJavaCompilationBody
|
||||
# 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!
|
||||
|
@ -238,6 +238,12 @@
|
||||
<to>jdk.management.resource</to>
|
||||
<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>
|
||||
|
@ -334,3 +334,4 @@ d52c09d5d98a81ee6102a25f662ec4b9ae614163 jdk-9+96
|
||||
68a36216f70c0de4c7e36f8978995934fc72ec03 jdk-9+98
|
||||
74ddd1339c57cf2c2a13e34e1760006c2e54d1fc jdk-9+99
|
||||
da397aea8adad7e6f743b60bfe0c415fc8508df5 jdk-9+100
|
||||
1916a2c680d8c33b59943dbb6dc2dd2000ec821a jdk-9+101
|
||||
|
@ -349,55 +349,121 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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;
|
||||
}
|
||||
|
||||
while(!operations.isEmpty()) {
|
||||
final GuardedInvocationComponent gic =
|
||||
getGuardedInvocationComponent(callSiteDescriptor,
|
||||
linkerServices, operations, name);
|
||||
if(gic != null) {
|
||||
return gic.getGuardedInvocation();
|
||||
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);
|
||||
}
|
||||
|
||||
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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
// 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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
// 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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
"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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
// 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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
// 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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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 {
|
||||
// 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);
|
||||
private GuardedInvocationComponent getMethodGetter(final ComponentLinkRequest req) throws Exception {
|
||||
if (req.name == null) {
|
||||
return getUnnamedMethodGetter(req);
|
||||
}
|
||||
|
||||
return getNamedMethodGetter(callSiteDescriptor, linkerServices, ops, name, type);
|
||||
return getNamedMethodGetter(req);
|
||||
}
|
||||
|
||||
private GuardedInvocationComponent getUnnamedMethodGetter(final CallSiteDescriptor callSiteDescriptor,
|
||||
final LinkerServices linkerServices, final List<Operation> ops, final MethodType type) throws Exception {
|
||||
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.
|
||||
return req.getDescriptor().getMethodType().changeReturnType(Object.class);
|
||||
}
|
||||
|
||||
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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
|
||||
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")
|
||||
|
@ -88,6 +88,7 @@ import java.lang.invoke.MethodHandles;
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
}
|
||||
|
||||
@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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
|
||||
// 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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
}
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
}
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
// 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 @@ class BeanLinker extends AbstractJavaLinker implements TypeBasedGuardingDynamicL
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,11 @@ import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||
* 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 @@ public class BeansLinker implements GuardingDynamicLinker {
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ public class BeansLinker implements GuardingDynamicLinker {
|
||||
* @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 @@ public class BeansLinker implements GuardingDynamicLinker {
|
||||
* @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 @@ public class BeansLinker implements GuardingDynamicLinker {
|
||||
* @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 @@ public class BeansLinker implements GuardingDynamicLinker {
|
||||
* @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 @@ public class BeansLinker implements GuardingDynamicLinker {
|
||||
// Can't operate on null
|
||||
return null;
|
||||
}
|
||||
return getLinkerForClass(receiver.getClass()).getGuardedInvocation(request, linkerServices);
|
||||
return getLinkerForClass(receiver.getClass()).getGuardedInvocation(request,
|
||||
LinkerServicesWithMissingMemberHandlerFactory.get(linkerServices,
|
||||
missingMemberHandlerFactory));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -91,6 +91,7 @@ import java.util.Arrays;
|
||||
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;
|
||||
@ -161,6 +162,27 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
|
||||
return null;
|
||||
}
|
||||
|
||||
@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;
|
||||
|
@ -202,6 +202,9 @@ public class GuardedInvocation {
|
||||
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 @@ public class GuardedInvocation {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1133,6 +1133,8 @@ public final class Global extends Scope {
|
||||
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);
|
||||
}
|
||||
|
@ -284,8 +284,8 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
// 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
|
||||
@ -908,21 +908,6 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
return getContinuousNonEmptyArrayDataCCE(self, IntElements.class).fastPopInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 long popLong(final Object self) {
|
||||
//must be non empty Int or LongArrayData
|
||||
return getContinuousNonEmptyArrayDataCCE(self, IntOrLongElements.class).fastPopLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of pop for ContinuousArrayData
|
||||
*
|
||||
@ -997,7 +982,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
||||
* @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());
|
||||
|
@ -168,9 +168,9 @@ public final class NativeBoolean extends ScriptObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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")
|
||||
|
@ -256,8 +256,9 @@ public final class NativeDate extends ScriptObject {
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,6 +48,7 @@ import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
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 @@ public final class NativeNumber extends ScriptObject {
|
||||
* @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")
|
||||
|
@ -776,7 +776,7 @@ public final class NativeObject {
|
||||
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) {
|
||||
|
@ -74,7 +74,7 @@ public final class NativeRegExpExecResult extends ScriptObject {
|
||||
@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;
|
||||
|
@ -146,7 +146,7 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
|
||||
|
||||
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 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
|
||||
* @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")
|
||||
|
@ -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.ScriptObject;
|
||||
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 @@ public final class NativeSymbol extends ScriptObject {
|
||||
|
||||
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 @@ public final class NativeSymbol extends ScriptObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public final class NativeSymbol extends ScriptObject {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user