This commit is contained in:
J. Duke 2017-07-05 21:12:50 +02:00
commit 8d15b19e9d
139 changed files with 4941 additions and 2730 deletions

View File

@ -343,3 +343,4 @@ cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
48987460c7d49a29013963ee44d090194396bb61 jdk-9+98
7c0577bea4c65d69c5bef67023a89d2efa4fb2f7 jdk-9+99
c1f30ac14db0eaff398429c04cd9fab92e1b4b2a jdk-9+100
c4d72a1620835b5d657b7b6792c2879367d0154f jdk-9+101

View File

@ -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

View File

@ -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-"

View File

@ -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

View File

@ -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

View File

@ -343,3 +343,4 @@ feb1bd85d7990dcf5584ca9e53104269c01db006 jdk-9+96
ea285530245cf4e0edf0479121a41347d3030eba jdk-9+98
180212ee1d8710691ba9944593dfc1ff3e4f1532 jdk-9+99
791d0d3ac0138faeb6110bd840a4545bc1950df2 jdk-9+100
30dfb3bd3d06b4bb80a087babc0d1841edba187b jdk-9+101

View File

@ -503,3 +503,4 @@ de592ea5f7ba0f8a8c5afc03bd169f7690c72b6f jdk-9+97
e5b1a23be1e105417ba1c4c576ab373eb3fa2c2b jdk-9+98
f008e8cc10d5b3212fb22d58c96fa01d38654f19 jdk-9+99
bdb0acafc63c42e84d9d8195bf2e2b25ee9c3306 jdk-9+100
9f45d3d57d6948cf526fbc2e2891a9a74ac6941a jdk-9+101

View File

@ -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) },

View File

@ -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
*/

View File

@ -343,3 +343,4 @@ fdd84b2265ddce7f50e084b7c8635189bba6f012 jdk-9+97
f86ee68d1107dad41a27efc34306e0e56244a12e jdk-9+98
e1a789be1535741274c9779f4d4ca3495196b5c3 jdk-9+99
3d452840f48299a36842760d17c0c8402f0e1266 jdk-9+100
5e8370fb3ed925335164afe340d1e54beab2d4d5 jdk-9+101

View File

@ -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)))

View File

@ -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) {

View File

@ -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();

View File

@ -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) {

View File

@ -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);

View File

@ -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.

View File

@ -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");

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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.
*/

View File

@ -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);
}

View File

@ -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;
}
}
/**

View File

@ -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();
}
/**

View File

@ -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;
});
}
}
}

View File

@ -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

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.misc;
package jdk.internal.perf;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

View File

@ -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;
}
}

View File

@ -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;
});
}
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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";

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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();

View File

@ -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.
*/

View File

@ -54,4 +54,7 @@ extern jlong Counter2Micros(jlong counts);
int UnsetEnv(char *name);
jboolean
GetApplicationHomeFromDll(char *buf, jint bufsize);
#endif /* JAVA_MD_H */

View File

@ -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;
/**

View File

@ -25,7 +25,7 @@
package sun.misc;
package sun.awt.util;
import java.util.Vector;
import java.io.FileWriter;

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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
*/

View File

@ -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>
*

View File

@ -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&trade; 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;

View File

@ -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&trade; 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>

View File

@ -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.
*/
}

View File

@ -25,7 +25,6 @@
package sun.jvmstat.perfdata.monitor;
import sun.misc.Perf;
import sun.jvmstat.monitor.*;
import java.util.*;
import java.io.*;

View File

@ -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.*;

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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";
};

View 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);
}
}

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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()");
}
}

View File

@ -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();
}
}

View 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");
}
}
}

View File

@ -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();
}

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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.");
}
}
}
}

View File

@ -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;

View File

@ -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) {

View 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");
}
}
}

View File

@ -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");
}
}
/*

View File

@ -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);

View File

@ -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;

View File

@ -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};

View File

@ -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");
}

View File

@ -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!

View File

@ -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>

View File

@ -334,3 +334,4 @@ d52c09d5d98a81ee6102a25f662ec4b9ae614163 jdk-9+96
68a36216f70c0de4c7e36f8978995934fc72ec03 jdk-9+98
74ddd1339c57cf2c2a13e34e1760006c2e54d1fc jdk-9+99
da397aea8adad7e6f743b60bfe0c415fc8508df5 jdk-9+100
1916a2c680d8c33b59943dbb6dc2dd2000ec821a jdk-9+101

View File

@ -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")

View File

@ -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());
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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());

View File

@ -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")

View File

@ -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();
}
/**

View File

@ -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")

View File

@ -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) {

View File

@ -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;

View File

@ -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")

View File

@ -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