mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-13 12:38:07 +00:00
Merge
This commit is contained in:
commit
3e132d770d
@ -11,3 +11,5 @@ nbproject/private/
|
||||
test/nashorn/script/external
|
||||
test/nashorn/lib
|
||||
NashornProfile.txt
|
||||
.*/JTreport/.*
|
||||
.*/JTwork/.*
|
||||
|
||||
2
.hgtags
2
.hgtags
@ -462,3 +462,5 @@ bbd692ad4fa300ecca7939ffbe3b1d5e52a28cc6 jdk-10+33
|
||||
d8c634b016c628622c9abbdc6bf50509e5dedbec jdk-10+35
|
||||
0ee20aad71c4f33c426372b4c8bcc1235ce2ec08 jdk-11+0
|
||||
959f2f7cbaa6d2ee45d50029744efb219721576c jdk-10+36
|
||||
4f830b447edf04fb4a52151a5ad44d9bb60723cd jdk-10+37
|
||||
e569e83139fdfbecfeb3cd9014d560917787f158 jdk-10+38
|
||||
|
||||
@ -210,7 +210,6 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
|
||||
jarsigner.1 \
|
||||
javac.1 \
|
||||
javadoc.1 \
|
||||
javah.1 \
|
||||
javap.1 \
|
||||
jconsole.1 \
|
||||
jcmd.1 \
|
||||
|
||||
@ -637,7 +637,7 @@ else
|
||||
# Declare dependencies between hotspot-<variant>* targets
|
||||
$(foreach v, $(JVM_VARIANTS), \
|
||||
$(eval hotspot-$v: hotspot-$v-gensrc hotspot-$v-libs) \
|
||||
$(eval hotspot-$v-libs: hotspot-$v-gensrc) \
|
||||
$(eval hotspot-$v-libs: hotspot-$v-gensrc java.base-copy) \
|
||||
)
|
||||
|
||||
hotspot-ide-project: hotspot exploded-image
|
||||
@ -691,8 +691,9 @@ else
|
||||
jdk.jdwp.agent-libs: jdk.jdwp.agent-gensrc
|
||||
|
||||
# The swing beans need to have java base properly generated to avoid errors
|
||||
# in javadoc.
|
||||
java.desktop-gensrc-src: java.base-gensrc
|
||||
# in javadoc. The X11 wrappers need the java.base include files to have been
|
||||
# copied and processed.
|
||||
java.desktop-gensrc-src: java.base-gensrc java.base-copy
|
||||
|
||||
# The annotation processing for jdk.internal.vm.ci and jdk.internal.vm.compiler
|
||||
# needs classes from the current JDK.
|
||||
|
||||
@ -110,7 +110,6 @@ OPENJDK_BUILD_CPU_ENDIAN := $(OPENJDK_TARGET_CPU_ENDIAN)
|
||||
# Java executable definitions
|
||||
JAVA_CMD := $(BOOT_JDK)/bin/java
|
||||
JAVAC_CMD := $(BOOT_JDK)/bin/javac
|
||||
JAVAH_CMD := $(BOOT_JDK)/bin/javah
|
||||
JAR_CMD := $(BOOT_JDK)/bin/jar
|
||||
JLINK_CMD := $(JDK_OUTPUTDIR)/bin/jlink
|
||||
JMOD_CMD := $(JDK_OUTPUTDIR)/bin/jmod
|
||||
@ -120,7 +119,6 @@ JAVA := $(FIXPATH) $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
||||
JAVA_SMALL := $(FIXPATH) $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
|
||||
JAVA_JAVAC := $(FIXPATH) $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
|
||||
JAVAC := $(FIXPATH) $(JAVAC_CMD)
|
||||
JAVAH := $(FIXPATH) $(JAVAH_CMD)
|
||||
JAR := $(FIXPATH) $(JAR_CMD)
|
||||
JLINK := $(FIXPATH) $(JLINK_CMD)
|
||||
JMOD := $(FIXPATH) $(JMOD_CMD)
|
||||
|
||||
@ -295,7 +295,6 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
|
||||
# Setup tools from the Boot JDK.
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVA, java)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAC, javac)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVAH, javah)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAVADOC, javadoc)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JAR, jar)
|
||||
BOOTJDK_CHECK_TOOL_IN_BOOTJDK(JARSIGNER, jarsigner)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -52,7 +52,6 @@ SJAVAC_SERVER_DIR:=$(patsubst $(OLD_OUTPUTDIR)%, $(OUTPUTDIR)%, $(SJAVAC_SERVER_
|
||||
|
||||
JAVA_CMD:=$(BOOT_JDK)/bin/java
|
||||
JAVAC_CMD:=$(BOOT_JDK)/bin/javac
|
||||
JAVAH_CMD:=$(BOOT_JDK)/bin/javah
|
||||
JAR_CMD:=$(BOOT_JDK)/bin/jar
|
||||
JARSIGNER_CMD:=$(BOOT_JDK)/bin/jarsigner
|
||||
SJAVAC_SERVER_JAVA_CMD:=$(JAVA_CMD)
|
||||
|
||||
@ -55,6 +55,7 @@ OPENJDK_TARGET_CPU_ARCH := @OPENJDK_BUILD_CPU_ARCH@
|
||||
OPENJDK_TARGET_CPU_BITS := @OPENJDK_BUILD_CPU_BITS@
|
||||
OPENJDK_TARGET_CPU_ENDIAN := @OPENJDK_BUILD_CPU_ENDIAN@
|
||||
OPENJDK_TARGET_CPU_LEGACY := @OPENJDK_BUILD_CPU_LEGACY@
|
||||
OPENJDK_TARGET_OS_INCLUDE_SUBDIR := @OPENJDK_BUILD_OS_INCLUDE_SUBDIR@
|
||||
|
||||
HOTSPOT_TARGET_OS := @HOTSPOT_BUILD_OS@
|
||||
HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_BUILD_OS_TYPE@
|
||||
|
||||
@ -1162,9 +1162,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
|
||||
# Setup some hard coded includes
|
||||
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK \
|
||||
-I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I${TOPDIR}/src/java.base/share/native/include \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_$1_OS/native/include \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/include \
|
||||
-I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base/\$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I${TOPDIR}/src/java.base/share/native/libjava \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_$1_OS_TYPE/native/libjava \
|
||||
-I${TOPDIR}/src/hotspot/share/include \
|
||||
|
||||
@ -881,12 +881,13 @@ BOOT_JDK_SOURCETARGET
|
||||
JARSIGNER
|
||||
JAR
|
||||
JAVADOC
|
||||
JAVAH
|
||||
JAVAC
|
||||
JAVA
|
||||
BOOT_JDK
|
||||
JAVA_CHECK
|
||||
JAVAC_CHECK
|
||||
VERSION_CLASSFILE_MINOR
|
||||
VERSION_CLASSFILE_MAJOR
|
||||
VENDOR_VERSION_STRING
|
||||
VERSION_DATE
|
||||
VERSION_IS_GA
|
||||
@ -901,10 +902,10 @@ VERSION_PATCH
|
||||
VERSION_UPDATE
|
||||
VERSION_INTERIM
|
||||
VERSION_FEATURE
|
||||
COMPANY_NAME
|
||||
MACOSX_BUNDLE_ID_BASE
|
||||
MACOSX_BUNDLE_NAME_BASE
|
||||
HOTSPOT_VM_DISTRO
|
||||
COMPANY_NAME
|
||||
JDK_RC_PLATFORM_NAME
|
||||
PRODUCT_SUFFIX
|
||||
PRODUCT_NAME
|
||||
@ -968,6 +969,7 @@ JDK_VARIANT
|
||||
USERNAME
|
||||
TOPDIR
|
||||
PATH_SEP
|
||||
OPENJDK_BUILD_OS_INCLUDE_SUBDIR
|
||||
HOTSPOT_BUILD_CPU_DEFINE
|
||||
HOTSPOT_BUILD_CPU_ARCH
|
||||
HOTSPOT_BUILD_CPU
|
||||
@ -978,6 +980,7 @@ OPENJDK_BUILD_CPU_OSARCH
|
||||
OPENJDK_BUILD_CPU_ISADIR
|
||||
OPENJDK_BUILD_CPU_LEGACY_LIB
|
||||
OPENJDK_BUILD_CPU_LEGACY
|
||||
OPENJDK_TARGET_OS_INCLUDE_SUBDIR
|
||||
HOTSPOT_TARGET_CPU_DEFINE
|
||||
HOTSPOT_TARGET_CPU_ARCH
|
||||
HOTSPOT_TARGET_CPU
|
||||
@ -1093,7 +1096,6 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@ -1147,6 +1149,7 @@ with_build_number
|
||||
with_version_major
|
||||
with_version_minor
|
||||
with_version_security
|
||||
with_vendor_name
|
||||
with_version_string
|
||||
with_version_pre
|
||||
with_version_opt
|
||||
@ -1299,7 +1302,6 @@ SETFILE
|
||||
PKG_CONFIG
|
||||
JAVA
|
||||
JAVAC
|
||||
JAVAH
|
||||
JAVADOC
|
||||
JAR
|
||||
JARSIGNER
|
||||
@ -1383,7 +1385,6 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
@ -1636,15 +1637,6 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@ -1782,7 +1774,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir runstatedir
|
||||
libdir localedir mandir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@ -1935,7 +1927,6 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@ -2083,6 +2074,7 @@ Optional Packages:
|
||||
compatibility and is ignored
|
||||
--with-version-security Deprecated. Option is kept for backwards
|
||||
compatibility and is ignored
|
||||
--with-vendor-name Set vendor name [not specified]
|
||||
--with-version-string Set version string [calculated]
|
||||
--with-version-pre Set the base part of the version 'PRE' field
|
||||
(pre-release identifier) ['internal']
|
||||
@ -2269,7 +2261,6 @@ Some influential environment variables:
|
||||
PKG_CONFIG path to pkg-config utility
|
||||
JAVA Override default value for JAVA
|
||||
JAVAC Override default value for JAVAC
|
||||
JAVAH Override default value for JAVAH
|
||||
JAVADOC Override default value for JAVADOC
|
||||
JAR Override default value for JAR
|
||||
JARSIGNER Override default value for JARSIGNER
|
||||
@ -5185,7 +5176,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=1513206608
|
||||
DATE_WHEN_GENERATED=1513805283
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -16316,6 +16307,14 @@ $as_echo "$COMPILE_TYPE" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
# For historical reasons, the OS include directories have odd names.
|
||||
OPENJDK_TARGET_OS_INCLUDE_SUBDIR="$OPENJDK_TARGET_OS"
|
||||
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
|
||||
OPENJDK_TARGET_OS_INCLUDE_SUBDIR="win32"
|
||||
elif test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
|
||||
OPENJDK_TARGET_OS_INCLUDE_SUBDIR="darwin"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Also store the legacy naming of the cpu.
|
||||
@ -16467,6 +16466,14 @@ $as_echo "$COMPILE_TYPE" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
# For historical reasons, the OS include directories have odd names.
|
||||
OPENJDK_BUILD_OS_INCLUDE_SUBDIR="$OPENJDK_TARGET_OS"
|
||||
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
|
||||
OPENJDK_BUILD_OS_INCLUDE_SUBDIR="win32"
|
||||
elif test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
|
||||
OPENJDK_BUILD_OS_INCLUDE_SUBDIR="darwin"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
@ -25055,6 +25062,21 @@ fi
|
||||
|
||||
|
||||
|
||||
# The vendor name, if any
|
||||
|
||||
# Check whether --with-vendor-name was given.
|
||||
if test "${with_vendor_name+set}" = set; then :
|
||||
withval=$with_vendor_name;
|
||||
fi
|
||||
|
||||
if test "x$with_vendor_name" = xyes; then
|
||||
as_fn_error $? "--with-vendor-name must have a value" "$LINENO" 5
|
||||
elif ! [[ $with_vendor_name =~ ^[[:print:]]*$ ]] ; then
|
||||
as_fn_error $? "--with--vendor-name contains non-printing characters: $with_vendor_name" "$LINENO" 5
|
||||
else
|
||||
COMPANY_NAME="$with_vendor_name"
|
||||
fi
|
||||
|
||||
|
||||
# Override version from arguments
|
||||
|
||||
@ -25457,6 +25479,10 @@ fi
|
||||
VENDOR_VERSION_STRING="$with_vendor_version_string"
|
||||
fi
|
||||
|
||||
# We could define --with flags for these, if really needed
|
||||
VERSION_CLASSFILE_MAJOR="$DEFAULT_VERSION_CLASSFILE_MAJOR"
|
||||
VERSION_CLASSFILE_MINOR="$DEFAULT_VERSION_CLASSFILE_MINOR"
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for version string" >&5
|
||||
$as_echo_n "checking for version string... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VERSION_STRING" >&5
|
||||
@ -25478,6 +25504,9 @@ $as_echo "$VERSION_STRING" >&6; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Setup BootJDK, used to bootstrap the build.
|
||||
@ -30903,144 +30932,6 @@ $as_echo "$tool_specified" >&6; }
|
||||
|
||||
|
||||
|
||||
# Use user overridden value if available, otherwise locate tool in the Boot JDK.
|
||||
|
||||
# Publish this variable in the help.
|
||||
|
||||
|
||||
if [ -z "${JAVAH+x}" ]; then
|
||||
# The variable is not set by user, try to locate tool using the code snippet
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for javah in Boot JDK" >&5
|
||||
$as_echo_n "checking for javah in Boot JDK... " >&6; }
|
||||
JAVAH=$BOOT_JDK/bin/javah
|
||||
if test ! -x $JAVAH; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
$as_echo "not found" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&5
|
||||
$as_echo "$as_me: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&6;}
|
||||
as_fn_error $? "Could not find javah in the Boot JDK" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
|
||||
$as_echo "ok" >&6; }
|
||||
|
||||
|
||||
else
|
||||
# The variable is set, but is it from the command line or the environment?
|
||||
|
||||
# Try to remove the string !JAVAH! from our list.
|
||||
try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!JAVAH!/}
|
||||
if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
|
||||
# If it failed, the variable was not from the command line. Ignore it,
|
||||
# but warn the user (except for BASH, which is always set by the calling BASH).
|
||||
if test "xJAVAH" != xBASH; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of JAVAH from the environment. Use command line variables instead." >&5
|
||||
$as_echo "$as_me: WARNING: Ignoring value of JAVAH from the environment. Use command line variables instead." >&2;}
|
||||
fi
|
||||
# Try to locate tool using the code snippet
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for javah in Boot JDK" >&5
|
||||
$as_echo_n "checking for javah in Boot JDK... " >&6; }
|
||||
JAVAH=$BOOT_JDK/bin/javah
|
||||
if test ! -x $JAVAH; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
$as_echo "not found" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&5
|
||||
$as_echo "$as_me: Your Boot JDK seems broken. This might be fixed by explicitly setting --with-boot-jdk" >&6;}
|
||||
as_fn_error $? "Could not find javah in the Boot JDK" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
|
||||
$as_echo "ok" >&6; }
|
||||
|
||||
|
||||
else
|
||||
# If it succeeded, then it was overridden by the user. We will use it
|
||||
# for the tool.
|
||||
|
||||
# First remove it from the list of overridden variables, so we can test
|
||||
# for unknown variables in the end.
|
||||
CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
|
||||
|
||||
# Check if we try to supply an empty value
|
||||
if test "x$JAVAH" = x; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool JAVAH= (no value)" >&5
|
||||
$as_echo "$as_me: Setting user supplied tool JAVAH= (no value)" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JAVAH" >&5
|
||||
$as_echo_n "checking for JAVAH... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
|
||||
$as_echo "disabled" >&6; }
|
||||
else
|
||||
# Check if the provided tool contains a complete path.
|
||||
tool_specified="$JAVAH"
|
||||
tool_basename="${tool_specified##*/}"
|
||||
if test "x$tool_basename" = "x$tool_specified"; then
|
||||
# A command without a complete path is provided, search $PATH.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool JAVAH=$tool_basename" >&5
|
||||
$as_echo "$as_me: Will search for user supplied tool JAVAH=$tool_basename" >&6;}
|
||||
# Extract the first word of "$tool_basename", so it can be a program name with args.
|
||||
set dummy $tool_basename; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_JAVAH+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $JAVAH in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_JAVAH="$JAVAH" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_JAVAH="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
JAVAH=$ac_cv_path_JAVAH
|
||||
if test -n "$JAVAH"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAH" >&5
|
||||
$as_echo "$JAVAH" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x$JAVAH" = x; then
|
||||
as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
|
||||
fi
|
||||
else
|
||||
# Otherwise we believe it is a complete path. Use it as it is.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool JAVAH=$tool_specified" >&5
|
||||
$as_echo "$as_me: Will use user supplied tool JAVAH=$tool_specified" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JAVAH" >&5
|
||||
$as_echo_n "checking for JAVAH... " >&6; }
|
||||
if test ! -x "$tool_specified"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
|
||||
$as_echo "not found" >&6; }
|
||||
as_fn_error $? "User supplied tool JAVAH=$tool_specified does not exist or is not executable" "$LINENO" 5
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
|
||||
$as_echo "$tool_specified" >&6; }
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Use user overridden value if available, otherwise locate tool in the Boot JDK.
|
||||
|
||||
# Publish this variable in the help.
|
||||
@ -52888,9 +52779,7 @@ fi
|
||||
# Setup some hard coded includes
|
||||
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
|
||||
-I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I${TOPDIR}/src/java.base/share/native/include \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
|
||||
-I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base/\$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I${TOPDIR}/src/java.base/share/native/libjava \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava \
|
||||
-I${TOPDIR}/src/hotspot/share/include \
|
||||
@ -53771,9 +53660,7 @@ fi
|
||||
# Setup some hard coded includes
|
||||
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK \
|
||||
-I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I${TOPDIR}/src/java.base/share/native/include \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS/native/include \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/include \
|
||||
-I\$(SUPPORT_OUTPUTDIR)/modules_include/java.base/\$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I${TOPDIR}/src/java.base/share/native/libjava \
|
||||
-I${TOPDIR}/src/java.base/$OPENJDK_BUILD_OS_TYPE/native/libjava \
|
||||
-I${TOPDIR}/src/hotspot/share/include \
|
||||
|
||||
@ -74,11 +74,22 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
AC_SUBST(PRODUCT_NAME)
|
||||
AC_SUBST(PRODUCT_SUFFIX)
|
||||
AC_SUBST(JDK_RC_PLATFORM_NAME)
|
||||
AC_SUBST(COMPANY_NAME)
|
||||
AC_SUBST(HOTSPOT_VM_DISTRO)
|
||||
AC_SUBST(MACOSX_BUNDLE_NAME_BASE)
|
||||
AC_SUBST(MACOSX_BUNDLE_ID_BASE)
|
||||
|
||||
# The vendor name, if any
|
||||
AC_ARG_WITH(vendor-name, [AS_HELP_STRING([--with-vendor-name],
|
||||
[Set vendor name @<:@not specified@:>@])])
|
||||
if test "x$with_vendor_name" = xyes; then
|
||||
AC_MSG_ERROR([--with-vendor-name must have a value])
|
||||
elif [ ! [[ $with_vendor_name =~ ^[[:print:]]*$ ]] ]; then
|
||||
AC_MSG_ERROR([--with--vendor-name contains non-printing characters: $with_vendor_name])
|
||||
else
|
||||
COMPANY_NAME="$with_vendor_name"
|
||||
fi
|
||||
AC_SUBST(COMPANY_NAME)
|
||||
|
||||
# Override version from arguments
|
||||
|
||||
# If --with-version-string is set, process it first. It is possible to
|
||||
@ -331,6 +342,10 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
VENDOR_VERSION_STRING="$with_vendor_version_string"
|
||||
fi
|
||||
|
||||
# We could define --with flags for these, if really needed
|
||||
VERSION_CLASSFILE_MAJOR="$DEFAULT_VERSION_CLASSFILE_MAJOR"
|
||||
VERSION_CLASSFILE_MINOR="$DEFAULT_VERSION_CLASSFILE_MINOR"
|
||||
|
||||
AC_MSG_CHECKING([for version string])
|
||||
AC_MSG_RESULT([$VERSION_STRING])
|
||||
|
||||
@ -348,4 +363,7 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
AC_SUBST(VERSION_IS_GA)
|
||||
AC_SUBST(VERSION_DATE)
|
||||
AC_SUBST(VENDOR_VERSION_STRING)
|
||||
AC_SUBST(VERSION_CLASSFILE_MAJOR)
|
||||
AC_SUBST(VERSION_CLASSFILE_MINOR)
|
||||
|
||||
])
|
||||
|
||||
@ -478,6 +478,14 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
|
||||
fi
|
||||
AC_SUBST(HOTSPOT_$1_CPU_DEFINE)
|
||||
|
||||
# For historical reasons, the OS include directories have odd names.
|
||||
OPENJDK_$1_OS_INCLUDE_SUBDIR="$OPENJDK_TARGET_OS"
|
||||
if test "x$OPENJDK_TARGET_OS" = "xwindows"; then
|
||||
OPENJDK_$1_OS_INCLUDE_SUBDIR="win32"
|
||||
elif test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
|
||||
OPENJDK_$1_OS_INCLUDE_SUBDIR="darwin"
|
||||
fi
|
||||
AC_SUBST(OPENJDK_$1_OS_INCLUDE_SUBDIR)
|
||||
])
|
||||
|
||||
AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES],
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -78,6 +78,7 @@ OPENJDK_TARGET_CPU_ISADIR:=@OPENJDK_TARGET_CPU_ISADIR@
|
||||
OPENJDK_TARGET_CPU_LEGACY:=@OPENJDK_TARGET_CPU_LEGACY@
|
||||
OPENJDK_TARGET_CPU_LEGACY_LIB:=@OPENJDK_TARGET_CPU_LEGACY_LIB@
|
||||
OPENJDK_TARGET_CPU_OSARCH:=@OPENJDK_TARGET_CPU_OSARCH@
|
||||
OPENJDK_TARGET_OS_INCLUDE_SUBIDR:=@OPENJDK_TARGET_OS_INCLUDE_SUBDIR@
|
||||
|
||||
HOTSPOT_TARGET_OS := @HOTSPOT_TARGET_OS@
|
||||
HOTSPOT_TARGET_OS_TYPE := @HOTSPOT_TARGET_OS_TYPE@
|
||||
@ -100,6 +101,8 @@ OPENJDK_BUILD_CPU_ARCH:=@OPENJDK_BUILD_CPU_ARCH@
|
||||
OPENJDK_BUILD_CPU_BITS:=@OPENJDK_BUILD_CPU_BITS@
|
||||
OPENJDK_BUILD_CPU_ENDIAN:=@OPENJDK_BUILD_CPU_ENDIAN@
|
||||
|
||||
OPENJDK_BUILD_OS_INCLUDE_SUBIDR:=@OPENJDK_TARGET_OS_INCLUDE_SUBDIR@
|
||||
|
||||
# Target platform value in ModuleTarget class file attribute.
|
||||
OPENJDK_MODULE_TARGET_PLATFORM:=@OPENJDK_MODULE_TARGET_PLATFORM@
|
||||
|
||||
@ -175,6 +178,10 @@ VERSION_DATE := @VERSION_DATE@
|
||||
# Vendor version string
|
||||
VENDOR_VERSION_STRING := @VENDOR_VERSION_STRING@
|
||||
|
||||
# Class-file version
|
||||
VERSION_CLASSFILE_MAJOR := @VERSION_CLASSFILE_MAJOR@
|
||||
VERSION_CLASSFILE_MINOR := @VERSION_CLASSFILE_MINOR@
|
||||
|
||||
# Convenience CFLAGS settings for passing version information into native programs.
|
||||
VERSION_CFLAGS := \
|
||||
-DVERSION_FEATURE=$(VERSION_FEATURE) \
|
||||
@ -190,6 +197,8 @@ VERSION_CFLAGS := \
|
||||
-DVERSION_SPECIFICATION='"$(VERSION_SPECIFICATION)"' \
|
||||
-DVERSION_DATE='"$(VERSION_DATE)"' \
|
||||
-DVENDOR_VERSION_STRING='"$(VENDOR_VERSION_STRING)"' \
|
||||
-DVERSION_CLASSFILE_MAJOR=$(VERSION_CLASSFILE_MAJOR) \
|
||||
-DVERSION_CLASSFILE_MINOR=$(VERSION_CLASSFILE_MINOR) \
|
||||
#
|
||||
|
||||
# Platform naming variables
|
||||
@ -540,7 +549,6 @@ SJAVAC_SERVER_JAVA_FLAGS:=@SJAVAC_SERVER_JAVA_FLAGS@
|
||||
# versions of the variables directly.
|
||||
JAVA_CMD:=@JAVA@
|
||||
JAVAC_CMD:=@JAVAC@
|
||||
JAVAH_CMD:=@JAVAH@
|
||||
JAVADOC_CMD:=@JAVADOC@
|
||||
JAR_CMD:=@JAR@
|
||||
JLINK_CMD := @JLINK@
|
||||
@ -553,7 +561,6 @@ JAVA=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
||||
JAVA_SMALL=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
|
||||
JAVA_JAVAC=@FIXPATH@ $(JAVA_CMD) $(JAVA_FLAGS_JAVAC) $(JAVA_FLAGS)
|
||||
JAVAC=@FIXPATH@ $(JAVAC_CMD)
|
||||
JAVAH=@FIXPATH@ $(JAVAH_CMD)
|
||||
JAVADOC=@FIXPATH@ $(JAVADOC_CMD)
|
||||
JAR=@FIXPATH@ $(JAR_CMD)
|
||||
JLINK = @FIXPATH@ $(JLINK_CMD) $(JAVA_TOOL_FLAGS_SMALL)
|
||||
@ -578,6 +585,8 @@ INTERIM_LANGTOOLS_BASE_MODULES := java.compiler jdk.compiler jdk.javadoc
|
||||
INTERIM_LANGTOOLS_MODULES := $(addsuffix .interim, $(INTERIM_LANGTOOLS_BASE_MODULES))
|
||||
INTERIM_LANGTOOLS_ADD_EXPORTS := \
|
||||
--add-exports java.base/sun.reflect.annotation=jdk.compiler.interim \
|
||||
--add-exports java.base/jdk.internal.jmod=jdk.compiler.interim \
|
||||
--add-exports java.base/jdk.internal.misc=jdk.compiler.interim \
|
||||
#
|
||||
INTERIM_LANGTOOLS_MODULES_COMMA := $(strip $(subst $(SPACE),$(COMMA),$(strip \
|
||||
$(INTERIM_LANGTOOLS_MODULES))))
|
||||
@ -717,7 +726,7 @@ INSTALL_PREFIX=@prefix@
|
||||
# Directories containing architecture-dependent files should be relative to exec_prefix
|
||||
INSTALL_EXECPREFIX=@exec_prefix@
|
||||
|
||||
# java,javac,javah,javap etc are installed here.
|
||||
# java,javac,javap etc are installed here.
|
||||
INSTALL_BINDIR=@bindir@
|
||||
|
||||
# Read only architecture-independent data
|
||||
|
||||
@ -30,6 +30,8 @@ DEFAULT_VERSION_INTERIM=0
|
||||
DEFAULT_VERSION_UPDATE=0
|
||||
DEFAULT_VERSION_PATCH=0
|
||||
DEFAULT_VERSION_DATE=2018-03-20
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
|
||||
LAUNCHER_NAME=openjdk
|
||||
PRODUCT_NAME=OpenJDK
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -46,7 +46,7 @@ include ZipArchive.gmk
|
||||
# passed to SetupJavaCompilation. This name is used as variable prefix.
|
||||
#
|
||||
# Remaining parameters are named arguments. These include:
|
||||
# JVM:=The jvm used to run the javac/javah command
|
||||
# JVM:=The jvm used to run the javac command
|
||||
# JAVAC:=The javac jar and bootstrap classpath changes, or just bin/javac if JVM is left out
|
||||
# FLAGS:=Flags to be supplied to javac
|
||||
# SERVER_DIR:=Use a javac server (-XDserver) and store the server related files here
|
||||
|
||||
@ -829,7 +829,7 @@ var getJibProfilesDependencies = function (input, common) {
|
||||
jtreg: {
|
||||
server: "javare",
|
||||
revision: "4.2",
|
||||
build_number: "b10",
|
||||
build_number: "b11",
|
||||
checksum_file: "MD5_VALUES",
|
||||
file: "jtreg_bin-4.2.zip",
|
||||
environment_name: "JT_HOME",
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#
|
||||
|
||||
include CopyCommon.gmk
|
||||
include TextFileProcessing.gmk
|
||||
|
||||
$(eval $(call IncludeCustomExtension, copy/Copy-java.base.gmk))
|
||||
|
||||
@ -244,3 +245,16 @@ ifeq ($(ENABLE_LIBFFI_BUNDLING), true)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Generate classfile_constants.h
|
||||
|
||||
$(eval $(call SetupTextFileProcessing, CREATE_CLASSFILE_CONSTANTS_H, \
|
||||
SOURCE_FILES := $(TOPDIR)/src/java.base/share/native/include/classfile_constants.h.template, \
|
||||
OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/modules_include/java.base/classfile_constants.h, \
|
||||
REPLACEMENTS := \
|
||||
@@VERSION_CLASSFILE_MAJOR@@ => $(VERSION_CLASSFILE_MAJOR) ; \
|
||||
@@VERSION_CLASSFILE_MINOR@@ => $(VERSION_CLASSFILE_MINOR) ; , \
|
||||
))
|
||||
|
||||
TARGETS += $(CREATE_CLASSFILE_CONSTANTS_H)
|
||||
|
||||
################################################################################
|
||||
|
||||
@ -39,20 +39,12 @@ ifneq ($(wildcard $(INCLUDE_SOURCE_DIR)/*), )
|
||||
$(eval $(call SetupCopyFiles, COPY_EXPORTED_INCLUDE, \
|
||||
SRC := $(INCLUDE_SOURCE_DIR), \
|
||||
DEST := $(INCLUDE_TARGET_DIR), \
|
||||
FILES := $(shell $(FIND) $(INCLUDE_SOURCE_DIR) -type f), \
|
||||
FILES := $(filter %.h, $(call CacheFind, $(INCLUDE_SOURCE_DIR))), \
|
||||
))
|
||||
|
||||
TARGETS += $(COPY_EXPORTED_INCLUDE)
|
||||
endif
|
||||
|
||||
# For historical reasons, the OS include directories have odd names.
|
||||
INCLUDE_TARGET_OS_SUBDIR := $(OPENJDK_TARGET_OS)
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
INCLUDE_TARGET_OS_SUBDIR := win32
|
||||
else ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
INCLUDE_TARGET_OS_SUBDIR := darwin
|
||||
endif
|
||||
|
||||
# Use the most specific of OS and OS_TYPE.
|
||||
INCLUDE_SOURCE_OS_DIR := $(TOPDIR)/src/$(MODULE)/$(OPENJDK_TARGET_OS)/native/include
|
||||
ifeq ($(wildcard $(INCLUDE_SOURCE_OS_DIR)/*), )
|
||||
@ -62,8 +54,8 @@ endif
|
||||
ifneq ($(wildcard $(INCLUDE_SOURCE_OS_DIR)/*), )
|
||||
$(eval $(call SetupCopyFiles, COPY_EXPORTED_INCLUDE_OS, \
|
||||
SRC := $(INCLUDE_SOURCE_OS_DIR), \
|
||||
DEST := $(INCLUDE_TARGET_DIR)/$(INCLUDE_TARGET_OS_SUBDIR), \
|
||||
FILES := $(shell $(FIND) $(INCLUDE_SOURCE_OS_DIR) -type f), \
|
||||
DEST := $(INCLUDE_TARGET_DIR)/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR), \
|
||||
FILES := $(filter %.h, $(call CacheFind, $(INCLUDE_SOURCE_OS_DIR))), \
|
||||
))
|
||||
|
||||
TARGETS += $(COPY_EXPORTED_INCLUDE_OS)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,11 +28,8 @@ include GensrcCommonLangtools.gmk
|
||||
$(eval $(call SetupVersionProperties,JAVAC_VERSION, \
|
||||
com/sun/tools/javac/resources/version.properties))
|
||||
|
||||
$(eval $(call SetupVersionProperties,JAVAH_VERSION, \
|
||||
com/sun/tools/javah/resources/version.properties))
|
||||
|
||||
$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
|
||||
$(JAVAC_VERSION) $(JAVAH_VERSION)))
|
||||
$(JAVAC_VERSION)))
|
||||
|
||||
$(eval $(call SetupParseProperties,PARSE_PROPERTIES, \
|
||||
com/sun/tools/javac/resources/compiler.properties))
|
||||
|
||||
@ -92,10 +92,10 @@ ifneq ($(COMPILE_TYPE), cross)
|
||||
endif
|
||||
|
||||
SIZER_CFLAGS := \
|
||||
-I${TOPDIR}/src/hotspot/share/include \
|
||||
-I${TOPDIR}/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \
|
||||
-I$(TOPDIR)/src/java.base/share/native/include \
|
||||
-I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \
|
||||
-I$(TOPDIR)/src/hotspot/share/include \
|
||||
-I$(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I$(TOPDIR)/src/java.base/share/native/libjava \
|
||||
-I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjava \
|
||||
-I$(TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \
|
||||
|
||||
@ -59,8 +59,8 @@ JVM_CFLAGS_INCLUDES += \
|
||||
-I$(TOPDIR)/src/hotspot/share/precompiled \
|
||||
-I$(TOPDIR)/src/hotspot/share/include \
|
||||
-I$(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \
|
||||
-I$(TOPDIR)/src/java.base/share/native/include \
|
||||
-I$(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/include \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I$(TOPDIR)/src/java.base/share/native/libjimage \
|
||||
#
|
||||
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,7 +60,6 @@ full.version = ${release}+${build.number}
|
||||
tool.javac.main.class=com.sun.tools.javac.Main
|
||||
tool.javadoc.main.class=jdk.javadoc.internal.tool.Main
|
||||
tool.javap.main.class=com.sun.tools.javap.Main
|
||||
tool.javah.main.class=com.sun.tools.javah.Main
|
||||
tool.sjavac.main.class=com.sun.tools.sjavac.Main
|
||||
tool.jshell.main.class=jdk.internal.jshell.tool.JShellToolProvider
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
~ Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
~ 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,7 @@
|
||||
The output of the build is as follows:
|
||||
|
||||
build
|
||||
|-bin (scripts to invoke various tools, javac, javah etc.)
|
||||
|-bin (scripts to invoke various tools, javac etc.)
|
||||
|-genrsc (generated sources - i.e. properties)
|
||||
|-modules (compiled classes in a modular layout)
|
||||
|-jtreg (test work/results)
|
||||
@ -254,7 +254,6 @@
|
||||
<build-tool name="javac"/>
|
||||
<build-tool name="javadoc"/>
|
||||
<build-tool name="javap"/>
|
||||
<build-tool name="javah"/>
|
||||
<build-tool name="jdeps"/>
|
||||
<build-tool name="sjavac"/>
|
||||
<build-tool name="jshell"/>
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="javah" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javah.Main" />
|
||||
<option name="VM_PARAMETERS" value='@XPATCH@ --add-exports=jdk.compiler/com.sun.tools.javah=ALL-UNNAMED' />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="langtools" />
|
||||
<envs />
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method>
|
||||
<option name="Make" enabled="false" />
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@ -7,7 +7,7 @@ edit, run, test and debug the tools in the OpenJDK langtools
|
||||
repository.
|
||||
|
||||
The repository contains a number of tools:
|
||||
javac, javadoc and its doclets, javah and javap.
|
||||
javac, javadoc and its doclets, and javap.
|
||||
|
||||
Build Properties.
|
||||
|
||||
|
||||
@ -11,9 +11,4 @@ public class HelloWorld {
|
||||
* @param args The parameters are ignored.
|
||||
*/
|
||||
public static void main(java.lang.String... args);
|
||||
|
||||
/**
|
||||
* This declaration is for the benefit of javah tests.
|
||||
*/
|
||||
public native void test();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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,9 +37,4 @@ public class HelloWorld
|
||||
public static void main(String... args) {
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
|
||||
/**
|
||||
* This declaration is for the benefit of javah tests.
|
||||
*/
|
||||
public native void test();
|
||||
}
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# @test
|
||||
# @summary Verify the basic execution of the bootstrap javah tool.
|
||||
|
||||
TESTSRC=${TESTSRC:-.}
|
||||
TOPDIR=${TESTSRC}/../../..
|
||||
|
||||
${TOPDIR}/dist/bootstrap/bin/javac -d . "${TESTSRC}"/../HelloWorld.java
|
||||
${TOPDIR}/dist/bootstrap/bin/javah -classpath . -d . HelloWorld
|
||||
|
||||
if diff ${TESTSRC}/../HelloWorld.gold.h HelloWorld.h ; then
|
||||
echo "Test passed."
|
||||
else
|
||||
echo "Test failed."
|
||||
exit 1
|
||||
fi
|
||||
@ -1,9 +1,7 @@
|
||||
./bootstrap/bin/javac
|
||||
./bootstrap/bin/javadoc
|
||||
./bootstrap/bin/javah
|
||||
./bootstrap/lib/doclets.jar
|
||||
./bootstrap/lib/javac.jar
|
||||
./bootstrap/lib/javadoc.jar
|
||||
./bootstrap/lib/javah.jar
|
||||
./lib/classes.jar
|
||||
./lib/src.zip
|
||||
|
||||
@ -1,9 +1,4 @@
|
||||
META-INF/MANIFEST.MF
|
||||
com/sun/tools/apt/Main.class
|
||||
com/sun/tools/apt/main/Main.class
|
||||
com/sun/tools/apt/resources/apt.class
|
||||
com/sun/tools/apt/resources/apt_ja.class
|
||||
com/sun/tools/apt/resources/apt_zh_CN.class
|
||||
com/sun/tools/doclets/formats/html/resources/standard.class
|
||||
com/sun/tools/doclets/formats/html/resources/standard_ja.class
|
||||
com/sun/tools/doclets/formats/html/resources/standard_zh_CN.class
|
||||
@ -26,13 +21,3 @@ com/sun/tools/javadoc/Main.class
|
||||
com/sun/tools/javadoc/resources/javadoc.class
|
||||
com/sun/tools/javadoc/resources/javadoc_ja.class
|
||||
com/sun/tools/javadoc/resources/javadoc_zh_CN.class
|
||||
com/sun/tools/javah/Main.class
|
||||
com/sun/tools/javah/resources/Linux_ppc.class
|
||||
com/sun/tools/javah/resources/Linux_sparc.class
|
||||
com/sun/tools/javah/resources/SunOS_sparc.class
|
||||
com/sun/tools/javah/resources/SunOS_sparcv9.class
|
||||
com/sun/tools/javah/resources/l10n.class
|
||||
com/sun/tools/javah/resources/l10n_ja.class
|
||||
com/sun/tools/javah/resources/l10n_zh_CN.class
|
||||
com/sun/tools/javah/resources/win32_x86.class
|
||||
sun/tools/javap/Main.class
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# @test
|
||||
# @summary Verify the basic execution of the javah classes in classes.jar.
|
||||
|
||||
TESTSRC=${TESTSRC:-.}
|
||||
TOPDIR=${TESTSRC}/../../..
|
||||
TESTJAVAEXE="${TESTJAVA:+${TESTJAVA}/bin/}java"
|
||||
|
||||
"${TESTJAVAEXE}" -Xbootclasspath/p:${TOPDIR}/dist/lib/classes.jar \
|
||||
com.sun.tools.javac.Main \
|
||||
-d . "${TESTSRC}"/../HelloWorld.java
|
||||
|
||||
"${TESTJAVAEXE}" -Xbootclasspath/p:${TOPDIR}/dist/lib/classes.jar \
|
||||
com.sun.tools.javah.Main \
|
||||
-classpath . -d . HelloWorld
|
||||
|
||||
if diff ${TESTSRC}/../HelloWorld.gold.h HelloWorld.h ; then
|
||||
echo "Test passed."
|
||||
else
|
||||
echo "Test failed."
|
||||
exit 1
|
||||
fi
|
||||
@ -29,15 +29,5 @@ com/sun/tools/javadoc/Main.java
|
||||
com/sun/tools/javadoc/resources/javadoc.properties
|
||||
com/sun/tools/javadoc/resources/javadoc_ja.properties
|
||||
com/sun/tools/javadoc/resources/javadoc_zh_CN.properties
|
||||
com/sun/tools/javah/Main.java
|
||||
com/sun/tools/javah/resources/Linux_ppc.properties
|
||||
com/sun/tools/javah/resources/Linux_sparc.properties
|
||||
com/sun/tools/javah/resources/SunOS_sparc.properties
|
||||
com/sun/tools/javah/resources/SunOS_sparcv9.properties
|
||||
com/sun/tools/javah/resources/l10n.properties
|
||||
com/sun/tools/javah/resources/l10n_ja.properties
|
||||
com/sun/tools/javah/resources/l10n_zh_CN.properties
|
||||
com/sun/tools/javah/resources/win32_x86.properties
|
||||
javax/lang/model/overview.html
|
||||
javax/tools/overview.html
|
||||
sun/tools/javap/Main.java
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -76,7 +76,6 @@ public class SelectToolTask extends Task {
|
||||
NONE(""),
|
||||
JAVAC("javac"),
|
||||
JAVADOC("javadoc"),
|
||||
JAVAH("javah"),
|
||||
JAVAP("javap"),
|
||||
JSHELL("jshell");
|
||||
|
||||
|
||||
@ -6670,18 +6670,6 @@
|
||||
<in>examples.not-yet.txt</in>
|
||||
</df>
|
||||
</df>
|
||||
<df name="javah">
|
||||
<df name="6572945">
|
||||
<df name="gold">
|
||||
<df name="jni.dir.1">
|
||||
<in>TestClass1.h</in>
|
||||
<in>TestClass1_Inner1.h</in>
|
||||
<in>TestClass1_Inner2.h</in>
|
||||
<in>TestClass2.h</in>
|
||||
</df>
|
||||
</df>
|
||||
</df>
|
||||
</df>
|
||||
<df name="jdeprscan">
|
||||
<df name="tests">
|
||||
<df name="jdk">
|
||||
@ -40851,26 +40839,6 @@
|
||||
tool="3"
|
||||
flavor2="0">
|
||||
</item>
|
||||
<item path="../../test/langtools/tools/javah/6572945/gold/jni.dir.1/TestClass1.h"
|
||||
ex="false"
|
||||
tool="3"
|
||||
flavor2="0">
|
||||
</item>
|
||||
<item path="../../test/langtools/tools/javah/6572945/gold/jni.dir.1/TestClass1_Inner1.h"
|
||||
ex="false"
|
||||
tool="3"
|
||||
flavor2="0">
|
||||
</item>
|
||||
<item path="../../test/langtools/tools/javah/6572945/gold/jni.dir.1/TestClass1_Inner2.h"
|
||||
ex="false"
|
||||
tool="3"
|
||||
flavor2="0">
|
||||
</item>
|
||||
<item path="../../test/langtools/tools/javah/6572945/gold/jni.dir.1/TestClass2.h"
|
||||
ex="false"
|
||||
tool="3"
|
||||
flavor2="0">
|
||||
</item>
|
||||
<item path="../../test/langtools/tools/jdeprscan/tests/jdk/jdeprscan/TestScanExpected.txt"
|
||||
ex="false"
|
||||
tool="3"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -63,7 +63,6 @@ if [ "$OPENJDK_TARGET_OS" = "linux" ]; then
|
||||
./bin/java
|
||||
./bin/javac
|
||||
./bin/javadoc
|
||||
./bin/javah
|
||||
./bin/javap
|
||||
./bin/jdeps
|
||||
./bin/jcmd
|
||||
@ -197,7 +196,6 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ];
|
||||
./bin/java
|
||||
./bin/javac
|
||||
./bin/javadoc
|
||||
./bin/javah
|
||||
./bin/javap
|
||||
./bin/jdeps
|
||||
./bin/jcmd
|
||||
@ -306,7 +304,6 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
|
||||
./bin/java
|
||||
./bin/javac
|
||||
./bin/javadoc
|
||||
./bin/javah
|
||||
./bin/javap
|
||||
./bin/jdeps
|
||||
./bin/jcmd
|
||||
@ -394,7 +391,6 @@ if [ "$OPENJDK_TARGET_OS" = "windows" ]; then
|
||||
./bin/java.exe
|
||||
./bin/javac.exe
|
||||
./bin/javadoc.exe
|
||||
./bin/javah.exe
|
||||
./bin/javap.exe
|
||||
./bin/jdeps.exe
|
||||
./bin/javaw.exe
|
||||
@ -486,7 +482,6 @@ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
|
||||
./bin/java
|
||||
./bin/javac
|
||||
./bin/javadoc
|
||||
./bin/javah
|
||||
./bin/javap
|
||||
./bin/javaws
|
||||
./bin/jdeps
|
||||
|
||||
@ -113,6 +113,8 @@ ifeq ($(TOOLCHAIN_TYPE), solstudio)
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHandshakeTransitionTest := -lc
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libHasNoEntryPoint := -lc
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libReturnError := -lc
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCNLookUp := -lc
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libTestCheckedEnsureLocalCapacity := -lc
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), linux)
|
||||
|
||||
@ -3742,13 +3742,16 @@ void MacroAssembler::decode_klass_not_null(Register r) {
|
||||
}
|
||||
|
||||
void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
|
||||
assert (UseCompressedOops, "should only be used for compressed oops");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
|
||||
#ifdef ASSERT
|
||||
{
|
||||
ThreadInVMfromUnknown tiv;
|
||||
assert (UseCompressedOops, "should only be used for compressed oops");
|
||||
assert (Universe::heap() != NULL, "java heap should be initialized");
|
||||
assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop");
|
||||
}
|
||||
#endif
|
||||
int oop_index = oop_recorder()->find_index(obj);
|
||||
assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop");
|
||||
|
||||
InstructionMark im(this);
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
code_section()->relocate(inst_mark(), rspec);
|
||||
@ -4006,8 +4009,13 @@ void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) {
|
||||
if (obj == NULL) {
|
||||
oop_index = oop_recorder()->allocate_oop_index(obj);
|
||||
} else {
|
||||
#ifdef ASSERT
|
||||
{
|
||||
ThreadInVMfromUnknown tiv;
|
||||
assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop");
|
||||
}
|
||||
#endif
|
||||
oop_index = oop_recorder()->find_index(obj);
|
||||
assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop");
|
||||
}
|
||||
RelocationHolder rspec = oop_Relocation::spec(oop_index);
|
||||
if (! immediate) {
|
||||
@ -4030,8 +4038,13 @@ void MacroAssembler::mov_metadata(Register dst, Metadata* obj) {
|
||||
}
|
||||
|
||||
Address MacroAssembler::constant_oop_address(jobject obj) {
|
||||
assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "not an oop");
|
||||
#ifdef ASSERT
|
||||
{
|
||||
ThreadInVMfromUnknown tiv;
|
||||
assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
|
||||
assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "not an oop");
|
||||
}
|
||||
#endif
|
||||
int oop_index = oop_recorder()->find_index(obj);
|
||||
return Address((address)obj, oop_Relocation::spec(oop_index));
|
||||
}
|
||||
|
||||
@ -3722,7 +3722,6 @@ void TemplateTable::_new() {
|
||||
Label slow_case;
|
||||
Label done;
|
||||
Label initialize_header;
|
||||
Label initialize_object; // Including clearing the fields.
|
||||
Label allocate_shared;
|
||||
|
||||
BLOCK_COMMENT("TemplateTable::_new {");
|
||||
@ -3760,65 +3759,41 @@ void TemplateTable::_new() {
|
||||
|
||||
// Allocate the instance
|
||||
// 1) Try to allocate in the TLAB.
|
||||
// 2) If fail and the object is large allocate in the shared Eden.
|
||||
// 3) If the above fails (or is not applicable), go to a slow case
|
||||
// 2) If the above fails (or is not applicable), go to a slow case
|
||||
// (creates a new TLAB, etc.).
|
||||
|
||||
// Always go the slow path. See comment above this template.
|
||||
const bool allow_shared_alloc = false;
|
||||
|
||||
// Note: compared to other architectures, s390's implementation always goes
|
||||
// to the slow path if TLAB is used and fails.
|
||||
if (UseTLAB) {
|
||||
Register RoldTopValue = RallocatedObject;
|
||||
Register RnewTopValue = tmp;
|
||||
__ z_lg(RoldTopValue, Address(Z_thread, JavaThread::tlab_top_offset()));
|
||||
__ load_address(RnewTopValue, Address(RoldTopValue, Rsize));
|
||||
__ z_cg(RnewTopValue, Address(Z_thread, JavaThread::tlab_end_offset()));
|
||||
__ z_brh(allow_shared_alloc ? allocate_shared : slow_case);
|
||||
__ z_brh(slow_case);
|
||||
__ z_stg(RnewTopValue, Address(Z_thread, JavaThread::tlab_top_offset()));
|
||||
if (ZeroTLAB) {
|
||||
// The fields have been already cleared.
|
||||
__ z_bru(initialize_header);
|
||||
} else {
|
||||
// Initialize both the header and fields.
|
||||
if (allow_shared_alloc) {
|
||||
__ z_bru(initialize_object);
|
||||
} else {
|
||||
// Fallthrough to initialize_object, but assert that it is on fall through path.
|
||||
prev_instr_address = __ pc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allow_shared_alloc) {
|
||||
// Allocation in shared Eden not implemented, because sapjvm allocation trace does not allow it.
|
||||
Unimplemented();
|
||||
}
|
||||
|
||||
if (UseTLAB) {
|
||||
Register RobjectFields = tmp;
|
||||
Register Rzero = Z_R1_scratch;
|
||||
|
||||
assert(ZeroTLAB || prev_instr_address == __ pc(),
|
||||
"must not omit jump to initialize_object above, as it is not on the fall through path");
|
||||
__ clear_reg(Rzero, true /*whole reg*/, false); // Load 0L into Rzero. Don't set CC.
|
||||
|
||||
// The object is initialized before the header. If the object size is
|
||||
// zero, go directly to the header initialization.
|
||||
__ bind(initialize_object);
|
||||
__ z_aghi(Rsize, (int)-sizeof(oopDesc)); // Subtract header size, set CC.
|
||||
__ z_bre(initialize_header); // Jump if size of fields is zero.
|
||||
if (!ZeroTLAB) {
|
||||
// The object is initialized before the header. If the object size is
|
||||
// zero, go directly to the header initialization.
|
||||
__ z_aghi(Rsize, (int)-sizeof(oopDesc)); // Subtract header size, set CC.
|
||||
__ z_bre(initialize_header); // Jump if size of fields is zero.
|
||||
|
||||
// Initialize object fields.
|
||||
// See documentation for MVCLE instruction!!!
|
||||
assert(RobjectFields->encoding() % 2 == 0, "RobjectFields must be an even register");
|
||||
assert(Rsize->encoding() == (RobjectFields->encoding()+1),
|
||||
"RobjectFields and Rsize must be a register pair");
|
||||
assert(Rzero->encoding() % 2 == 1, "Rzero must be an odd register");
|
||||
// Initialize object fields.
|
||||
// See documentation for MVCLE instruction!!!
|
||||
assert(RobjectFields->encoding() % 2 == 0, "RobjectFields must be an even register");
|
||||
assert(Rsize->encoding() == (RobjectFields->encoding()+1),
|
||||
"RobjectFields and Rsize must be a register pair");
|
||||
assert(Rzero->encoding() % 2 == 1, "Rzero must be an odd register");
|
||||
|
||||
// Set Rzero to 0 and use it as src length, then mvcle will copy nothing
|
||||
// and fill the object with the padding value 0.
|
||||
__ add2reg(RobjectFields, sizeof(oopDesc), RallocatedObject);
|
||||
__ move_long_ext(RobjectFields, as_Register(Rzero->encoding() - 1), 0);
|
||||
// Set Rzero to 0 and use it as src length, then mvcle will copy nothing
|
||||
// and fill the object with the padding value 0.
|
||||
__ add2reg(RobjectFields, sizeof(oopDesc), RallocatedObject);
|
||||
__ move_long_ext(RobjectFields, as_Register(Rzero->encoding() - 1), 0);
|
||||
}
|
||||
|
||||
// Initialize object header only.
|
||||
__ bind(initialize_header);
|
||||
|
||||
@ -765,6 +765,11 @@ ALIGNED_(8) juint _log2_pow[] =
|
||||
0xfefa39efUL, 0x3fe62e42UL, 0xfefa39efUL, 0xbfe62e42UL
|
||||
};
|
||||
|
||||
ALIGNED_(8) juint _DOUBLE2[] =
|
||||
{
|
||||
0x00000000UL, 0x40000000UL
|
||||
};
|
||||
|
||||
//registers,
|
||||
// input: xmm0, xmm1
|
||||
// scratch: xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
|
||||
@ -803,6 +808,7 @@ void MacroAssembler::fast_pow(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xm
|
||||
address HIGHMASK_LOG_X = (address)_HIGHMASK_LOG_X;
|
||||
address HALFMASK = (address)_HALFMASK;
|
||||
address log2 = (address)_log2_pow;
|
||||
address DOUBLE2 = (address)_DOUBLE2;
|
||||
|
||||
|
||||
bind(start);
|
||||
@ -810,6 +816,13 @@ void MacroAssembler::fast_pow(XMMRegister xmm0, XMMRegister xmm1, XMMRegister xm
|
||||
movsd(Address(rsp, 8), xmm0);
|
||||
movsd(Address(rsp, 16), xmm1);
|
||||
|
||||
// Special case: pow(x, 2.0) => x * x
|
||||
movdq(tmp1, xmm1);
|
||||
cmp64(tmp1, ExternalAddress(DOUBLE2));
|
||||
jccb(Assembler::notEqual, B1_2);
|
||||
mulsd(xmm0, xmm0);
|
||||
jmp(B1_5);
|
||||
|
||||
bind(B1_2);
|
||||
pextrw(eax, xmm0, 3);
|
||||
xorpd(xmm2, xmm2);
|
||||
|
||||
@ -882,7 +882,7 @@ void VM_Version::get_processor_features() {
|
||||
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA) {
|
||||
if (UseSHA && supports_avx2() && supports_bmi2()) {
|
||||
if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
|
||||
}
|
||||
|
||||
@ -547,8 +547,12 @@ source %{
|
||||
|
||||
#define __ _masm.
|
||||
|
||||
static bool generate_vzeroupper(Compile* C) {
|
||||
return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper
|
||||
}
|
||||
|
||||
static int clear_avx_size() {
|
||||
return (VM_Version::supports_vzeroupper()) ? 3: 0; // vzeroupper
|
||||
return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper
|
||||
}
|
||||
|
||||
// !!!!! Special hack to get all types of calls to specify the byte offset
|
||||
@ -931,7 +935,7 @@ int MachPrologNode::reloc() const
|
||||
void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||
{
|
||||
Compile* C = ra_->C;
|
||||
if (VM_Version::supports_vzeroupper()) {
|
||||
if (generate_vzeroupper(C)) {
|
||||
st->print("vzeroupper");
|
||||
st->cr(); st->print("\t");
|
||||
}
|
||||
@ -971,9 +975,11 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
||||
Compile* C = ra_->C;
|
||||
MacroAssembler _masm(&cbuf);
|
||||
|
||||
// Clear upper bits of YMM registers when current compiled code uses
|
||||
// wide vectors to avoid AVX <-> SSE transition penalty during call.
|
||||
__ vzeroupper();
|
||||
if (generate_vzeroupper(C)) {
|
||||
// Clear upper bits of YMM registers when current compiled code uses
|
||||
// wide vectors to avoid AVX <-> SSE transition penalty during call.
|
||||
__ vzeroupper();
|
||||
}
|
||||
|
||||
int framesize = C->frame_size_in_bytes();
|
||||
assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
|
||||
@ -2112,11 +2118,13 @@ encode %{
|
||||
|
||||
enc_class clear_avx %{
|
||||
debug_only(int off0 = cbuf.insts_size());
|
||||
// Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty
|
||||
// Clear upper bits of YMM registers when current compiled code uses
|
||||
// wide vectors to avoid AVX <-> SSE transition penalty during call.
|
||||
MacroAssembler _masm(&cbuf);
|
||||
__ vzeroupper();
|
||||
if (generate_vzeroupper(Compile::current())) {
|
||||
// Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty
|
||||
// Clear upper bits of YMM registers when current compiled code uses
|
||||
// wide vectors to avoid AVX <-> SSE transition penalty during call.
|
||||
MacroAssembler _masm(&cbuf);
|
||||
__ vzeroupper();
|
||||
}
|
||||
debug_only(int off1 = cbuf.insts_size());
|
||||
assert(off1 - off0 == clear_avx_size(), "correct size prediction");
|
||||
%}
|
||||
|
||||
@ -31,16 +31,11 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "osContainer_linux.hpp"
|
||||
|
||||
/*
|
||||
* Warning: Some linux distros use 0x7FFFFFFFFFFFF000
|
||||
* and others use 0x7FFFFFFFFFFFFFFF for unlimited.
|
||||
*/
|
||||
#define UNLIMITED_MEM CONST64(0x7FFFFFFFFFFFF000)
|
||||
|
||||
#define PER_CPU_SHARES 1024
|
||||
|
||||
bool OSContainer::_is_initialized = false;
|
||||
bool OSContainer::_is_containerized = false;
|
||||
julong _unlimited_memory;
|
||||
|
||||
class CgroupSubsystem: CHeapObj<mtInternal> {
|
||||
friend class OSContainer;
|
||||
@ -217,6 +212,8 @@ void OSContainer::init() {
|
||||
_is_initialized = true;
|
||||
_is_containerized = false;
|
||||
|
||||
_unlimited_memory = (LONG_MAX / os::vm_page_size()) * os::vm_page_size();
|
||||
|
||||
log_trace(os, container)("OSContainer::init: Initializing Container Support");
|
||||
if (!UseContainerSupport) {
|
||||
log_trace(os, container)("Container Support not enabled");
|
||||
@ -419,37 +416,37 @@ char * OSContainer::container_type() {
|
||||
* OSCONTAINER_ERROR for not supported
|
||||
*/
|
||||
jlong OSContainer::memory_limit_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, memory, "/memory.limit_in_bytes",
|
||||
"Memory Limit is: " JLONG_FORMAT, JLONG_FORMAT, memlimit);
|
||||
GET_CONTAINER_INFO(julong, memory, "/memory.limit_in_bytes",
|
||||
"Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit);
|
||||
|
||||
if (memlimit >= UNLIMITED_MEM) {
|
||||
if (memlimit >= _unlimited_memory) {
|
||||
log_trace(os, container)("Memory Limit is: Unlimited");
|
||||
return (jlong)-1;
|
||||
}
|
||||
else {
|
||||
return memlimit;
|
||||
return (jlong)memlimit;
|
||||
}
|
||||
}
|
||||
|
||||
jlong OSContainer::memory_and_swap_limit_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, memory, "/memory.memsw.limit_in_bytes",
|
||||
"Memory and Swap Limit is: " JLONG_FORMAT, JLONG_FORMAT, memswlimit);
|
||||
if (memswlimit >= UNLIMITED_MEM) {
|
||||
GET_CONTAINER_INFO(julong, memory, "/memory.memsw.limit_in_bytes",
|
||||
"Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit);
|
||||
if (memswlimit >= _unlimited_memory) {
|
||||
log_trace(os, container)("Memory and Swap Limit is: Unlimited");
|
||||
return (jlong)-1;
|
||||
} else {
|
||||
return memswlimit;
|
||||
return (jlong)memswlimit;
|
||||
}
|
||||
}
|
||||
|
||||
jlong OSContainer::memory_soft_limit_in_bytes() {
|
||||
GET_CONTAINER_INFO(jlong, memory, "/memory.soft_limit_in_bytes",
|
||||
"Memory Soft Limit is: " JLONG_FORMAT, JLONG_FORMAT, memsoftlimit);
|
||||
if (memsoftlimit >= UNLIMITED_MEM) {
|
||||
GET_CONTAINER_INFO(julong, memory, "/memory.soft_limit_in_bytes",
|
||||
"Memory Soft Limit is: " JULONG_FORMAT, JULONG_FORMAT, memsoftlimit);
|
||||
if (memsoftlimit >= _unlimited_memory) {
|
||||
log_trace(os, container)("Memory Soft Limit is: Unlimited");
|
||||
return (jlong)-1;
|
||||
} else {
|
||||
return memsoftlimit;
|
||||
return (jlong)memsoftlimit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -234,7 +234,9 @@ void ciField::initialize_from(fieldDescriptor* fd) {
|
||||
// Get the flags, offset, and canonical holder of the field.
|
||||
_flags = ciFlags(fd->access_flags());
|
||||
_offset = fd->offset();
|
||||
_holder = CURRENT_ENV->get_instance_klass(fd->field_holder());
|
||||
Klass* field_holder = fd->field_holder();
|
||||
assert(field_holder != NULL, "null field_holder");
|
||||
_holder = CURRENT_ENV->get_instance_klass(field_holder);
|
||||
|
||||
// Check to see if the field is constant.
|
||||
Klass* k = _holder->get_Klass();
|
||||
|
||||
@ -86,8 +86,6 @@
|
||||
|
||||
#define JAVA_CLASSFILE_MAGIC 0xCAFEBABE
|
||||
#define JAVA_MIN_SUPPORTED_VERSION 45
|
||||
#define JAVA_MAX_SUPPORTED_VERSION 54
|
||||
#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
|
||||
|
||||
// Used for two backward compatibility reasons:
|
||||
// - to check for new additions to the class file format in JDK1.5
|
||||
@ -110,6 +108,8 @@
|
||||
|
||||
#define JAVA_10_VERSION 54
|
||||
|
||||
#define JAVA_11_VERSION 55
|
||||
|
||||
void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
|
||||
assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
|
||||
"Unexpected bad constant pool entry");
|
||||
@ -4642,11 +4642,11 @@ static bool has_illegal_visibility(jint flags) {
|
||||
}
|
||||
|
||||
static bool is_supported_version(u2 major, u2 minor){
|
||||
const u2 max_version = JAVA_MAX_SUPPORTED_VERSION;
|
||||
const u2 max_version = JVM_CLASSFILE_MAJOR_VERSION;
|
||||
return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
|
||||
(major <= max_version) &&
|
||||
((major != max_version) ||
|
||||
(minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION));
|
||||
(minor <= JVM_CLASSFILE_MINOR_VERSION));
|
||||
}
|
||||
|
||||
void ClassFileParser::verify_legal_field_modifiers(jint flags,
|
||||
@ -5808,8 +5808,8 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream,
|
||||
_class_name->as_C_string(),
|
||||
_major_version,
|
||||
_minor_version,
|
||||
JAVA_MAX_SUPPORTED_VERSION,
|
||||
JAVA_MAX_SUPPORTED_MINOR_VERSION);
|
||||
JVM_CLASSFILE_MAJOR_VERSION,
|
||||
JVM_CLASSFILE_MINOR_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -315,12 +315,13 @@ InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS
|
||||
return k;
|
||||
}
|
||||
|
||||
InstanceKlass* ClassListParser::load_current_class(TRAPS) {
|
||||
Klass* ClassListParser::load_current_class(TRAPS) {
|
||||
TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name, THREAD);
|
||||
guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
|
||||
|
||||
InstanceKlass *klass = NULL;
|
||||
Klass *klass = NULL;
|
||||
if (!is_loading_from_source()) {
|
||||
// Load classes for the boot/platform/app loaders only.
|
||||
if (is_super_specified()) {
|
||||
error("If source location is not specified, super class must not be specified");
|
||||
}
|
||||
@ -330,40 +331,36 @@ InstanceKlass* ClassListParser::load_current_class(TRAPS) {
|
||||
|
||||
bool non_array = !FieldType::is_array(class_name_symbol);
|
||||
|
||||
Handle s = java_lang_String::create_from_symbol(class_name_symbol, CHECK_0);
|
||||
// Translate to external class name format, i.e., convert '/' chars to '.'
|
||||
Handle string = java_lang_String::externalize_classname(s, CHECK_0);
|
||||
JavaValue result(T_OBJECT);
|
||||
InstanceKlass* spec_klass = non_array ?
|
||||
SystemDictionary::ClassLoader_klass() : SystemDictionary::Class_klass();
|
||||
Symbol* method_name = non_array ?
|
||||
vmSymbols::loadClass_name() : vmSymbols::forName_name();
|
||||
Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
|
||||
|
||||
if (non_array) {
|
||||
// At this point, we are executing in the context of the boot loader. We
|
||||
// cannot call Class.forName because that is context dependent and
|
||||
// would load only classes for the boot loader.
|
||||
//
|
||||
// Instead, let's call java_system_loader().loadClass() directly, which will
|
||||
// delegate to the correct loader (boot, platform or app) depending on
|
||||
// the class name.
|
||||
|
||||
Handle s = java_lang_String::create_from_symbol(class_name_symbol, CHECK_0);
|
||||
// ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.'
|
||||
Handle ext_class_name = java_lang_String::externalize_classname(s, CHECK_0);
|
||||
Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
|
||||
|
||||
JavaCalls::call_virtual(&result,
|
||||
loader, //SystemDictionary::java_system_loader(),
|
||||
spec_klass,
|
||||
method_name, //vmSymbols::loadClass_name(),
|
||||
SystemDictionary::ClassLoader_klass(),
|
||||
vmSymbols::loadClass_name(),
|
||||
vmSymbols::string_class_signature(),
|
||||
string,
|
||||
ext_class_name,
|
||||
THREAD);
|
||||
} else {
|
||||
JavaCalls::call_static(&result,
|
||||
spec_klass,
|
||||
method_name,
|
||||
vmSymbols::string_class_signature(),
|
||||
string,
|
||||
CHECK_NULL);
|
||||
// array classes are not supported in class list.
|
||||
THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
|
||||
}
|
||||
assert(result.get_type() == T_OBJECT, "just checking");
|
||||
oop obj = (oop) result.get_jobject();
|
||||
if (!HAS_PENDING_EXCEPTION && (obj != NULL)) {
|
||||
if (non_array) {
|
||||
klass = InstanceKlass::cast(java_lang_Class::as_Klass(obj));
|
||||
} else {
|
||||
klass = static_cast<InstanceKlass*>(java_lang_Class::array_klass_acquire(obj));
|
||||
}
|
||||
klass = java_lang_Class::as_Klass(obj);
|
||||
} else { // load classes in bootclasspath/a
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
@ -372,7 +369,7 @@ InstanceKlass* ClassListParser::load_current_class(TRAPS) {
|
||||
if (non_array) {
|
||||
Klass* k = SystemDictionary::resolve_or_null(class_name_symbol, CHECK_NULL);
|
||||
if (k != NULL) {
|
||||
klass = InstanceKlass::cast(k);
|
||||
klass = k;
|
||||
} else {
|
||||
if (!HAS_PENDING_EXCEPTION) {
|
||||
THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
|
||||
@ -388,14 +385,15 @@ InstanceKlass* ClassListParser::load_current_class(TRAPS) {
|
||||
}
|
||||
}
|
||||
|
||||
if (klass != NULL && is_id_specified()) {
|
||||
if (klass != NULL && klass->is_instance_klass() && is_id_specified()) {
|
||||
InstanceKlass* ik = InstanceKlass::cast(klass);
|
||||
int id = this->id();
|
||||
SystemDictionaryShared::update_shared_entry(klass, id);
|
||||
SystemDictionaryShared::update_shared_entry(ik, id);
|
||||
InstanceKlass* old = table()->lookup(id);
|
||||
if (old != NULL && old != klass) {
|
||||
if (old != NULL && old != ik) {
|
||||
error("Duplicated ID %d for class %s", id, _class_name);
|
||||
}
|
||||
table()->add(id, klass);
|
||||
table()->add(id, ik);
|
||||
}
|
||||
|
||||
return klass;
|
||||
|
||||
@ -136,7 +136,7 @@ public:
|
||||
return _class_name;
|
||||
}
|
||||
|
||||
InstanceKlass* load_current_class(TRAPS);
|
||||
Klass* load_current_class(TRAPS);
|
||||
|
||||
bool is_loading_from_source();
|
||||
|
||||
|
||||
@ -574,9 +574,9 @@ void ClassLoaderData::unload() {
|
||||
ls.cr();
|
||||
}
|
||||
|
||||
// In some rare cases items added to this list will not be freed elsewhere.
|
||||
// To keep it simple, just free everything in it here.
|
||||
free_deallocate_list();
|
||||
// Some items on the _deallocate_list need to free their C heap structures
|
||||
// if they are not already on the _klasses list.
|
||||
unload_deallocate_list();
|
||||
|
||||
// Clean up global class iterator for compiler
|
||||
static_klass_iterator.adjust_saved_class(this);
|
||||
@ -755,6 +755,7 @@ OopHandle ClassLoaderData::add_handle(Handle h) {
|
||||
}
|
||||
|
||||
void ClassLoaderData::remove_handle(OopHandle h) {
|
||||
assert(!is_unloading(), "Do not remove a handle for a CLD that is unloading");
|
||||
oop* ptr = h.ptr_raw();
|
||||
if (ptr != NULL) {
|
||||
assert(_handles.contains(ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr));
|
||||
@ -799,6 +800,7 @@ void ClassLoaderData::add_to_deallocate_list(Metadata* m) {
|
||||
void ClassLoaderData::free_deallocate_list() {
|
||||
// Don't need lock, at safepoint
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
||||
assert(!is_unloading(), "only called for ClassLoaderData that are not unloading");
|
||||
if (_deallocate_list == NULL) {
|
||||
return;
|
||||
}
|
||||
@ -828,6 +830,36 @@ void ClassLoaderData::free_deallocate_list() {
|
||||
}
|
||||
}
|
||||
|
||||
// This is distinct from free_deallocate_list. For class loader data that are
|
||||
// unloading, this frees the C heap memory for items on the list, and unlinks
|
||||
// scratch or error classes so that unloading events aren't triggered for these
|
||||
// classes. The metadata is removed with the unloading metaspace.
|
||||
// There isn't C heap memory allocated for methods, so nothing is done for them.
|
||||
void ClassLoaderData::unload_deallocate_list() {
|
||||
// Don't need lock, at safepoint
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
||||
assert(is_unloading(), "only called for ClassLoaderData that are unloading");
|
||||
if (_deallocate_list == NULL) {
|
||||
return;
|
||||
}
|
||||
// Go backwards because this removes entries that are freed.
|
||||
for (int i = _deallocate_list->length() - 1; i >= 0; i--) {
|
||||
Metadata* m = _deallocate_list->at(i);
|
||||
assert (!m->on_stack(), "wouldn't be unloading if this were so");
|
||||
_deallocate_list->remove_at(i);
|
||||
if (m->is_constantPool()) {
|
||||
((ConstantPool*)m)->release_C_heap_structures();
|
||||
} else if (m->is_klass()) {
|
||||
InstanceKlass* ik = (InstanceKlass*)m;
|
||||
// also releases ik->constants() C heap memory
|
||||
InstanceKlass::release_C_heap_structures(ik);
|
||||
// Remove the class so unloading events aren't triggered for
|
||||
// this class (scratch or error class) in do_unloading().
|
||||
remove_class(ik);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These anonymous class loaders are to contain classes used for JSR292
|
||||
ClassLoaderData* ClassLoaderData::anonymous_class_loader_data(oop loader, TRAPS) {
|
||||
// Add a new class loader data to the graph.
|
||||
|
||||
@ -307,7 +307,8 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
void packages_do(void f(PackageEntry*));
|
||||
|
||||
// Deallocate free list during class unloading.
|
||||
void free_deallocate_list();
|
||||
void free_deallocate_list(); // for the classes that are not unloaded
|
||||
void unload_deallocate_list(); // for the classes that are unloaded
|
||||
|
||||
// Allocate out of this class loader data
|
||||
MetaWord* allocate(size_t size);
|
||||
|
||||
@ -996,8 +996,8 @@
|
||||
do_name( montgomerySquare_name, "implMontgomerySquare") \
|
||||
do_signature(montgomerySquare_signature, "([I[IIJ[I)[I") \
|
||||
\
|
||||
do_class(java_util_ArraysSupport, "java/util/ArraysSupport") \
|
||||
do_intrinsic(_vectorizedMismatch, java_util_ArraysSupport, vectorizedMismatch_name, vectorizedMismatch_signature, F_S)\
|
||||
do_class(jdk_internal_util_ArraysSupport, "jdk/internal/util/ArraysSupport") \
|
||||
do_intrinsic(_vectorizedMismatch, jdk_internal_util_ArraysSupport, vectorizedMismatch_name, vectorizedMismatch_signature, F_S)\
|
||||
do_name(vectorizedMismatch_name, "vectorizedMismatch") \
|
||||
do_signature(vectorizedMismatch_signature, "(Ljava/lang/Object;JLjava/lang/Object;JII)I") \
|
||||
\
|
||||
|
||||
@ -1852,17 +1852,23 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
||||
TraceTime t1("compilation", &time);
|
||||
EventCompilation event;
|
||||
|
||||
JVMCIEnv env(task, system_dictionary_modification_counter);
|
||||
methodHandle method(thread, target_handle);
|
||||
jvmci->compile_method(method, osr_bci, &env);
|
||||
// Skip redefined methods
|
||||
if (target_handle->is_old()) {
|
||||
failure_reason = "redefined method";
|
||||
retry_message = "not retryable";
|
||||
compilable = ciEnv::MethodCompilable_never;
|
||||
} else {
|
||||
JVMCIEnv env(task, system_dictionary_modification_counter);
|
||||
methodHandle method(thread, target_handle);
|
||||
jvmci->compile_method(method, osr_bci, &env);
|
||||
|
||||
post_compile(thread, task, event, task->code() != NULL, NULL);
|
||||
|
||||
failure_reason = env.failure_reason();
|
||||
if (!env.retryable()) {
|
||||
retry_message = "not retryable";
|
||||
compilable = ciEnv::MethodCompilable_not_at_tier;
|
||||
failure_reason = env.failure_reason();
|
||||
if (!env.retryable()) {
|
||||
retry_message = "not retryable";
|
||||
compilable = ciEnv::MethodCompilable_not_at_tier;
|
||||
}
|
||||
}
|
||||
post_compile(thread, task, event, task->code() != NULL, NULL);
|
||||
|
||||
} else
|
||||
#endif // INCLUDE_JVMCI
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,17 +42,17 @@ void G1AllocRegion::setup(G1CollectedHeap* g1h, HeapRegion* dummy_region) {
|
||||
|
||||
// Make sure that any allocation attempt on this region will fail
|
||||
// and will not trigger any asserts.
|
||||
assert(allocate(dummy_region, 1, false) == NULL, "should fail");
|
||||
assert(par_allocate(dummy_region, 1, false) == NULL, "should fail");
|
||||
assert(allocate(dummy_region, 1, true) == NULL, "should fail");
|
||||
assert(par_allocate(dummy_region, 1, true) == NULL, "should fail");
|
||||
assert(dummy_region->allocate_no_bot_updates(1) == NULL, "should fail");
|
||||
assert(dummy_region->allocate(1) == NULL, "should fail");
|
||||
DEBUG_ONLY(size_t assert_tmp);
|
||||
assert(dummy_region->par_allocate_no_bot_updates(1, 1, &assert_tmp) == NULL, "should fail");
|
||||
assert(dummy_region->par_allocate(1, 1, &assert_tmp) == NULL, "should fail");
|
||||
|
||||
_g1h = g1h;
|
||||
_dummy_region = dummy_region;
|
||||
}
|
||||
|
||||
size_t G1AllocRegion::fill_up_remaining_space(HeapRegion* alloc_region,
|
||||
bool bot_updates) {
|
||||
size_t G1AllocRegion::fill_up_remaining_space(HeapRegion* alloc_region) {
|
||||
assert(alloc_region != NULL && alloc_region != _dummy_region,
|
||||
"pre-condition");
|
||||
size_t result = 0;
|
||||
@ -74,7 +74,7 @@ size_t G1AllocRegion::fill_up_remaining_space(HeapRegion* alloc_region,
|
||||
size_t min_word_size_to_fill = CollectedHeap::min_fill_size();
|
||||
|
||||
while (free_word_size >= min_word_size_to_fill) {
|
||||
HeapWord* dummy = par_allocate(alloc_region, free_word_size, bot_updates);
|
||||
HeapWord* dummy = par_allocate(alloc_region, free_word_size);
|
||||
if (dummy != NULL) {
|
||||
// If the allocation was successful we should fill in the space.
|
||||
CollectedHeap::fill_with_object(dummy, free_word_size);
|
||||
@ -110,7 +110,7 @@ size_t G1AllocRegion::retire(bool fill_up) {
|
||||
"the alloc region should never be empty");
|
||||
|
||||
if (fill_up) {
|
||||
result = fill_up_remaining_space(alloc_region, _bot_updates);
|
||||
result = fill_up_remaining_space(alloc_region);
|
||||
}
|
||||
|
||||
assert_alloc_region(alloc_region->used() >= _used_bytes_before, "invariant");
|
||||
@ -135,7 +135,7 @@ HeapWord* G1AllocRegion::new_alloc_region_and_allocate(size_t word_size,
|
||||
new_alloc_region->reset_pre_dummy_top();
|
||||
// Need to do this before the allocation
|
||||
_used_bytes_before = new_alloc_region->used();
|
||||
HeapWord* result = allocate(new_alloc_region, word_size, _bot_updates);
|
||||
HeapWord* result = allocate(new_alloc_region, word_size);
|
||||
assert_alloc_region(result != NULL, "the allocation should succeeded");
|
||||
|
||||
OrderAccess::storestore();
|
||||
@ -301,7 +301,7 @@ HeapRegion* OldGCAllocRegion::release() {
|
||||
// possible object. In this case this region will not be retained, so the
|
||||
// original problem cannot occur.
|
||||
if (to_allocate_words >= G1CollectedHeap::min_fill_size()) {
|
||||
HeapWord* dummy = attempt_allocation(to_allocate_words, true /* bot_updates */);
|
||||
HeapWord* dummy = attempt_allocation(to_allocate_words);
|
||||
CollectedHeap::fill_with_object(dummy, to_allocate_words);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -83,37 +83,27 @@ private:
|
||||
// whether the _alloc_region is NULL or not.
|
||||
static HeapRegion* _dummy_region;
|
||||
|
||||
// Some of the methods below take a bot_updates parameter. Its value
|
||||
// should be the same as the _bot_updates field. The idea is that
|
||||
// the parameter will be a constant for a particular alloc region
|
||||
// and, given that these methods will be hopefully inlined, the
|
||||
// compiler should compile out the test.
|
||||
|
||||
// Perform a non-MT-safe allocation out of the given region.
|
||||
static inline HeapWord* allocate(HeapRegion* alloc_region,
|
||||
size_t word_size,
|
||||
bool bot_updates);
|
||||
inline HeapWord* allocate(HeapRegion* alloc_region,
|
||||
size_t word_size);
|
||||
|
||||
// Perform a MT-safe allocation out of the given region.
|
||||
static inline HeapWord* par_allocate(HeapRegion* alloc_region,
|
||||
size_t word_size,
|
||||
bool bot_updates);
|
||||
inline HeapWord* par_allocate(HeapRegion* alloc_region,
|
||||
size_t word_size);
|
||||
// Perform a MT-safe allocation out of the given region, with the given
|
||||
// minimum and desired size. Returns the actual size allocated (between
|
||||
// minimum and desired size) in actual_word_size if the allocation has been
|
||||
// successful.
|
||||
static inline HeapWord* par_allocate(HeapRegion* alloc_region,
|
||||
size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size,
|
||||
bool bot_updates);
|
||||
inline HeapWord* par_allocate(HeapRegion* alloc_region,
|
||||
size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size);
|
||||
|
||||
// Ensure that the region passed as a parameter has been filled up
|
||||
// so that noone else can allocate out of it any more.
|
||||
// Returns the number of bytes that have been wasted by filled up
|
||||
// the space.
|
||||
static size_t fill_up_remaining_space(HeapRegion* alloc_region,
|
||||
bool bot_updates);
|
||||
size_t fill_up_remaining_space(HeapRegion* alloc_region);
|
||||
|
||||
// After a region is allocated by alloc_new_region, this
|
||||
// method is used to set it as the active alloc_region
|
||||
@ -160,8 +150,7 @@ public:
|
||||
// First-level allocation: Should be called without holding a
|
||||
// lock. It will try to allocate lock-free out of the active region,
|
||||
// or return NULL if it was unable to.
|
||||
inline HeapWord* attempt_allocation(size_t word_size,
|
||||
bool bot_updates);
|
||||
inline HeapWord* attempt_allocation(size_t word_size);
|
||||
// Perform an allocation out of the current allocation region, with the given
|
||||
// minimum and desired size. Returns the actual size allocated (between
|
||||
// minimum and desired size) in actual_word_size if the allocation has been
|
||||
@ -170,8 +159,7 @@ public:
|
||||
// out of the active region, or return NULL if it was unable to.
|
||||
inline HeapWord* attempt_allocation(size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size,
|
||||
bool bot_updates);
|
||||
size_t* actual_word_size);
|
||||
|
||||
// Second-level allocation: Should be called while holding a
|
||||
// lock. It will try to first allocate lock-free out of the active
|
||||
@ -179,23 +167,20 @@ public:
|
||||
// alloc region with a new one. We require that the caller takes the
|
||||
// appropriate lock before calling this so that it is easier to make
|
||||
// it conform to its locking protocol.
|
||||
inline HeapWord* attempt_allocation_locked(size_t word_size,
|
||||
bool bot_updates);
|
||||
inline HeapWord* attempt_allocation_locked(size_t word_size);
|
||||
// Same as attempt_allocation_locked(size_t, bool), but allowing specification
|
||||
// of minimum word size of the block in min_word_size, and the maximum word
|
||||
// size of the allocation in desired_word_size. The actual size of the block is
|
||||
// returned in actual_word_size.
|
||||
inline HeapWord* attempt_allocation_locked(size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size,
|
||||
bool bot_updates);
|
||||
size_t* actual_word_size);
|
||||
|
||||
// Should be called to allocate a new region even if the max of this
|
||||
// type of regions has been reached. Should only be called if other
|
||||
// allocation attempts have failed and we are not holding a valid
|
||||
// active region.
|
||||
inline HeapWord* attempt_allocation_force(size_t word_size,
|
||||
bool bot_updates);
|
||||
inline HeapWord* attempt_allocation_force(size_t word_size);
|
||||
|
||||
// Should be called before we start using this object.
|
||||
void init();
|
||||
@ -236,7 +221,7 @@ protected:
|
||||
virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
|
||||
|
||||
virtual size_t retire(bool fill_up);
|
||||
public:
|
||||
|
||||
G1GCAllocRegion(const char* name, bool bot_updates, G1EvacStats* stats, InCSetState::in_cset_state_t purpose)
|
||||
: G1AllocRegion(name, bot_updates), _stats(stats), _purpose(purpose) {
|
||||
assert(stats != NULL, "Must pass non-NULL PLAB statistics");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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,52 +37,47 @@
|
||||
|
||||
|
||||
inline HeapWord* G1AllocRegion::allocate(HeapRegion* alloc_region,
|
||||
size_t word_size,
|
||||
bool bot_updates) {
|
||||
size_t word_size) {
|
||||
assert(alloc_region != NULL, "pre-condition");
|
||||
|
||||
if (!bot_updates) {
|
||||
if (!_bot_updates) {
|
||||
return alloc_region->allocate_no_bot_updates(word_size);
|
||||
} else {
|
||||
return alloc_region->allocate(word_size);
|
||||
}
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::par_allocate(HeapRegion* alloc_region, size_t word_size, bool bot_updates) {
|
||||
inline HeapWord* G1AllocRegion::par_allocate(HeapRegion* alloc_region, size_t word_size) {
|
||||
size_t temp;
|
||||
return par_allocate(alloc_region, word_size, word_size, &temp, bot_updates);
|
||||
return par_allocate(alloc_region, word_size, word_size, &temp);
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::par_allocate(HeapRegion* alloc_region,
|
||||
size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size,
|
||||
bool bot_updates) {
|
||||
size_t* actual_word_size) {
|
||||
assert(alloc_region != NULL, "pre-condition");
|
||||
assert(!alloc_region->is_empty(), "pre-condition");
|
||||
|
||||
if (!bot_updates) {
|
||||
if (!_bot_updates) {
|
||||
return alloc_region->par_allocate_no_bot_updates(min_word_size, desired_word_size, actual_word_size);
|
||||
} else {
|
||||
return alloc_region->par_allocate(min_word_size, desired_word_size, actual_word_size);
|
||||
}
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation(size_t word_size, bool bot_updates) {
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation(size_t word_size) {
|
||||
size_t temp;
|
||||
return attempt_allocation(word_size, word_size, &temp, bot_updates);
|
||||
return attempt_allocation(word_size, word_size, &temp);
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation(size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size,
|
||||
bool bot_updates) {
|
||||
assert_alloc_region(bot_updates == _bot_updates, "pre-condition");
|
||||
|
||||
size_t* actual_word_size) {
|
||||
HeapRegion* alloc_region = _alloc_region;
|
||||
assert_alloc_region(alloc_region != NULL, "not initialized properly");
|
||||
|
||||
HeapWord* result = par_allocate(alloc_region, min_word_size, desired_word_size, actual_word_size, bot_updates);
|
||||
HeapWord* result = par_allocate(alloc_region, min_word_size, desired_word_size, actual_word_size);
|
||||
if (result != NULL) {
|
||||
trace("alloc", min_word_size, desired_word_size, *actual_word_size, result);
|
||||
return result;
|
||||
@ -91,19 +86,18 @@ inline HeapWord* G1AllocRegion::attempt_allocation(size_t min_word_size,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation_locked(size_t word_size, bool bot_updates) {
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation_locked(size_t word_size) {
|
||||
size_t temp;
|
||||
return attempt_allocation_locked(word_size, word_size, &temp, bot_updates);
|
||||
return attempt_allocation_locked(word_size, word_size, &temp);
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation_locked(size_t min_word_size,
|
||||
size_t desired_word_size,
|
||||
size_t* actual_word_size,
|
||||
bool bot_updates) {
|
||||
size_t* actual_word_size) {
|
||||
// First we have to redo the allocation, assuming we're holding the
|
||||
// appropriate lock, in case another thread changed the region while
|
||||
// we were waiting to get the lock.
|
||||
HeapWord* result = attempt_allocation(min_word_size, desired_word_size, actual_word_size, bot_updates);
|
||||
HeapWord* result = attempt_allocation(min_word_size, desired_word_size, actual_word_size);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
@ -119,9 +113,7 @@ inline HeapWord* G1AllocRegion::attempt_allocation_locked(size_t min_word_size,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation_force(size_t word_size,
|
||||
bool bot_updates) {
|
||||
assert_alloc_region(bot_updates == _bot_updates, "pre-condition");
|
||||
inline HeapWord* G1AllocRegion::attempt_allocation_force(size_t word_size) {
|
||||
assert_alloc_region(_alloc_region != NULL, "not initialized properly");
|
||||
|
||||
trace("forcing alloc", word_size, word_size);
|
||||
|
||||
@ -190,14 +190,12 @@ HeapWord* G1Allocator::survivor_attempt_allocation(size_t min_word_size,
|
||||
|
||||
HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(min_word_size,
|
||||
desired_word_size,
|
||||
actual_word_size,
|
||||
false /* bot_updates */);
|
||||
actual_word_size);
|
||||
if (result == NULL && !survivor_is_full(context)) {
|
||||
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
|
||||
result = survivor_gc_alloc_region(context)->attempt_allocation_locked(min_word_size,
|
||||
desired_word_size,
|
||||
actual_word_size,
|
||||
false /* bot_updates */);
|
||||
actual_word_size);
|
||||
if (result == NULL) {
|
||||
set_survivor_full(context);
|
||||
}
|
||||
@ -217,14 +215,12 @@ HeapWord* G1Allocator::old_attempt_allocation(size_t min_word_size,
|
||||
|
||||
HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(min_word_size,
|
||||
desired_word_size,
|
||||
actual_word_size,
|
||||
true /* bot_updates */);
|
||||
actual_word_size);
|
||||
if (result == NULL && !old_is_full(context)) {
|
||||
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
|
||||
result = old_gc_alloc_region(context)->attempt_allocation_locked(min_word_size,
|
||||
desired_word_size,
|
||||
actual_word_size,
|
||||
true /* bot_updates */);
|
||||
actual_word_size);
|
||||
if (result == NULL) {
|
||||
set_old_full(context);
|
||||
}
|
||||
|
||||
@ -30,18 +30,18 @@
|
||||
#include "gc/shared/plab.inline.hpp"
|
||||
|
||||
HeapWord* G1Allocator::attempt_allocation(size_t word_size, AllocationContext_t context) {
|
||||
return mutator_alloc_region(context)->attempt_allocation(word_size, false /* bot_updates */);
|
||||
return mutator_alloc_region(context)->attempt_allocation(word_size);
|
||||
}
|
||||
|
||||
HeapWord* G1Allocator::attempt_allocation_locked(size_t word_size, AllocationContext_t context) {
|
||||
HeapWord* result = mutator_alloc_region(context)->attempt_allocation_locked(word_size, false /* bot_updates */);
|
||||
HeapWord* result = mutator_alloc_region(context)->attempt_allocation_locked(word_size);
|
||||
assert(result != NULL || mutator_alloc_region(context)->get() == NULL,
|
||||
"Must not have a mutator alloc region if there is no memory, but is " PTR_FORMAT, p2i(mutator_alloc_region(context)->get()));
|
||||
return result;
|
||||
}
|
||||
|
||||
HeapWord* G1Allocator::attempt_allocation_force(size_t word_size, AllocationContext_t context) {
|
||||
return mutator_alloc_region(context)->attempt_allocation_force(word_size, false /* bot_updates */);
|
||||
return mutator_alloc_region(context)->attempt_allocation_force(word_size);
|
||||
}
|
||||
|
||||
inline HeapWord* G1PLABAllocator::plab_allocate(InCSetState dest,
|
||||
|
||||
@ -600,6 +600,9 @@ JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Hand
|
||||
|
||||
if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
|
||||
oop stubName = HotSpotCompiledCode::name(compiled_code_obj);
|
||||
if (oopDesc::is_null(stubName)) {
|
||||
JVMCI_ERROR_OK("stub should have a name");
|
||||
}
|
||||
char* name = strdup(java_lang_String::as_utf8_string(stubName));
|
||||
cb = RuntimeStub::new_runtime_stub(name,
|
||||
&buffer,
|
||||
|
||||
@ -761,6 +761,10 @@ C2V_END
|
||||
|
||||
C2V_VMENTRY(jboolean, isCompilable,(JNIEnv *, jobject, jobject jvmci_method))
|
||||
methodHandle method = CompilerToVM::asMethod(jvmci_method);
|
||||
// Skip redefined methods
|
||||
if (method->is_old()) {
|
||||
return false;
|
||||
}
|
||||
return !method->is_not_compilable(CompLevel_full_optimization);
|
||||
C2V_END
|
||||
|
||||
|
||||
@ -3695,7 +3695,6 @@ void Metaspace::ergo_initialize() {
|
||||
MaxMetaspaceExpansion = align_down_bounded(MaxMetaspaceExpansion, _commit_alignment);
|
||||
|
||||
CompressedClassSpaceSize = align_down_bounded(CompressedClassSpaceSize, _reserve_alignment);
|
||||
set_compressed_class_space_size(CompressedClassSpaceSize);
|
||||
|
||||
// Initial virtual space size will be calculated at global_initialize()
|
||||
size_t min_metaspace_sz =
|
||||
@ -3714,6 +3713,7 @@ void Metaspace::ergo_initialize() {
|
||||
min_metaspace_sz);
|
||||
}
|
||||
|
||||
set_compressed_class_space_size(CompressedClassSpaceSize);
|
||||
}
|
||||
|
||||
void Metaspace::global_initialize() {
|
||||
|
||||
@ -1627,14 +1627,16 @@ int MetaspaceShared::preload_classes(const char* class_list_path, TRAPS) {
|
||||
log_trace(cds)("Shared spaces preloaded: %s", klass->external_name());
|
||||
}
|
||||
|
||||
InstanceKlass* ik = InstanceKlass::cast(klass);
|
||||
if (klass->is_instance_klass()) {
|
||||
InstanceKlass* ik = InstanceKlass::cast(klass);
|
||||
|
||||
// Link the class to cause the bytecodes to be rewritten and the
|
||||
// cpcache to be created. The linking is done as soon as classes
|
||||
// are loaded in order that the related data structures (klass and
|
||||
// cpCache) are located together.
|
||||
try_link_class(ik, THREAD);
|
||||
guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
|
||||
// Link the class to cause the bytecodes to be rewritten and the
|
||||
// cpcache to be created. The linking is done as soon as classes
|
||||
// are loaded in order that the related data structures (klass and
|
||||
// cpCache) are located together.
|
||||
try_link_class(ik, THREAD);
|
||||
guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
|
||||
}
|
||||
|
||||
class_count++;
|
||||
}
|
||||
|
||||
@ -1094,6 +1094,7 @@ void Compile::Init(int aliaslevel) {
|
||||
_major_progress = true; // start out assuming good things will happen
|
||||
set_has_unsafe_access(false);
|
||||
set_max_vector_size(0);
|
||||
set_clear_upper_avx(false); //false as default for clear upper bits of ymm registers
|
||||
Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
|
||||
set_decompile_count(0);
|
||||
|
||||
|
||||
@ -378,7 +378,8 @@ class Compile : public Phase {
|
||||
bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated
|
||||
bool _has_boxed_value; // True if a boxed object is allocated
|
||||
bool _has_reserved_stack_access; // True if the method or an inlined method is annotated with ReservedStackAccess
|
||||
int _max_vector_size; // Maximum size of generated vectors
|
||||
uint _max_vector_size; // Maximum size of generated vectors
|
||||
bool _clear_upper_avx; // Clear upper bits of ymm registers using vzeroupper
|
||||
uint _trap_hist[trapHistLength]; // Cumulative traps
|
||||
bool _trap_can_recompile; // Have we emitted a recompiling trap?
|
||||
uint _decompile_count; // Cumulative decompilation counts.
|
||||
@ -656,8 +657,10 @@ class Compile : public Phase {
|
||||
void set_has_boxed_value(bool z) { _has_boxed_value = z; }
|
||||
bool has_reserved_stack_access() const { return _has_reserved_stack_access; }
|
||||
void set_has_reserved_stack_access(bool z) { _has_reserved_stack_access = z; }
|
||||
int max_vector_size() const { return _max_vector_size; }
|
||||
void set_max_vector_size(int s) { _max_vector_size = s; }
|
||||
uint max_vector_size() const { return _max_vector_size; }
|
||||
void set_max_vector_size(uint s) { _max_vector_size = s; }
|
||||
bool clear_upper_avx() const { return _clear_upper_avx; }
|
||||
void set_clear_upper_avx(bool s) { _clear_upper_avx = s; }
|
||||
void set_trap_count(uint r, uint c) { assert(r < trapHistLength, "oob"); _trap_hist[r] = c; }
|
||||
uint trap_count(uint r) const { assert(r < trapHistLength, "oob"); return _trap_hist[r]; }
|
||||
bool trap_can_recompile() const { return _trap_can_recompile; }
|
||||
|
||||
@ -328,6 +328,13 @@ class LibraryCallKit : public GraphKit {
|
||||
|
||||
bool inline_profileBoolean();
|
||||
bool inline_isCompileConstant();
|
||||
void clear_upper_avx() {
|
||||
#ifdef X86
|
||||
if (UseAVX >= 2) {
|
||||
C->set_clear_upper_avx(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------make_vm_intrinsic----------------------------
|
||||
@ -1082,6 +1089,7 @@ Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node
|
||||
|
||||
// All these intrinsics have checks.
|
||||
C->set_has_split_ifs(true); // Has chance for split-if optimization
|
||||
clear_upper_avx();
|
||||
|
||||
return _gvn.transform(result);
|
||||
}
|
||||
@ -1156,6 +1164,8 @@ bool LibraryCallKit::inline_array_equals(StrIntrinsicNode::ArgEnc ae) {
|
||||
|
||||
const TypeAryPtr* mtype = (ae == StrIntrinsicNode::UU) ? TypeAryPtr::CHARS : TypeAryPtr::BYTES;
|
||||
set_result(_gvn.transform(new AryEqNode(control(), memory(mtype), arg1, arg2, ae)));
|
||||
clear_upper_avx();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1227,6 +1237,7 @@ bool LibraryCallKit::inline_preconditions_checkIndex() {
|
||||
result = _gvn.transform(result);
|
||||
set_result(result);
|
||||
replace_in_map(index, result);
|
||||
clear_upper_avx();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1325,6 +1336,7 @@ bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
|
||||
set_control(_gvn.transform(region));
|
||||
record_for_igvn(region);
|
||||
set_result(_gvn.transform(phi));
|
||||
clear_upper_avx();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1488,6 +1500,8 @@ bool LibraryCallKit::inline_string_copy(bool compress) {
|
||||
if (compress) {
|
||||
set_result(_gvn.transform(count));
|
||||
}
|
||||
clear_upper_avx();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1585,6 +1599,8 @@ bool LibraryCallKit::inline_string_toBytesU() {
|
||||
if (!stopped()) {
|
||||
set_result(newcopy);
|
||||
}
|
||||
clear_upper_avx();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1789,10 +1805,19 @@ bool LibraryCallKit::inline_math_native(vmIntrinsics::ID id) {
|
||||
return StubRoutines::dexp() != NULL ?
|
||||
runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(), "dexp") :
|
||||
runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp), "EXP");
|
||||
case vmIntrinsics::_dpow:
|
||||
return StubRoutines::dpow() != NULL ?
|
||||
runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
|
||||
case vmIntrinsics::_dpow: {
|
||||
Node* exp = round_double_node(argument(2));
|
||||
const TypeD* d = _gvn.type(exp)->isa_double_constant();
|
||||
if (d != NULL && d->getd() == 2.0) {
|
||||
// Special case: pow(x, 2.0) => x * x
|
||||
Node* base = round_double_node(argument(0));
|
||||
set_result(_gvn.transform(new MulDNode(base, base)));
|
||||
return true;
|
||||
}
|
||||
return StubRoutines::dexp() != NULL ?
|
||||
runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
|
||||
runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow), "POW");
|
||||
}
|
||||
#undef FN_PTR
|
||||
|
||||
// These intrinsics are not yet correctly implemented
|
||||
@ -5286,6 +5311,8 @@ bool LibraryCallKit::inline_arraycopy() {
|
||||
assert(validated, "shouldn't transform if all arguments not validated");
|
||||
set_all_memory(n);
|
||||
}
|
||||
clear_upper_avx();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -5406,6 +5433,8 @@ bool LibraryCallKit::inline_encodeISOArray() {
|
||||
Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
|
||||
set_memory(res_mem, mtype);
|
||||
set_result(enc);
|
||||
clear_upper_avx();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -2442,7 +2442,9 @@ void SuperWord::output() {
|
||||
}
|
||||
}//for (int i = 0; i < _block.length(); i++)
|
||||
|
||||
C->set_max_vector_size(max_vlen_in_bytes);
|
||||
if (max_vlen_in_bytes > C->max_vector_size()) {
|
||||
C->set_max_vector_size(max_vlen_in_bytes);
|
||||
}
|
||||
if (max_vlen_in_bytes > 0) {
|
||||
cl->mark_loop_vectorized();
|
||||
}
|
||||
|
||||
@ -826,7 +826,10 @@ JNI_ENTRY_CHECKED(jint,
|
||||
}
|
||||
jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
|
||||
if (result == JNI_OK) {
|
||||
add_planned_handle_capacity(thr->active_handles(), capacity);
|
||||
// increase local ref capacity if needed
|
||||
if ((size_t)capacity > thr->active_handles()->get_planned_capacity()) {
|
||||
add_planned_handle_capacity(thr->active_handles(), capacity);
|
||||
}
|
||||
}
|
||||
functionExit(thr);
|
||||
return result;
|
||||
|
||||
@ -497,7 +497,7 @@ static SpecialFlag const special_jvm_flags[] = {
|
||||
{ "MaxRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
{ "MinRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
{ "InitialRAMFraction", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
{ "UseMembar", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "UseMembar", JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
|
||||
{ "FastTLABRefill", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "SafepointSpinBeforeYield", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
{ "DeferThrSuspendLoopCount", JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
|
||||
|
||||
@ -470,8 +470,12 @@ void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m
|
||||
if (bci != InvocationEntryBci) {
|
||||
MethodData* mdo = m->method_data();
|
||||
if (mdo != NULL) {
|
||||
int count = mdo->bci_to_data(branch_bci)->as_JumpData()->taken();
|
||||
tty->print_cr("back branch count = %d", count);
|
||||
ProfileData *pd = mdo->bci_to_data(branch_bci);
|
||||
if (pd == NULL) {
|
||||
tty->print_cr("back branch count = N/A (missing ProfileData)");
|
||||
} else {
|
||||
tty->print_cr("back branch count = %d", pd->as_JumpData()->taken());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ void print_statistics() {
|
||||
MemTracker::final_report(tty);
|
||||
}
|
||||
|
||||
ThreadsSMRSupport::log_smr_statistics();
|
||||
ThreadsSMRSupport::log_statistics();
|
||||
}
|
||||
|
||||
#else // PRODUCT MODE STATISTICS
|
||||
@ -399,7 +399,7 @@ void print_statistics() {
|
||||
Method::print_touched_methods(tty);
|
||||
}
|
||||
|
||||
ThreadsSMRSupport::log_smr_statistics();
|
||||
ThreadsSMRSupport::log_statistics();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -2946,8 +2946,9 @@ void JavaThread::metadata_do(void f(Metadata*)) {
|
||||
if (ct->env() != NULL) {
|
||||
ct->env()->metadata_do(f);
|
||||
}
|
||||
if (ct->task() != NULL) {
|
||||
ct->task()->metadata_do(f);
|
||||
CompileTask* task = ct->task();
|
||||
if (task != NULL) {
|
||||
task->metadata_do(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3001,10 +3002,10 @@ void JavaThread::print_on(outputStream *st) const {
|
||||
_safepoint_state->print_on(st);
|
||||
#endif // PRODUCT
|
||||
if (is_Compiler_thread()) {
|
||||
CompilerThread* ct = (CompilerThread*)this;
|
||||
if (ct->task() != NULL) {
|
||||
CompileTask *task = ((CompilerThread*)this)->task();
|
||||
if (task != NULL) {
|
||||
st->print(" Compiling: ");
|
||||
ct->task()->print(st, NULL, true, false);
|
||||
task->print(st, NULL, true, false);
|
||||
} else {
|
||||
st->print(" No compile task");
|
||||
}
|
||||
@ -3473,7 +3474,7 @@ static inline void *prefetch_and_load_ptr(void **addr, intx prefetch_interval) {
|
||||
X = (JavaThread*)prefetch_and_load_ptr((void**)MACRO_current_p, (intx)MACRO_scan_interval))
|
||||
|
||||
// All JavaThreads
|
||||
#define ALL_JAVA_THREADS(X) DO_JAVA_THREADS(ThreadsSMRSupport::get_smr_java_thread_list(), X)
|
||||
#define ALL_JAVA_THREADS(X) DO_JAVA_THREADS(ThreadsSMRSupport::get_java_thread_list(), X)
|
||||
|
||||
// All JavaThreads + all non-JavaThreads (i.e., every thread in the system)
|
||||
void Threads::threads_do(ThreadClosure* tc) {
|
||||
@ -4382,7 +4383,7 @@ void Threads::remove(JavaThread* p) {
|
||||
// that we do not remove thread without safepoint code notice
|
||||
{ MutexLocker ml(Threads_lock);
|
||||
|
||||
assert(ThreadsSMRSupport::get_smr_java_thread_list()->includes(p), "p must be present");
|
||||
assert(ThreadsSMRSupport::get_java_thread_list()->includes(p), "p must be present");
|
||||
|
||||
// Maintain fast thread list
|
||||
ThreadsSMRSupport::remove_thread(p);
|
||||
@ -4610,7 +4611,7 @@ void Threads::print_on(outputStream* st, bool print_stacks,
|
||||
}
|
||||
#endif // INCLUDE_SERVICES
|
||||
|
||||
ThreadsSMRSupport::print_smr_info_on(st);
|
||||
ThreadsSMRSupport::print_info_on(st);
|
||||
st->cr();
|
||||
|
||||
ALL_JAVA_THREADS(p) {
|
||||
@ -4679,7 +4680,7 @@ class PrintOnErrorClosure : public ThreadClosure {
|
||||
// memory (even in resource area), it might deadlock the error handler.
|
||||
void Threads::print_on_error(outputStream* st, Thread* current, char* buf,
|
||||
int buflen) {
|
||||
ThreadsSMRSupport::print_smr_info_on(st);
|
||||
ThreadsSMRSupport::print_info_on(st);
|
||||
st->cr();
|
||||
|
||||
bool found_current = false;
|
||||
@ -4712,9 +4713,15 @@ void Threads::print_threads_compiling(outputStream* st, char* buf, int buflen) {
|
||||
ALL_JAVA_THREADS(thread) {
|
||||
if (thread->is_Compiler_thread()) {
|
||||
CompilerThread* ct = (CompilerThread*) thread;
|
||||
if (ct->task() != NULL) {
|
||||
|
||||
// Keep task in local variable for NULL check.
|
||||
// ct->_task might be set to NULL by concurring compiler thread
|
||||
// because it completed the compilation. The task is never freed,
|
||||
// though, just returned to a free list.
|
||||
CompileTask* task = ct->task();
|
||||
if (task != NULL) {
|
||||
thread->print_name_on_error(st, buf, buflen);
|
||||
ct->task()->print(st, NULL, true, true);
|
||||
task->print(st, NULL, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2064,13 +2064,13 @@ class CompilerThread : public JavaThread {
|
||||
private:
|
||||
CompilerCounters* _counters;
|
||||
|
||||
ciEnv* _env;
|
||||
CompileLog* _log;
|
||||
CompileTask* _task;
|
||||
CompileQueue* _queue;
|
||||
BufferBlob* _buffer_blob;
|
||||
ciEnv* _env;
|
||||
CompileLog* _log;
|
||||
CompileTask* volatile _task; // print_threads_compiling can read this concurrently.
|
||||
CompileQueue* _queue;
|
||||
BufferBlob* _buffer_blob;
|
||||
|
||||
AbstractCompiler* _compiler;
|
||||
AbstractCompiler* _compiler;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@ -31,131 +31,131 @@
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
Monitor* ThreadsSMRSupport::_smr_delete_lock =
|
||||
new Monitor(Monitor::special, "smr_delete_lock",
|
||||
Monitor* ThreadsSMRSupport::_delete_lock =
|
||||
new Monitor(Monitor::special, "Thread_SMR_delete_lock",
|
||||
false /* allow_vm_block */,
|
||||
Monitor::_safepoint_check_never);
|
||||
// The '_cnt', '_max' and '_times" fields are enabled via
|
||||
// -XX:+EnableThreadSMRStatistics:
|
||||
|
||||
// # of parallel threads in _smr_delete_lock->wait().
|
||||
// # of parallel threads in _delete_lock->wait().
|
||||
// Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit,
|
||||
// but there is no nice 16-bit _FORMAT support.
|
||||
uint ThreadsSMRSupport::_smr_delete_lock_wait_cnt = 0;
|
||||
uint ThreadsSMRSupport::_delete_lock_wait_cnt = 0;
|
||||
|
||||
// Max # of parallel threads in _smr_delete_lock->wait().
|
||||
// Impl note: See _smr_delete_lock_wait_cnt note.
|
||||
uint ThreadsSMRSupport::_smr_delete_lock_wait_max = 0;
|
||||
// Max # of parallel threads in _delete_lock->wait().
|
||||
// Impl note: See _delete_lock_wait_cnt note.
|
||||
uint ThreadsSMRSupport::_delete_lock_wait_max = 0;
|
||||
|
||||
// Flag to indicate when an _smr_delete_lock->notify() is needed.
|
||||
// Impl note: See _smr_delete_lock_wait_cnt note.
|
||||
volatile uint ThreadsSMRSupport::_smr_delete_notify = 0;
|
||||
// Flag to indicate when an _delete_lock->notify() is needed.
|
||||
// Impl note: See _delete_lock_wait_cnt note.
|
||||
volatile uint ThreadsSMRSupport::_delete_notify = 0;
|
||||
|
||||
// # of threads deleted over VM lifetime.
|
||||
// Impl note: Atomically incremented over VM lifetime so use unsigned for more
|
||||
// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
|
||||
// isn't available everywhere (or is it?).
|
||||
volatile uint ThreadsSMRSupport::_smr_deleted_thread_cnt = 0;
|
||||
volatile uint ThreadsSMRSupport::_deleted_thread_cnt = 0;
|
||||
|
||||
// Max time in millis to delete a thread.
|
||||
// Impl note: 16-bit might be too small on an overloaded machine. Use
|
||||
// unsigned since this is a time value. Set via Atomic::cmpxchg() in a
|
||||
// loop for correctness.
|
||||
volatile uint ThreadsSMRSupport::_smr_deleted_thread_time_max = 0;
|
||||
volatile uint ThreadsSMRSupport::_deleted_thread_time_max = 0;
|
||||
|
||||
// Cumulative time in millis to delete threads.
|
||||
// Impl note: Atomically added to over VM lifetime so use unsigned for more
|
||||
// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
|
||||
// isn't available everywhere (or is it?).
|
||||
volatile uint ThreadsSMRSupport::_smr_deleted_thread_times = 0;
|
||||
volatile uint ThreadsSMRSupport::_deleted_thread_times = 0;
|
||||
|
||||
ThreadsList* volatile ThreadsSMRSupport::_smr_java_thread_list = new ThreadsList(0);
|
||||
ThreadsList* volatile ThreadsSMRSupport::_java_thread_list = new ThreadsList(0);
|
||||
|
||||
// # of ThreadsLists allocated over VM lifetime.
|
||||
// Impl note: We allocate a new ThreadsList for every thread create and
|
||||
// every thread delete so we need a bigger type than the
|
||||
// _smr_deleted_thread_cnt field.
|
||||
uint64_t ThreadsSMRSupport::_smr_java_thread_list_alloc_cnt = 1;
|
||||
// _deleted_thread_cnt field.
|
||||
uint64_t ThreadsSMRSupport::_java_thread_list_alloc_cnt = 1;
|
||||
|
||||
// # of ThreadsLists freed over VM lifetime.
|
||||
// Impl note: See _smr_java_thread_list_alloc_cnt note.
|
||||
uint64_t ThreadsSMRSupport::_smr_java_thread_list_free_cnt = 0;
|
||||
// Impl note: See _java_thread_list_alloc_cnt note.
|
||||
uint64_t ThreadsSMRSupport::_java_thread_list_free_cnt = 0;
|
||||
|
||||
// Max size ThreadsList allocated.
|
||||
// Impl note: Max # of threads alive at one time should fit in unsigned 32-bit.
|
||||
uint ThreadsSMRSupport::_smr_java_thread_list_max = 0;
|
||||
uint ThreadsSMRSupport::_java_thread_list_max = 0;
|
||||
|
||||
// Max # of nested ThreadsLists for a thread.
|
||||
// Impl note: Hard to imagine > 64K nested ThreadsLists so this could be
|
||||
// 16-bit, but there is no nice 16-bit _FORMAT support.
|
||||
uint ThreadsSMRSupport::_smr_nested_thread_list_max = 0;
|
||||
uint ThreadsSMRSupport::_nested_thread_list_max = 0;
|
||||
|
||||
// # of ThreadsListHandles deleted over VM lifetime.
|
||||
// Impl note: Atomically incremented over VM lifetime so use unsigned for
|
||||
// more range. There will be fewer ThreadsListHandles than threads so
|
||||
// unsigned 32-bit should be fine.
|
||||
volatile uint ThreadsSMRSupport::_smr_tlh_cnt = 0;
|
||||
volatile uint ThreadsSMRSupport::_tlh_cnt = 0;
|
||||
|
||||
// Max time in millis to delete a ThreadsListHandle.
|
||||
// Impl note: 16-bit might be too small on an overloaded machine. Use
|
||||
// unsigned since this is a time value. Set via Atomic::cmpxchg() in a
|
||||
// loop for correctness.
|
||||
volatile uint ThreadsSMRSupport::_smr_tlh_time_max = 0;
|
||||
volatile uint ThreadsSMRSupport::_tlh_time_max = 0;
|
||||
|
||||
// Cumulative time in millis to delete ThreadsListHandles.
|
||||
// Impl note: Atomically added to over VM lifetime so use unsigned for more
|
||||
// range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc
|
||||
// isn't available everywhere (or is it?).
|
||||
volatile uint ThreadsSMRSupport::_smr_tlh_times = 0;
|
||||
volatile uint ThreadsSMRSupport::_tlh_times = 0;
|
||||
|
||||
ThreadsList* ThreadsSMRSupport::_smr_to_delete_list = NULL;
|
||||
ThreadsList* ThreadsSMRSupport::_to_delete_list = NULL;
|
||||
|
||||
// # of parallel ThreadsLists on the to-delete list.
|
||||
// Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so
|
||||
// this could be 16-bit, but there is no nice 16-bit _FORMAT support.
|
||||
uint ThreadsSMRSupport::_smr_to_delete_list_cnt = 0;
|
||||
uint ThreadsSMRSupport::_to_delete_list_cnt = 0;
|
||||
|
||||
// Max # of parallel ThreadsLists on the to-delete list.
|
||||
// Impl note: See _smr_to_delete_list_cnt note.
|
||||
uint ThreadsSMRSupport::_smr_to_delete_list_max = 0;
|
||||
// Impl note: See _to_delete_list_cnt note.
|
||||
uint ThreadsSMRSupport::_to_delete_list_max = 0;
|
||||
|
||||
|
||||
// 'inline' functions first so the definitions are before first use:
|
||||
|
||||
inline void ThreadsSMRSupport::add_smr_deleted_thread_times(uint add_value) {
|
||||
Atomic::add(add_value, &_smr_deleted_thread_times);
|
||||
inline void ThreadsSMRSupport::add_deleted_thread_times(uint add_value) {
|
||||
Atomic::add(add_value, &_deleted_thread_times);
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::inc_smr_deleted_thread_cnt() {
|
||||
Atomic::inc(&_smr_deleted_thread_cnt);
|
||||
inline void ThreadsSMRSupport::inc_deleted_thread_cnt() {
|
||||
Atomic::inc(&_deleted_thread_cnt);
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt() {
|
||||
_smr_java_thread_list_alloc_cnt++;
|
||||
inline void ThreadsSMRSupport::inc_java_thread_list_alloc_cnt() {
|
||||
_java_thread_list_alloc_cnt++;
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::update_smr_deleted_thread_time_max(uint new_value) {
|
||||
inline void ThreadsSMRSupport::update_deleted_thread_time_max(uint new_value) {
|
||||
while (true) {
|
||||
uint cur_value = _smr_deleted_thread_time_max;
|
||||
uint cur_value = _deleted_thread_time_max;
|
||||
if (new_value <= cur_value) {
|
||||
// No need to update max value so we're done.
|
||||
break;
|
||||
}
|
||||
if (Atomic::cmpxchg(new_value, &_smr_deleted_thread_time_max, cur_value) == cur_value) {
|
||||
if (Atomic::cmpxchg(new_value, &_deleted_thread_time_max, cur_value) == cur_value) {
|
||||
// Updated max value so we're done. Otherwise try it all again.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::update_smr_java_thread_list_max(uint new_value) {
|
||||
if (new_value > _smr_java_thread_list_max) {
|
||||
_smr_java_thread_list_max = new_value;
|
||||
inline void ThreadsSMRSupport::update_java_thread_list_max(uint new_value) {
|
||||
if (new_value > _java_thread_list_max) {
|
||||
_java_thread_list_max = new_value;
|
||||
}
|
||||
}
|
||||
|
||||
inline ThreadsList* ThreadsSMRSupport::xchg_smr_java_thread_list(ThreadsList* new_list) {
|
||||
return (ThreadsList*)Atomic::xchg(new_list, &_smr_java_thread_list);
|
||||
inline ThreadsList* ThreadsSMRSupport::xchg_java_thread_list(ThreadsList* new_list) {
|
||||
return (ThreadsList*)Atomic::xchg(new_list, &_java_thread_list);
|
||||
}
|
||||
|
||||
|
||||
@ -268,7 +268,7 @@ class ScanHazardPtrGatherProtectedThreadsClosure : public ThreadClosure {
|
||||
}
|
||||
|
||||
// The current JavaThread has a hazard ptr (ThreadsList reference)
|
||||
// which might be _smr_java_thread_list or it might be an older
|
||||
// which might be _java_thread_list or it might be an older
|
||||
// ThreadsList that has been removed but not freed. In either case,
|
||||
// the hazard ptr is protecting all the JavaThreads on that
|
||||
// ThreadsList.
|
||||
@ -347,7 +347,7 @@ class ScanHazardPtrPrintMatchingThreadsClosure : public ThreadClosure {
|
||||
if (Thread::is_hazard_ptr_tagged(current_list)) return;
|
||||
|
||||
// The current JavaThread has a hazard ptr (ThreadsList reference)
|
||||
// which might be _smr_java_thread_list or it might be an older
|
||||
// which might be _java_thread_list or it might be an older
|
||||
// ThreadsList that has been removed but not freed. In either case,
|
||||
// the hazard ptr is protecting all the JavaThreads on that
|
||||
// ThreadsList, but we only care about matching a specific JavaThread.
|
||||
@ -476,7 +476,7 @@ ThreadsListHandle::~ThreadsListHandle() {
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_timer.stop();
|
||||
uint millis = (uint)_timer.milliseconds();
|
||||
ThreadsSMRSupport::update_smr_tlh_stats(millis);
|
||||
ThreadsSMRSupport::update_tlh_stats(millis);
|
||||
}
|
||||
}
|
||||
|
||||
@ -574,12 +574,12 @@ ThreadsList *ThreadsSMRSupport::acquire_stable_list_fast_path(Thread *self) {
|
||||
ThreadsList* threads;
|
||||
|
||||
// Stable recording of a hazard ptr for SMR. This code does not use
|
||||
// locks so its use of the _smr_java_thread_list & _threads_hazard_ptr
|
||||
// locks so its use of the _java_thread_list & _threads_hazard_ptr
|
||||
// fields is racy relative to code that uses those fields with locks.
|
||||
// OrderAccess and Atomic functions are used to deal with those races.
|
||||
//
|
||||
while (true) {
|
||||
threads = get_smr_java_thread_list();
|
||||
threads = get_java_thread_list();
|
||||
|
||||
// Publish a tagged hazard ptr to denote that the hazard ptr is not
|
||||
// yet verified as being stable. Due to the fence after the hazard
|
||||
@ -590,9 +590,9 @@ ThreadsList *ThreadsSMRSupport::acquire_stable_list_fast_path(Thread *self) {
|
||||
ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads);
|
||||
self->set_threads_hazard_ptr(unverified_threads);
|
||||
|
||||
// If _smr_java_thread_list has changed, we have lost a race with
|
||||
// If _java_thread_list has changed, we have lost a race with
|
||||
// Threads::add() or Threads::remove() and have to try again.
|
||||
if (get_smr_java_thread_list() != threads) {
|
||||
if (get_java_thread_list() != threads) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -634,15 +634,15 @@ ThreadsList *ThreadsSMRSupport::acquire_stable_list_nested_path(Thread *self) {
|
||||
{
|
||||
// Only grab the Threads_lock if we don't already own it.
|
||||
MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock);
|
||||
node = new NestedThreadsList(get_smr_java_thread_list());
|
||||
node = new NestedThreadsList(get_java_thread_list());
|
||||
// We insert at the front of the list to match up with the delete
|
||||
// in release_stable_list().
|
||||
node->set_next(self->get_nested_threads_hazard_ptr());
|
||||
self->set_nested_threads_hazard_ptr(node);
|
||||
if (EnableThreadSMRStatistics) {
|
||||
self->inc_nested_threads_hazard_ptr_cnt();
|
||||
if (self->nested_threads_hazard_ptr_cnt() > _smr_nested_thread_list_max) {
|
||||
_smr_nested_thread_list_max = self->nested_threads_hazard_ptr_cnt();
|
||||
if (self->nested_threads_hazard_ptr_cnt() > _nested_thread_list_max) {
|
||||
_nested_thread_list_max = self->nested_threads_hazard_ptr_cnt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -652,25 +652,101 @@ ThreadsList *ThreadsSMRSupport::acquire_stable_list_nested_path(Thread *self) {
|
||||
}
|
||||
|
||||
void ThreadsSMRSupport::add_thread(JavaThread *thread){
|
||||
ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread);
|
||||
ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_java_thread_list(), thread);
|
||||
if (EnableThreadSMRStatistics) {
|
||||
ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt();
|
||||
ThreadsSMRSupport::update_smr_java_thread_list_max(new_list->length());
|
||||
ThreadsSMRSupport::inc_java_thread_list_alloc_cnt();
|
||||
ThreadsSMRSupport::update_java_thread_list_max(new_list->length());
|
||||
}
|
||||
// Initial _smr_java_thread_list will not generate a "Threads::add" mesg.
|
||||
// Initial _java_thread_list will not generate a "Threads::add" mesg.
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
|
||||
|
||||
ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list);
|
||||
ThreadsSMRSupport::smr_free_list(old_list);
|
||||
ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list);
|
||||
ThreadsSMRSupport::free_list(old_list);
|
||||
}
|
||||
|
||||
// set_smr_delete_notify() and clear_smr_delete_notify() are called
|
||||
// under the protection of the smr_delete_lock, but we also use an
|
||||
// set_delete_notify() and clear_delete_notify() are called
|
||||
// under the protection of the delete_lock, but we also use an
|
||||
// Atomic operation to ensure the memory update is seen earlier than
|
||||
// when the smr_delete_lock is dropped.
|
||||
// when the delete_lock is dropped.
|
||||
//
|
||||
void ThreadsSMRSupport::clear_smr_delete_notify() {
|
||||
Atomic::dec(&_smr_delete_notify);
|
||||
void ThreadsSMRSupport::clear_delete_notify() {
|
||||
Atomic::dec(&_delete_notify);
|
||||
}
|
||||
|
||||
bool ThreadsSMRSupport::delete_notify() {
|
||||
// Use load_acquire() in order to see any updates to _delete_notify
|
||||
// earlier than when delete_lock is grabbed.
|
||||
return (OrderAccess::load_acquire(&_delete_notify) != 0);
|
||||
}
|
||||
|
||||
// Safely free a ThreadsList after a Threads::add() or Threads::remove().
|
||||
// The specified ThreadsList may not get deleted during this call if it
|
||||
// is still in-use (referenced by a hazard ptr). Other ThreadsLists
|
||||
// in the chain may get deleted by this call if they are no longer in-use.
|
||||
void ThreadsSMRSupport::free_list(ThreadsList* threads) {
|
||||
assert_locked_or_safepoint(Threads_lock);
|
||||
|
||||
threads->set_next_list(_to_delete_list);
|
||||
_to_delete_list = threads;
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_to_delete_list_cnt++;
|
||||
if (_to_delete_list_cnt > _to_delete_list_max) {
|
||||
_to_delete_list_max = _to_delete_list_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
// Hash table size should be first power of two higher than twice the length of the ThreadsList
|
||||
int hash_table_size = MIN2((int)get_java_thread_list()->length(), 32) << 1;
|
||||
hash_table_size--;
|
||||
hash_table_size |= hash_table_size >> 1;
|
||||
hash_table_size |= hash_table_size >> 2;
|
||||
hash_table_size |= hash_table_size >> 4;
|
||||
hash_table_size |= hash_table_size >> 8;
|
||||
hash_table_size |= hash_table_size >> 16;
|
||||
hash_table_size++;
|
||||
|
||||
// Gather a hash table of the current hazard ptrs:
|
||||
ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size);
|
||||
ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table);
|
||||
Threads::threads_do(&scan_cl);
|
||||
|
||||
// Walk through the linked list of pending freeable ThreadsLists
|
||||
// and free the ones that are not referenced from hazard ptrs.
|
||||
ThreadsList* current = _to_delete_list;
|
||||
ThreadsList* prev = NULL;
|
||||
ThreadsList* next = NULL;
|
||||
bool threads_is_freed = false;
|
||||
while (current != NULL) {
|
||||
next = current->next_list();
|
||||
if (!scan_table->has_entry((void*)current)) {
|
||||
// This ThreadsList is not referenced by a hazard ptr.
|
||||
if (prev != NULL) {
|
||||
prev->set_next_list(next);
|
||||
}
|
||||
if (_to_delete_list == current) {
|
||||
_to_delete_list = next;
|
||||
}
|
||||
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current));
|
||||
if (current == threads) threads_is_freed = true;
|
||||
delete current;
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_java_thread_list_free_cnt++;
|
||||
_to_delete_list_cnt--;
|
||||
}
|
||||
} else {
|
||||
prev = current;
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
|
||||
if (!threads_is_freed) {
|
||||
// Only report "is not freed" on the original call to
|
||||
// free_list() for this ThreadsList.
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads));
|
||||
}
|
||||
|
||||
delete scan_table;
|
||||
}
|
||||
|
||||
// Return true if the specified JavaThread is protected by a hazard
|
||||
@ -681,7 +757,7 @@ bool ThreadsSMRSupport::is_a_protected_JavaThread(JavaThread *thread) {
|
||||
|
||||
// Hash table size should be first power of two higher than twice
|
||||
// the length of the Threads list.
|
||||
int hash_table_size = MIN2((int)get_smr_java_thread_list()->length(), 32) << 1;
|
||||
int hash_table_size = MIN2((int)get_java_thread_list()->length(), 32) << 1;
|
||||
hash_table_size--;
|
||||
hash_table_size |= hash_table_size >> 1;
|
||||
hash_table_size |= hash_table_size >> 2;
|
||||
@ -736,10 +812,10 @@ void ThreadsSMRSupport::release_stable_list_fast_path(Thread *self) {
|
||||
self->set_threads_hazard_ptr(NULL);
|
||||
|
||||
// We use double-check locking to reduce traffic on the system
|
||||
// wide smr_delete_lock.
|
||||
if (ThreadsSMRSupport::smr_delete_notify()) {
|
||||
// wide Thread-SMR delete_lock.
|
||||
if (ThreadsSMRSupport::delete_notify()) {
|
||||
// An exiting thread might be waiting in smr_delete(); we need to
|
||||
// check with smr_delete_lock to be sure.
|
||||
// check with delete_lock to be sure.
|
||||
release_stable_list_wake_up((char *) "regular hazard ptr");
|
||||
}
|
||||
}
|
||||
@ -772,7 +848,7 @@ void ThreadsSMRSupport::release_stable_list_nested_path(Thread *self) {
|
||||
}
|
||||
|
||||
// An exiting thread might be waiting in smr_delete(); we need to
|
||||
// check with smr_delete_lock to be sure.
|
||||
// check with delete_lock to be sure.
|
||||
release_stable_list_wake_up((char *) "nested hazard ptr");
|
||||
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list: delete NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list()));
|
||||
@ -781,21 +857,21 @@ void ThreadsSMRSupport::release_stable_list_nested_path(Thread *self) {
|
||||
}
|
||||
|
||||
// Wake up portion of the release stable ThreadsList protocol;
|
||||
// uses the smr_delete_lock().
|
||||
// uses the delete_lock().
|
||||
//
|
||||
void ThreadsSMRSupport::release_stable_list_wake_up(char *log_str) {
|
||||
assert(log_str != NULL, "sanity check");
|
||||
|
||||
// Note: smr_delete_lock is held in smr_delete() for the entire
|
||||
// Note: delete_lock is held in smr_delete() for the entire
|
||||
// hazard ptr search so that we do not lose this notify() if
|
||||
// the exiting thread has to wait. That code path also holds
|
||||
// Threads_lock (which was grabbed before smr_delete_lock) so that
|
||||
// Threads_lock (which was grabbed before delete_lock) so that
|
||||
// threads_do() can be called. This means the system can't start a
|
||||
// safepoint which means this thread can't take too long to get to
|
||||
// a safepoint because of being blocked on smr_delete_lock.
|
||||
// a safepoint because of being blocked on delete_lock.
|
||||
//
|
||||
MonitorLockerEx ml(ThreadsSMRSupport::smr_delete_lock(), Monitor::_no_safepoint_check_flag);
|
||||
if (ThreadsSMRSupport::smr_delete_notify()) {
|
||||
MonitorLockerEx ml(ThreadsSMRSupport::delete_lock(), Monitor::_no_safepoint_check_flag);
|
||||
if (ThreadsSMRSupport::delete_notify()) {
|
||||
// Notify any exiting JavaThreads that are waiting in smr_delete()
|
||||
// that we've released a ThreadsList.
|
||||
ml.notify_all();
|
||||
@ -804,23 +880,23 @@ void ThreadsSMRSupport::release_stable_list_wake_up(char *log_str) {
|
||||
}
|
||||
|
||||
void ThreadsSMRSupport::remove_thread(JavaThread *thread) {
|
||||
ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread);
|
||||
ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_java_thread_list(), thread);
|
||||
if (EnableThreadSMRStatistics) {
|
||||
ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt();
|
||||
ThreadsSMRSupport::inc_java_thread_list_alloc_cnt();
|
||||
// This list is smaller so no need to check for a "longest" update.
|
||||
}
|
||||
|
||||
// Final _smr_java_thread_list will not generate a "Threads::remove" mesg.
|
||||
// Final _java_thread_list will not generate a "Threads::remove" mesg.
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
|
||||
|
||||
ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list);
|
||||
ThreadsSMRSupport::smr_free_list(old_list);
|
||||
ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list);
|
||||
ThreadsSMRSupport::free_list(old_list);
|
||||
}
|
||||
|
||||
// See note for clear_smr_delete_notify().
|
||||
// See note for clear_delete_notify().
|
||||
//
|
||||
void ThreadsSMRSupport::set_smr_delete_notify() {
|
||||
Atomic::inc(&_smr_delete_notify);
|
||||
void ThreadsSMRSupport::set_delete_notify() {
|
||||
Atomic::inc(&_delete_notify);
|
||||
}
|
||||
|
||||
// Safely delete a JavaThread when it is no longer in use by a
|
||||
@ -842,16 +918,16 @@ void ThreadsSMRSupport::smr_delete(JavaThread *thread) {
|
||||
MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
|
||||
// Cannot use a MonitorLockerEx helper here because we have
|
||||
// to drop the Threads_lock first if we wait.
|
||||
ThreadsSMRSupport::smr_delete_lock()->lock_without_safepoint_check();
|
||||
// Set the smr_delete_notify flag after we grab smr_delete_lock
|
||||
ThreadsSMRSupport::delete_lock()->lock_without_safepoint_check();
|
||||
// Set the delete_notify flag after we grab delete_lock
|
||||
// and before we scan hazard ptrs because we're doing
|
||||
// double-check locking in release_stable_list().
|
||||
ThreadsSMRSupport::set_smr_delete_notify();
|
||||
ThreadsSMRSupport::set_delete_notify();
|
||||
|
||||
if (!is_a_protected_JavaThread(thread)) {
|
||||
// This is the common case.
|
||||
ThreadsSMRSupport::clear_smr_delete_notify();
|
||||
ThreadsSMRSupport::smr_delete_lock()->unlock();
|
||||
ThreadsSMRSupport::clear_delete_notify();
|
||||
ThreadsSMRSupport::delete_lock()->unlock();
|
||||
break;
|
||||
}
|
||||
if (!has_logged_once) {
|
||||
@ -865,22 +941,22 @@ void ThreadsSMRSupport::smr_delete(JavaThread *thread) {
|
||||
} // We have to drop the Threads_lock to wait or delete the thread
|
||||
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_smr_delete_lock_wait_cnt++;
|
||||
if (_smr_delete_lock_wait_cnt > _smr_delete_lock_wait_max) {
|
||||
_smr_delete_lock_wait_max = _smr_delete_lock_wait_cnt;
|
||||
_delete_lock_wait_cnt++;
|
||||
if (_delete_lock_wait_cnt > _delete_lock_wait_max) {
|
||||
_delete_lock_wait_max = _delete_lock_wait_cnt;
|
||||
}
|
||||
}
|
||||
// Wait for a release_stable_list() call before we check again. No
|
||||
// safepoint check, no timeout, and not as suspend equivalent flag
|
||||
// because this JavaThread is not on the Threads list.
|
||||
ThreadsSMRSupport::smr_delete_lock()->wait(Mutex::_no_safepoint_check_flag, 0,
|
||||
ThreadsSMRSupport::delete_lock()->wait(Mutex::_no_safepoint_check_flag, 0,
|
||||
!Mutex::_as_suspend_equivalent_flag);
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_smr_delete_lock_wait_cnt--;
|
||||
_delete_lock_wait_cnt--;
|
||||
}
|
||||
|
||||
ThreadsSMRSupport::clear_smr_delete_notify();
|
||||
ThreadsSMRSupport::smr_delete_lock()->unlock();
|
||||
ThreadsSMRSupport::clear_delete_notify();
|
||||
ThreadsSMRSupport::delete_lock()->unlock();
|
||||
// Retry the whole scenario.
|
||||
}
|
||||
|
||||
@ -893,166 +969,89 @@ void ThreadsSMRSupport::smr_delete(JavaThread *thread) {
|
||||
if (EnableThreadSMRStatistics) {
|
||||
timer.stop();
|
||||
uint millis = (uint)timer.milliseconds();
|
||||
ThreadsSMRSupport::inc_smr_deleted_thread_cnt();
|
||||
ThreadsSMRSupport::add_smr_deleted_thread_times(millis);
|
||||
ThreadsSMRSupport::update_smr_deleted_thread_time_max(millis);
|
||||
ThreadsSMRSupport::inc_deleted_thread_cnt();
|
||||
ThreadsSMRSupport::add_deleted_thread_times(millis);
|
||||
ThreadsSMRSupport::update_deleted_thread_time_max(millis);
|
||||
}
|
||||
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread));
|
||||
}
|
||||
|
||||
bool ThreadsSMRSupport::smr_delete_notify() {
|
||||
// Use load_acquire() in order to see any updates to _smr_delete_notify
|
||||
// earlier than when smr_delete_lock is grabbed.
|
||||
return (OrderAccess::load_acquire(&_smr_delete_notify) != 0);
|
||||
}
|
||||
|
||||
// Safely free a ThreadsList after a Threads::add() or Threads::remove().
|
||||
// The specified ThreadsList may not get deleted during this call if it
|
||||
// is still in-use (referenced by a hazard ptr). Other ThreadsLists
|
||||
// in the chain may get deleted by this call if they are no longer in-use.
|
||||
void ThreadsSMRSupport::smr_free_list(ThreadsList* threads) {
|
||||
assert_locked_or_safepoint(Threads_lock);
|
||||
|
||||
threads->set_next_list(_smr_to_delete_list);
|
||||
_smr_to_delete_list = threads;
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_smr_to_delete_list_cnt++;
|
||||
if (_smr_to_delete_list_cnt > _smr_to_delete_list_max) {
|
||||
_smr_to_delete_list_max = _smr_to_delete_list_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
// Hash table size should be first power of two higher than twice the length of the ThreadsList
|
||||
int hash_table_size = MIN2((int)get_smr_java_thread_list()->length(), 32) << 1;
|
||||
hash_table_size--;
|
||||
hash_table_size |= hash_table_size >> 1;
|
||||
hash_table_size |= hash_table_size >> 2;
|
||||
hash_table_size |= hash_table_size >> 4;
|
||||
hash_table_size |= hash_table_size >> 8;
|
||||
hash_table_size |= hash_table_size >> 16;
|
||||
hash_table_size++;
|
||||
|
||||
// Gather a hash table of the current hazard ptrs:
|
||||
ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size);
|
||||
ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table);
|
||||
Threads::threads_do(&scan_cl);
|
||||
|
||||
// Walk through the linked list of pending freeable ThreadsLists
|
||||
// and free the ones that are not referenced from hazard ptrs.
|
||||
ThreadsList* current = _smr_to_delete_list;
|
||||
ThreadsList* prev = NULL;
|
||||
ThreadsList* next = NULL;
|
||||
bool threads_is_freed = false;
|
||||
while (current != NULL) {
|
||||
next = current->next_list();
|
||||
if (!scan_table->has_entry((void*)current)) {
|
||||
// This ThreadsList is not referenced by a hazard ptr.
|
||||
if (prev != NULL) {
|
||||
prev->set_next_list(next);
|
||||
}
|
||||
if (_smr_to_delete_list == current) {
|
||||
_smr_to_delete_list = next;
|
||||
}
|
||||
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current));
|
||||
if (current == threads) threads_is_freed = true;
|
||||
delete current;
|
||||
if (EnableThreadSMRStatistics) {
|
||||
_smr_java_thread_list_free_cnt++;
|
||||
_smr_to_delete_list_cnt--;
|
||||
}
|
||||
} else {
|
||||
prev = current;
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
|
||||
if (!threads_is_freed) {
|
||||
// Only report "is not freed" on the original call to
|
||||
// smr_free_list() for this ThreadsList.
|
||||
log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads));
|
||||
}
|
||||
|
||||
delete scan_table;
|
||||
}
|
||||
|
||||
|
||||
// Debug, logging, and printing stuff at the end:
|
||||
|
||||
// Log Threads class SMR info.
|
||||
void ThreadsSMRSupport::log_smr_statistics() {
|
||||
void ThreadsSMRSupport::log_statistics() {
|
||||
LogTarget(Info, thread, smr) log;
|
||||
if (log.is_enabled()) {
|
||||
LogStream out(log);
|
||||
print_smr_info_on(&out);
|
||||
print_info_on(&out);
|
||||
}
|
||||
}
|
||||
|
||||
// Print Threads class SMR info.
|
||||
void ThreadsSMRSupport::print_smr_info_on(outputStream* st) {
|
||||
void ThreadsSMRSupport::print_info_on(outputStream* st) {
|
||||
// Only grab the Threads_lock if we don't already own it
|
||||
// and if we are not reporting an error.
|
||||
MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock);
|
||||
|
||||
st->print_cr("Threads class SMR info:");
|
||||
st->print_cr("_smr_java_thread_list=" INTPTR_FORMAT ", length=%u, "
|
||||
"elements={", p2i(_smr_java_thread_list),
|
||||
_smr_java_thread_list->length());
|
||||
print_smr_info_elements_on(st, _smr_java_thread_list);
|
||||
st->print_cr("_java_thread_list=" INTPTR_FORMAT ", length=%u, "
|
||||
"elements={", p2i(_java_thread_list),
|
||||
_java_thread_list->length());
|
||||
print_info_elements_on(st, _java_thread_list);
|
||||
st->print_cr("}");
|
||||
if (_smr_to_delete_list != NULL) {
|
||||
st->print_cr("_smr_to_delete_list=" INTPTR_FORMAT ", length=%u, "
|
||||
"elements={", p2i(_smr_to_delete_list),
|
||||
_smr_to_delete_list->length());
|
||||
print_smr_info_elements_on(st, _smr_to_delete_list);
|
||||
if (_to_delete_list != NULL) {
|
||||
st->print_cr("_to_delete_list=" INTPTR_FORMAT ", length=%u, "
|
||||
"elements={", p2i(_to_delete_list),
|
||||
_to_delete_list->length());
|
||||
print_info_elements_on(st, _to_delete_list);
|
||||
st->print_cr("}");
|
||||
for (ThreadsList *t_list = _smr_to_delete_list->next_list();
|
||||
for (ThreadsList *t_list = _to_delete_list->next_list();
|
||||
t_list != NULL; t_list = t_list->next_list()) {
|
||||
st->print("next-> " INTPTR_FORMAT ", length=%u, "
|
||||
"elements={", p2i(t_list), t_list->length());
|
||||
print_smr_info_elements_on(st, t_list);
|
||||
print_info_elements_on(st, t_list);
|
||||
st->print_cr("}");
|
||||
}
|
||||
}
|
||||
if (!EnableThreadSMRStatistics) {
|
||||
return;
|
||||
}
|
||||
st->print_cr("_smr_java_thread_list_alloc_cnt=" UINT64_FORMAT ","
|
||||
"_smr_java_thread_list_free_cnt=" UINT64_FORMAT ","
|
||||
"_smr_java_thread_list_max=%u, "
|
||||
"_smr_nested_thread_list_max=%u",
|
||||
_smr_java_thread_list_alloc_cnt,
|
||||
_smr_java_thread_list_free_cnt,
|
||||
_smr_java_thread_list_max,
|
||||
_smr_nested_thread_list_max);
|
||||
if (_smr_tlh_cnt > 0) {
|
||||
st->print_cr("_smr_tlh_cnt=%u"
|
||||
", _smr_tlh_times=%u"
|
||||
", avg_smr_tlh_time=%0.2f"
|
||||
", _smr_tlh_time_max=%u",
|
||||
_smr_tlh_cnt, _smr_tlh_times,
|
||||
((double) _smr_tlh_times / _smr_tlh_cnt),
|
||||
_smr_tlh_time_max);
|
||||
st->print_cr("_java_thread_list_alloc_cnt=" UINT64_FORMAT ","
|
||||
"_java_thread_list_free_cnt=" UINT64_FORMAT ","
|
||||
"_java_thread_list_max=%u, "
|
||||
"_nested_thread_list_max=%u",
|
||||
_java_thread_list_alloc_cnt,
|
||||
_java_thread_list_free_cnt,
|
||||
_java_thread_list_max,
|
||||
_nested_thread_list_max);
|
||||
if (_tlh_cnt > 0) {
|
||||
st->print_cr("_tlh_cnt=%u"
|
||||
", _tlh_times=%u"
|
||||
", avg_tlh_time=%0.2f"
|
||||
", _tlh_time_max=%u",
|
||||
_tlh_cnt, _tlh_times,
|
||||
((double) _tlh_times / _tlh_cnt),
|
||||
_tlh_time_max);
|
||||
}
|
||||
if (_smr_deleted_thread_cnt > 0) {
|
||||
st->print_cr("_smr_deleted_thread_cnt=%u"
|
||||
", _smr_deleted_thread_times=%u"
|
||||
", avg_smr_deleted_thread_time=%0.2f"
|
||||
", _smr_deleted_thread_time_max=%u",
|
||||
_smr_deleted_thread_cnt, _smr_deleted_thread_times,
|
||||
((double) _smr_deleted_thread_times / _smr_deleted_thread_cnt),
|
||||
_smr_deleted_thread_time_max);
|
||||
if (_deleted_thread_cnt > 0) {
|
||||
st->print_cr("_deleted_thread_cnt=%u"
|
||||
", _deleted_thread_times=%u"
|
||||
", avg_deleted_thread_time=%0.2f"
|
||||
", _deleted_thread_time_max=%u",
|
||||
_deleted_thread_cnt, _deleted_thread_times,
|
||||
((double) _deleted_thread_times / _deleted_thread_cnt),
|
||||
_deleted_thread_time_max);
|
||||
}
|
||||
st->print_cr("_smr_delete_lock_wait_cnt=%u, _smr_delete_lock_wait_max=%u",
|
||||
_smr_delete_lock_wait_cnt, _smr_delete_lock_wait_max);
|
||||
st->print_cr("_smr_to_delete_list_cnt=%u, _smr_to_delete_list_max=%u",
|
||||
_smr_to_delete_list_cnt, _smr_to_delete_list_max);
|
||||
st->print_cr("_delete_lock_wait_cnt=%u, _delete_lock_wait_max=%u",
|
||||
_delete_lock_wait_cnt, _delete_lock_wait_max);
|
||||
st->print_cr("_to_delete_list_cnt=%u, _to_delete_list_max=%u",
|
||||
_to_delete_list_cnt, _to_delete_list_max);
|
||||
}
|
||||
|
||||
// Print ThreadsList elements (4 per line).
|
||||
void ThreadsSMRSupport::print_smr_info_elements_on(outputStream* st,
|
||||
ThreadsList* t_list) {
|
||||
void ThreadsSMRSupport::print_info_elements_on(outputStream* st, ThreadsList* t_list) {
|
||||
uint cnt = 0;
|
||||
JavaThreadIterator jti(t_list);
|
||||
for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) {
|
||||
|
||||
@ -81,67 +81,68 @@
|
||||
//
|
||||
class ThreadsSMRSupport : AllStatic {
|
||||
// The coordination between ThreadsSMRSupport::release_stable_list() and
|
||||
// ThreadsSMRSupport::smr_delete() uses the smr_delete_lock in order to
|
||||
// ThreadsSMRSupport::smr_delete() uses the delete_lock in order to
|
||||
// reduce the traffic on the Threads_lock.
|
||||
static Monitor* _smr_delete_lock;
|
||||
static Monitor* _delete_lock;
|
||||
// The '_cnt', '_max' and '_times" fields are enabled via
|
||||
// -XX:+EnableThreadSMRStatistics (see thread.cpp for a
|
||||
// description about each field):
|
||||
static uint _smr_delete_lock_wait_cnt;
|
||||
static uint _smr_delete_lock_wait_max;
|
||||
// The smr_delete_notify flag is used for proper double-check
|
||||
// locking in order to reduce the traffic on the smr_delete_lock.
|
||||
static volatile uint _smr_delete_notify;
|
||||
static volatile uint _smr_deleted_thread_cnt;
|
||||
static volatile uint _smr_deleted_thread_time_max;
|
||||
static volatile uint _smr_deleted_thread_times;
|
||||
static ThreadsList* volatile _smr_java_thread_list;
|
||||
static uint64_t _smr_java_thread_list_alloc_cnt;
|
||||
static uint64_t _smr_java_thread_list_free_cnt;
|
||||
static uint _smr_java_thread_list_max;
|
||||
static uint _smr_nested_thread_list_max;
|
||||
static volatile uint _smr_tlh_cnt;
|
||||
static volatile uint _smr_tlh_time_max;
|
||||
static volatile uint _smr_tlh_times;
|
||||
static ThreadsList* _smr_to_delete_list;
|
||||
static uint _smr_to_delete_list_cnt;
|
||||
static uint _smr_to_delete_list_max;
|
||||
static uint _delete_lock_wait_cnt;
|
||||
static uint _delete_lock_wait_max;
|
||||
// The delete_notify flag is used for proper double-check
|
||||
// locking in order to reduce the traffic on the system wide
|
||||
// Thread-SMR delete_lock.
|
||||
static volatile uint _delete_notify;
|
||||
static volatile uint _deleted_thread_cnt;
|
||||
static volatile uint _deleted_thread_time_max;
|
||||
static volatile uint _deleted_thread_times;
|
||||
static ThreadsList* volatile _java_thread_list;
|
||||
static uint64_t _java_thread_list_alloc_cnt;
|
||||
static uint64_t _java_thread_list_free_cnt;
|
||||
static uint _java_thread_list_max;
|
||||
static uint _nested_thread_list_max;
|
||||
static volatile uint _tlh_cnt;
|
||||
static volatile uint _tlh_time_max;
|
||||
static volatile uint _tlh_times;
|
||||
static ThreadsList* _to_delete_list;
|
||||
static uint _to_delete_list_cnt;
|
||||
static uint _to_delete_list_max;
|
||||
|
||||
static ThreadsList *acquire_stable_list_fast_path(Thread *self);
|
||||
static ThreadsList *acquire_stable_list_nested_path(Thread *self);
|
||||
static void add_smr_deleted_thread_times(uint add_value);
|
||||
static void add_smr_tlh_times(uint add_value);
|
||||
static void clear_smr_delete_notify();
|
||||
static void inc_smr_deleted_thread_cnt();
|
||||
static void inc_smr_java_thread_list_alloc_cnt();
|
||||
static void inc_smr_tlh_cnt();
|
||||
static void add_deleted_thread_times(uint add_value);
|
||||
static void add_tlh_times(uint add_value);
|
||||
static void clear_delete_notify();
|
||||
static Monitor* delete_lock() { return _delete_lock; }
|
||||
static bool delete_notify();
|
||||
static void free_list(ThreadsList* threads);
|
||||
static void inc_deleted_thread_cnt();
|
||||
static void inc_java_thread_list_alloc_cnt();
|
||||
static void inc_tlh_cnt();
|
||||
static bool is_a_protected_JavaThread(JavaThread *thread);
|
||||
static void release_stable_list_fast_path(Thread *self);
|
||||
static void release_stable_list_nested_path(Thread *self);
|
||||
static void release_stable_list_wake_up(char *log_str);
|
||||
static void set_smr_delete_notify();
|
||||
static Monitor* smr_delete_lock() { return _smr_delete_lock; }
|
||||
static bool smr_delete_notify();
|
||||
static void smr_free_list(ThreadsList* threads);
|
||||
static void update_smr_deleted_thread_time_max(uint new_value);
|
||||
static void update_smr_java_thread_list_max(uint new_value);
|
||||
static void update_smr_tlh_time_max(uint new_value);
|
||||
static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list);
|
||||
static void set_delete_notify();
|
||||
static void update_deleted_thread_time_max(uint new_value);
|
||||
static void update_java_thread_list_max(uint new_value);
|
||||
static void update_tlh_time_max(uint new_value);
|
||||
static ThreadsList* xchg_java_thread_list(ThreadsList* new_list);
|
||||
|
||||
public:
|
||||
static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter);
|
||||
static void add_thread(JavaThread *thread);
|
||||
static ThreadsList* get_smr_java_thread_list();
|
||||
static ThreadsList* get_java_thread_list();
|
||||
static bool is_a_protected_JavaThread_with_lock(JavaThread *thread);
|
||||
static void release_stable_list(Thread *self);
|
||||
static void remove_thread(JavaThread *thread);
|
||||
static void smr_delete(JavaThread *thread);
|
||||
static void update_smr_tlh_stats(uint millis);
|
||||
static void update_tlh_stats(uint millis);
|
||||
|
||||
// Logging and printing support:
|
||||
static void log_smr_statistics();
|
||||
static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list);
|
||||
static void print_smr_info_on(outputStream* st);
|
||||
static void log_statistics();
|
||||
static void print_info_elements_on(outputStream* st, ThreadsList* t_list);
|
||||
static void print_info_on(outputStream* st);
|
||||
};
|
||||
|
||||
// A fast list of JavaThreads.
|
||||
|
||||
@ -53,24 +53,24 @@ inline void ThreadsList::threads_do(T *cl) const {
|
||||
}
|
||||
|
||||
// These three inlines are private to ThreadsSMRSupport, but
|
||||
// they are called by public inline update_smr_tlh_stats() below:
|
||||
// they are called by public inline update_tlh_stats() below:
|
||||
|
||||
inline void ThreadsSMRSupport::add_smr_tlh_times(uint add_value) {
|
||||
Atomic::add(add_value, &_smr_tlh_times);
|
||||
inline void ThreadsSMRSupport::add_tlh_times(uint add_value) {
|
||||
Atomic::add(add_value, &_tlh_times);
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::inc_smr_tlh_cnt() {
|
||||
Atomic::inc(&_smr_tlh_cnt);
|
||||
inline void ThreadsSMRSupport::inc_tlh_cnt() {
|
||||
Atomic::inc(&_tlh_cnt);
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::update_smr_tlh_time_max(uint new_value) {
|
||||
inline void ThreadsSMRSupport::update_tlh_time_max(uint new_value) {
|
||||
while (true) {
|
||||
uint cur_value = _smr_tlh_time_max;
|
||||
uint cur_value = _tlh_time_max;
|
||||
if (new_value <= cur_value) {
|
||||
// No need to update max value so we're done.
|
||||
break;
|
||||
}
|
||||
if (Atomic::cmpxchg(new_value, &_smr_tlh_time_max, cur_value) == cur_value) {
|
||||
if (Atomic::cmpxchg(new_value, &_tlh_time_max, cur_value) == cur_value) {
|
||||
// Updated max value so we're done. Otherwise try it all again.
|
||||
break;
|
||||
}
|
||||
@ -85,8 +85,8 @@ inline ThreadsList* ThreadsListSetter::list() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline ThreadsList* ThreadsSMRSupport::get_smr_java_thread_list() {
|
||||
return (ThreadsList*)OrderAccess::load_acquire(&_smr_java_thread_list);
|
||||
inline ThreadsList* ThreadsSMRSupport::get_java_thread_list() {
|
||||
return (ThreadsList*)OrderAccess::load_acquire(&_java_thread_list);
|
||||
}
|
||||
|
||||
inline bool ThreadsSMRSupport::is_a_protected_JavaThread_with_lock(JavaThread *thread) {
|
||||
@ -94,10 +94,10 @@ inline bool ThreadsSMRSupport::is_a_protected_JavaThread_with_lock(JavaThread *t
|
||||
return is_a_protected_JavaThread(thread);
|
||||
}
|
||||
|
||||
inline void ThreadsSMRSupport::update_smr_tlh_stats(uint millis) {
|
||||
ThreadsSMRSupport::inc_smr_tlh_cnt();
|
||||
ThreadsSMRSupport::add_smr_tlh_times(millis);
|
||||
ThreadsSMRSupport::update_smr_tlh_time_max(millis);
|
||||
inline void ThreadsSMRSupport::update_tlh_stats(uint millis) {
|
||||
ThreadsSMRSupport::inc_tlh_cnt();
|
||||
ThreadsSMRSupport::add_tlh_times(millis);
|
||||
ThreadsSMRSupport::update_tlh_time_max(millis);
|
||||
}
|
||||
|
||||
#endif // SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP
|
||||
|
||||
@ -48,6 +48,7 @@ class Constants {
|
||||
1.8 to 1.8.X 52,0
|
||||
1.9 to 1.9.X 53,0
|
||||
1.10 to 1.10.X 54,0
|
||||
1.11 to 1.11.X 55,0
|
||||
*/
|
||||
|
||||
public static final Package.Version JAVA_MIN_CLASS_VERSION =
|
||||
@ -71,6 +72,9 @@ class Constants {
|
||||
public static final Package.Version JAVA10_MAX_CLASS_VERSION =
|
||||
Package.Version.of(54, 00);
|
||||
|
||||
public static final Package.Version JAVA11_MAX_CLASS_VERSION =
|
||||
Package.Version.of(55, 00);
|
||||
|
||||
public static final int JAVA_PACKAGE_MAGIC = 0xCAFED00D;
|
||||
|
||||
public static final Package.Version JAVA5_PACKAGE_VERSION =
|
||||
@ -87,7 +91,7 @@ class Constants {
|
||||
|
||||
// upper limit, should point to the latest class version
|
||||
public static final Package.Version JAVA_MAX_CLASS_VERSION =
|
||||
JAVA10_MAX_CLASS_VERSION;
|
||||
JAVA11_MAX_CLASS_VERSION;
|
||||
|
||||
// upper limit should point to the latest package version, for version info!.
|
||||
public static final Package.Version MAX_PACKAGE_VERSION =
|
||||
|
||||
@ -27,6 +27,7 @@ package java.io;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class implements an output stream in which the data is
|
||||
@ -147,10 +148,7 @@ public class ByteArrayOutputStream extends OutputStream {
|
||||
* @param len the number of bytes to write.
|
||||
*/
|
||||
public synchronized void write(byte b[], int off, int len) {
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) - b.length > 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
Objects.checkFromIndexSize(off, len, b.length);
|
||||
ensureCapacity(count + len);
|
||||
System.arraycopy(b, off, buf, count, len);
|
||||
count += len;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2256,7 +2256,7 @@ public class File
|
||||
private transient volatile Path filePath;
|
||||
|
||||
/**
|
||||
* Returns a {@link Path java.nio.file.Path} object constructed from the
|
||||
* Returns a {@link Path java.nio.file.Path} object constructed from
|
||||
* this abstract path. The resulting {@code Path} is associated with the
|
||||
* {@link java.nio.file.FileSystems#getDefault default-filesystem}.
|
||||
*
|
||||
|
||||
@ -25,7 +25,9 @@
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -229,30 +231,55 @@ public abstract class InputStream implements Closeable {
|
||||
* @since 9
|
||||
*/
|
||||
public byte[] readAllBytes() throws IOException {
|
||||
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int capacity = buf.length;
|
||||
int nread = 0;
|
||||
List<byte[]> bufs = null;
|
||||
byte[] result = null;
|
||||
int total = 0;
|
||||
int n;
|
||||
for (;;) {
|
||||
// read to EOF which may read more or less than initial buffer size
|
||||
while ((n = read(buf, nread, capacity - nread)) > 0)
|
||||
do {
|
||||
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
|
||||
int nread = 0;
|
||||
|
||||
// read to EOF which may read more or less than buffer size
|
||||
while ((n = read(buf, nread, buf.length - nread)) > 0) {
|
||||
nread += n;
|
||||
|
||||
// if the last call to read returned -1, then we're done
|
||||
if (n < 0)
|
||||
break;
|
||||
|
||||
// need to allocate a larger buffer
|
||||
if (capacity <= MAX_BUFFER_SIZE - capacity) {
|
||||
capacity = capacity << 1;
|
||||
} else {
|
||||
if (capacity == MAX_BUFFER_SIZE)
|
||||
throw new OutOfMemoryError("Required array size too large");
|
||||
capacity = MAX_BUFFER_SIZE;
|
||||
}
|
||||
buf = Arrays.copyOf(buf, capacity);
|
||||
|
||||
if (nread > 0) {
|
||||
if (MAX_BUFFER_SIZE - total < nread) {
|
||||
throw new OutOfMemoryError("Required array size too large");
|
||||
}
|
||||
total += nread;
|
||||
if (result == null) {
|
||||
result = buf;
|
||||
} else {
|
||||
if (bufs == null) {
|
||||
bufs = new ArrayList<>();
|
||||
bufs.add(result);
|
||||
}
|
||||
bufs.add(buf);
|
||||
}
|
||||
}
|
||||
} while (n >= 0); // if the last call to read returned -1, then break
|
||||
|
||||
if (bufs == null) {
|
||||
if (result == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
return result.length == total ?
|
||||
result : Arrays.copyOf(result, total);
|
||||
}
|
||||
return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
|
||||
|
||||
result = new byte[total];
|
||||
int offset = 0;
|
||||
int remaining = total;
|
||||
for (byte[] b : bufs) {
|
||||
int len = Math.min(b.length, remaining);
|
||||
System.arraycopy(b, 0, result, offset, len);
|
||||
offset += len;
|
||||
remaining -= len;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1296,7 +1296,6 @@ public class ObjectInputStream
|
||||
* @throws InvalidClassException if the filter rejects creation
|
||||
*/
|
||||
private void checkArray(Class<?> arrayType, int arrayLength) throws InvalidClassException {
|
||||
Objects.requireNonNull(arrayType);
|
||||
if (! arrayType.isArray()) {
|
||||
throw new IllegalArgumentException("not an array type");
|
||||
}
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
@ -2521,7 +2521,7 @@ public class ModuleDescriptor
|
||||
* the {@code packageFinder} throws an {@link UncheckedIOException} then
|
||||
* {@link IOException} cause will be re-thrown. </p>
|
||||
*
|
||||
* <p> The module descriptor is read from the buffer stating at index
|
||||
* <p> The module descriptor is read from the buffer starting at index
|
||||
* {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
|
||||
* position} when this method is invoked. Upon return the buffer's position
|
||||
* will be equal to {@code p + n} where {@code n} is the number of bytes
|
||||
|
||||
@ -140,14 +140,6 @@ public abstract class Reference<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* system property to disable clearing before enqueuing.
|
||||
*/
|
||||
private static final class ClearBeforeEnqueue {
|
||||
static final boolean DISABLE =
|
||||
Boolean.getBoolean("jdk.lang.ref.disableClearBeforeEnqueue");
|
||||
}
|
||||
|
||||
/*
|
||||
* Atomically get and clear (set to null) the VM's pending list.
|
||||
*/
|
||||
@ -299,8 +291,7 @@ public abstract class Reference<T> {
|
||||
* it was not registered with a queue when it was created
|
||||
*/
|
||||
public boolean enqueue() {
|
||||
if (!ClearBeforeEnqueue.DISABLE)
|
||||
this.referent = null;
|
||||
this.referent = null;
|
||||
return this.queue.enqueue(this);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -317,10 +317,9 @@ public class InetSocketAddress
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the {@code InetAddress}.
|
||||
*
|
||||
* @return the InetAdress or {@code null} if it is unresolved.
|
||||
* @return the InetAddress or {@code null} if it is unresolved.
|
||||
*/
|
||||
public final InetAddress getAddress() {
|
||||
return holder.getAddress();
|
||||
|
||||
@ -63,38 +63,38 @@ class Bits { // package-private
|
||||
|
||||
// -- Unsafe access --
|
||||
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
|
||||
static Unsafe unsafe() {
|
||||
return unsafe;
|
||||
return UNSAFE;
|
||||
}
|
||||
|
||||
|
||||
// -- Processor and memory-system properties --
|
||||
|
||||
private static final ByteOrder byteOrder
|
||||
= unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
|
||||
private static final ByteOrder BYTE_ORDER
|
||||
= UNSAFE.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
|
||||
|
||||
static ByteOrder byteOrder() {
|
||||
return byteOrder;
|
||||
return BYTE_ORDER;
|
||||
}
|
||||
|
||||
private static int pageSize = -1;
|
||||
private static int PAGE_SIZE = -1;
|
||||
|
||||
static int pageSize() {
|
||||
if (pageSize == -1)
|
||||
pageSize = unsafe().pageSize();
|
||||
return pageSize;
|
||||
if (PAGE_SIZE == -1)
|
||||
PAGE_SIZE = unsafe().pageSize();
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
static int pageCount(long size) {
|
||||
return (int)(size + (long)pageSize() - 1L) / pageSize();
|
||||
}
|
||||
|
||||
private static boolean unaligned = unsafe.unalignedAccess();
|
||||
private static boolean UNALIGNED = UNSAFE.unalignedAccess();
|
||||
|
||||
static boolean unaligned() {
|
||||
return unaligned;
|
||||
return UNALIGNED;
|
||||
}
|
||||
|
||||
|
||||
@ -103,11 +103,11 @@ class Bits { // package-private
|
||||
// A user-settable upper limit on the maximum amount of allocatable
|
||||
// direct buffer memory. This value may be changed during VM
|
||||
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
|
||||
private static volatile long maxMemory = VM.maxDirectMemory();
|
||||
private static final AtomicLong reservedMemory = new AtomicLong();
|
||||
private static final AtomicLong totalCapacity = new AtomicLong();
|
||||
private static final AtomicLong count = new AtomicLong();
|
||||
private static volatile boolean memoryLimitSet;
|
||||
private static volatile long MAX_MEMORY = VM.maxDirectMemory();
|
||||
private static final AtomicLong RESERVED_MEMORY = new AtomicLong();
|
||||
private static final AtomicLong TOTAL_CAPACITY = new AtomicLong();
|
||||
private static final AtomicLong COUNT = new AtomicLong();
|
||||
private static volatile boolean MEMORY_LIMIT_SET;
|
||||
|
||||
// max. number of sleeps during try-reserving with exponentially
|
||||
// increasing delay before throwing OutOfMemoryError:
|
||||
@ -120,9 +120,9 @@ class Bits { // package-private
|
||||
// which a process may access. All sizes are specified in bytes.
|
||||
static void reserveMemory(long size, int cap) {
|
||||
|
||||
if (!memoryLimitSet && VM.initLevel() >= 1) {
|
||||
maxMemory = VM.maxDirectMemory();
|
||||
memoryLimitSet = true;
|
||||
if (!MEMORY_LIMIT_SET && VM.initLevel() >= 1) {
|
||||
MAX_MEMORY = VM.maxDirectMemory();
|
||||
MEMORY_LIMIT_SET = true;
|
||||
}
|
||||
|
||||
// optimist!
|
||||
@ -200,10 +200,10 @@ class Bits { // package-private
|
||||
// actual memory usage, which will differ when buffers are page
|
||||
// aligned.
|
||||
long totalCap;
|
||||
while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
|
||||
if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
|
||||
reservedMemory.addAndGet(size);
|
||||
count.incrementAndGet();
|
||||
while (cap <= MAX_MEMORY - (totalCap = TOTAL_CAPACITY.get())) {
|
||||
if (TOTAL_CAPACITY.compareAndSet(totalCap, totalCap + cap)) {
|
||||
RESERVED_MEMORY.addAndGet(size);
|
||||
COUNT.incrementAndGet();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -213,9 +213,9 @@ class Bits { // package-private
|
||||
|
||||
|
||||
static void unreserveMemory(long size, int cap) {
|
||||
long cnt = count.decrementAndGet();
|
||||
long reservedMem = reservedMemory.addAndGet(-size);
|
||||
long totalCap = totalCapacity.addAndGet(-cap);
|
||||
long cnt = COUNT.decrementAndGet();
|
||||
long reservedMem = RESERVED_MEMORY.addAndGet(-size);
|
||||
long totalCap = TOTAL_CAPACITY.addAndGet(-cap);
|
||||
assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
|
||||
}
|
||||
|
||||
@ -234,15 +234,15 @@ class Bits { // package-private
|
||||
}
|
||||
@Override
|
||||
public long getCount() {
|
||||
return Bits.count.get();
|
||||
return Bits.COUNT.get();
|
||||
}
|
||||
@Override
|
||||
public long getTotalCapacity() {
|
||||
return Bits.totalCapacity.get();
|
||||
return Bits.TOTAL_CAPACITY.get();
|
||||
}
|
||||
@Override
|
||||
public long getMemoryUsed() {
|
||||
return Bits.reservedMemory.get();
|
||||
return Bits.RESERVED_MEMORY.get();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
package java.nio;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import java.util.Spliterator;
|
||||
|
||||
@ -181,6 +182,8 @@ import java.util.Spliterator;
|
||||
*/
|
||||
|
||||
public abstract class Buffer {
|
||||
// Cached unsafe-access object
|
||||
static final Unsafe UNSAFE = Bits.unsafe();
|
||||
|
||||
/**
|
||||
* The characteristics of Spliterators that traverse and split elements
|
||||
@ -616,6 +619,14 @@ public abstract class Buffer {
|
||||
|
||||
// -- Package-private methods for bounds checking, etc. --
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the base reference, paired with the address
|
||||
* field, which in combination can be used for unsafe access into a heap
|
||||
* buffer or direct byte buffer (and views of).
|
||||
*/
|
||||
abstract Object base();
|
||||
|
||||
/**
|
||||
* Checks the current position against the limit, throwing a {@link
|
||||
* BufferUnderflowException} if it is not smaller than the limit, and then
|
||||
|
||||
198
src/java.base/share/classes/java/nio/BufferMismatch.java
Normal file
198
src/java.base/share/classes/java/nio/BufferMismatch.java
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.nio;
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* Mismatch methods for buffers
|
||||
*/
|
||||
final class BufferMismatch {
|
||||
|
||||
static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 7) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + aOff,
|
||||
b.base(), b.address + bOff,
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
// Ensure only heap or off-heap buffer instances use the
|
||||
// vectorized mismatch. If either buffer is a StringCharBuffer
|
||||
// (order is null) then the slow path is taken
|
||||
if (length > 3 && a.charRegionOrder() == b.charRegionOrder()
|
||||
&& a.charRegionOrder() != null && b.charRegionOrder() != null) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 3 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 1 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE);
|
||||
if (i >= 0) return i;
|
||||
i = length - ~i;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 1 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);
|
||||
// Mismatched
|
||||
if (i >= 0) {
|
||||
// Check if mismatch is not associated with two NaN values; and
|
||||
// is not associated with +0 and -0
|
||||
float av = a.get(aOff + i);
|
||||
float bv = b.get(bOff + i);
|
||||
if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
|
||||
return i;
|
||||
|
||||
// Fall back to slow mechanism
|
||||
// ISSUE: Consider looping over vectorizedMismatch adjusting ranges
|
||||
// However, requires that returned value be relative to input ranges
|
||||
i++;
|
||||
}
|
||||
// Matched
|
||||
else {
|
||||
i = length - ~i;
|
||||
}
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
float av = a.get(aOff + i);
|
||||
float bv = b.get(bOff + i);
|
||||
if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 0 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE);
|
||||
return i >= 0 ? i : -1;
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
if (a.get(aOff + i) != b.get(bOff + i))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) {
|
||||
int i = 0;
|
||||
if (length > 0 && a.order() == b.order()) {
|
||||
i = ArraysSupport.vectorizedMismatch(
|
||||
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
|
||||
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
|
||||
length,
|
||||
ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);
|
||||
// Mismatched
|
||||
if (i >= 0) {
|
||||
// Check if mismatch is not associated with two NaN values; and
|
||||
// is not associated with +0 and -0
|
||||
double av = a.get(aOff + i);
|
||||
double bv = b.get(bOff + i);
|
||||
if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
|
||||
return i;
|
||||
|
||||
// Fall back to slow mechanism
|
||||
// ISSUE: Consider looping over vectorizedMismatch adjusting ranges
|
||||
// However, requires that returned value be relative to input ranges
|
||||
i++;
|
||||
}
|
||||
// Matched
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (; i < length; i++) {
|
||||
double av = a.get(aOff + i);
|
||||
double bv = b.get(bOff + i);
|
||||
if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -36,9 +36,6 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
|
||||
#if[rw]
|
||||
|
||||
// Cached unsafe-access object
|
||||
private static final Unsafe unsafe = Bits.unsafe();
|
||||
|
||||
protected final ByteBuffer bb;
|
||||
|
||||
#end[rw]
|
||||
@ -74,6 +71,11 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
@Override
|
||||
Object base() {
|
||||
return bb.hb;
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
int pos = this.position();
|
||||
int lim = this.limit();
|
||||
@ -117,20 +119,20 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
}
|
||||
|
||||
public $type$ get() {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
public $type$ get(int i) {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
#if[streamableType]
|
||||
$type$ getUnchecked(int i) {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(bb.hb, byteOffset(i),
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(i),
|
||||
{#if[boB]?true:false});
|
||||
return $fromBits$(x);
|
||||
}
|
||||
@ -141,7 +143,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
$memtype$ y = $toBits$(x);
|
||||
unsafe.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
|
||||
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
|
||||
{#if[boB]?true:false});
|
||||
return this;
|
||||
#else[rw]
|
||||
@ -152,7 +154,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
$memtype$ y = $toBits$(x);
|
||||
unsafe.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
|
||||
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
|
||||
{#if[boB]?true:false});
|
||||
return this;
|
||||
#else[rw]
|
||||
@ -241,4 +243,9 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
#end[boL]
|
||||
}
|
||||
|
||||
#if[char]
|
||||
ByteOrder charRegionOrder() {
|
||||
return order();
|
||||
}
|
||||
#end[char]
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ class XXX {
|
||||
#if[rw]
|
||||
|
||||
private $type$ get$Type$(long a) {
|
||||
$memtype$ x = unsafe.get$Memtype$Unaligned(null, a, bigEndian);
|
||||
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
|
||||
return $fromBits$(x);
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ class XXX {
|
||||
private ByteBuffer put$Type$(long a, $type$ x) {
|
||||
#if[rw]
|
||||
$memtype$ y = $toBits$(x);
|
||||
unsafe.put$Memtype$Unaligned(null, a, y, bigEndian);
|
||||
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -81,7 +81,7 @@ class XXX {
|
||||
int rem = (off <= lim ? lim - off : 0);
|
||||
|
||||
int size = rem >> $LG_BYTES_PER_VALUE$;
|
||||
if (!unaligned && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
|
||||
if (!UNALIGNED && ((address + off) % $BYTES_PER_VALUE$ != 0)) {
|
||||
return (bigEndian
|
||||
? ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$B(this,
|
||||
-1,
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
package java.nio;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.ref.Cleaner;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
@ -45,14 +44,11 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
#if[rw]
|
||||
|
||||
// Cached unsafe-access object
|
||||
protected static final Unsafe unsafe = Bits.unsafe();
|
||||
|
||||
// Cached array base offset
|
||||
private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
|
||||
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
|
||||
|
||||
// Cached unaligned-access capability
|
||||
protected static final boolean unaligned = Bits.unaligned();
|
||||
protected static final boolean UNALIGNED = Bits.unaligned();
|
||||
|
||||
// Base address, used in all indexing calculations
|
||||
// NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
|
||||
@ -73,8 +69,6 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
implements Runnable
|
||||
{
|
||||
|
||||
private static Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
private long address;
|
||||
private long size;
|
||||
private int capacity;
|
||||
@ -91,7 +85,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
// Paranoia
|
||||
return;
|
||||
}
|
||||
unsafe.freeMemory(address);
|
||||
UNSAFE.freeMemory(address);
|
||||
address = 0;
|
||||
Bits.unreserveMemory(size, capacity);
|
||||
}
|
||||
@ -124,12 +118,12 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
long base = 0;
|
||||
try {
|
||||
base = unsafe.allocateMemory(size);
|
||||
base = UNSAFE.allocateMemory(size);
|
||||
} catch (OutOfMemoryError x) {
|
||||
Bits.unreserveMemory(size, cap);
|
||||
throw x;
|
||||
}
|
||||
unsafe.setMemory(base, size, (byte) 0);
|
||||
UNSAFE.setMemory(base, size, (byte) 0);
|
||||
if (pa && (base % ps != 0)) {
|
||||
// Round up to page boundary
|
||||
address = base + ps - (base & (ps - 1));
|
||||
@ -206,6 +200,11 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
@Override
|
||||
Object base() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
int pos = this.position();
|
||||
int lim = this.limit();
|
||||
@ -258,16 +257,16 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
}
|
||||
|
||||
public $type$ get() {
|
||||
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
|
||||
}
|
||||
|
||||
public $type$ get(int i) {
|
||||
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
|
||||
}
|
||||
|
||||
#if[streamableType]
|
||||
$type$ getUnchecked(int i) {
|
||||
return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
|
||||
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(i))));
|
||||
}
|
||||
#end[streamableType]
|
||||
|
||||
@ -282,10 +281,10 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
if (length > rem)
|
||||
throw new BufferUnderflowException();
|
||||
|
||||
long dstOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
long dstOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
unsafe.copySwapMemory(null,
|
||||
UNSAFE.copySwapMemory(null,
|
||||
ix(pos),
|
||||
dst,
|
||||
dstOffset,
|
||||
@ -293,7 +292,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
unsafe.copyMemory(null,
|
||||
UNSAFE.copyMemory(null,
|
||||
ix(pos),
|
||||
dst,
|
||||
dstOffset,
|
||||
@ -312,7 +311,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
public $Type$Buffer put($type$ x) {
|
||||
#if[rw]
|
||||
unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
||||
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -321,7 +320,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
public $Type$Buffer put(int i, $type$ x) {
|
||||
#if[rw]
|
||||
unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
||||
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -347,7 +346,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
if (srem > rem)
|
||||
throw new BufferOverflowException();
|
||||
unsafe.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
|
||||
UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
|
||||
sb.position(spos + srem);
|
||||
position(pos + srem);
|
||||
} else if (src.hb != null) {
|
||||
@ -380,10 +379,10 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
if (length > rem)
|
||||
throw new BufferOverflowException();
|
||||
|
||||
long srcOffset = arrayBaseOffset + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
long srcOffset = ARRAY_BASE_OFFSET + ((long)offset << $LG_BYTES_PER_VALUE$);
|
||||
#if[!byte]
|
||||
if (order() != ByteOrder.nativeOrder())
|
||||
unsafe.copySwapMemory(src,
|
||||
UNSAFE.copySwapMemory(src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(pos),
|
||||
@ -391,7 +390,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
(long)1 << $LG_BYTES_PER_VALUE$);
|
||||
else
|
||||
#end[!byte]
|
||||
unsafe.copyMemory(src,
|
||||
UNSAFE.copyMemory(src,
|
||||
srcOffset,
|
||||
null,
|
||||
ix(pos),
|
||||
@ -413,7 +412,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
unsafe.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
|
||||
UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
|
||||
position(rem);
|
||||
limit(capacity());
|
||||
discardMark();
|
||||
@ -490,17 +489,22 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
#end[!byte]
|
||||
|
||||
#if[char]
|
||||
ByteOrder charRegionOrder() {
|
||||
return order();
|
||||
}
|
||||
#end[char]
|
||||
|
||||
|
||||
#if[byte]
|
||||
|
||||
byte _get(int i) { // package-private
|
||||
return unsafe.getByte(address + i);
|
||||
return UNSAFE.getByte(address + i);
|
||||
}
|
||||
|
||||
void _put(int i, byte b) { // package-private
|
||||
#if[rw]
|
||||
unsafe.putByte(address + i, b);
|
||||
UNSAFE.putByte(address + i, b);
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
#end[rw]
|
||||
|
||||
@ -27,8 +27,6 @@
|
||||
|
||||
package java.nio;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/**
|
||||
#if[rw]
|
||||
* A read/write Heap$Type$Buffer.
|
||||
@ -43,6 +41,11 @@ import jdk.internal.misc.Unsafe;
|
||||
class Heap$Type$Buffer$RW$
|
||||
extends {#if[ro]?Heap}$Type$Buffer
|
||||
{
|
||||
// Cached array base offset
|
||||
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
|
||||
|
||||
// Cached array base offset
|
||||
private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class);
|
||||
|
||||
// For speed these fields are actually declared in X-Buffer;
|
||||
// these declarations are here as documentation
|
||||
@ -53,16 +56,6 @@ class Heap$Type$Buffer$RW$
|
||||
#end[rw]
|
||||
*/
|
||||
|
||||
#if[byte]
|
||||
|
||||
// Cached unsafe-access object
|
||||
private static final Unsafe unsafe = Bits.unsafe();
|
||||
|
||||
// Cached array base offset
|
||||
private static final long arrayBaseOffset = unsafe.arrayBaseOffset($type$[].class);
|
||||
|
||||
#end[byte]
|
||||
|
||||
Heap$Type$Buffer$RW$(int cap, int lim) { // package-private
|
||||
#if[rw]
|
||||
super(-1, 0, lim, cap, new $type$[cap], 0);
|
||||
@ -70,13 +63,11 @@ class Heap$Type$Buffer$RW$
|
||||
hb = new $type$[cap];
|
||||
offset = 0;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET;
|
||||
#else[rw]
|
||||
super(cap, lim);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
|
||||
@ -86,13 +77,11 @@ class Heap$Type$Buffer$RW$
|
||||
hb = buf;
|
||||
offset = 0;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET;
|
||||
#else[rw]
|
||||
super(buf, off, len);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
protected Heap$Type$Buffer$RW$($type$[] buf,
|
||||
@ -105,13 +94,11 @@ class Heap$Type$Buffer$RW$
|
||||
hb = buf;
|
||||
offset = off;
|
||||
*/
|
||||
this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE;
|
||||
#else[rw]
|
||||
super(buf, mark, pos, lim, cap, off);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset + off;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
@ -296,18 +283,18 @@ class Heap$Type$Buffer$RW$
|
||||
#if[rw]
|
||||
|
||||
public char getChar() {
|
||||
return unsafe.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
}
|
||||
|
||||
public char getChar(int i) {
|
||||
return unsafe.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putChar(char x) {
|
||||
#if[rw]
|
||||
unsafe.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -316,7 +303,7 @@ class Heap$Type$Buffer$RW$
|
||||
|
||||
public $Type$Buffer putChar(int i, char x) {
|
||||
#if[rw]
|
||||
unsafe.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -347,18 +334,18 @@ class Heap$Type$Buffer$RW$
|
||||
#if[rw]
|
||||
|
||||
public short getShort() {
|
||||
return unsafe.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
|
||||
}
|
||||
|
||||
public short getShort(int i) {
|
||||
return unsafe.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putShort(short x) {
|
||||
#if[rw]
|
||||
unsafe.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -367,7 +354,7 @@ class Heap$Type$Buffer$RW$
|
||||
|
||||
public $Type$Buffer putShort(int i, short x) {
|
||||
#if[rw]
|
||||
unsafe.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -398,18 +385,18 @@ class Heap$Type$Buffer$RW$
|
||||
#if[rw]
|
||||
|
||||
public int getInt() {
|
||||
return unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
}
|
||||
|
||||
public int getInt(int i) {
|
||||
return unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putInt(int x) {
|
||||
#if[rw]
|
||||
unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -418,7 +405,7 @@ class Heap$Type$Buffer$RW$
|
||||
|
||||
public $Type$Buffer putInt(int i, int x) {
|
||||
#if[rw]
|
||||
unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -449,18 +436,18 @@ class Heap$Type$Buffer$RW$
|
||||
#if[rw]
|
||||
|
||||
public long getLong() {
|
||||
return unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
}
|
||||
|
||||
public long getLong(int i) {
|
||||
return unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
}
|
||||
|
||||
#end[rw]
|
||||
|
||||
public $Type$Buffer putLong(long x) {
|
||||
#if[rw]
|
||||
unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -469,7 +456,7 @@ class Heap$Type$Buffer$RW$
|
||||
|
||||
public $Type$Buffer putLong(int i, long x) {
|
||||
#if[rw]
|
||||
unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -500,12 +487,12 @@ class Heap$Type$Buffer$RW$
|
||||
#if[rw]
|
||||
|
||||
public float getFloat() {
|
||||
int x = unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
|
||||
return Float.intBitsToFloat(x);
|
||||
}
|
||||
|
||||
public float getFloat(int i) {
|
||||
int x = unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
|
||||
return Float.intBitsToFloat(x);
|
||||
}
|
||||
|
||||
@ -514,7 +501,7 @@ class Heap$Type$Buffer$RW$
|
||||
public $Type$Buffer putFloat(float x) {
|
||||
#if[rw]
|
||||
int y = Float.floatToRawIntBits(x);
|
||||
unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -524,7 +511,7 @@ class Heap$Type$Buffer$RW$
|
||||
public $Type$Buffer putFloat(int i, float x) {
|
||||
#if[rw]
|
||||
int y = Float.floatToRawIntBits(x);
|
||||
unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
|
||||
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -555,12 +542,12 @@ class Heap$Type$Buffer$RW$
|
||||
#if[rw]
|
||||
|
||||
public double getDouble() {
|
||||
long x = unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
|
||||
return Double.longBitsToDouble(x);
|
||||
}
|
||||
|
||||
public double getDouble(int i) {
|
||||
long x = unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
|
||||
return Double.longBitsToDouble(x);
|
||||
}
|
||||
|
||||
@ -569,7 +556,7 @@ class Heap$Type$Buffer$RW$
|
||||
public $Type$Buffer putDouble(double x) {
|
||||
#if[rw]
|
||||
long y = Double.doubleToRawLongBits(x);
|
||||
unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -579,7 +566,7 @@ class Heap$Type$Buffer$RW$
|
||||
public $Type$Buffer putDouble(int i, double x) {
|
||||
#if[rw]
|
||||
long y = Double.doubleToRawLongBits(x);
|
||||
unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
|
||||
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
|
||||
return this;
|
||||
#else[rw]
|
||||
throw new ReadOnlyBufferException();
|
||||
@ -643,7 +630,11 @@ class Heap$Type$Buffer$RW$
|
||||
public ByteOrder order() {
|
||||
return ByteOrder.nativeOrder();
|
||||
}
|
||||
|
||||
#end[!byte]
|
||||
#if[char]
|
||||
|
||||
ByteOrder charRegionOrder() {
|
||||
return order();
|
||||
}
|
||||
#end[char]
|
||||
}
|
||||
|
||||
@ -127,4 +127,30 @@ class StringCharBuffer // package-private
|
||||
return ByteOrder.nativeOrder();
|
||||
}
|
||||
|
||||
ByteOrder charRegionOrder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean equals(Object ob) {
|
||||
if (this == ob)
|
||||
return true;
|
||||
if (!(ob instanceof CharBuffer))
|
||||
return false;
|
||||
CharBuffer that = (CharBuffer)ob;
|
||||
if (this.remaining() != that.remaining())
|
||||
return false;
|
||||
return BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
this.remaining()) < 0;
|
||||
}
|
||||
|
||||
public int compareTo(CharBuffer that) {
|
||||
int i = BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
Math.min(this.remaining(), that.remaining()));
|
||||
if (i >= 0) {
|
||||
return Character.compare(this.get(this.position() + i), that.get(this.position() + i));
|
||||
}
|
||||
return this.remaining() - that.remaining();
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,8 @@ import java.util.stream.StreamSupport;
|
||||
import java.util.stream.$Streamtype$Stream;
|
||||
#end[streamableType]
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* $A$ $type$ buffer.
|
||||
*
|
||||
@ -287,6 +289,11 @@ public abstract class $Type$Buffer
|
||||
this(mark, pos, lim, cap, null, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
Object base() {
|
||||
return hb;
|
||||
}
|
||||
|
||||
#if[byte]
|
||||
|
||||
/**
|
||||
@ -1297,19 +1304,9 @@ public abstract class $Type$Buffer
|
||||
$Type$Buffer that = ($Type$Buffer)ob;
|
||||
if (this.remaining() != that.remaining())
|
||||
return false;
|
||||
int p = this.position();
|
||||
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
|
||||
if (!equals(this.get(i), that.get(j)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean equals($type$ x, $type$ y) {
|
||||
#if[floatingPointType]
|
||||
return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y));
|
||||
#else[floatingPointType]
|
||||
return x == y;
|
||||
#end[floatingPointType]
|
||||
return BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
this.remaining()) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1336,11 +1333,11 @@ public abstract class $Type$Buffer
|
||||
* is less than, equal to, or greater than the given buffer
|
||||
*/
|
||||
public int compareTo($Type$Buffer that) {
|
||||
int n = this.position() + Math.min(this.remaining(), that.remaining());
|
||||
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
|
||||
int cmp = compare(this.get(i), that.get(j));
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
int i = BufferMismatch.mismatch(this, this.position(),
|
||||
that, that.position(),
|
||||
Math.min(this.remaining(), that.remaining()));
|
||||
if (i >= 0) {
|
||||
return compare(this.get(this.position() + i), that.get(this.position() + i));
|
||||
}
|
||||
return this.remaining() - that.remaining();
|
||||
}
|
||||
@ -1571,6 +1568,12 @@ public abstract class $Type$Buffer
|
||||
|
||||
#end[!byte]
|
||||
|
||||
#if[char]
|
||||
// The order or null if the buffer does not cover a memory region,
|
||||
// such as StringCharBuffer
|
||||
abstract ByteOrder charRegionOrder();
|
||||
#end[char]
|
||||
|
||||
#if[byte]
|
||||
|
||||
boolean bigEndian // package-private
|
||||
|
||||
@ -2954,22 +2954,6 @@ public final class Files {
|
||||
return newBufferedWriter(path, StandardCharsets.UTF_8, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all bytes from an input stream and writes them to an output stream.
|
||||
*/
|
||||
private static long copy(InputStream source, OutputStream sink)
|
||||
throws IOException
|
||||
{
|
||||
long nread = 0L;
|
||||
byte[] buf = new byte[BUFFER_SIZE];
|
||||
int n;
|
||||
while ((n = source.read(buf)) > 0) {
|
||||
sink.write(buf, 0, n);
|
||||
nread += n;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all bytes from an input stream to a file. On return, the input
|
||||
* stream will be at end of stream.
|
||||
@ -3082,7 +3066,7 @@ public final class Files {
|
||||
|
||||
// do the copy
|
||||
try (OutputStream out = ostream) {
|
||||
return copy(in, out);
|
||||
return in.transferTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3124,7 +3108,7 @@ public final class Files {
|
||||
Objects.requireNonNull(out);
|
||||
|
||||
try (InputStream in = newInputStream(source)) {
|
||||
return copy(in, out);
|
||||
return in.transferTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
package java.util;
|
||||
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
@ -204,58 +204,70 @@ import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
|
||||
* known concrete subclasses {@code ListResourceBundle} and
|
||||
* {@code PropertyResourceBundle} are thread-safe.
|
||||
*
|
||||
* <h3><a id="bundleprovider">Resource Bundles in Named Modules</a></h3>
|
||||
* <h3><a id="resource-bundle-modules">Resource Bundles and Named Modules</a></h3>
|
||||
*
|
||||
* When resource bundles are deployed in named modules, the following
|
||||
* module-specific requirements and restrictions are applied.
|
||||
* Resource bundles can be deployed in modules in the following ways:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Code in a named module that calls {@link #getBundle(String, Locale)}
|
||||
* will locate resource bundles in the caller's module (<em>caller module</em>).</li>
|
||||
* <li>If resource bundles are deployed in named modules separate from
|
||||
* the caller module, those resource bundles need to be loaded from service
|
||||
* providers of {@link ResourceBundleProvider}. The caller module must declare
|
||||
* "{@code uses}" and the service interface name is the concatenation of the
|
||||
* package name of the base name, string "{@code .spi.}", the simple class
|
||||
* name of the base name, and the string "{@code Provider}". The
|
||||
* <em>bundle provider modules</em> containing resource bundles must
|
||||
* declare "{@code provides}" with the service interface name and
|
||||
* its implementation class name. For example, if the base name is
|
||||
* "{@code com.example.app.MyResources}", the caller module must declare
|
||||
* "{@code uses com.example.app.spi.MyResourcesProvider;}" and a module containing resource
|
||||
* bundles must declare "{@code provides com.example.app.spi.MyResourcesProvider
|
||||
* with com.example.app.internal.MyResourcesProviderImpl;}"
|
||||
* where {@code com.example.app.internal.MyResourcesProviderImpl} is an
|
||||
* implementation class of {@code com.example.app.spi.MyResourcesProvider}.</li>
|
||||
* <li>If you want to use non-standard formats in named modules, such as XML,
|
||||
* {@link ResourceBundleProvider} needs to be used.</li>
|
||||
* <li>The {@code getBundle} method with a {@code ClassLoader} may not be able to
|
||||
* find resource bundles using the given {@code ClassLoader} in named modules.
|
||||
* The {@code getBundle} method with a {@code Module} can be used, instead.</li>
|
||||
* <li>{@code ResourceBundle.Control} is <em>not</em> supported in named modules.
|
||||
* If the {@code getBundle} method with a {@code ResourceBundle.Control} is called
|
||||
* in a named module, the method will throw an {@code UnsupportedOperationException}.
|
||||
* Any service providers of {@link ResourceBundleControlProvider} are ignored in
|
||||
* named modules.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <h4>Resource bundles together with an application</h4>
|
||||
*
|
||||
* <h3><a id="RBP_support">ResourceBundleProvider Service Providers</a></h3>
|
||||
* Resource bundles can be deployed together with an application in the same
|
||||
* module. In that case, the resource bundles are loaded
|
||||
* by code in the module by calling the {@link #getBundle(String)}
|
||||
* or {@link #getBundle(String, Locale)} method.
|
||||
*
|
||||
* The {@code getBundle} factory methods load service providers of
|
||||
* {@link ResourceBundleProvider}, if available, using {@link ServiceLoader}.
|
||||
* The service type is designated by
|
||||
* {@code <package name> + ".spi." + <simple name> + "Provider"}. For
|
||||
* example, if the base name is "{@code com.example.app.MyResources}", the service
|
||||
* type is {@code com.example.app.spi.MyResourcesProvider}.
|
||||
* <p>
|
||||
* In named modules, the loaded service providers for the given base name are
|
||||
* used to load resource bundles. If no service provider is available, or if
|
||||
* none of the service providers returns a resource bundle and the caller module
|
||||
* doesn't have its own service provider, the {@code getBundle} factory method
|
||||
* searches for resource bundles that are local in the caller module and that
|
||||
* are visible to the class loader of the caller module. The resource bundle
|
||||
* formats for local module searching are "java.class" and "java.properties".
|
||||
* <h4><a id="service-providers">Resource bundles as service providers</a></h4>
|
||||
*
|
||||
* Resource bundles can be deployed in one or more <em>service provider modules</em>
|
||||
* and they can be located using {@link ServiceLoader}.
|
||||
* A {@linkplain ResourceBundleProvider service} interface or class must be
|
||||
* defined. The caller module declares that it uses the service, the service
|
||||
* provider modules declare that they provide implementations of the service.
|
||||
* Refer to {@link ResourceBundleProvider} for developing resource bundle
|
||||
* services and deploying resource bundle providers.
|
||||
* The module obtaining the resource bundle can be a resource bundle
|
||||
* provider itself; in which case this module only locates the resource bundle
|
||||
* via service provider mechanism.
|
||||
*
|
||||
* <p>A {@linkplain ResourceBundleProvider resource bundle provider} can
|
||||
* provide resource bundles in any format such XML which replaces the need
|
||||
* of {@link Control ResourceBundle.Control}.
|
||||
*
|
||||
* <h4><a id="other-modules">Resource bundles in other modules and class path</a></h4>
|
||||
*
|
||||
* Resource bundles in a named module may be <em>encapsulated</em> so that
|
||||
* it cannot be located by code in other modules. Resource bundles
|
||||
* in unnamed modules and class path are open for any module to access.
|
||||
* Resource bundle follows the resource encapsulation rules as specified
|
||||
* in {@link Module#getResourceAsStream(String)}.
|
||||
*
|
||||
* <p>The {@code getBundle} factory methods with no {@code Control} parameter
|
||||
* locate and load resource bundles from
|
||||
* {@linkplain ResourceBundleProvider service providers}.
|
||||
* It may continue the search as if calling {@link Module#getResourceAsStream(String)}
|
||||
* to find the named resource from a given module and calling
|
||||
* {@link ClassLoader#getResourceAsStream(String)}; refer to
|
||||
* the specification of the {@code getBundle} method for details.
|
||||
* Only non-encapsulated resource bundles of "{@code java.class}"
|
||||
* or "{@code java.properties}" format are searched.
|
||||
*
|
||||
* <p>If the caller module is a
|
||||
* <a href="{@docRoot}/java/util/spi/ResourceBundleProvider.html#obtain-resource-bundle">
|
||||
* resource bundle provider</a>, it does not fall back to the
|
||||
* class loader search.
|
||||
*
|
||||
* <h4>Resource bundles in automatic modules</h4>
|
||||
*
|
||||
* A common format of resource bundles is in {@linkplain PropertyResourceBundle
|
||||
* .properties} file format. Typically {@code .properties} resource bundles
|
||||
* are packaged in a JAR file. Resource bundle only JAR file can be readily
|
||||
* deployed as an <a href="{@docRoot}/java/lang/module/ModuleFinder.html#automatic-modules">
|
||||
* automatic module</a>. For example, if the JAR file contains the
|
||||
* entry "{@code p/q/Foo_ja.properties}" and no {@code .class} entry,
|
||||
* when resolved and defined as an automatic module, no package is derived
|
||||
* for this module. This allows resource bundles in {@code .properties}
|
||||
* format packaged in one or more JAR files that may contain entries
|
||||
* in the same directory and can be resolved successfully as
|
||||
* automatic modules.
|
||||
*
|
||||
* <h3>ResourceBundle.Control</h3>
|
||||
*
|
||||
@ -268,6 +280,14 @@ import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
|
||||
* {@link #getBundle(String, Locale, ClassLoader, Control) getBundle}
|
||||
* factory method for details.
|
||||
*
|
||||
* <p> {@link ResourceBundle.Control} is designed for an application deployed
|
||||
* in an unnamed module, for example to support resource bundles in
|
||||
* non-standard formats or package localized resources in a non-traditional
|
||||
* convention. {@link ResourceBundleProvider} is the replacement for
|
||||
* {@code ResourceBundle.Control} when migrating to modules.
|
||||
* {@code UnsupportedOperationException} will be thrown when a factory
|
||||
* method that takes the {@code ResourceBundle.Control} parameter is called.
|
||||
*
|
||||
* <p><a id="modify_default_behavior">For the {@code getBundle} factory</a>
|
||||
* methods that take no {@link Control} instance, their <a
|
||||
* href="#default_behavior"> default behavior</a> of resource bundle loading
|
||||
@ -815,14 +835,10 @@ public abstract class ResourceBundle {
|
||||
|
||||
/**
|
||||
* Gets a resource bundle using the specified base name, the default locale,
|
||||
* and the caller's class loader. Calling this method is equivalent to calling
|
||||
* and the caller module. Calling this method is equivalent to calling
|
||||
* <blockquote>
|
||||
* <code>getBundle(baseName, Locale.getDefault(), this.getClass().getClassLoader())</code>,
|
||||
* <code>getBundle(baseName, Locale.getDefault(), callerModule)</code>,
|
||||
* </blockquote>
|
||||
* except that <code>getClassLoader()</code> is run with the security
|
||||
* privileges of <code>ResourceBundle</code>.
|
||||
* See {@link #getBundle(String, Locale, ClassLoader) getBundle}
|
||||
* for a complete description of the search and instantiation strategy.
|
||||
*
|
||||
* @param baseName the base name of the resource bundle, a fully qualified class name
|
||||
* @exception java.lang.NullPointerException
|
||||
@ -830,6 +846,9 @@ public abstract class ResourceBundle {
|
||||
* @exception MissingResourceException
|
||||
* if no resource bundle for the specified base name can be found
|
||||
* @return a resource bundle for the given base name and the default locale
|
||||
*
|
||||
* @see <a href="#default_behavior">Resource Bundle Search and Loading Strategy</a>
|
||||
* @see <a href="#resource-bundle-modules">Resource Bundles and Named Modules</a>
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final ResourceBundle getBundle(String baseName)
|
||||
@ -887,14 +906,10 @@ public abstract class ResourceBundle {
|
||||
|
||||
/**
|
||||
* Gets a resource bundle using the specified base name and locale,
|
||||
* and the caller's class loader. Calling this method is equivalent to calling
|
||||
* and the caller module. Calling this method is equivalent to calling
|
||||
* <blockquote>
|
||||
* <code>getBundle(baseName, locale, this.getClass().getClassLoader())</code>,
|
||||
* <code>getBundle(baseName, locale, callerModule)</code>,
|
||||
* </blockquote>
|
||||
* except that <code>getClassLoader()</code> is run with the security
|
||||
* privileges of <code>ResourceBundle</code>.
|
||||
* See {@link #getBundle(String, Locale, ClassLoader) getBundle}
|
||||
* for a complete description of the search and instantiation strategy.
|
||||
*
|
||||
* @param baseName
|
||||
* the base name of the resource bundle, a fully qualified class name
|
||||
@ -905,6 +920,9 @@ public abstract class ResourceBundle {
|
||||
* @exception MissingResourceException
|
||||
* if no resource bundle for the specified base name can be found
|
||||
* @return a resource bundle for the given base name and locale
|
||||
*
|
||||
* @see <a href="#default_behavior">Resource Bundle Search and Loading Strategy</a>
|
||||
* @see <a href="#resource-bundle-modules">Resource Bundles and Named Modules</a>
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static final ResourceBundle getBundle(String baseName,
|
||||
@ -922,19 +940,6 @@ public abstract class ResourceBundle {
|
||||
* <code>getBundle(baseName, Locale.getDefault(), module)</code>
|
||||
* </blockquote>
|
||||
*
|
||||
* <p> Resource bundles in named modules may be encapsulated. When
|
||||
* the resource bundle is loaded from a provider, the caller module
|
||||
* must have an appropriate <i>uses</i> clause in its <i>module descriptor</i>
|
||||
* to declare that the module uses implementations of
|
||||
* {@code <package name> + ".spi." + <simple name> + "Provider"}.
|
||||
* Otherwise, it will load the resource bundles that are local in the
|
||||
* given module or that are visible to the class loader of the given module
|
||||
* (refer to the <a href="#bundleprovider">Resource Bundles in Named Modules</a>
|
||||
* section for details).
|
||||
* When the resource bundle is loaded from the specified module, it is
|
||||
* subject to the encapsulation rules specified by
|
||||
* {@link Module#getResourceAsStream Module.getResourceAsStream}.
|
||||
*
|
||||
* @param baseName the base name of the resource bundle,
|
||||
* a fully qualified class name
|
||||
* @param module the module for which the resource bundle is searched
|
||||
@ -950,6 +955,8 @@ public abstract class ResourceBundle {
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see ResourceBundleProvider
|
||||
* @see <a href="#default_behavior">Resource Bundle Search and Loading Strategy</a>
|
||||
* @see <a href="#resource-bundle-modules">Resource Bundles and Named Modules</a>
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static ResourceBundle getBundle(String baseName, Module module) {
|
||||
@ -963,14 +970,15 @@ public abstract class ResourceBundle {
|
||||
* on behalf of the specified module.
|
||||
*
|
||||
* <p> Resource bundles in named modules may be encapsulated. When
|
||||
* the resource bundle is loaded from a provider, the caller module
|
||||
* the resource bundle is loaded from a
|
||||
* {@linkplain ResourceBundleProvider service provider}, the caller module
|
||||
* must have an appropriate <i>uses</i> clause in its <i>module descriptor</i>
|
||||
* to declare that the module uses implementations of
|
||||
* {@code <package name> + ".spi." + <simple name> + "Provider"}.
|
||||
* to declare that the module uses of {@link ResourceBundleProvider}
|
||||
* for the named resource bundle.
|
||||
* Otherwise, it will load the resource bundles that are local in the
|
||||
* given module or that are visible to the class loader of the given module
|
||||
* (refer to the <a href="#bundleprovider">Resource Bundles in Named Modules</a>
|
||||
* section for details).
|
||||
* given module as if calling {@link Module#getResourceAsStream(String)}
|
||||
* or that are visible to the class loader of the given module
|
||||
* as if calling {@link ClassLoader#getResourceAsStream(String)}.
|
||||
* When the resource bundle is loaded from the specified module, it is
|
||||
* subject to the encapsulation rules specified by
|
||||
* {@link Module#getResourceAsStream Module.getResourceAsStream}.
|
||||
@ -1000,6 +1008,8 @@ public abstract class ResourceBundle {
|
||||
* @return a resource bundle for the given base name and locale in the module
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see <a href="#default_behavior">Resource Bundle Search and Loading Strategy</a>
|
||||
* @see <a href="#resource-bundle-modules">Resource Bundles and Named Modules</a>
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static ResourceBundle getBundle(String baseName, Locale targetLocale, Module module) {
|
||||
@ -1060,28 +1070,25 @@ public abstract class ResourceBundle {
|
||||
* Gets a resource bundle using the specified base name, locale, and class
|
||||
* loader.
|
||||
*
|
||||
* <p>This method behaves the same as calling
|
||||
* {@link #getBundle(String, Locale, ClassLoader, Control)} passing a
|
||||
* default instance of {@link Control} unless another {@link Control} is
|
||||
* provided with the {@link ResourceBundleControlProvider} SPI. Refer to the
|
||||
* description of <a href="#modify_default_behavior">modifying the default
|
||||
* behavior</a>.
|
||||
* <p>When this method is called from a named module and the given
|
||||
* loader is the class loader of the caller module, this is equivalent
|
||||
* to calling:
|
||||
* <blockquote><pre>
|
||||
* getBundle(baseName, targetLocale, callerModule)
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* <p><a id="default_behavior">The following describes the default
|
||||
* behavior</a>.
|
||||
* otherwise, this is equivalent to calling:
|
||||
* <blockquote><pre>
|
||||
* getBundle(baseName, targetLocale, loader, control)
|
||||
* </pre></blockquote>
|
||||
* where {@code control} is the default instance of {@link Control} unless
|
||||
* a {@code Control} instance is provided by
|
||||
* {@link ResourceBundleControlProvider} SPI. Refer to the
|
||||
* description of <a href="#modify_default_behavior">modifying the default
|
||||
* behavior</a>. The following describes the default behavior.
|
||||
*
|
||||
* <p>
|
||||
* Resource bundles in a named module are private to that module. If
|
||||
* the caller is in a named module, this method will find resource bundles
|
||||
* from the service providers of {@link java.util.spi.ResourceBundleProvider}
|
||||
* if any. Otherwise, it will load the resource bundles that are visible to
|
||||
* the given {@code loader} (refer to the
|
||||
* <a href="#bundleprovider">Resource Bundles in Named Modules</a> section
|
||||
* for details).
|
||||
* If the caller is in a named module and the given {@code loader} is
|
||||
* different than the caller's class loader, or if the caller is not in
|
||||
* a named module, this method will not find resource bundles from named
|
||||
* modules.
|
||||
* <b><a id="default_behavior">Resource Bundle Search and Loading Strategy</a></b>
|
||||
*
|
||||
* <p><code>getBundle</code> uses the base name, the specified locale, and
|
||||
* the default locale (obtained from {@link java.util.Locale#getDefault()
|
||||
@ -1201,7 +1208,7 @@ public abstract class ResourceBundle {
|
||||
*
|
||||
* <p><b>Note:</b>The <code>baseName</code> argument should be a fully
|
||||
* qualified class name. However, for compatibility with earlier versions,
|
||||
* Sun's Java SE Runtime Environments do not verify this, and so it is
|
||||
* Java SE Runtime Environments do not verify this, and so it is
|
||||
* possible to access <code>PropertyResourceBundle</code>s by specifying a
|
||||
* path name (using "/") instead of a fully qualified class name (using
|
||||
* ".").
|
||||
@ -1248,7 +1255,7 @@ public abstract class ResourceBundle {
|
||||
*
|
||||
* @apiNote If the caller module is a named module and the given
|
||||
* {@code loader} is the caller module's class loader, this method is
|
||||
* equivalent to {@code getBundle(baseName, locale)}; otherwise, it will not
|
||||
* equivalent to {@code getBundle(baseName, locale)}; otherwise, it may not
|
||||
* find resource bundles from named modules.
|
||||
* Use {@link #getBundle(String, Locale, Module)} to load resource bundles
|
||||
* on behalf on a specific module instead.
|
||||
@ -1264,6 +1271,7 @@ public abstract class ResourceBundle {
|
||||
* @since 1.2
|
||||
* @revised 9
|
||||
* @spec JPMS
|
||||
* @see <a href="#resource-bundle-modules">Resource Bundles and Named Modules</a>
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static ResourceBundle getBundle(String baseName, Locale locale,
|
||||
@ -1278,9 +1286,9 @@ public abstract class ResourceBundle {
|
||||
|
||||
/**
|
||||
* Returns a resource bundle using the specified base name, target
|
||||
* locale, class loader and control. Unlike the {@linkplain
|
||||
* #getBundle(String, Locale, ClassLoader) <code>getBundle</code>
|
||||
* factory methods with no <code>control</code> argument}, the given
|
||||
* locale, class loader and control. Unlike the {@link
|
||||
* #getBundle(String, Locale, ClassLoader) getBundle}
|
||||
* factory methods with no {@code control} argument, the given
|
||||
* <code>control</code> specifies how to locate and instantiate resource
|
||||
* bundles. Conceptually, the bundle loading process with the given
|
||||
* <code>control</code> is performed in the following steps.
|
||||
@ -2365,7 +2373,14 @@ public abstract class ResourceBundle {
|
||||
* the callback methods provides the information necessary for the
|
||||
* factory methods to perform the <a
|
||||
* href="./ResourceBundle.html#default_behavior">default behavior</a>.
|
||||
* <a href="#note">Note that this class is not supported in named modules.</a>
|
||||
*
|
||||
* <p> {@link ResourceBundle.Control} is designed for an application deployed
|
||||
* in an unnamed module, for example to support resource bundles in
|
||||
* non-standard formats or package localized resources in a non-traditional
|
||||
* convention. {@link ResourceBundleProvider} is the replacement for
|
||||
* {@code ResourceBundle.Control} when migrating to modules.
|
||||
* {@code UnsupportedOperationException} will be thrown when a factory
|
||||
* method that takes the {@code ResourceBundle.Control} parameter is called.
|
||||
*
|
||||
* <p>In addition to the callback methods, the {@link
|
||||
* #toBundleName(String, Locale) toBundleName} and {@link
|
||||
@ -2501,8 +2516,8 @@ public abstract class ResourceBundle {
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @apiNote <a id="note">{@code ResourceBundle.Control} is not supported
|
||||
* in named modules.</a> If the {@code ResourceBundle.getBundle} method with
|
||||
* @apiNote {@code ResourceBundle.Control} is not supported
|
||||
* in named modules. If the {@code ResourceBundle.getBundle} method with
|
||||
* a {@code ResourceBundle.Control} is called in a named module, the method
|
||||
* will throw an {@link UnsupportedOperationException}. Any service providers
|
||||
* of {@link ResourceBundleControlProvider} are ignored in named modules.
|
||||
|
||||
@ -45,42 +45,46 @@ import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
|
||||
*
|
||||
* <p>
|
||||
* Resource bundles can be packaged in one or more
|
||||
* named modules, <em>bundle modules</em>. The <em>consumer</em> of the
|
||||
* named modules, <em>service provider modules</em>. The <em>consumer</em> of the
|
||||
* resource bundle is the one calling {@link ResourceBundle#getBundle(String)}.
|
||||
* In order for the consumer module to load a resource bundle
|
||||
* "{@code com.example.app.MyResources}" provided by another module,
|
||||
* it will use the {@linkplain java.util.ServiceLoader service loader}
|
||||
* mechanism. A service interface named "{@code com.example.app.MyResourcesProvider}"
|
||||
* must be defined and a <em>bundle provider module</em> will provide an
|
||||
* implementation class of "{@code com.example.app.MyResourcesProvider}"
|
||||
* mechanism. A service interface named "{@code com.example.app.spi.MyResourcesProvider}"
|
||||
* must be defined and a <em>service provider module</em> will provide an
|
||||
* implementation class of "{@code com.example.app.spi.MyResourcesProvider}"
|
||||
* as follows:
|
||||
*
|
||||
* <pre><code>
|
||||
* import com.example.app.MyResourcesProvider;
|
||||
* <blockquote><pre>
|
||||
* {@code import com.example.app.spi.MyResourcesProvider;
|
||||
* class MyResourcesProviderImpl extends AbstractResourceBundleProvider
|
||||
* implements MyResourcesProvider
|
||||
* {
|
||||
* public MyResourcesProviderImpl() {
|
||||
* super("java.properties");
|
||||
* }
|
||||
* // this provider maps the resource bundle to per-language package
|
||||
* protected String toBundleName(String baseName, Locale locale) {
|
||||
* // return the bundle name per the naming of the resource bundle
|
||||
* :
|
||||
* return "p." + locale.getLanguage() + "." + baseName;
|
||||
* }
|
||||
*
|
||||
* public ResourceBundle getBundle(String baseName, Locale locale) {
|
||||
* // this module only provides bundles in french
|
||||
* // this module only provides bundles in French
|
||||
* if (locale.equals(Locale.FRENCH)) {
|
||||
* return super.getBundle(baseName, locale);
|
||||
* }
|
||||
* // otherwise return null
|
||||
* return null;
|
||||
* }
|
||||
* }</code></pre>
|
||||
* }}</pre></blockquote>
|
||||
*
|
||||
* @see <a href="../ResourceBundle.html#bundleprovider">
|
||||
* Resource Bundles in Named Modules</a>
|
||||
* @see <a href="../ResourceBundle.html#RBP_support">
|
||||
* ResourceBundleProvider Service Providers</a>
|
||||
* Refer to {@link ResourceBundleProvider} for details.
|
||||
*
|
||||
* @see <a href="../ResourceBundle.html#resource-bundle-modules">
|
||||
* Resource Bundles and Named Modules</a>
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
|
||||
*/
|
||||
public abstract class AbstractResourceBundleProvider implements ResourceBundleProvider {
|
||||
private static final JavaUtilResourceBundleAccess RB_ACCESS =
|
||||
|
||||
@ -29,33 +29,117 @@ import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* {@code ResourceBundleProvider} is a provider interface that is used for
|
||||
* loading resource bundles for named modules. Implementation classes of
|
||||
* this interface are loaded with {@link java.util.ServiceLoader ServiceLoader}
|
||||
* during a call to the
|
||||
* {@link ResourceBundle#getBundle(String, Locale, ClassLoader)
|
||||
* ResourceBundle.getBundle} method. The provider service type is determined by
|
||||
* {@code <package name> + ".spi." + <simple name> + "Provider"}.
|
||||
* {@code ResourceBundleProvider} is a service provider interface for
|
||||
* resource bundles. It is used by
|
||||
* {@link ResourceBundle#getBundle(String) ResourceBundle.getBundle}
|
||||
* factory methods to locate and load the service providers that are deployed as
|
||||
* modules via {@link java.util.ServiceLoader ServiceLoader}.
|
||||
*
|
||||
* <p>
|
||||
* For example, if the base name is "com.example.app.MyResources",
|
||||
* {@code com.example.app.spi.MyResourcesProvider} will be the provider service type:
|
||||
* <pre>{@code
|
||||
* <h3>Developing resource bundle services</h3>
|
||||
*
|
||||
* A service for a resource bundle of a given <em>{@code baseName}</em> must have
|
||||
* a fully-qualified class name of the form:
|
||||
* <blockquote>
|
||||
* {@code <package of baseName> + ".spi." + <simple name of baseName> + "Provider"}
|
||||
* </blockquote>
|
||||
*
|
||||
* The service type is in a {@code spi} subpackage as it may be packaged in
|
||||
* a module separate from the resource bundle providers.
|
||||
* For example, the service for a resource bundle named
|
||||
* {@code com.example.app.MyResources} must be
|
||||
* {@code com.example.app.spi.MyResourcesProvider}:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* {@code package com.example.app.spi;
|
||||
* public interface MyResourcesProvider extends ResourceBundleProvider {
|
||||
* }
|
||||
* }</pre>
|
||||
* }</pre></blockquote>
|
||||
*
|
||||
* <p>
|
||||
* This providers's {@link #getBundle(String, Locale) getBundle} method is called
|
||||
* through the resource bundle loading process instead of {@link
|
||||
* java.util.ResourceBundle.Control#newBundle(String, Locale, String, ClassLoader, boolean)
|
||||
* ResourceBundle.Control.newBundle()}. Refer to {@link ResourceBundle} for
|
||||
* details.
|
||||
* <h3>Deploying resource bundle service providers</h3>
|
||||
*
|
||||
* @see <a href="../ResourceBundle.html#bundleprovider">
|
||||
* Resource Bundles in Named Modules</a>
|
||||
* @see <a href="../ResourceBundle.html#RBP_support">
|
||||
* ResourceBundleProvider Service Providers</a>
|
||||
* Resource bundles can be deployed in one or more service providers
|
||||
* in modules. For example, a provider for a service
|
||||
* named "{@code com.example.app.spi.MyResourcesProvider}"
|
||||
* has the following implementation class:
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* {@code import com.example.app.spi.MyResourcesProvider;
|
||||
* class MyResourcesProviderImpl extends AbstractResourceBundleProvider
|
||||
* implements MyResourcesProvider
|
||||
* {
|
||||
* public MyResourcesProviderImpl() {
|
||||
* super("java.properties");
|
||||
* }
|
||||
* // this provider maps the resource bundle to per-language package
|
||||
* protected String toBundleName(String baseName, Locale locale) {
|
||||
* return "p." + locale.getLanguage() + "." + baseName;
|
||||
* }
|
||||
*
|
||||
* public ResourceBundle getBundle(String baseName, Locale locale) {
|
||||
* // this module only provides bundles in French
|
||||
* if (locale.equals(Locale.FRENCH)) {
|
||||
* return super.getBundle(baseName, locale);
|
||||
* }
|
||||
* // otherwise return null
|
||||
* return null;
|
||||
* }
|
||||
* }}</pre></blockquote>
|
||||
*
|
||||
* This example provides "{@code com.example.app.MyResources}"
|
||||
* resource bundle of the French locale. Traditionally resource bundles of
|
||||
* all locales are packaged in the same package as the resource bundle base name.
|
||||
* When deploying resource bundles in more than one modules and two modules
|
||||
* containing a package of the same name, <em>split package</em>,
|
||||
* is not supported, resource bundles in each module can be packaged in
|
||||
* a different package as shown in this example where this provider packages
|
||||
* the resource bundles in per-language package, i.e. {@code com.example.app.fr}
|
||||
* for French locale.
|
||||
*
|
||||
* <p> A provider can provide more than one services, each of which is a service
|
||||
* for a resource bundle of a different base name.
|
||||
*
|
||||
* <p>{@link AbstractResourceBundleProvider}
|
||||
* provides the basic implementation for {@code ResourceBundleProvider}
|
||||
* and a subclass can override the {@link
|
||||
* AbstractResourceBundleProvider#toBundleName(String, Locale) toBundleName}
|
||||
* method to return a provider-specific location of the resource to be loaded,
|
||||
* for example, per-language package.
|
||||
* A provider can override {@link #getBundle ResourceBundleProvider.getBundle}
|
||||
* method for example to only search the known supported locales or
|
||||
* return resource bundles in other formats such as XML.
|
||||
*
|
||||
* <p>The module declaration of this provider module specifies the following
|
||||
* directive:
|
||||
* <pre>
|
||||
* provides com.example.app.spi.MyResourcesProvider with com.example.impl.MyResourcesProviderImpl;
|
||||
* </pre>
|
||||
*
|
||||
* <h3><a id="obtain-resource-bundle">Obtaining resource bundles from providers</a></h3>
|
||||
*
|
||||
* The module declaration of the <em>consumer module</em> that calls one of the
|
||||
* {@code ResourceBundle.getBundle} factory methods to obtain a resource
|
||||
* bundle from service providers must specify the following directive:
|
||||
* <pre>
|
||||
* uses com.example.app.spi.MyResourcesProvider;
|
||||
* </pre>
|
||||
*
|
||||
* {@link ResourceBundle#getBundle(String, Locale)
|
||||
* ResourceBundle.getBundle("com.example.app.MyResource", locale)}
|
||||
* locates and loads the providers for {@code com.example.app.spi.MyResourcesProvider}
|
||||
* service and then invokes {@link #getBundle(String, Locale)
|
||||
* ResourceBundleProvider.getBundle("com.example.app.MyResource", locale)} to
|
||||
* find the resource bundle of the given base name and locale.
|
||||
* If the consumer module is a resource bundle service provider for
|
||||
* {@code com.example.app.spi.MyResourcesProvider}, {@code ResourceBundle.getBundle}
|
||||
* will locate resource bundles only from service providers.
|
||||
* Otherwise, {@code ResourceBundle.getBundle} may continue the search of
|
||||
* the resource bundle in other modules and class path per the specification
|
||||
* of the {@code ResourceBundle.getBundle} method being called.
|
||||
*
|
||||
* @see AbstractResourceBundleProvider
|
||||
* @see <a href="../ResourceBundle.html#resource-bundle-modules">
|
||||
* Resource Bundles and Named Modules</a>
|
||||
* @see java.util.ServiceLoader
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -95,7 +95,7 @@ final class WhileOps {
|
||||
|
||||
@Override
|
||||
public void accept(T t) {
|
||||
if (take = predicate.test(t)) {
|
||||
if (take && (take = predicate.test(t))) {
|
||||
downstream.accept(t);
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ final class WhileOps {
|
||||
|
||||
@Override
|
||||
public void accept(int t) {
|
||||
if (take = predicate.test(t)) {
|
||||
if (take && (take = predicate.test(t))) {
|
||||
downstream.accept(t);
|
||||
}
|
||||
}
|
||||
@ -209,7 +209,7 @@ final class WhileOps {
|
||||
|
||||
@Override
|
||||
public void accept(long t) {
|
||||
if (take = predicate.test(t)) {
|
||||
if (take && (take = predicate.test(t))) {
|
||||
downstream.accept(t);
|
||||
}
|
||||
}
|
||||
@ -266,7 +266,7 @@ final class WhileOps {
|
||||
|
||||
@Override
|
||||
public void accept(double t) {
|
||||
if (take = predicate.test(t)) {
|
||||
if (take && (take = predicate.test(t))) {
|
||||
downstream.accept(t);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user