mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
Merge
This commit is contained in:
commit
e0f6f70d3f
62 changed files with 1423 additions and 424 deletions
233
bin/idea.sh
233
bin/idea.sh
|
@ -25,21 +25,7 @@
|
||||||
# Shell script for generating an IDEA project from a given list of modules
|
# Shell script for generating an IDEA project from a given list of modules
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 [-h|--help] [-q|--quiet] [-a|--absolute-paths] [-o|--output <path>] [modules...]"
|
echo "usage: $0 [-h|--help] [-v|--verbose] [-o|--output <path>] [modules]+"
|
||||||
echo " -h | --help"
|
|
||||||
echo " -q | --quiet
|
|
||||||
No stdout output"
|
|
||||||
echo " -a | --absolute-paths
|
|
||||||
Use absolute paths to this jdk, so that generated .idea
|
|
||||||
project files can be moved independently of jdk sources"
|
|
||||||
echo " -o | --output <path>
|
|
||||||
Where .idea directory with project files will be generated
|
|
||||||
(e.g. using '-o .' will place project files in './.idea')
|
|
||||||
Default: $TOPLEVEL_DIR"
|
|
||||||
echo " [modules...]
|
|
||||||
Generate project modules for specific java modules
|
|
||||||
(e.g. 'java.base java.desktop')
|
|
||||||
Default: all existing modules (java.* and jdk.*)"
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,12 +33,10 @@ SCRIPT_DIR=`dirname $0`
|
||||||
#assume TOP is the dir from which the script has been called
|
#assume TOP is the dir from which the script has been called
|
||||||
TOP=`pwd`
|
TOP=`pwd`
|
||||||
cd $SCRIPT_DIR; SCRIPT_DIR=`pwd`
|
cd $SCRIPT_DIR; SCRIPT_DIR=`pwd`
|
||||||
cd .. ; TOPLEVEL_DIR=`pwd`
|
|
||||||
cd $TOP;
|
cd $TOP;
|
||||||
|
|
||||||
IDEA_OUTPUT=$TOPLEVEL_DIR/.idea
|
IDEA_OUTPUT=$TOP/.idea
|
||||||
VERBOSE=true
|
VERBOSE="false"
|
||||||
ABSOLUTE_PATHS=false
|
|
||||||
while [ $# -gt 0 ]
|
while [ $# -gt 0 ]
|
||||||
do
|
do
|
||||||
case $1 in
|
case $1 in
|
||||||
|
@ -60,12 +44,8 @@ do
|
||||||
usage
|
usage
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-q | --quiet )
|
-v | --vebose )
|
||||||
VERBOSE=false
|
VERBOSE="true"
|
||||||
;;
|
|
||||||
|
|
||||||
-a | --absolute-paths )
|
|
||||||
ABSOLUTE_PATHS=true
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
-o | --output )
|
-o | --output )
|
||||||
|
@ -86,13 +66,18 @@ done
|
||||||
|
|
||||||
mkdir -p $IDEA_OUTPUT || exit 1
|
mkdir -p $IDEA_OUTPUT || exit 1
|
||||||
cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd`
|
cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd`
|
||||||
cd ..; IDEA_OUTPUT_PARENT=`pwd`
|
|
||||||
|
|
||||||
MAKE_DIR="$TOPLEVEL_DIR/make"
|
if [ "x$TOPLEVEL_DIR" = "x" ] ; then
|
||||||
|
cd $SCRIPT_DIR/..
|
||||||
|
TOPLEVEL_DIR=`pwd`
|
||||||
|
cd $IDEA_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
MAKE_DIR="$SCRIPT_DIR/../make"
|
||||||
IDEA_MAKE="$MAKE_DIR/ide/idea/jdk"
|
IDEA_MAKE="$MAKE_DIR/ide/idea/jdk"
|
||||||
IDEA_TEMPLATE="$IDEA_MAKE/template"
|
IDEA_TEMPLATE="$IDEA_MAKE/template"
|
||||||
|
|
||||||
cp -rn "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT"
|
cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT"
|
||||||
|
|
||||||
#override template
|
#override template
|
||||||
if [ -d "$TEMPLATES_OVERRIDE" ] ; then
|
if [ -d "$TEMPLATES_OVERRIDE" ] ; then
|
||||||
|
@ -101,31 +86,31 @@ if [ -d "$TEMPLATES_OVERRIDE" ] ; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$VERBOSE" = true ] ; then
|
if [ "$VERBOSE" = "true" ] ; then
|
||||||
echo "Will generate IDEA project files in \"$IDEA_OUTPUT\" for project \"$TOPLEVEL_DIR\""
|
echo "output dir: $IDEA_OUTPUT"
|
||||||
|
echo "idea template dir: $IDEA_TEMPLATE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I "$TOPLEVEL_DIR" idea \
|
cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I $MAKE_DIR/.. idea MAKEOVERRIDES= OUT=$IDEA_OUTPUT/env.cfg MODULES="$*" || exit 1
|
||||||
MAKEOVERRIDES= IDEA_OUTPUT_PARENT="$IDEA_OUTPUT_PARENT" OUT="$IDEA_OUTPUT/env.cfg" MODULES="$*" || exit 1
|
|
||||||
cd $SCRIPT_DIR
|
cd $SCRIPT_DIR
|
||||||
|
|
||||||
. $IDEA_OUTPUT/env.cfg
|
. $IDEA_OUTPUT/env.cfg
|
||||||
|
|
||||||
# Expect MODULES, MODULE_NAMES, RELATIVE_PROJECT_DIR, RELATIVE_BUILD_DIR to be set
|
# Expect MODULE_ROOTS, MODULE_NAMES, BOOT_JDK & SPEC to be set
|
||||||
if [ "xMODULES" = "x" ] ; then
|
if [ "x$MODULE_ROOTS" = "x" ] ; then
|
||||||
echo "FATAL: MODULES is empty" >&2; exit 1
|
echo "FATAL: MODULE_ROOTS is empty" >&2; exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "x$MODULE_NAMES" = "x" ] ; then
|
if [ "x$MODULE_NAMES" = "x" ] ; then
|
||||||
echo "FATAL: MODULE_NAMES is empty" >&2; exit 1
|
echo "FATAL: MODULE_NAMES is empty" >&2; exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "x$RELATIVE_PROJECT_DIR" = "x" ] ; then
|
if [ "x$BOOT_JDK" = "x" ] ; then
|
||||||
echo "FATAL: RELATIVE_PROJECT_DIR is empty" >&2; exit 1
|
echo "FATAL: BOOT_JDK is empty" >&2; exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "x$RELATIVE_BUILD_DIR" = "x" ] ; then
|
if [ "x$SPEC" = "x" ] ; then
|
||||||
echo "FATAL: RELATIVE_BUILD_DIR is empty" >&2; exit 1
|
echo "FATAL: SPEC is empty" >&2; exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -d "$TOPLEVEL_DIR/.hg" ] ; then
|
if [ -d "$TOPLEVEL_DIR/.hg" ] ; then
|
||||||
|
@ -136,29 +121,6 @@ if [ -d "$TOPLEVEL_DIR/.git" ] ; then
|
||||||
VCS_TYPE="Git"
|
VCS_TYPE="Git"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$ABSOLUTE_PATHS" = true ] ; then
|
|
||||||
if [ "x$PATHTOOL" != "x" ]; then
|
|
||||||
PROJECT_DIR="`$PATHTOOL -am $TOPLEVEL_DIR`"
|
|
||||||
else
|
|
||||||
PROJECT_DIR="$TOPLEVEL_DIR"
|
|
||||||
fi
|
|
||||||
MODULE_DIR="$PROJECT_DIR"
|
|
||||||
cd "$TOPLEVEL_DIR" && cd "$RELATIVE_BUILD_DIR" && BUILD_DIR="`pwd`"
|
|
||||||
else
|
|
||||||
if [ "$RELATIVE_PROJECT_DIR" = "." ] ; then
|
|
||||||
PROJECT_DIR=""
|
|
||||||
else
|
|
||||||
PROJECT_DIR="/$RELATIVE_PROJECT_DIR"
|
|
||||||
fi
|
|
||||||
MODULE_DIR="\$MODULE_DIR\$$PROJECT_DIR"
|
|
||||||
PROJECT_DIR="\$PROJECT_DIR\$$PROJECT_DIR"
|
|
||||||
BUILD_DIR="\$PROJECT_DIR\$/$RELATIVE_BUILD_DIR"
|
|
||||||
fi
|
|
||||||
if [ "$VERBOSE" = true ] ; then
|
|
||||||
echo "Project root: $PROJECT_DIR"
|
|
||||||
echo "Generating IDEA project files..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
### Replace template variables
|
### Replace template variables
|
||||||
|
|
||||||
NUM_REPLACEMENTS=0
|
NUM_REPLACEMENTS=0
|
||||||
|
@ -182,82 +144,105 @@ add_replacement() {
|
||||||
eval TO$NUM_REPLACEMENTS='$2'
|
eval TO$NUM_REPLACEMENTS='$2'
|
||||||
}
|
}
|
||||||
|
|
||||||
add_replacement "###PROJECT_DIR###" "$PROJECT_DIR"
|
|
||||||
add_replacement "###MODULE_DIR###" "$MODULE_DIR"
|
|
||||||
add_replacement "###MODULE_NAMES###" "$MODULE_NAMES"
|
add_replacement "###MODULE_NAMES###" "$MODULE_NAMES"
|
||||||
add_replacement "###VCS_TYPE###" "$VCS_TYPE"
|
add_replacement "###VCS_TYPE###" "$VCS_TYPE"
|
||||||
add_replacement "###BUILD_DIR###" "$BUILD_DIR"
|
SPEC_DIR=`dirname $SPEC`
|
||||||
if [ "x$PATHTOOL" != "x" ]; then
|
if [ "x$CYGPATH" != "x" ]; then
|
||||||
add_replacement "###BASH_RUNNER_PREFIX###" "\$PROJECT_DIR\$/.idea/bash.bat"
|
add_replacement "###BUILD_DIR###" "`cygpath -am $SPEC_DIR`"
|
||||||
else
|
add_replacement "###IMAGES_DIR###" "`cygpath -am $SPEC_DIR`/images/jdk"
|
||||||
add_replacement "###BASH_RUNNER_PREFIX###" ""
|
add_replacement "###ROOT_DIR###" "`cygpath -am $TOPLEVEL_DIR`"
|
||||||
fi
|
add_replacement "###IDEA_DIR###" "`cygpath -am $IDEA_OUTPUT`"
|
||||||
if [ "x$PATHTOOL" != "x" ]; then
|
|
||||||
if [ "x$JT_HOME" = "x" ]; then
|
if [ "x$JT_HOME" = "x" ]; then
|
||||||
add_replacement "###JTREG_HOME###" ""
|
add_replacement "###JTREG_HOME###" ""
|
||||||
else
|
else
|
||||||
add_replacement "###JTREG_HOME###" "`$PATHTOOL -am $JT_HOME`"
|
add_replacement "###JTREG_HOME###" "`cygpath -am $JT_HOME`"
|
||||||
|
fi
|
||||||
|
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||||
|
add_replacement "###BUILD_DIR###" "`wslpath -am $SPEC_DIR`"
|
||||||
|
add_replacement "###IMAGES_DIR###" "`wslpath -am $SPEC_DIR`/images/jdk"
|
||||||
|
add_replacement "###ROOT_DIR###" "`wslpath -am $TOPLEVEL_DIR`"
|
||||||
|
add_replacement "###IDEA_DIR###" "`wslpath -am $IDEA_OUTPUT`"
|
||||||
|
if [ "x$JT_HOME" = "x" ]; then
|
||||||
|
add_replacement "###JTREG_HOME###" ""
|
||||||
|
else
|
||||||
|
add_replacement "###JTREG_HOME###" "`wslpath -am $JT_HOME`"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
add_replacement "###BUILD_DIR###" "$SPEC_DIR"
|
||||||
add_replacement "###JTREG_HOME###" "$JT_HOME"
|
add_replacement "###JTREG_HOME###" "$JT_HOME"
|
||||||
|
add_replacement "###IMAGES_DIR###" "$SPEC_DIR/images/jdk"
|
||||||
|
add_replacement "###ROOT_DIR###" "$TOPLEVEL_DIR"
|
||||||
|
add_replacement "###IDEA_DIR###" "$IDEA_OUTPUT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
MODULE_IMLS=""
|
SOURCE_PREFIX="<sourceFolder url=\"file://"
|
||||||
TEST_MODULE_DEPENDENCIES=""
|
SOURCE_POSTFIX="\" isTestSource=\"false\" />"
|
||||||
for module in $MODULE_NAMES; do
|
|
||||||
MODULE_IMLS="$MODULE_IMLS<module fileurl=\"file://\$PROJECT_DIR$/.idea/$module.iml\" filepath=\"\$PROJECT_DIR$/.idea/$module.iml\" /> "
|
for root in $MODULE_ROOTS; do
|
||||||
TEST_MODULE_DEPENDENCIES="$TEST_MODULE_DEPENDENCIES<orderEntry type=\"module\" module-name=\"$module\" scope=\"TEST\" /> "
|
if [ "x$CYGPATH" != "x" ]; then
|
||||||
|
root=`cygpath -am $root`
|
||||||
|
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||||
|
root=`wslpath -am $root`
|
||||||
|
fi
|
||||||
|
|
||||||
|
VM_CI="jdk.internal.vm.ci/share/classes"
|
||||||
|
VM_COMPILER="src/jdk.internal.vm.compiler/share/classes"
|
||||||
|
if test "${root#*$VM_CI}" != "$root" || test "${root#*$VM_COMPILER}" != "$root"; then
|
||||||
|
for subdir in "$root"/*; do
|
||||||
|
if [ -d "$subdir" ]; then
|
||||||
|
SOURCES=$SOURCES" $SOURCE_PREFIX""$subdir"/src"$SOURCE_POSTFIX"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
SOURCES=$SOURCES" $SOURCE_PREFIX""$root""$SOURCE_POSTFIX"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
add_replacement "###MODULE_IMLS###" "$MODULE_IMLS"
|
|
||||||
add_replacement "###TEST_MODULE_DEPENDENCIES###" "$TEST_MODULE_DEPENDENCIES"
|
add_replacement "###SOURCE_ROOTS###" "$SOURCES"
|
||||||
|
|
||||||
replace_template_dir "$IDEA_OUTPUT"
|
replace_template_dir "$IDEA_OUTPUT"
|
||||||
|
|
||||||
### Generate module project files
|
### Compile the custom Logger
|
||||||
|
|
||||||
if [ "$VERBOSE" = true ] ; then
|
CLASSES=$IDEA_OUTPUT/classes
|
||||||
echo "Generating project modules:"
|
|
||||||
fi
|
|
||||||
(
|
|
||||||
DEFAULT_IFS="$IFS"
|
|
||||||
IFS='#'
|
|
||||||
for value in $MODULES; do
|
|
||||||
(
|
|
||||||
eval "$value"
|
|
||||||
if [ "$VERBOSE" = true ] ; then
|
|
||||||
echo " $module"
|
|
||||||
fi
|
|
||||||
add_replacement "###MODULE_CONTENT###" "src/$module"
|
|
||||||
SOURCE_DIRS=""
|
|
||||||
IFS=' '
|
|
||||||
for dir in $moduleSrcDirs; do
|
|
||||||
case $dir in # Exclude generated sources to avoid module-info conflicts, see https://youtrack.jetbrains.com/issue/IDEA-185108
|
|
||||||
"src/"*) SOURCE_DIRS="$SOURCE_DIRS<sourceFolder url=\"file://$MODULE_DIR/$dir\" isTestSource=\"false\" /> "
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
add_replacement "###SOURCE_DIRS###" "$SOURCE_DIRS"
|
|
||||||
DEPENDENCIES=""
|
|
||||||
for dep in $moduleDependencies; do
|
|
||||||
case $MODULE_NAMES in # Exclude skipped modules from dependencies
|
|
||||||
*"$dep"*) DEPENDENCIES="$DEPENDENCIES<orderEntry type=\"module\" module-name=\"$dep\" /> "
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
add_replacement "###DEPENDENCIES###" "$DEPENDENCIES"
|
|
||||||
cp "$IDEA_OUTPUT/module.iml" "$IDEA_OUTPUT/$module.iml"
|
|
||||||
IFS="$DEFAULT_IFS"
|
|
||||||
replace_template_file "$IDEA_OUTPUT/$module.iml"
|
|
||||||
)
|
|
||||||
done
|
|
||||||
)
|
|
||||||
rm "$IDEA_OUTPUT/module.iml"
|
|
||||||
|
|
||||||
### Create shell script runner for Windows
|
if [ "x$ANT_HOME" = "x" ] ; then
|
||||||
|
# try some common locations, before giving up
|
||||||
if [ "x$PATHTOOL" != "x" ]; then
|
if [ -f "/usr/share/ant/lib/ant.jar" ] ; then
|
||||||
echo "@echo off" > "$IDEA_OUTPUT/bash.bat"
|
ANT_HOME="/usr/share/ant"
|
||||||
if [ "x$WSL_DISTRO_NAME" != "x" ] ; then
|
elif [ -f "/usr/local/Cellar/ant/1.9.4/libexec/lib/ant.jar" ] ; then
|
||||||
echo "wsl -d $WSL_DISTRO_NAME --cd \"%cd%\" -e %*" >> "$IDEA_OUTPUT/bash.bat"
|
ANT_HOME="/usr/local/Cellar/ant/1.9.4/libexec"
|
||||||
else
|
else
|
||||||
echo "$WINENV_ROOT\bin\bash.exe -l -c \"cd %CD:\=/%/ && %*\"" >> "$IDEA_OUTPUT/bash.bat"
|
echo "FATAL: cannot find ant. Try setting ANT_HOME." >&2; exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
CP=$ANT_HOME/lib/ant.jar
|
||||||
|
rm -rf $CLASSES; mkdir $CLASSES
|
||||||
|
|
||||||
|
if [ "x$CYGPATH" != "x" ] ; then ## CYGPATH may be set in env.cfg
|
||||||
|
JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
|
||||||
|
JAVAC_SOURCE_PATH=`cygpath -am $IDEA_OUTPUT/src`
|
||||||
|
JAVAC_CLASSES=`cygpath -am $CLASSES`
|
||||||
|
JAVAC_CP=`cygpath -am $CP`
|
||||||
|
JAVAC=javac
|
||||||
|
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||||
|
JAVAC_SOURCE_FILE=`realpath --relative-to=./ $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
|
||||||
|
JAVAC_SOURCE_PATH=`realpath --relative-to=./ $IDEA_OUTPUT/src`
|
||||||
|
JAVAC_CLASSES=`realpath --relative-to=./ $CLASSES`
|
||||||
|
ANT_TEMP=`mktemp -d -p ./`
|
||||||
|
cp $ANT_HOME/lib/ant.jar $ANT_TEMP/ant.jar
|
||||||
|
JAVAC_CP=$ANT_TEMP/ant.jar
|
||||||
|
JAVAC=javac.exe
|
||||||
|
else
|
||||||
|
JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java
|
||||||
|
JAVAC_SOURCE_PATH=$IDEA_OUTPUT/src
|
||||||
|
JAVAC_CLASSES=$CLASSES
|
||||||
|
JAVAC_CP=$CP
|
||||||
|
JAVAC=javac
|
||||||
|
fi
|
||||||
|
|
||||||
|
$BOOT_JDK/bin/$JAVAC -d $JAVAC_CLASSES -sourcepath $JAVAC_SOURCE_PATH -cp $JAVAC_CP $JAVAC_SOURCE_FILE
|
||||||
|
|
||||||
|
if [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||||
|
rm -rf $ANT_TEMP
|
||||||
|
fi
|
|
@ -542,6 +542,9 @@ AC_DEFUN([JVM_FEATURES_VERIFY],
|
||||||
if ! JVM_FEATURES_IS_ACTIVE(jvmci); then
|
if ! JVM_FEATURES_IS_ACTIVE(jvmci); then
|
||||||
INCLUDE_JVMCI="false"
|
INCLUDE_JVMCI="false"
|
||||||
fi
|
fi
|
||||||
|
if JVM_FEATURES_IS_ACTIVE(compiler2); then
|
||||||
|
INCLUDE_COMPILER2="true"
|
||||||
|
fi
|
||||||
|
|
||||||
# Verify that we have at least one gc selected (i.e., feature named "*gc").
|
# Verify that we have at least one gc selected (i.e., feature named "*gc").
|
||||||
if ! JVM_FEATURES_IS_ACTIVE(.*gc); then
|
if ! JVM_FEATURES_IS_ACTIVE(.*gc); then
|
||||||
|
@ -565,6 +568,7 @@ AC_DEFUN_ONCE([JVM_FEATURES_SETUP],
|
||||||
# missing any of them.
|
# missing any of them.
|
||||||
ENABLE_CDS="true"
|
ENABLE_CDS="true"
|
||||||
INCLUDE_JVMCI="true"
|
INCLUDE_JVMCI="true"
|
||||||
|
INCLUDE_COMPILER2="false"
|
||||||
|
|
||||||
for variant in $JVM_VARIANTS; do
|
for variant in $JVM_VARIANTS; do
|
||||||
# Figure out if any features are unavailable, or should be filtered out
|
# Figure out if any features are unavailable, or should be filtered out
|
||||||
|
@ -601,5 +605,6 @@ AC_DEFUN_ONCE([JVM_FEATURES_SETUP],
|
||||||
AC_SUBST(JVM_FEATURES_custom)
|
AC_SUBST(JVM_FEATURES_custom)
|
||||||
|
|
||||||
AC_SUBST(INCLUDE_JVMCI)
|
AC_SUBST(INCLUDE_JVMCI)
|
||||||
|
AC_SUBST(INCLUDE_COMPILER2)
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
|
@ -853,6 +853,7 @@ PNG_CFLAGS:=@PNG_CFLAGS@
|
||||||
|
|
||||||
INCLUDE_SA=@INCLUDE_SA@
|
INCLUDE_SA=@INCLUDE_SA@
|
||||||
INCLUDE_JVMCI=@INCLUDE_JVMCI@
|
INCLUDE_JVMCI=@INCLUDE_JVMCI@
|
||||||
|
INCLUDE_COMPILER2=@INCLUDE_COMPILER2@
|
||||||
|
|
||||||
OS_VERSION_MAJOR:=@OS_VERSION_MAJOR@
|
OS_VERSION_MAJOR:=@OS_VERSION_MAJOR@
|
||||||
OS_VERSION_MINOR:=@OS_VERSION_MINOR@
|
OS_VERSION_MINOR:=@OS_VERSION_MINOR@
|
||||||
|
|
42
make/ide/idea/jdk/build.xml
Normal file
42
make/ide/idea/jdk/build.xml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<!-- importing.xml -->
|
||||||
|
<project name="jdk">
|
||||||
|
|
||||||
|
<taskdef name="wrapLogger" classname="idea.IdeaLoggerWrapper" classpath="${idea.dir}/classes"/>
|
||||||
|
|
||||||
|
<wrapLogger/>
|
||||||
|
|
||||||
|
<macrodef name="call-make">
|
||||||
|
<attribute name="dir"/>
|
||||||
|
<attribute name="args"/>
|
||||||
|
<sequential>
|
||||||
|
<exec executable="make" dir="@{dir}" failonerror="true">
|
||||||
|
<arg line="@{args}"/>
|
||||||
|
<env key="CLASSPATH" value = ""/>
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<target name="cond-clean" unless="${intellij.ismake}">
|
||||||
|
<antcall target="clean"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="post-make" depends="cond-clean, build-module"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
**** Global JDK Build Targets
|
||||||
|
-->
|
||||||
|
|
||||||
|
<target name="clean">
|
||||||
|
<echo message="base = ${basedir}"/>
|
||||||
|
<call-make dir = "${build.target.dir}" args = "reconfigure"/>
|
||||||
|
<call-make dir = "${build.target.dir}" args = "clean"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="images">
|
||||||
|
<call-make dir = "${build.target.dir}" args = "images"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="build-module">
|
||||||
|
<call-make dir = "${build.target.dir}" args = "${module.name}"/>
|
||||||
|
</target>
|
||||||
|
</project>
|
|
@ -46,16 +46,13 @@ else #with SPEC
|
||||||
endif
|
endif
|
||||||
|
|
||||||
idea:
|
idea:
|
||||||
$(ECHO) "MODULES=\"$(foreach mod, $(SEL_MODULES), \
|
$(ECHO) "SUPPORT=$(SUPPORT_OUTPUTDIR)" >> $(OUT)
|
||||||
module='$(mod)' \
|
$(ECHO) "MODULE_ROOTS=\"$(foreach mod, $(SEL_MODULES), $(call FindModuleSrcDirs,$(mod)))\"" >> $(OUT)
|
||||||
moduleSrcDirs='$(foreach m,$(call FindModuleSrcDirs,$(mod)),$(call RelativePath,$m,$(topdir)))' \
|
|
||||||
moduleDependencies='$(call FindTransitiveDepsForModule,$(mod))' \
|
|
||||||
#)\"" > $(OUT)
|
|
||||||
$(ECHO) "MODULE_NAMES=\"$(strip $(foreach mod, $(SEL_MODULES), $(mod)))\"" >> $(OUT)
|
$(ECHO) "MODULE_NAMES=\"$(strip $(foreach mod, $(SEL_MODULES), $(mod)))\"" >> $(OUT)
|
||||||
$(ECHO) "RELATIVE_PROJECT_DIR=\"$(call RelativePath,$(topdir),$(IDEA_OUTPUT_PARENT))\"" >> $(OUT)
|
$(ECHO) "SEL_MODULES=\"$(SEL_MODULES)\"" >> $(OUT)
|
||||||
$(ECHO) "RELATIVE_BUILD_DIR=\"$(call RelativePath,$(OUTPUTDIR),$(IDEA_OUTPUT_PARENT))\"" >> $(OUT)
|
$(ECHO) "BOOT_JDK=\"$(BOOT_JDK)\"" >> $(OUT)
|
||||||
$(ECHO) "PATHTOOL=\"$(PATHTOOL)\"" >> $(OUT)
|
$(ECHO) "CYGPATH=\"$(PATHTOOL)\"" >> $(OUT)
|
||||||
|
$(ECHO) "SPEC=\"$(SPEC)\"" >> $(OUT)
|
||||||
$(ECHO) "JT_HOME=\"$(JT_HOME)\"" >> $(OUT)
|
$(ECHO) "JT_HOME=\"$(JT_HOME)\"" >> $(OUT)
|
||||||
$(ECHO) "WINENV_ROOT=\"$(WINENV_ROOT)\"" >> $(OUT)
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
14
make/ide/idea/jdk/template/ant.xml
Normal file
14
make/ide/idea/jdk/template/ant.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AntConfiguration">
|
||||||
|
<buildFile url="file://###ROOT_DIR###/make/ide/idea/jdk/build.xml">
|
||||||
|
<properties>
|
||||||
|
<property name="intellij.ismake" value="$IsMake$" />
|
||||||
|
<property name="build.target.dir" value="###BUILD_DIR###" />
|
||||||
|
<property name="module.name" value="###MODULE_NAMES###" />
|
||||||
|
<property name="idea.dir" value="###IDEA_DIR###" />
|
||||||
|
</properties>
|
||||||
|
<executeOn event="afterCompilation" target="post-make" />
|
||||||
|
</buildFile>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -3,10 +3,10 @@
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
<excludeFromCompile>
|
<excludeFromCompile>
|
||||||
<directory url="file://###PROJECT_DIR###/src" includeSubdirectories="true" />
|
<directory url="file://###ROOT_DIR###/src" includeSubdirectories="true" />
|
||||||
<directory url="file://###PROJECT_DIR###/build" includeSubdirectories="true" />
|
<directory url="file://###ROOT_DIR###/build" includeSubdirectories="true" />
|
||||||
<directory url="file://###PROJECT_DIR###/make" includeSubdirectories="true" />
|
<directory url="file://###ROOT_DIR###/make" includeSubdirectories="true" />
|
||||||
<directory url="file://###PROJECT_DIR###/test" includeSubdirectories="false" />
|
<directory url="file://###ROOT_DIR###/test" includeSubdirectories="true" />
|
||||||
</excludeFromCompile>
|
</excludeFromCompile>
|
||||||
<resourceExtensions />
|
<resourceExtensions />
|
||||||
<wildcardResourcePatterns>
|
<wildcardResourcePatterns>
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
<module type="JAVA_MODULE" version="4">
|
<module type="JAVA_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://###MODULE_DIR###">
|
<content url="file://###ROOT_DIR###">
|
||||||
<excludeFolder url="file://###MODULE_DIR###/build" />
|
###SOURCE_ROOTS###
|
||||||
<excludeFolder url="file://###MODULE_DIR###/make" />
|
<excludeFolder url="file://###ROOT_DIR###/build" />
|
||||||
|
<excludeFolder url="file://###ROOT_DIR###/make" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
<component name="JTRegService">
|
<component name="JTRegService">
|
||||||
<path>###JTREG_HOME###</path>
|
<path>###JTREG_HOME###</path>
|
||||||
<workDir>###BUILD_DIR###</workDir>
|
<workDir>###BUILD_DIR###</workDir>
|
||||||
<jre alt="true" value="###BUILD_DIR###/images/jdk" />
|
<jre alt="true" value="###IMAGES_DIR###" />
|
||||||
<options></options>
|
<options></options>
|
||||||
|
<ant>
|
||||||
|
<target file="file://###ROOT_DIR###/make/ide/idea/jdk/build.xml" name="images" />
|
||||||
|
</ant>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" assert-keyword="true" jdk-15="true">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" assert-keyword="true" jdk-15="true">
|
||||||
<output url="file://###BUILD_DIR###/idea" />
|
<output url="file://###BUILD_DIR###/idea" />
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/jdk.iml" filepath="$PROJECT_DIR$/.idea/jdk.iml" />
|
<module fileurl="file://$PROJECT_DIR$/.idea/jdk.iml" filepath="$PROJECT_DIR$/.idea/jdk.iml" />
|
||||||
###MODULE_IMLS###
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/test.iml" filepath="$PROJECT_DIR$/.idea/test.iml" />
|
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
13
make/ide/idea/jdk/template/src/idea/IdeaLoggerWrapper.java
Normal file
13
make/ide/idea/jdk/template/src/idea/IdeaLoggerWrapper.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package idea;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.Task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements a custom Ant task which replaces the standard Intellij IDEA Ant logger
|
||||||
|
* with a custom one which generates tighter output.
|
||||||
|
*/
|
||||||
|
public class IdeaLoggerWrapper extends Task {
|
||||||
|
public void execute() {
|
||||||
|
new JdkIdeaAntLogger(getProject());
|
||||||
|
}
|
||||||
|
}
|
375
make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java
Normal file
375
make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package idea;
|
||||||
|
|
||||||
|
import org.apache.tools.ant.BuildEvent;
|
||||||
|
import org.apache.tools.ant.BuildListener;
|
||||||
|
import org.apache.tools.ant.DefaultLogger;
|
||||||
|
import org.apache.tools.ant.Project;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import static org.apache.tools.ant.Project.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to wrap the IntelliJ ant logger in order to provide more meaningful
|
||||||
|
* output when building langtools. The basic ant output in IntelliJ can be quite cumbersome to
|
||||||
|
* work with, as it provides two separate views: (i) a tree view, which is good to display build task
|
||||||
|
* in a hierarchical fashion as they are processed; and a (ii) plain text view, which gives you
|
||||||
|
* the full ant output. The main problem is that javac-related messages are buried into the
|
||||||
|
* ant output (which is made very verbose by IntelliJ in order to support the tree view). It is
|
||||||
|
* not easy to figure out which node to expand in order to see the error message; switching
|
||||||
|
* to plain text doesn't help either, as now the output is totally flat.
|
||||||
|
*
|
||||||
|
* This logger class removes a lot of verbosity from the IntelliJ ant logger by not propagating
|
||||||
|
* all the events to the IntelliJ's logger. In addition, certain events are handled in a custom
|
||||||
|
* fashion, to generate better output during the build.
|
||||||
|
*/
|
||||||
|
public final class JdkIdeaAntLogger extends DefaultLogger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is just a way to pass in customized binary string predicates;
|
||||||
|
*
|
||||||
|
* TODO: replace with @code{BiPredicate<String, String>} and method reference when moving to 8
|
||||||
|
*/
|
||||||
|
enum StringBinaryPredicate {
|
||||||
|
CONTAINS() {
|
||||||
|
@Override
|
||||||
|
boolean apply(String s1, String s2) {
|
||||||
|
return s1.contains(s2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
STARTS_WITH {
|
||||||
|
@Override
|
||||||
|
boolean apply(String s1, String s2) {
|
||||||
|
return s1.startsWith(s2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MATCHES {
|
||||||
|
@Override
|
||||||
|
boolean apply(String s1, String s2) {
|
||||||
|
return s1.matches(s2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract boolean apply(String s1, String s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various kinds of ant messages that we shall intercept
|
||||||
|
*/
|
||||||
|
enum MessageKind {
|
||||||
|
|
||||||
|
/** a make error */
|
||||||
|
MAKE_ERROR(StringBinaryPredicate.CONTAINS, MSG_ERR, "error:", "compiler.err"),
|
||||||
|
/** a make warning */
|
||||||
|
MAKE_WARNING(StringBinaryPredicate.CONTAINS, MSG_WARN, "warning:", "compiler.warn"),
|
||||||
|
/** a make note */
|
||||||
|
MAKE_NOTE(StringBinaryPredicate.CONTAINS, MSG_INFO, "note:", "compiler.note"),
|
||||||
|
/** std make output */
|
||||||
|
MAKE_OTHER(StringBinaryPredicate.MATCHES, MSG_INFO, ".*"),
|
||||||
|
/** a javac crash */
|
||||||
|
JAVAC_CRASH(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "An exception has occurred in the compiler"),
|
||||||
|
/** jtreg test success */
|
||||||
|
JTREG_TEST_PASSED(StringBinaryPredicate.STARTS_WITH, MSG_INFO, "Passed: "),
|
||||||
|
/** jtreg test failure */
|
||||||
|
JTREG_TEST_FAILED(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "FAILED: "),
|
||||||
|
/** jtreg test error */
|
||||||
|
JTREG_TEST_ERROR(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "Error: "),
|
||||||
|
/** jtreg report */
|
||||||
|
JTREG_TEST_REPORT(StringBinaryPredicate.STARTS_WITH, MSG_INFO, "Report written");
|
||||||
|
|
||||||
|
StringBinaryPredicate sbp;
|
||||||
|
int priority;
|
||||||
|
String[] keys;
|
||||||
|
|
||||||
|
MessageKind(StringBinaryPredicate sbp, int priority, String... keys) {
|
||||||
|
this.sbp = sbp;
|
||||||
|
this.priority = priority;
|
||||||
|
this.keys = keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does a given message string matches this kind?
|
||||||
|
*/
|
||||||
|
boolean matches(String s) {
|
||||||
|
for (String key : keys) {
|
||||||
|
if (sbp.apply(s, key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum is used to represent the list of tasks we need to keep track of during logging.
|
||||||
|
*/
|
||||||
|
enum Task {
|
||||||
|
/** javac task - invoked during compilation */
|
||||||
|
MAKE("exec", MessageKind.MAKE_ERROR, MessageKind.MAKE_WARNING, MessageKind.MAKE_NOTE,
|
||||||
|
MessageKind.MAKE_OTHER, MessageKind.JAVAC_CRASH),
|
||||||
|
/** jtreg task - invoked during test execution */
|
||||||
|
JTREG("jtreg", MessageKind.JTREG_TEST_PASSED, MessageKind.JTREG_TEST_FAILED, MessageKind.JTREG_TEST_ERROR, MessageKind.JTREG_TEST_REPORT),
|
||||||
|
/** initial synthetic task when the logger is created */
|
||||||
|
ROOT("") {
|
||||||
|
@Override
|
||||||
|
boolean matches(String s) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** synthetic task catching any other tasks not in this list */
|
||||||
|
ANY("") {
|
||||||
|
@Override
|
||||||
|
boolean matches(String s) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
String taskName;
|
||||||
|
MessageKind[] msgs;
|
||||||
|
|
||||||
|
Task(String taskName, MessageKind... msgs) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
this.msgs = msgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean matches(String s) {
|
||||||
|
return s.equals(taskName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum is used to represent the list of targets we need to keep track of during logging.
|
||||||
|
* A regular expression is used to match a given target name.
|
||||||
|
*/
|
||||||
|
enum Target {
|
||||||
|
/** jtreg target - executed when launching tests */
|
||||||
|
JTREG("jtreg") {
|
||||||
|
@Override
|
||||||
|
String getDisplayMessage(BuildEvent e) {
|
||||||
|
return "Running jtreg tests: " + e.getProject().getProperty("jtreg.tests");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** build selected modules */
|
||||||
|
BUILD_MODULE("build-module") {
|
||||||
|
@Override
|
||||||
|
String getDisplayMessage(BuildEvent e) {
|
||||||
|
return "Building modules: " + e.getProject().getProperty("module.name") + "...";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** build images */
|
||||||
|
BUILD_IMAGES("images") {
|
||||||
|
@Override
|
||||||
|
String getDisplayMessage(BuildEvent e) {
|
||||||
|
return "Building images...";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** build images */
|
||||||
|
CONFIGURE("-do-configure") {
|
||||||
|
@Override
|
||||||
|
String getDisplayMessage(BuildEvent e) {
|
||||||
|
return "Configuring build...";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** synthetic target catching any other target not in this list */
|
||||||
|
ANY("") {
|
||||||
|
@Override
|
||||||
|
String getDisplayMessage(BuildEvent e) {
|
||||||
|
return "Executing Ant target(s): " + e.getProject().getProperty("ant.project.invoked-targets");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
boolean matches(String msg) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
String targetRegex;
|
||||||
|
|
||||||
|
Target(String targetRegex) {
|
||||||
|
this.targetRegex = targetRegex;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean matches(String msg) {
|
||||||
|
return msg.matches(targetRegex);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract String getDisplayMessage(BuildEvent e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom build event used to represent status changes which should be notified inside
|
||||||
|
* Intellij
|
||||||
|
*/
|
||||||
|
static class StatusEvent extends BuildEvent {
|
||||||
|
|
||||||
|
/** the target to which the status update refers */
|
||||||
|
Target target;
|
||||||
|
|
||||||
|
StatusEvent(BuildEvent e, Target target) {
|
||||||
|
super(new StatusTask(e, target.getDisplayMessage(e)));
|
||||||
|
this.target = target;
|
||||||
|
setMessage(getTask().getTaskName(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom task used to channel info regarding a status change
|
||||||
|
*/
|
||||||
|
static class StatusTask extends org.apache.tools.ant.Task {
|
||||||
|
StatusTask(BuildEvent event, String msg) {
|
||||||
|
setProject(event.getProject());
|
||||||
|
setOwningTarget(event.getTarget());
|
||||||
|
setTaskName(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** wrapped ant logger (IntelliJ's own logger) */
|
||||||
|
DefaultLogger logger;
|
||||||
|
|
||||||
|
/** flag - is this the first target we encounter? */
|
||||||
|
boolean firstTarget = true;
|
||||||
|
|
||||||
|
/** flag - should subsequenet failures be suppressed ? */
|
||||||
|
boolean suppressTaskFailures = false;
|
||||||
|
|
||||||
|
/** flag - have we ran into a javac crash ? */
|
||||||
|
boolean crashFound = false;
|
||||||
|
|
||||||
|
/** stack of status changes associated with pending targets */
|
||||||
|
Stack<StatusEvent> statusEvents = new Stack<>();
|
||||||
|
|
||||||
|
/** stack of pending tasks */
|
||||||
|
Stack<Task> tasks = new Stack<>();
|
||||||
|
|
||||||
|
public JdkIdeaAntLogger(Project project) {
|
||||||
|
for (Object o : project.getBuildListeners()) {
|
||||||
|
if (o instanceof DefaultLogger) {
|
||||||
|
this.logger = (DefaultLogger)o;
|
||||||
|
project.removeBuildListener((BuildListener)o);
|
||||||
|
project.addBuildListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasks.push(Task.ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildStarted(BuildEvent event) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildFinished(BuildEvent event) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetStarted(BuildEvent event) {
|
||||||
|
EnumSet<Target> statusKinds = firstTarget ?
|
||||||
|
EnumSet.allOf(Target.class) :
|
||||||
|
EnumSet.complementOf(EnumSet.of(Target.ANY));
|
||||||
|
|
||||||
|
String targetName = event.getTarget().getName();
|
||||||
|
|
||||||
|
for (Target statusKind : statusKinds) {
|
||||||
|
if (statusKind.matches(targetName)) {
|
||||||
|
StatusEvent statusEvent = new StatusEvent(event, statusKind);
|
||||||
|
statusEvents.push(statusEvent);
|
||||||
|
logger.taskStarted(statusEvent);
|
||||||
|
firstTarget = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void targetFinished(BuildEvent event) {
|
||||||
|
if (!statusEvents.isEmpty()) {
|
||||||
|
StatusEvent lastEvent = statusEvents.pop();
|
||||||
|
if (lastEvent.target.matches(event.getTarget().getName())) {
|
||||||
|
logger.taskFinished(lastEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void taskStarted(BuildEvent event) {
|
||||||
|
String taskName = event.getTask().getTaskName();
|
||||||
|
System.err.println("task started " + taskName);
|
||||||
|
for (Task task : Task.values()) {
|
||||||
|
if (task.matches(taskName)) {
|
||||||
|
tasks.push(task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void taskFinished(BuildEvent event) {
|
||||||
|
if (tasks.peek() == Task.ROOT) {
|
||||||
|
//we need to 'close' the root task to get nicer output
|
||||||
|
logger.taskFinished(event);
|
||||||
|
} else if (!suppressTaskFailures && event.getException() != null) {
|
||||||
|
//the first (innermost) task failure should always be logged
|
||||||
|
event.setMessage(event.getException().toString(), 0);
|
||||||
|
event.setException(null);
|
||||||
|
//note: we turn this into a plain message to avoid stack trace being logged by Idea
|
||||||
|
logger.messageLogged(event);
|
||||||
|
suppressTaskFailures = true;
|
||||||
|
}
|
||||||
|
tasks.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageLogged(BuildEvent event) {
|
||||||
|
String msg = event.getMessage();
|
||||||
|
|
||||||
|
boolean processed = false;
|
||||||
|
|
||||||
|
if (!tasks.isEmpty()) {
|
||||||
|
Task task = tasks.peek();
|
||||||
|
for (MessageKind messageKind : task.msgs) {
|
||||||
|
if (messageKind.matches(msg)) {
|
||||||
|
event.setMessage(msg, messageKind.priority);
|
||||||
|
processed = true;
|
||||||
|
if (messageKind == MessageKind.JAVAC_CRASH) {
|
||||||
|
crashFound = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getPriority() == MSG_ERR || crashFound) {
|
||||||
|
//we log errors regardless of owning task
|
||||||
|
logger.messageLogged(event);
|
||||||
|
suppressTaskFailures = true;
|
||||||
|
} else if (processed) {
|
||||||
|
logger.messageLogged(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="###PROJECT_DIR###" vcs="###VCS_TYPE###" />
|
<mapping directory="###ROOT_DIR###" vcs="###VCS_TYPE###" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -2,62 +2,63 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<ignored path="jdk.iws" />
|
<ignored path="jdk.iws" />
|
||||||
<ignored path="###PROJECT_DIR###/build/idea/out/" />
|
<ignored path="###ROOT_DIR###/build/idea/out/" />
|
||||||
<ignored path=".idea/" />
|
<ignored path=".idea/" />
|
||||||
</component>
|
</component>
|
||||||
<component name="StructureViewFactory">
|
<component name="StructureViewFactory">
|
||||||
<option name="ACTIVE_ACTIONS" value=",ALPHA_COMPARATOR" />
|
<option name="ACTIVE_ACTIONS" value=",ALPHA_COMPARATOR" />
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Shell Script.images">
|
<component name="antWorkspaceConfiguration">
|
||||||
<configuration name="clean" type="ShConfigurationType" folderName="make">
|
<option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
|
||||||
<option name="SCRIPT_TEXT" value="###BASH_RUNNER_PREFIX### make clean" />
|
<option name="FILTER_TARGETS" value="false" />
|
||||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
<buildFile url="file://###ROOT_DIR###/make/ide/idea/jdk/build.xml">
|
||||||
<option name="SCRIPT_PATH" value="" />
|
<runInBackground value="false" />
|
||||||
<option name="SCRIPT_OPTIONS" value="" />
|
<targetFilters>
|
||||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
<filter targetName="clean" isVisible="true" />
|
||||||
<option name="SCRIPT_WORKING_DIRECTORY" value="###PROJECT_DIR###" />
|
<filter targetName="images" isVisible="true" />
|
||||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
</targetFilters>
|
||||||
<option name="INTERPRETER_PATH" value="" />
|
<treeView value="false" />
|
||||||
<option name="INTERPRETER_OPTIONS" value="" />
|
<expanded value="true" />
|
||||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
</buildFile>
|
||||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
</component>
|
||||||
<envs />
|
<component name="ProjectView">
|
||||||
<method v="2" />
|
<navigator currentView="ProjectPane" proportions="" version="1">
|
||||||
</configuration>
|
<flattenPackages />
|
||||||
<configuration name="images" type="ShConfigurationType" folderName="make">
|
<showMembers />
|
||||||
<option name="SCRIPT_TEXT" value="###BASH_RUNNER_PREFIX### make images" />
|
<showModules />
|
||||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
<showLibraryContents />
|
||||||
<option name="SCRIPT_PATH" value="" />
|
<hideEmptyPackages />
|
||||||
<option name="SCRIPT_OPTIONS" value="" />
|
<abbreviatePackageNames />
|
||||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
<autoscrollToSource />
|
||||||
<option name="SCRIPT_WORKING_DIRECTORY" value="###PROJECT_DIR###" />
|
<autoscrollFromSource />
|
||||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
<sortByType />
|
||||||
<option name="INTERPRETER_PATH" value="" />
|
</navigator>
|
||||||
<option name="INTERPRETER_OPTIONS" value="" />
|
<panes>
|
||||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
<pane id="ProjectPane">
|
||||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
<subPane>
|
||||||
<envs />
|
<PATH>
|
||||||
<method v="2" />
|
<PATH_ELEMENT>
|
||||||
</configuration>
|
<option name="myItemId" value="jdk" />
|
||||||
<configuration name="reconfigure" type="ShConfigurationType" folderName="make">
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||||
<option name="SCRIPT_TEXT" value="###BASH_RUNNER_PREFIX### make reconfigure" />
|
</PATH_ELEMENT>
|
||||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
</PATH>
|
||||||
<option name="SCRIPT_PATH" value="" />
|
</subPane>
|
||||||
<option name="SCRIPT_OPTIONS" value="" />
|
</pane>
|
||||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
<pane id="PackagesPane">
|
||||||
<option name="SCRIPT_WORKING_DIRECTORY" value="###PROJECT_DIR###" />
|
<subPane>
|
||||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
|
<PATH>
|
||||||
<option name="INTERPRETER_PATH" value="" />
|
<PATH_ELEMENT>
|
||||||
<option name="INTERPRETER_OPTIONS" value="" />
|
<option name="myItemId" value="jdk" />
|
||||||
<option name="EXECUTE_IN_TERMINAL" value="true" />
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
|
||||||
<option name="EXECUTE_SCRIPT_FILE" value="false" />
|
</PATH_ELEMENT>
|
||||||
<envs />
|
<PATH_ELEMENT>
|
||||||
<method v="2" />
|
<option name="myItemId" value="jdk" />
|
||||||
</configuration>
|
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
|
||||||
<list>
|
</PATH_ELEMENT>
|
||||||
<item itemvalue="Shell Script.images" />
|
</PATH>
|
||||||
<item itemvalue="Shell Script.clean" />
|
</subPane>
|
||||||
<item itemvalue="Shell Script.reconfigure" />
|
</pane>
|
||||||
</list>
|
<pane id="Scope" />
|
||||||
|
</panes>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -27,7 +27,7 @@ include LibCommon.gmk
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
ifeq ($(call isTargetOs, linux windows)+$(call isTargetCpu, x86_64), true+true)
|
ifeq ($(call isTargetOs, linux windows)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2), true+true+true)
|
||||||
$(eval $(call SetupJdkLibrary, BUILD_LIBSVML, \
|
$(eval $(call SetupJdkLibrary, BUILD_LIBSVML, \
|
||||||
NAME := svml, \
|
NAME := svml, \
|
||||||
CFLAGS := $(CFLAGS_JDKLIB), \
|
CFLAGS := $(CFLAGS_JDKLIB), \
|
||||||
|
|
|
@ -643,7 +643,8 @@ void LinearScan::compute_local_live_sets() {
|
||||||
CodeEmitInfo* info = visitor.info_at(k);
|
CodeEmitInfo* info = visitor.info_at(k);
|
||||||
ValueStack* stack = info->stack();
|
ValueStack* stack = info->stack();
|
||||||
for_each_state_value(stack, value,
|
for_each_state_value(stack, value,
|
||||||
set_live_gen_kill(value, op, live_gen, live_kill)
|
set_live_gen_kill(value, op, live_gen, live_kill);
|
||||||
|
local_has_fpu_registers = local_has_fpu_registers || value->type()->is_float_kind();
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1659,22 +1660,33 @@ void LinearScan::allocate_registers() {
|
||||||
Interval* precolored_cpu_intervals, *not_precolored_cpu_intervals;
|
Interval* precolored_cpu_intervals, *not_precolored_cpu_intervals;
|
||||||
Interval* precolored_fpu_intervals, *not_precolored_fpu_intervals;
|
Interval* precolored_fpu_intervals, *not_precolored_fpu_intervals;
|
||||||
|
|
||||||
// allocate cpu registers
|
// collect cpu intervals
|
||||||
create_unhandled_lists(&precolored_cpu_intervals, ¬_precolored_cpu_intervals,
|
create_unhandled_lists(&precolored_cpu_intervals, ¬_precolored_cpu_intervals,
|
||||||
is_precolored_cpu_interval, is_virtual_cpu_interval);
|
is_precolored_cpu_interval, is_virtual_cpu_interval);
|
||||||
|
|
||||||
// allocate fpu registers
|
// collect fpu intervals
|
||||||
create_unhandled_lists(&precolored_fpu_intervals, ¬_precolored_fpu_intervals,
|
create_unhandled_lists(&precolored_fpu_intervals, ¬_precolored_fpu_intervals,
|
||||||
is_precolored_fpu_interval, is_virtual_fpu_interval);
|
is_precolored_fpu_interval, is_virtual_fpu_interval);
|
||||||
|
// this fpu interval collection cannot be moved down below with the allocation section as
|
||||||
// the fpu interval allocation cannot be moved down below with the fpu section as
|
|
||||||
// the cpu_lsw.walk() changes interval positions.
|
// the cpu_lsw.walk() changes interval positions.
|
||||||
|
|
||||||
|
if (!has_fpu_registers()) {
|
||||||
|
#ifdef ASSERT
|
||||||
|
assert(not_precolored_fpu_intervals == Interval::end(), "missed an uncolored fpu interval");
|
||||||
|
#else
|
||||||
|
if (not_precolored_fpu_intervals != Interval::end()) {
|
||||||
|
BAILOUT("missed an uncolored fpu interval");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate cpu registers
|
||||||
LinearScanWalker cpu_lsw(this, precolored_cpu_intervals, not_precolored_cpu_intervals);
|
LinearScanWalker cpu_lsw(this, precolored_cpu_intervals, not_precolored_cpu_intervals);
|
||||||
cpu_lsw.walk();
|
cpu_lsw.walk();
|
||||||
cpu_lsw.finish_allocation();
|
cpu_lsw.finish_allocation();
|
||||||
|
|
||||||
if (has_fpu_registers()) {
|
if (has_fpu_registers()) {
|
||||||
|
// allocate fpu registers
|
||||||
LinearScanWalker fpu_lsw(this, precolored_fpu_intervals, not_precolored_fpu_intervals);
|
LinearScanWalker fpu_lsw(this, precolored_fpu_intervals, not_precolored_fpu_intervals);
|
||||||
fpu_lsw.walk();
|
fpu_lsw.walk();
|
||||||
fpu_lsw.finish_allocation();
|
fpu_lsw.finish_allocation();
|
||||||
|
|
|
@ -390,7 +390,7 @@ static void rewrite_nofast_bytecode(const methodHandle& method) {
|
||||||
void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread* thread, InstanceKlass* ik) {
|
void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread* thread, InstanceKlass* ik) {
|
||||||
for (int i = 0; i < ik->methods()->length(); i++) {
|
for (int i = 0; i < ik->methods()->length(); i++) {
|
||||||
methodHandle m(thread, ik->methods()->at(i));
|
methodHandle m(thread, ik->methods()->at(i));
|
||||||
if (!ik->can_be_verified_at_dumptime()) {
|
if (ik->can_be_verified_at_dumptime()) {
|
||||||
rewrite_nofast_bytecode(m);
|
rewrite_nofast_bytecode(m);
|
||||||
}
|
}
|
||||||
Fingerprinter fp(m);
|
Fingerprinter fp(m);
|
||||||
|
@ -574,7 +574,7 @@ public:
|
||||||
bool MetaspaceShared::linking_required(InstanceKlass* ik) {
|
bool MetaspaceShared::linking_required(InstanceKlass* ik) {
|
||||||
// For static CDS dump, do not link old classes.
|
// For static CDS dump, do not link old classes.
|
||||||
// For dynamic CDS dump, only link classes loaded by the builtin class loaders.
|
// For dynamic CDS dump, only link classes loaded by the builtin class loaders.
|
||||||
return DumpSharedSpaces ? !ik->can_be_verified_at_dumptime() : !ik->is_shared_unregistered_class();
|
return DumpSharedSpaces ? ik->can_be_verified_at_dumptime() : !ik->is_shared_unregistered_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) {
|
bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) {
|
||||||
|
@ -750,7 +750,7 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) {
|
||||||
ExceptionMark em(current);
|
ExceptionMark em(current);
|
||||||
JavaThread* THREAD = current; // For exception macros.
|
JavaThread* THREAD = current; // For exception macros.
|
||||||
Arguments::assert_is_dumping_archive();
|
Arguments::assert_is_dumping_archive();
|
||||||
if (ik->is_loaded() && !ik->is_linked() && !ik->can_be_verified_at_dumptime() &&
|
if (ik->is_loaded() && !ik->is_linked() && ik->can_be_verified_at_dumptime() &&
|
||||||
!SystemDictionaryShared::has_class_failed_verification(ik)) {
|
!SystemDictionaryShared::has_class_failed_verification(ik)) {
|
||||||
bool saved = BytecodeVerificationLocal;
|
bool saved = BytecodeVerificationLocal;
|
||||||
if (ik->is_shared_unregistered_class() && ik->class_loader() == NULL) {
|
if (ik->is_shared_unregistered_class() && ik->class_loader() == NULL) {
|
||||||
|
|
|
@ -1411,7 +1411,7 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) {
|
||||||
if (has_class_failed_verification(k)) {
|
if (has_class_failed_verification(k)) {
|
||||||
return warn_excluded(k, "Failed verification");
|
return warn_excluded(k, "Failed verification");
|
||||||
} else {
|
} else {
|
||||||
if (!k->can_be_verified_at_dumptime()) {
|
if (k->can_be_verified_at_dumptime()) {
|
||||||
return warn_excluded(k, "Not linked");
|
return warn_excluded(k, "Not linked");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1425,7 +1425,7 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k->can_be_verified_at_dumptime() && k->is_linked()) {
|
if (!k->can_be_verified_at_dumptime() && k->is_linked()) {
|
||||||
return warn_excluded(k, "Old class has been linked");
|
return warn_excluded(k, "Old class has been linked");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -571,7 +571,7 @@ void Rewriter::rewrite(InstanceKlass* klass, TRAPS) {
|
||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
if (klass->is_shared()) {
|
if (klass->is_shared()) {
|
||||||
assert(!klass->is_rewritten(), "rewritten shared classes cannot be rewritten again");
|
assert(!klass->is_rewritten(), "rewritten shared classes cannot be rewritten again");
|
||||||
assert(klass->can_be_verified_at_dumptime(), "only shared old classes aren't rewritten");
|
assert(!klass->can_be_verified_at_dumptime(), "only shared old classes aren't rewritten");
|
||||||
}
|
}
|
||||||
#endif // INCLUDE_CDS
|
#endif // INCLUDE_CDS
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
|
|
|
@ -370,7 +370,7 @@ void ConstantPool::restore_unshareable_info(TRAPS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstantPool::remove_unshareable_info() {
|
void ConstantPool::remove_unshareable_info() {
|
||||||
if (!_pool_holder->is_linked() && _pool_holder->is_shared_old_klass()) {
|
if (!_pool_holder->is_linked() && !_pool_holder->verified_at_dump_time()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Resolved references are not in the shared archive.
|
// Resolved references are not in the shared archive.
|
||||||
|
|
|
@ -2403,8 +2403,8 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
|
||||||
void InstanceKlass::remove_unshareable_info() {
|
void InstanceKlass::remove_unshareable_info() {
|
||||||
|
|
||||||
if (can_be_verified_at_dumptime()) {
|
if (can_be_verified_at_dumptime()) {
|
||||||
// Set the old class bit.
|
// Remember this so we can avoid walking the hierarchy at runtime.
|
||||||
set_is_shared_old_klass();
|
set_verified_at_dump_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
Klass::remove_unshareable_info();
|
Klass::remove_unshareable_info();
|
||||||
|
@ -2549,19 +2549,19 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
|
||||||
// Verification of archived old classes will be performed during run time.
|
// Verification of archived old classes will be performed during run time.
|
||||||
bool InstanceKlass::can_be_verified_at_dumptime() const {
|
bool InstanceKlass::can_be_verified_at_dumptime() const {
|
||||||
if (major_version() < 50 /*JAVA_6_VERSION*/) {
|
if (major_version() < 50 /*JAVA_6_VERSION*/) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
if (java_super() != NULL && java_super()->can_be_verified_at_dumptime()) {
|
if (java_super() != NULL && !java_super()->can_be_verified_at_dumptime()) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
Array<InstanceKlass*>* interfaces = local_interfaces();
|
Array<InstanceKlass*>* interfaces = local_interfaces();
|
||||||
int len = interfaces->length();
|
int len = interfaces->length();
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (interfaces->at(i)->can_be_verified_at_dumptime()) {
|
if (!interfaces->at(i)->can_be_verified_at_dumptime()) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceKlass::set_shared_class_loader_type(s2 loader_type) {
|
void InstanceKlass::set_shared_class_loader_type(s2 loader_type) {
|
||||||
|
|
|
@ -178,7 +178,7 @@ private:
|
||||||
enum {
|
enum {
|
||||||
_archived_lambda_proxy_is_available = 2,
|
_archived_lambda_proxy_is_available = 2,
|
||||||
_has_value_based_class_annotation = 4,
|
_has_value_based_class_annotation = 4,
|
||||||
_is_shared_old_klass = 8
|
_verified_at_dump_time = 8
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -334,11 +334,11 @@ protected:
|
||||||
NOT_CDS(return false;)
|
NOT_CDS(return false;)
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_is_shared_old_klass() {
|
void set_verified_at_dump_time() {
|
||||||
CDS_ONLY(_shared_class_flags |= _is_shared_old_klass;)
|
CDS_ONLY(_shared_class_flags |= _verified_at_dump_time;)
|
||||||
}
|
}
|
||||||
bool is_shared_old_klass() const {
|
bool verified_at_dump_time() const {
|
||||||
CDS_ONLY(return (_shared_class_flags & _is_shared_old_klass) != 0;)
|
CDS_ONLY(return (_shared_class_flags & _verified_at_dump_time) != 0;)
|
||||||
NOT_CDS(return false;)
|
NOT_CDS(return false;)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ inline InstanceKlass* klassVtable::ik() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool klassVtable::is_preinitialized_vtable() {
|
bool klassVtable::is_preinitialized_vtable() {
|
||||||
return _klass->is_shared() && !MetaspaceShared::remapped_readwrite() && !_klass->is_shared_old_klass();
|
return _klass->is_shared() && !MetaspaceShared::remapped_readwrite() && _klass->verified_at_dump_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1094,8 +1094,8 @@ void itableMethodEntry::initialize(InstanceKlass* klass, Method* m) {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (MetaspaceShared::is_in_shared_metaspace((void*)&_method) &&
|
if (MetaspaceShared::is_in_shared_metaspace((void*)&_method) &&
|
||||||
!MetaspaceShared::remapped_readwrite() &&
|
!MetaspaceShared::remapped_readwrite() &&
|
||||||
!m->method_holder()->can_be_verified_at_dumptime() &&
|
m->method_holder()->verified_at_dump_time() &&
|
||||||
!klass->can_be_verified_at_dumptime()) {
|
klass->verified_at_dump_time()) {
|
||||||
// At runtime initialize_itable is rerun as part of link_class_impl()
|
// At runtime initialize_itable is rerun as part of link_class_impl()
|
||||||
// for a shared class loaded by the non-boot loader.
|
// for a shared class loaded by the non-boot loader.
|
||||||
// The dumptime itable method entry should be the same as the runtime entry.
|
// The dumptime itable method entry should be the same as the runtime entry.
|
||||||
|
|
|
@ -409,7 +409,7 @@ void Method::remove_unshareable_info() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Method::set_vtable_index(int index) {
|
void Method::set_vtable_index(int index) {
|
||||||
if (is_shared() && !MetaspaceShared::remapped_readwrite() && !method_holder()->is_shared_old_klass()) {
|
if (is_shared() && !MetaspaceShared::remapped_readwrite() && method_holder()->verified_at_dump_time()) {
|
||||||
// At runtime initialize_vtable is rerun as part of link_class_impl()
|
// At runtime initialize_vtable is rerun as part of link_class_impl()
|
||||||
// for a shared class loaded by the non-boot loader to obtain the loader
|
// for a shared class loaded by the non-boot loader to obtain the loader
|
||||||
// constraints based on the runtime classloaders' context.
|
// constraints based on the runtime classloaders' context.
|
||||||
|
@ -420,7 +420,7 @@ void Method::set_vtable_index(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Method::set_itable_index(int index) {
|
void Method::set_itable_index(int index) {
|
||||||
if (is_shared() && !MetaspaceShared::remapped_readwrite() && !method_holder()->is_shared_old_klass()) {
|
if (is_shared() && !MetaspaceShared::remapped_readwrite() && method_holder()->verified_at_dump_time()) {
|
||||||
// At runtime initialize_itable is rerun as part of link_class_impl()
|
// At runtime initialize_itable is rerun as part of link_class_impl()
|
||||||
// for a shared class loaded by the non-boot loader to obtain the loader
|
// for a shared class loaded by the non-boot loader to obtain the loader
|
||||||
// constraints based on the runtime classloaders' context. The dumptime
|
// constraints based on the runtime classloaders' context. The dumptime
|
||||||
|
|
|
@ -45,6 +45,9 @@ const char* C2Compiler::retry_no_subsuming_loads() {
|
||||||
const char* C2Compiler::retry_no_escape_analysis() {
|
const char* C2Compiler::retry_no_escape_analysis() {
|
||||||
return "retry without escape analysis";
|
return "retry without escape analysis";
|
||||||
}
|
}
|
||||||
|
const char* C2Compiler::retry_no_locks_coarsening() {
|
||||||
|
return "retry without locks coarsening";
|
||||||
|
}
|
||||||
const char* C2Compiler::retry_class_loading_during_parsing() {
|
const char* C2Compiler::retry_class_loading_during_parsing() {
|
||||||
return "retry class loading during parsing";
|
return "retry class loading during parsing";
|
||||||
}
|
}
|
||||||
|
@ -97,10 +100,11 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, boo
|
||||||
bool subsume_loads = SubsumeLoads;
|
bool subsume_loads = SubsumeLoads;
|
||||||
bool do_escape_analysis = DoEscapeAnalysis;
|
bool do_escape_analysis = DoEscapeAnalysis;
|
||||||
bool eliminate_boxing = EliminateAutoBox;
|
bool eliminate_boxing = EliminateAutoBox;
|
||||||
|
bool do_locks_coarsening = EliminateLocks;
|
||||||
|
|
||||||
while (!env->failing()) {
|
while (!env->failing()) {
|
||||||
// Attempt to compile while subsuming loads into machine instructions.
|
// Attempt to compile while subsuming loads into machine instructions.
|
||||||
Compile C(env, target, entry_bci, subsume_loads, do_escape_analysis, eliminate_boxing, install_code, directive);
|
Compile C(env, target, entry_bci, subsume_loads, do_escape_analysis, eliminate_boxing, do_locks_coarsening, install_code, directive);
|
||||||
|
|
||||||
// Check result and retry if appropriate.
|
// Check result and retry if appropriate.
|
||||||
if (C.failure_reason() != NULL) {
|
if (C.failure_reason() != NULL) {
|
||||||
|
@ -120,6 +124,12 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, boo
|
||||||
env->report_failure(C.failure_reason());
|
env->report_failure(C.failure_reason());
|
||||||
continue; // retry
|
continue; // retry
|
||||||
}
|
}
|
||||||
|
if (C.failure_reason_is(retry_no_locks_coarsening())) {
|
||||||
|
assert(do_locks_coarsening, "must make progress");
|
||||||
|
do_locks_coarsening = false;
|
||||||
|
env->report_failure(C.failure_reason());
|
||||||
|
continue; // retry
|
||||||
|
}
|
||||||
if (C.has_boxed_value()) {
|
if (C.has_boxed_value()) {
|
||||||
// Recompile without boxing elimination regardless failure reason.
|
// Recompile without boxing elimination regardless failure reason.
|
||||||
assert(eliminate_boxing, "must make progress");
|
assert(eliminate_boxing, "must make progress");
|
||||||
|
@ -141,6 +151,10 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, boo
|
||||||
do_escape_analysis = false;
|
do_escape_analysis = false;
|
||||||
continue; // retry
|
continue; // retry
|
||||||
}
|
}
|
||||||
|
if (do_locks_coarsening) {
|
||||||
|
do_locks_coarsening = false;
|
||||||
|
continue; // retry
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// print inlining for last compilation only
|
// print inlining for last compilation only
|
||||||
C.dump_print_inlining();
|
C.dump_print_inlining();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -49,6 +49,7 @@ public:
|
||||||
// sentinel value used to trigger backtracking in compile_method().
|
// sentinel value used to trigger backtracking in compile_method().
|
||||||
static const char* retry_no_subsuming_loads();
|
static const char* retry_no_subsuming_loads();
|
||||||
static const char* retry_no_escape_analysis();
|
static const char* retry_no_escape_analysis();
|
||||||
|
static const char* retry_no_locks_coarsening();
|
||||||
static const char* retry_class_loading_during_parsing();
|
static const char* retry_class_loading_during_parsing();
|
||||||
|
|
||||||
// Print compilation timers and statistics
|
// Print compilation timers and statistics
|
||||||
|
|
|
@ -2054,6 +2054,12 @@ bool AbstractLockNode::find_unlocks_for_region(const RegionNode* region, LockNod
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* AbstractLockNode::_kind_names[] = {"Regular", "NonEscObj", "Coarsened", "Nested"};
|
||||||
|
|
||||||
|
const char * AbstractLockNode::kind_as_string() const {
|
||||||
|
return _kind_names[_kind];
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
//
|
//
|
||||||
// Create a counter which counts the number of times this lock is acquired
|
// Create a counter which counts the number of times this lock is acquired
|
||||||
|
@ -2071,8 +2077,6 @@ void AbstractLockNode::set_eliminated_lock_counter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* AbstractLockNode::_kind_names[] = {"Regular", "NonEscObj", "Coarsened", "Nested"};
|
|
||||||
|
|
||||||
void AbstractLockNode::dump_spec(outputStream* st) const {
|
void AbstractLockNode::dump_spec(outputStream* st) const {
|
||||||
st->print("%s ", _kind_names[_kind]);
|
st->print("%s ", _kind_names[_kind]);
|
||||||
CallNode::dump_spec(st);
|
CallNode::dump_spec(st);
|
||||||
|
@ -2124,6 +2128,9 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!phase->C->do_locks_coarsening()) {
|
||||||
|
return result; // Compiling without locks coarsening
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Try lock coarsening
|
// Try lock coarsening
|
||||||
//
|
//
|
||||||
|
@ -2161,6 +2168,9 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
if (PrintEliminateLocks) {
|
if (PrintEliminateLocks) {
|
||||||
int locks = 0;
|
int locks = 0;
|
||||||
int unlocks = 0;
|
int unlocks = 0;
|
||||||
|
if (Verbose) {
|
||||||
|
tty->print_cr("=== Locks coarsening ===");
|
||||||
|
}
|
||||||
for (int i = 0; i < lock_ops.length(); i++) {
|
for (int i = 0; i < lock_ops.length(); i++) {
|
||||||
AbstractLockNode* lock = lock_ops.at(i);
|
AbstractLockNode* lock = lock_ops.at(i);
|
||||||
if (lock->Opcode() == Op_Lock)
|
if (lock->Opcode() == Op_Lock)
|
||||||
|
@ -2168,10 +2178,11 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
else
|
else
|
||||||
unlocks++;
|
unlocks++;
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
lock->dump(1);
|
tty->print(" %d: ", i);
|
||||||
|
lock->dump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks);
|
tty->print_cr("=== Coarsened %d unlocks and %d locks", unlocks, locks);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2186,6 +2197,8 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
#endif
|
#endif
|
||||||
lock->set_coarsened();
|
lock->set_coarsened();
|
||||||
}
|
}
|
||||||
|
// Record this coarsened group.
|
||||||
|
phase->C->add_coarsened_locks(lock_ops);
|
||||||
} else if (ctrl->is_Region() &&
|
} else if (ctrl->is_Region() &&
|
||||||
iter->_worklist.member(ctrl)) {
|
iter->_worklist.member(ctrl)) {
|
||||||
// We weren't able to find any opportunities but the region this
|
// We weren't able to find any opportunities but the region this
|
||||||
|
@ -2219,15 +2232,34 @@ bool LockNode::is_nested_lock_region(Compile * c) {
|
||||||
// Ignore complex cases: merged locks or multiple locks.
|
// Ignore complex cases: merged locks or multiple locks.
|
||||||
Node* obj = obj_node();
|
Node* obj = obj_node();
|
||||||
LockNode* unique_lock = NULL;
|
LockNode* unique_lock = NULL;
|
||||||
if (!box->is_simple_lock_region(&unique_lock, obj)) {
|
Node* bad_lock = NULL;
|
||||||
|
if (!box->is_simple_lock_region(&unique_lock, obj, &bad_lock)) {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
this->log_lock_optimization(c, "eliminate_lock_INLR_2a");
|
this->log_lock_optimization(c, "eliminate_lock_INLR_2a", bad_lock);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (unique_lock != this) {
|
if (unique_lock != this) {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
this->log_lock_optimization(c, "eliminate_lock_INLR_2b");
|
this->log_lock_optimization(c, "eliminate_lock_INLR_2b", (unique_lock != NULL ? unique_lock : bad_lock));
|
||||||
|
if (PrintEliminateLocks && Verbose) {
|
||||||
|
tty->print_cr("=============== unique_lock != this ============");
|
||||||
|
tty->print(" this: ");
|
||||||
|
this->dump();
|
||||||
|
tty->print(" box: ");
|
||||||
|
box->dump();
|
||||||
|
tty->print(" obj: ");
|
||||||
|
obj->dump();
|
||||||
|
if (unique_lock != NULL) {
|
||||||
|
tty->print(" unique_lock: ");
|
||||||
|
unique_lock->dump();
|
||||||
|
}
|
||||||
|
if (bad_lock != NULL) {
|
||||||
|
tty->print(" bad_lock: ");
|
||||||
|
bad_lock->dump();
|
||||||
|
}
|
||||||
|
tty->print_cr("===============");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2294,23 +2326,21 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * AbstractLockNode::kind_as_string() const {
|
void AbstractLockNode::log_lock_optimization(Compile *C, const char * tag, Node* bad_lock) const {
|
||||||
return is_coarsened() ? "coarsened" :
|
|
||||||
is_nested() ? "nested" :
|
|
||||||
is_non_esc_obj() ? "non_escaping" :
|
|
||||||
"?";
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractLockNode::log_lock_optimization(Compile *C, const char * tag) const {
|
|
||||||
if (C == NULL) {
|
if (C == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CompileLog* log = C->log();
|
CompileLog* log = C->log();
|
||||||
if (log != NULL) {
|
if (log != NULL) {
|
||||||
log->begin_head("%s lock='%d' compile_id='%d' class_id='%s' kind='%s'",
|
Node* box = box_node();
|
||||||
tag, is_Lock(), C->compile_id(),
|
Node* obj = obj_node();
|
||||||
|
int box_id = box != NULL ? box->_idx : -1;
|
||||||
|
int obj_id = obj != NULL ? obj->_idx : -1;
|
||||||
|
|
||||||
|
log->begin_head("%s compile_id='%d' lock_id='%d' class='%s' kind='%s' box_id='%d' obj_id='%d' bad_id='%d'",
|
||||||
|
tag, C->compile_id(), this->_idx,
|
||||||
is_Unlock() ? "unlock" : is_Lock() ? "lock" : "?",
|
is_Unlock() ? "unlock" : is_Lock() ? "lock" : "?",
|
||||||
kind_as_string());
|
kind_as_string(), box_id, obj_id, (bad_lock != NULL ? bad_lock->_idx : -1));
|
||||||
log->stamp();
|
log->stamp();
|
||||||
log->end_head();
|
log->end_head();
|
||||||
JVMState* p = is_Unlock() ? (as_Unlock()->dbg_jvms()) : jvms();
|
JVMState* p = is_Unlock() ? (as_Unlock()->dbg_jvms()) : jvms();
|
||||||
|
|
|
@ -1056,9 +1056,11 @@ private:
|
||||||
Coarsened, // Lock was coarsened
|
Coarsened, // Lock was coarsened
|
||||||
Nested // Nested lock
|
Nested // Nested lock
|
||||||
} _kind;
|
} _kind;
|
||||||
|
|
||||||
|
static const char* _kind_names[Nested+1];
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
NamedCounter* _counter;
|
NamedCounter* _counter;
|
||||||
static const char* _kind_names[Nested+1];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1101,7 +1103,7 @@ public:
|
||||||
bool is_nested() const { return (_kind == Nested); }
|
bool is_nested() const { return (_kind == Nested); }
|
||||||
|
|
||||||
const char * kind_as_string() const;
|
const char * kind_as_string() const;
|
||||||
void log_lock_optimization(Compile* c, const char * tag) const;
|
void log_lock_optimization(Compile* c, const char * tag, Node* bad_lock = NULL) const;
|
||||||
|
|
||||||
void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
|
void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
|
||||||
void set_coarsened() { _kind = Coarsened; set_eliminated_lock_counter(); }
|
void set_coarsened() { _kind = Coarsened; set_eliminated_lock_counter(); }
|
||||||
|
|
|
@ -432,6 +432,7 @@ void Compile::remove_useless_nodes(Unique_Node_List &useful) {
|
||||||
remove_useless_nodes(_skeleton_predicate_opaqs, useful);
|
remove_useless_nodes(_skeleton_predicate_opaqs, useful);
|
||||||
remove_useless_nodes(_expensive_nodes, useful); // remove useless expensive nodes
|
remove_useless_nodes(_expensive_nodes, useful); // remove useless expensive nodes
|
||||||
remove_useless_nodes(_for_post_loop_igvn, useful); // remove useless node recorded for post loop opts IGVN pass
|
remove_useless_nodes(_for_post_loop_igvn, useful); // remove useless node recorded for post loop opts IGVN pass
|
||||||
|
remove_useless_coarsened_locks(useful); // remove useless coarsened locks nodes
|
||||||
|
|
||||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||||
bs->eliminate_useless_gc_barriers(useful, this);
|
bs->eliminate_useless_gc_barriers(useful, this);
|
||||||
|
@ -501,6 +502,12 @@ void Compile::print_compile_messages() {
|
||||||
tty->print_cr("** Bailout: Recompile without boxing elimination **");
|
tty->print_cr("** Bailout: Recompile without boxing elimination **");
|
||||||
tty->print_cr("*********************************************************");
|
tty->print_cr("*********************************************************");
|
||||||
}
|
}
|
||||||
|
if ((_do_locks_coarsening != EliminateLocks) && PrintOpto) {
|
||||||
|
// Recompiling without locks coarsening
|
||||||
|
tty->print_cr("*********************************************************");
|
||||||
|
tty->print_cr("** Bailout: Recompile without locks coarsening **");
|
||||||
|
tty->print_cr("*********************************************************");
|
||||||
|
}
|
||||||
if (env()->break_at_compile()) {
|
if (env()->break_at_compile()) {
|
||||||
// Open the debugger when compiling this method.
|
// Open the debugger when compiling this method.
|
||||||
tty->print("### Breaking when compiling: ");
|
tty->print("### Breaking when compiling: ");
|
||||||
|
@ -528,13 +535,15 @@ debug_only( int Compile::_debug_idx = 100000; )
|
||||||
|
|
||||||
|
|
||||||
Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
|
Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
|
||||||
bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing, bool install_code, DirectiveSet* directive)
|
bool subsume_loads, bool do_escape_analysis, bool eliminate_boxing,
|
||||||
|
bool do_locks_coarsening, bool install_code, DirectiveSet* directive)
|
||||||
: Phase(Compiler),
|
: Phase(Compiler),
|
||||||
_compile_id(ci_env->compile_id()),
|
_compile_id(ci_env->compile_id()),
|
||||||
_subsume_loads(subsume_loads),
|
_subsume_loads(subsume_loads),
|
||||||
_do_escape_analysis(do_escape_analysis),
|
_do_escape_analysis(do_escape_analysis),
|
||||||
_install_code(install_code),
|
_install_code(install_code),
|
||||||
_eliminate_boxing(eliminate_boxing),
|
_eliminate_boxing(eliminate_boxing),
|
||||||
|
_do_locks_coarsening(do_locks_coarsening),
|
||||||
_method(target),
|
_method(target),
|
||||||
_entry_bci(osr_bci),
|
_entry_bci(osr_bci),
|
||||||
_stub_function(NULL),
|
_stub_function(NULL),
|
||||||
|
@ -566,6 +575,7 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
|
||||||
_skeleton_predicate_opaqs (comp_arena(), 8, 0, NULL),
|
_skeleton_predicate_opaqs (comp_arena(), 8, 0, NULL),
|
||||||
_expensive_nodes (comp_arena(), 8, 0, NULL),
|
_expensive_nodes (comp_arena(), 8, 0, NULL),
|
||||||
_for_post_loop_igvn(comp_arena(), 8, 0, NULL),
|
_for_post_loop_igvn(comp_arena(), 8, 0, NULL),
|
||||||
|
_coarsened_locks (comp_arena(), 8, 0, NULL),
|
||||||
_congraph(NULL),
|
_congraph(NULL),
|
||||||
NOT_PRODUCT(_printer(NULL) COMMA)
|
NOT_PRODUCT(_printer(NULL) COMMA)
|
||||||
_dead_node_list(comp_arena()),
|
_dead_node_list(comp_arena()),
|
||||||
|
@ -832,6 +842,7 @@ Compile::Compile( ciEnv* ci_env,
|
||||||
_do_escape_analysis(false),
|
_do_escape_analysis(false),
|
||||||
_install_code(true),
|
_install_code(true),
|
||||||
_eliminate_boxing(false),
|
_eliminate_boxing(false),
|
||||||
|
_do_locks_coarsening(false),
|
||||||
_method(NULL),
|
_method(NULL),
|
||||||
_entry_bci(InvocationEntryBci),
|
_entry_bci(InvocationEntryBci),
|
||||||
_stub_function(stub_function),
|
_stub_function(stub_function),
|
||||||
|
@ -4447,6 +4458,101 @@ void Compile::add_expensive_node(Node * n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track coarsened Lock and Unlock nodes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Lock_List : public Node_List {
|
||||||
|
uint _origin_cnt;
|
||||||
|
public:
|
||||||
|
Lock_List(Arena *a, uint cnt) : Node_List(a), _origin_cnt(cnt) {}
|
||||||
|
uint origin_cnt() const { return _origin_cnt; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void Compile::add_coarsened_locks(GrowableArray<AbstractLockNode*>& locks) {
|
||||||
|
int length = locks.length();
|
||||||
|
if (length > 0) {
|
||||||
|
// Have to keep this list until locks elimination during Macro nodes elimination.
|
||||||
|
Lock_List* locks_list = new (comp_arena()) Lock_List(comp_arena(), length);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
AbstractLockNode* lock = locks.at(i);
|
||||||
|
assert(lock->is_coarsened(), "expecting only coarsened AbstractLock nodes, but got '%s'[%d] node", lock->Name(), lock->_idx);
|
||||||
|
locks_list->push(lock);
|
||||||
|
}
|
||||||
|
_coarsened_locks.append(locks_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compile::remove_useless_coarsened_locks(Unique_Node_List& useful) {
|
||||||
|
int count = coarsened_count();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Node_List* locks_list = _coarsened_locks.at(i);
|
||||||
|
for (uint j = 0; j < locks_list->size(); j++) {
|
||||||
|
Node* lock = locks_list->at(j);
|
||||||
|
assert(lock->is_AbstractLock(), "sanity");
|
||||||
|
if (!useful.member(lock)) {
|
||||||
|
locks_list->yank(lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compile::remove_coarsened_lock(Node* n) {
|
||||||
|
if (n->is_AbstractLock()) {
|
||||||
|
int count = coarsened_count();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Node_List* locks_list = _coarsened_locks.at(i);
|
||||||
|
locks_list->yank(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compile::coarsened_locks_consistent() {
|
||||||
|
int count = coarsened_count();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
bool unbalanced = false;
|
||||||
|
bool modified = false; // track locks kind modifications
|
||||||
|
Lock_List* locks_list = (Lock_List*)_coarsened_locks.at(i);
|
||||||
|
uint size = locks_list->size();
|
||||||
|
if (size != locks_list->origin_cnt()) {
|
||||||
|
unbalanced = true; // Some locks were removed from list
|
||||||
|
} else {
|
||||||
|
for (uint j = 0; j < size; j++) {
|
||||||
|
Node* lock = locks_list->at(j);
|
||||||
|
// All nodes in group should have the same state (modified or not)
|
||||||
|
if (!lock->as_AbstractLock()->is_coarsened()) {
|
||||||
|
if (j == 0) {
|
||||||
|
// first on list was modified, the rest should be too for consistency
|
||||||
|
modified = true;
|
||||||
|
} else if (!modified) {
|
||||||
|
// this lock was modified but previous locks on the list were not
|
||||||
|
unbalanced = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (modified) {
|
||||||
|
// previous locks on list were modified but not this lock
|
||||||
|
unbalanced = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unbalanced) {
|
||||||
|
// unbalanced monitor enter/exit - only some [un]lock nodes were removed or modified
|
||||||
|
#ifdef ASSERT
|
||||||
|
if (PrintEliminateLocks) {
|
||||||
|
tty->print_cr("=== unbalanced coarsened locks ===");
|
||||||
|
for (uint l = 0; l < size; l++) {
|
||||||
|
locks_list->at(l)->dump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
record_failure(C2Compiler::retry_no_locks_coarsening());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the speculative part of types and clean up the graph
|
* Remove the speculative part of types and clean up the graph
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "runtime/vmThread.hpp"
|
#include "runtime/vmThread.hpp"
|
||||||
#include "utilities/ticks.hpp"
|
#include "utilities/ticks.hpp"
|
||||||
|
|
||||||
|
class AbstractLockNode;
|
||||||
class AddPNode;
|
class AddPNode;
|
||||||
class Block;
|
class Block;
|
||||||
class Bundle;
|
class Bundle;
|
||||||
|
@ -63,6 +64,7 @@ class MachOper;
|
||||||
class MachSafePointNode;
|
class MachSafePointNode;
|
||||||
class Node;
|
class Node;
|
||||||
class Node_Array;
|
class Node_Array;
|
||||||
|
class Node_List;
|
||||||
class Node_Notes;
|
class Node_Notes;
|
||||||
class NodeCloneInfo;
|
class NodeCloneInfo;
|
||||||
class OptoReg;
|
class OptoReg;
|
||||||
|
@ -248,6 +250,7 @@ class Compile : public Phase {
|
||||||
const bool _do_escape_analysis; // Do escape analysis.
|
const bool _do_escape_analysis; // Do escape analysis.
|
||||||
const bool _install_code; // Install the code that was compiled
|
const bool _install_code; // Install the code that was compiled
|
||||||
const bool _eliminate_boxing; // Do boxing elimination.
|
const bool _eliminate_boxing; // Do boxing elimination.
|
||||||
|
const bool _do_locks_coarsening; // Do locks coarsening
|
||||||
ciMethod* _method; // The method being compiled.
|
ciMethod* _method; // The method being compiled.
|
||||||
int _entry_bci; // entry bci for osr methods.
|
int _entry_bci; // entry bci for osr methods.
|
||||||
const TypeFunc* _tf; // My kind of signature
|
const TypeFunc* _tf; // My kind of signature
|
||||||
|
@ -317,6 +320,7 @@ class Compile : public Phase {
|
||||||
GrowableArray<Node*> _skeleton_predicate_opaqs; // List of Opaque4 nodes for the loop skeleton predicates.
|
GrowableArray<Node*> _skeleton_predicate_opaqs; // List of Opaque4 nodes for the loop skeleton predicates.
|
||||||
GrowableArray<Node*> _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
|
GrowableArray<Node*> _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
|
||||||
GrowableArray<Node*> _for_post_loop_igvn; // List of nodes for IGVN after loop opts are over
|
GrowableArray<Node*> _for_post_loop_igvn; // List of nodes for IGVN after loop opts are over
|
||||||
|
GrowableArray<Node_List*> _coarsened_locks; // List of coarsened Lock and Unlock nodes
|
||||||
ConnectionGraph* _congraph;
|
ConnectionGraph* _congraph;
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
IdealGraphPrinter* _printer;
|
IdealGraphPrinter* _printer;
|
||||||
|
@ -508,6 +512,8 @@ class Compile : public Phase {
|
||||||
/** Do aggressive boxing elimination. */
|
/** Do aggressive boxing elimination. */
|
||||||
bool aggressive_unboxing() const { return _eliminate_boxing && AggressiveUnboxing; }
|
bool aggressive_unboxing() const { return _eliminate_boxing && AggressiveUnboxing; }
|
||||||
bool should_install_code() const { return _install_code; }
|
bool should_install_code() const { return _install_code; }
|
||||||
|
/** Do locks coarsening. */
|
||||||
|
bool do_locks_coarsening() const { return _do_locks_coarsening; }
|
||||||
|
|
||||||
// Other fixed compilation parameters.
|
// Other fixed compilation parameters.
|
||||||
ciMethod* method() const { return _method; }
|
ciMethod* method() const { return _method; }
|
||||||
|
@ -656,6 +662,7 @@ class Compile : public Phase {
|
||||||
int predicate_count() const { return _predicate_opaqs.length(); }
|
int predicate_count() const { return _predicate_opaqs.length(); }
|
||||||
int skeleton_predicate_count() const { return _skeleton_predicate_opaqs.length(); }
|
int skeleton_predicate_count() const { return _skeleton_predicate_opaqs.length(); }
|
||||||
int expensive_count() const { return _expensive_nodes.length(); }
|
int expensive_count() const { return _expensive_nodes.length(); }
|
||||||
|
int coarsened_count() const { return _coarsened_locks.length(); }
|
||||||
|
|
||||||
Node* macro_node(int idx) const { return _macro_nodes.at(idx); }
|
Node* macro_node(int idx) const { return _macro_nodes.at(idx); }
|
||||||
Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs.at(idx); }
|
Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs.at(idx); }
|
||||||
|
@ -677,6 +684,10 @@ class Compile : public Phase {
|
||||||
if (predicate_count() > 0) {
|
if (predicate_count() > 0) {
|
||||||
_predicate_opaqs.remove_if_existing(n);
|
_predicate_opaqs.remove_if_existing(n);
|
||||||
}
|
}
|
||||||
|
// Remove from coarsened locks list if present
|
||||||
|
if (coarsened_count() > 0) {
|
||||||
|
remove_coarsened_lock(n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void add_expensive_node(Node* n);
|
void add_expensive_node(Node* n);
|
||||||
void remove_expensive_node(Node* n) {
|
void remove_expensive_node(Node* n) {
|
||||||
|
@ -696,6 +707,10 @@ class Compile : public Phase {
|
||||||
_skeleton_predicate_opaqs.remove_if_existing(n);
|
_skeleton_predicate_opaqs.remove_if_existing(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void add_coarsened_locks(GrowableArray<AbstractLockNode*>& locks);
|
||||||
|
void remove_coarsened_lock(Node* n);
|
||||||
|
bool coarsened_locks_consistent();
|
||||||
|
|
||||||
bool post_loop_opts_phase() { return _post_loop_opts_phase; }
|
bool post_loop_opts_phase() { return _post_loop_opts_phase; }
|
||||||
void set_post_loop_opts_phase() { _post_loop_opts_phase = true; }
|
void set_post_loop_opts_phase() { _post_loop_opts_phase = true; }
|
||||||
void reset_post_loop_opts_phase() { _post_loop_opts_phase = false; }
|
void reset_post_loop_opts_phase() { _post_loop_opts_phase = false; }
|
||||||
|
@ -952,6 +967,8 @@ class Compile : public Phase {
|
||||||
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
|
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
|
||||||
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Node* dead);
|
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Node* dead);
|
||||||
|
|
||||||
|
void remove_useless_coarsened_locks(Unique_Node_List& useful);
|
||||||
|
|
||||||
void process_print_inlining();
|
void process_print_inlining();
|
||||||
void dump_print_inlining();
|
void dump_print_inlining();
|
||||||
|
|
||||||
|
@ -1018,7 +1035,8 @@ class Compile : public Phase {
|
||||||
// continuation.
|
// continuation.
|
||||||
Compile(ciEnv* ci_env, ciMethod* target,
|
Compile(ciEnv* ci_env, ciMethod* target,
|
||||||
int entry_bci, bool subsume_loads, bool do_escape_analysis,
|
int entry_bci, bool subsume_loads, bool do_escape_analysis,
|
||||||
bool eliminate_boxing, bool install_code, DirectiveSet* directive);
|
bool eliminate_boxing, bool do_locks_coarsening,
|
||||||
|
bool install_code, DirectiveSet* directive);
|
||||||
|
|
||||||
// Second major entry point. From the TypeFunc signature, generate code
|
// Second major entry point. From the TypeFunc signature, generate code
|
||||||
// to pass arguments from the Java calling convention to the C calling
|
// to pass arguments from the Java calling convention to the C calling
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -85,7 +85,7 @@ OptoReg::Name BoxLockNode::reg(Node* box) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is BoxLock node used for one simple lock region (same box and obj)?
|
// Is BoxLock node used for one simple lock region (same box and obj)?
|
||||||
bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj) {
|
bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj, Node** bad_lock) {
|
||||||
LockNode* lock = NULL;
|
LockNode* lock = NULL;
|
||||||
bool has_one_lock = false;
|
bool has_one_lock = false;
|
||||||
for (uint i = 0; i < this->outcnt(); i++) {
|
for (uint i = 0; i < this->outcnt(); i++) {
|
||||||
|
@ -102,9 +102,15 @@ bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj) {
|
||||||
has_one_lock = true;
|
has_one_lock = true;
|
||||||
} else if (lock != alock->as_Lock()) {
|
} else if (lock != alock->as_Lock()) {
|
||||||
has_one_lock = false;
|
has_one_lock = false;
|
||||||
|
if (bad_lock != NULL) {
|
||||||
|
*bad_lock = alock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (bad_lock != NULL) {
|
||||||
|
*bad_lock = alock;
|
||||||
|
}
|
||||||
return false; // Different objects
|
return false; // Different objects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
void set_eliminated() { _is_eliminated = true; }
|
void set_eliminated() { _is_eliminated = true; }
|
||||||
|
|
||||||
// Is BoxLock node used for one simple lock region?
|
// Is BoxLock node used for one simple lock region?
|
||||||
bool is_simple_lock_region(LockNode** unique_lock, Node* obj);
|
bool is_simple_lock_region(LockNode** unique_lock, Node* obj, Node** bad_lock);
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
virtual void format( PhaseRegAlloc *, outputStream *st ) const;
|
virtual void format( PhaseRegAlloc *, outputStream *st ) const;
|
||||||
|
|
|
@ -1909,15 +1909,15 @@ void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) {
|
||||||
// Mark all associated (same box and obj) lock and unlock nodes for
|
// Mark all associated (same box and obj) lock and unlock nodes for
|
||||||
// elimination if some of them marked already.
|
// elimination if some of them marked already.
|
||||||
void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) {
|
void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) {
|
||||||
if (oldbox->as_BoxLock()->is_eliminated())
|
if (oldbox->as_BoxLock()->is_eliminated()) {
|
||||||
return; // This BoxLock node was processed already.
|
return; // This BoxLock node was processed already.
|
||||||
|
}
|
||||||
// New implementation (EliminateNestedLocks) has separate BoxLock
|
// New implementation (EliminateNestedLocks) has separate BoxLock
|
||||||
// node for each locked region so mark all associated locks/unlocks as
|
// node for each locked region so mark all associated locks/unlocks as
|
||||||
// eliminated even if different objects are referenced in one locked region
|
// eliminated even if different objects are referenced in one locked region
|
||||||
// (for example, OSR compilation of nested loop inside locked scope).
|
// (for example, OSR compilation of nested loop inside locked scope).
|
||||||
if (EliminateNestedLocks ||
|
if (EliminateNestedLocks ||
|
||||||
oldbox->as_BoxLock()->is_simple_lock_region(NULL, obj)) {
|
oldbox->as_BoxLock()->is_simple_lock_region(NULL, obj, NULL)) {
|
||||||
// Box is used only in one lock region. Mark this box as eliminated.
|
// Box is used only in one lock region. Mark this box as eliminated.
|
||||||
_igvn.hash_delete(oldbox);
|
_igvn.hash_delete(oldbox);
|
||||||
oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value
|
oldbox->as_BoxLock()->set_eliminated(); // This changes box's hash value
|
||||||
|
@ -2089,11 +2089,7 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (PrintEliminateLocks) {
|
if (PrintEliminateLocks) {
|
||||||
if (alock->is_Lock()) {
|
tty->print_cr("++++ Eliminated: %d %s '%s'", alock->_idx, (alock->is_Lock() ? "Lock" : "Unlock"), alock->kind_as_string());
|
||||||
tty->print_cr("++++ Eliminated: %d Lock", alock->_idx);
|
|
||||||
} else {
|
|
||||||
tty->print_cr("++++ Eliminated: %d Unlock", alock->_idx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2502,16 +2498,21 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||||
if (C->macro_count() == 0)
|
if (C->macro_count() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// First, attempt to eliminate locks
|
// Before elimination may re-mark (change to Nested or NonEscObj)
|
||||||
|
// all associated (same box and obj) lock and unlock nodes.
|
||||||
int cnt = C->macro_count();
|
int cnt = C->macro_count();
|
||||||
for (int i=0; i < cnt; i++) {
|
for (int i=0; i < cnt; i++) {
|
||||||
Node *n = C->macro_node(i);
|
Node *n = C->macro_node(i);
|
||||||
if (n->is_AbstractLock()) { // Lock and Unlock nodes
|
if (n->is_AbstractLock()) { // Lock and Unlock nodes
|
||||||
// Before elimination mark all associated (same box and obj)
|
|
||||||
// lock and unlock nodes.
|
|
||||||
mark_eliminated_locking_nodes(n->as_AbstractLock());
|
mark_eliminated_locking_nodes(n->as_AbstractLock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Re-marking may break consistency of Coarsened locks.
|
||||||
|
if (!C->coarsened_locks_consistent()) {
|
||||||
|
return; // recompile without Coarsened locks if broken
|
||||||
|
}
|
||||||
|
|
||||||
|
// First, attempt to eliminate locks
|
||||||
bool progress = true;
|
bool progress = true;
|
||||||
while (progress) {
|
while (progress) {
|
||||||
progress = false;
|
progress = false;
|
||||||
|
@ -2574,6 +2575,7 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||||
bool PhaseMacroExpand::expand_macro_nodes() {
|
bool PhaseMacroExpand::expand_macro_nodes() {
|
||||||
// Last attempt to eliminate macro nodes.
|
// Last attempt to eliminate macro nodes.
|
||||||
eliminate_macro_nodes();
|
eliminate_macro_nodes();
|
||||||
|
if (C->failing()) return true;
|
||||||
|
|
||||||
// Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.
|
// Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.
|
||||||
bool progress = true;
|
bool progress = true;
|
||||||
|
|
|
@ -41,7 +41,7 @@ import static com.sun.crypto.provider.KWUtil.*;
|
||||||
class AESKeyWrap extends FeedbackCipher {
|
class AESKeyWrap extends FeedbackCipher {
|
||||||
|
|
||||||
// default integrity check value (icv) if iv is not supplied
|
// default integrity check value (icv) if iv is not supplied
|
||||||
private static final byte[] ICV1 = { // SEMI_BLKSIZE long
|
static final byte[] ICV1 = { // SEMI_BLKSIZE long
|
||||||
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6,
|
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6,
|
||||||
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6
|
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,7 +42,7 @@ import static com.sun.crypto.provider.KWUtil.*;
|
||||||
class AESKeyWrapPadded extends FeedbackCipher {
|
class AESKeyWrapPadded extends FeedbackCipher {
|
||||||
|
|
||||||
// default integrity check value (icv) if iv is not supplied
|
// default integrity check value (icv) if iv is not supplied
|
||||||
private static final byte[] ICV2 = { // SEMI_BLKSIZE/2 long
|
static final byte[] ICV2 = { // SEMI_BLKSIZE/2 long
|
||||||
(byte) 0xA6, (byte) 0x59, (byte) 0x59, (byte) 0xA6,
|
(byte) 0xA6, (byte) 0x59, (byte) 0x59, (byte) 0xA6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,7 @@ abstract class KeyWrapCipher extends CipherSpi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal cipher object which does the real work.
|
// internal cipher object which does the real work.
|
||||||
|
// AESKeyWrap for KW, AESKeyWrapPadded for KWP
|
||||||
private final FeedbackCipher cipher;
|
private final FeedbackCipher cipher;
|
||||||
|
|
||||||
// internal padding object; null if NoPadding
|
// internal padding object; null if NoPadding
|
||||||
|
@ -279,13 +280,15 @@ abstract class KeyWrapCipher extends CipherSpi {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the initialization vector (IV).
|
* Returns the initialization vector (IV) in a new buffer.
|
||||||
*
|
*
|
||||||
* @return the user-specified iv or null if default iv is used.
|
* @return the user-specified iv, or null if the underlying algorithm does
|
||||||
|
* not use an IV, or if the IV has not yet been set.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected byte[] engineGetIV() {
|
protected byte[] engineGetIV() {
|
||||||
return cipher.getIV().clone();
|
byte[] iv = cipher.getIV();
|
||||||
|
return (iv == null? null : iv.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
// actual impl for various engineInit(...) methods
|
// actual impl for various engineInit(...) methods
|
||||||
|
@ -623,13 +626,18 @@ abstract class KeyWrapCipher extends CipherSpi {
|
||||||
/**
|
/**
|
||||||
* Returns the parameters used with this cipher.
|
* Returns the parameters used with this cipher.
|
||||||
*
|
*
|
||||||
* @return AlgorithmParameters object containing IV.
|
* @return AlgorithmParameters object containing IV, or null if this cipher
|
||||||
|
* does not use any parameters.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected AlgorithmParameters engineGetParameters() {
|
protected AlgorithmParameters engineGetParameters() {
|
||||||
AlgorithmParameters params = null;
|
AlgorithmParameters params = null;
|
||||||
|
|
||||||
byte[] iv = cipher.getIV();
|
byte[] iv = cipher.getIV();
|
||||||
|
if (iv == null) {
|
||||||
|
iv = (cipher instanceof AESKeyWrap?
|
||||||
|
AESKeyWrap.ICV1 : AESKeyWrapPadded.ICV2);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
params = AlgorithmParameters.getInstance("AES");
|
params = AlgorithmParameters.getInstance("AES");
|
||||||
params.init(new IvParameterSpec(iv));
|
params.init(new IvParameterSpec(iv));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -54,7 +54,8 @@ public interface AutoCloseable {
|
||||||
* This method is invoked automatically on objects managed by the
|
* This method is invoked automatically on objects managed by the
|
||||||
* {@code try}-with-resources statement.
|
* {@code try}-with-resources statement.
|
||||||
*
|
*
|
||||||
* <p>While this interface method is declared to throw {@code
|
* @apiNote
|
||||||
|
* While this interface method is declared to throw {@code
|
||||||
* Exception}, implementers are <em>strongly</em> encouraged to
|
* Exception}, implementers are <em>strongly</em> encouraged to
|
||||||
* declare concrete implementations of the {@code close} method to
|
* declare concrete implementations of the {@code close} method to
|
||||||
* throw more specific exceptions, or to throw no exception at all
|
* throw more specific exceptions, or to throw no exception at all
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
package sun.security.jca;
|
package sun.security.jca;
|
||||||
|
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
|
import sun.security.x509.AlgorithmId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of methods to get and set provider list. Also includes
|
* Collection of methods to get and set provider list. Also includes
|
||||||
|
@ -150,7 +151,17 @@ public class Providers {
|
||||||
} else {
|
} else {
|
||||||
changeThreadProviderList(newList);
|
changeThreadProviderList(newList);
|
||||||
}
|
}
|
||||||
|
clearCachedValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the cached provider-list-specific values. These values need to
|
||||||
|
* be re-generated whenever provider list is changed. The logic for
|
||||||
|
* generating them is in the respective classes.
|
||||||
|
*/
|
||||||
|
private static void clearCachedValues() {
|
||||||
JCAUtil.clearDefSecureRandom();
|
JCAUtil.clearDefSecureRandom();
|
||||||
|
AlgorithmId.clearAliasOidsTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -536,6 +536,11 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
// oid string cache index'ed by algorithm name and oid strings
|
// oid string cache index'ed by algorithm name and oid strings
|
||||||
private static volatile Map<String,String> aliasOidsTable;
|
private static volatile Map<String,String> aliasOidsTable;
|
||||||
|
|
||||||
|
// called by sun.security.jca.Providers whenever provider list is changed
|
||||||
|
public static void clearAliasOidsTable() {
|
||||||
|
aliasOidsTable = null;
|
||||||
|
}
|
||||||
|
|
||||||
// returns the aliasOidsTable, lazily initializing it on first access.
|
// returns the aliasOidsTable, lazily initializing it on first access.
|
||||||
private static Map<String,String> aliasOidsTable() {
|
private static Map<String,String> aliasOidsTable() {
|
||||||
// Double checked locking; safe because aliasOidsTable is volatile
|
// Double checked locking; safe because aliasOidsTable is volatile
|
||||||
|
|
|
@ -1310,7 +1310,7 @@ By default this option is disabled.
|
||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B \f[CB]\-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] (or)\f[CB]\-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R]
|
.B \f[CB]\-XX:FlightRecorderOptions=\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R] (or)\f[CB]\-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R]
|
||||||
Sets the parameters that control the behavior of JFR.
|
Sets the parameters that control the behavior of JFR.
|
||||||
.RS
|
.RS
|
||||||
.PP
|
.PP
|
||||||
|
@ -1636,7 +1636,7 @@ By default, this option is disabled.
|
||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B \f[CB]\-XX:StartFlightRecording:\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R]
|
.B \f[CB]\-XX:StartFlightRecording=\f[R]\f[I]parameter\f[R]\f[CB]=\f[R]\f[I]value\f[R]
|
||||||
Starts a JFR recording for the Java application.
|
Starts a JFR recording for the Java application.
|
||||||
This option is equivalent to the \f[CB]JFR.start\f[R] diagnostic command
|
This option is equivalent to the \f[CB]JFR.start\f[R] diagnostic command
|
||||||
that starts a recording during runtime.
|
that starts a recording during runtime.
|
||||||
|
@ -1757,22 +1757,6 @@ is needed.
|
||||||
.PP
|
.PP
|
||||||
You can specify values for multiple parameters by separating them with a
|
You can specify values for multiple parameters by separating them with a
|
||||||
comma.
|
comma.
|
||||||
.PP
|
|
||||||
Event settings and .jfc options can also be specified using the following
|
|
||||||
syntax:
|
|
||||||
.TP
|
|
||||||
.B \f[CB]option=\f[R]\f[I]value\f[R]
|
|
||||||
Specifies the option value to modify. To list available options, use the
|
|
||||||
JAVA_HOME/bin/jfr tool.
|
|
||||||
.TP
|
|
||||||
.B \f[CB]event-setting=\f[R]\f[I]value\f[R]
|
|
||||||
Specifies the event setting value to modify. Use the form:
|
|
||||||
<event-name>#<setting-name>=<value>
|
|
||||||
To add a new event setting, prefix the event name with '+'.
|
|
||||||
.PP
|
|
||||||
In case of a conflict between a parameter and a .jfc option, the parameter
|
|
||||||
will take precedence. The whitespace delimiter can be omitted for timespan values, i.e. 20ms. For
|
|
||||||
more information about the settings syntax, see Javadoc of the jdk.jfr package.
|
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B \f[CB]\-XX:ThreadStackSize=\f[R]\f[I]size\f[R]
|
.B \f[CB]\-XX:ThreadStackSize=\f[R]\f[I]size\f[R]
|
||||||
|
@ -3888,68 +3872,6 @@ future JDK release.
|
||||||
They\[aq]re still accepted and acted upon, but a warning is issued when
|
They\[aq]re still accepted and acted upon, but a warning is issued when
|
||||||
they\[aq]re used.
|
they\[aq]re used.
|
||||||
.TP
|
.TP
|
||||||
.B \f[CB]\-\-illegal\-access=\f[R]\f[I]parameter\f[R]
|
|
||||||
When present at run time, \f[CB]\-\-illegal\-access=\f[R] takes a keyword
|
|
||||||
\f[I]parameter\f[R] to specify a mode of operation:
|
|
||||||
.RS
|
|
||||||
.RS
|
|
||||||
.PP
|
|
||||||
\f[B]Note:\f[R] This option will be removed in a future release.
|
|
||||||
.RE
|
|
||||||
.IP \[bu] 2
|
|
||||||
\f[CB]permit\f[R]: This mode opens each package in each module in the
|
|
||||||
run\-time image to code in all unnamed modules ( such as code on the
|
|
||||||
class path), if that package existed in JDK 8.
|
|
||||||
This enables both static access, (for example, by compiled bytecode, and
|
|
||||||
deep reflective access) through the platform\[aq]s various reflection
|
|
||||||
APIs.
|
|
||||||
The first reflective\-access operation to any such package causes a
|
|
||||||
warning to be issued.
|
|
||||||
However, no warnings are issued after the first occurrence.
|
|
||||||
This single warning describes how to enable further warnings.
|
|
||||||
.IP \[bu] 2
|
|
||||||
\f[CB]warn\f[R]: This mode is identical to \f[CB]permit\f[R] except that a
|
|
||||||
warning message is issued for each illegal reflective\-access operation.
|
|
||||||
.IP \[bu] 2
|
|
||||||
\f[CB]debug\f[R]: This mode is identical to \f[CB]warn\f[R] except that both
|
|
||||||
a warning message and a stack trace are issued for each illegal
|
|
||||||
reflective\-access operation.
|
|
||||||
.IP \[bu] 2
|
|
||||||
\f[CB]deny\f[R]: This mode disables all illegal\-access operations except
|
|
||||||
for those enabled by other command\-line options, such as
|
|
||||||
\f[CB]\-\-add\-opens\f[R].
|
|
||||||
This mode is the default.
|
|
||||||
.PP
|
|
||||||
If your application does not work with the default mode of
|
|
||||||
\f[CB]\-\-illegal\-access=deny\f[R] then you can learn more about what is
|
|
||||||
going on with the \f[CB]warn\f[R] and \f[CB]debug\f[R] modes.
|
|
||||||
For each library or framework on the class path that requires illegal
|
|
||||||
access, you have two options:
|
|
||||||
.IP \[bu] 2
|
|
||||||
If the component\[aq]s maintainers have already released a fixed version
|
|
||||||
that no longer uses JDK\-internal APIs then you can consider upgrading
|
|
||||||
to that version.
|
|
||||||
.IP \[bu] 2
|
|
||||||
If the component still needs to be fixed, then you can contact its
|
|
||||||
maintainers and ask them to replace their use of JDK\-internal APIs with
|
|
||||||
the proper exported APIs.
|
|
||||||
.PP
|
|
||||||
If you must continue to use a component that requires illegal access,
|
|
||||||
then you can eliminate the warning messages by using one or more
|
|
||||||
\f[CB]\-\-add\-opens\f[R] options to open only those internal packages to
|
|
||||||
which access is required.
|
|
||||||
.PP
|
|
||||||
To verify that your application is ready for a future version of the
|
|
||||||
JDK, run it with \f[CB]\-\-illegal\-access=deny\f[R] along with any
|
|
||||||
necessary \f[CB]\-\-add\-opens\f[R] options.
|
|
||||||
Any remaining illegal\-access errors will most likely be due to static
|
|
||||||
references from compiled code to JDK\-internal APIs.
|
|
||||||
You can identify those by running the \f[B]jdeps\f[R] tool with the
|
|
||||||
\f[CB]\-\-jdk\-internals\f[R] option.
|
|
||||||
For performance reasons, the current JDK does not issue warnings for
|
|
||||||
illegal static\-access operations.
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B \f[CB]\-Xfuture\f[R]
|
.B \f[CB]\-Xfuture\f[R]
|
||||||
Enables strict class\-file format checks that enforce close conformance
|
Enables strict class\-file format checks that enforce close conformance
|
||||||
to the class\-file format specification.
|
to the class\-file format specification.
|
||||||
|
@ -4032,8 +3954,16 @@ By default, this option is disabled.
|
||||||
.PP
|
.PP
|
||||||
These \f[CB]java\f[R] options are still accepted but ignored, and a
|
These \f[CB]java\f[R] options are still accepted but ignored, and a
|
||||||
warning is issued when they\[aq]re used.
|
warning is issued when they\[aq]re used.
|
||||||
.PP
|
.TP
|
||||||
None in JDK 17.
|
.B \f[CB]\-\-illegal\-access=\f[R]\f[I]parameter\f[R]
|
||||||
|
Controlled \f[I]relaxed strong encapsulation\f[R], as defined in \f[B]JEP
|
||||||
|
261\f[R]
|
||||||
|
[https://openjdk.java.net/jeps/261#Relaxed\-strong\-encapsulation].
|
||||||
|
This option was deprecated in JDK 16 by \f[B]JEP 396\f[R]
|
||||||
|
[https://openjdk.java.net/jeps/396] and made obsolete in JDK 17 by
|
||||||
|
\f[B]JEP 403\f[R] [https://openjdk.java.net/jeps/403].
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
.SH REMOVED JAVA OPTIONS
|
.SH REMOVED JAVA OPTIONS
|
||||||
.PP
|
.PP
|
||||||
These \f[CB]java\f[R] options have been removed in JDK 17 and using them
|
These \f[CB]java\f[R] options have been removed in JDK 17 and using them
|
||||||
|
@ -4374,6 +4304,8 @@ the Java Virtual Machine (JVM) unified logging framework.
|
||||||
.RS
|
.RS
|
||||||
.PP
|
.PP
|
||||||
\f[CB]\-Xlog\f[R][\f[CB]:\f[R][\f[I]what\f[R]][\f[CB]:\f[R][\f[I]output\f[R]][\f[CB]:\f[R][\f[I]decorators\f[R]][\f[CB]:\f[R]\f[I]output\-options\f[R][\f[CB],\f[R]...]]]]]
|
\f[CB]\-Xlog\f[R][\f[CB]:\f[R][\f[I]what\f[R]][\f[CB]:\f[R][\f[I]output\f[R]][\f[CB]:\f[R][\f[I]decorators\f[R]][\f[CB]:\f[R]\f[I]output\-options\f[R][\f[CB],\f[R]...]]]]]
|
||||||
|
.PP
|
||||||
|
\f[CB]\-Xlog:\f[R]\f[I]directive\f[R]
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B \f[I]what\f[R]
|
.B \f[I]what\f[R]
|
||||||
|
@ -4404,6 +4336,11 @@ See \f[B]Decorations\f[R].
|
||||||
Sets the \f[CB]\-Xlog\f[R] logging output options.
|
Sets the \f[CB]\-Xlog\f[R] logging output options.
|
||||||
.RS
|
.RS
|
||||||
.RE
|
.RE
|
||||||
|
.TP
|
||||||
|
.B \f[I]directive\f[R]
|
||||||
|
A global option or subcommand: help, disable, async
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
.SS Description
|
.SS Description
|
||||||
.PP
|
.PP
|
||||||
The Java Virtual Machine (JVM) unified logging framework provides a
|
The Java Virtual Machine (JVM) unified logging framework provides a
|
||||||
|
@ -4554,6 +4491,29 @@ Specifying \f[CB]filecount=0\f[R] means that the log file shouldn\[aq]t be
|
||||||
rotated.
|
rotated.
|
||||||
There\[aq]s a possibility of the pre\-existing log file getting
|
There\[aq]s a possibility of the pre\-existing log file getting
|
||||||
overwritten.
|
overwritten.
|
||||||
|
.SS \-Xlog Output Mode
|
||||||
|
.PP
|
||||||
|
By default logging messages are output synchronously \- each log message
|
||||||
|
is written to the designated output when the logging call is made.
|
||||||
|
But you can instead use asynchronous logging mode by specifying:
|
||||||
|
.TP
|
||||||
|
.B \f[CB]\-Xlog:async\f[R]
|
||||||
|
Write all logging asynchronously.
|
||||||
|
.RS
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
In asynchronous logging mode, log sites enqueue all logging messages to
|
||||||
|
an intermediate buffer and a standalone thread is responsible for
|
||||||
|
flushing them to the corresponding outputs.
|
||||||
|
The intermediate buffer is bounded and on buffer exhaustion the
|
||||||
|
enqueuing message is discarded.
|
||||||
|
Log entry write operations are guaranteed non\-blocking.
|
||||||
|
.PP
|
||||||
|
The option \f[CB]\-XX:AsyncLogBufferSize=N\f[R] specifies the memory
|
||||||
|
budget in bytes for the intermediate buffer.
|
||||||
|
The default value should be big enough to cater for most cases.
|
||||||
|
Users can provide a custom value to trade memory overhead for log
|
||||||
|
accuracy if they need to.
|
||||||
.SS Decorations
|
.SS Decorations
|
||||||
.PP
|
.PP
|
||||||
Logging messages are decorated with information about the message.
|
Logging messages are decorated with information about the message.
|
||||||
|
|
|
@ -468,7 +468,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons
|
||||||
if (tsym == null || tsym.name == null) {
|
if (tsym == null || tsym.name == null) {
|
||||||
sb.append("<none>");
|
sb.append("<none>");
|
||||||
} else {
|
} else {
|
||||||
sb.append(tsym.name);
|
sb.append(tsym.name.toString());
|
||||||
}
|
}
|
||||||
if (moreInfo && hasTag(TYPEVAR)) {
|
if (moreInfo && hasTag(TYPEVAR)) {
|
||||||
sb.append(hashCode());
|
sb.append(hashCode());
|
||||||
|
|
|
@ -2392,6 +2392,10 @@ public class Flow {
|
||||||
JCCase c = l.head;
|
JCCase c = l.head;
|
||||||
for (JCCaseLabel pat : c.labels) {
|
for (JCCaseLabel pat : c.labels) {
|
||||||
scan(pat);
|
scan(pat);
|
||||||
|
if (inits.isReset()) {
|
||||||
|
inits.assign(initsWhenTrue);
|
||||||
|
uninits.assign(uninitsWhenTrue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (l.head.stats.isEmpty() &&
|
if (l.head.stats.isEmpty() &&
|
||||||
l.tail.nonEmpty() &&
|
l.tail.nonEmpty() &&
|
||||||
|
|
|
@ -431,6 +431,7 @@ public class TransPatterns extends TreeTranslator {
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
boolean previousCompletesNormally = false;
|
boolean previousCompletesNormally = false;
|
||||||
|
boolean hasDefault = false;
|
||||||
|
|
||||||
for (var c : cases) {
|
for (var c : cases) {
|
||||||
List<JCCaseLabel> clearedPatterns = c.labels;
|
List<JCCaseLabel> clearedPatterns = c.labels;
|
||||||
|
@ -477,7 +478,9 @@ public class TransPatterns extends TreeTranslator {
|
||||||
for (var p : c.labels) {
|
for (var p : c.labels) {
|
||||||
if (p.hasTag(Tag.DEFAULTCASELABEL)) {
|
if (p.hasTag(Tag.DEFAULTCASELABEL)) {
|
||||||
translatedLabels.add(p);
|
translatedLabels.add(p);
|
||||||
} else if (hasTotalPattern && c == lastCase && p.isPattern()) {
|
hasDefault = true;
|
||||||
|
} else if (hasTotalPattern && !hasDefault &&
|
||||||
|
c == lastCase && p.isPattern()) {
|
||||||
//If the switch has total pattern, the last case will contain it.
|
//If the switch has total pattern, the last case will contain it.
|
||||||
//Convert the total pattern to default:
|
//Convert the total pattern to default:
|
||||||
translatedLabels.add(make.DefaultCaseLabel());
|
translatedLabels.add(make.DefaultCaseLabel());
|
||||||
|
|
|
@ -2668,6 +2668,9 @@ public class JavacParser implements Parser {
|
||||||
case PLUSPLUS: case SUBSUB:
|
case PLUSPLUS: case SUBSUB:
|
||||||
isYieldStatement = S.token(2).kind != SEMI;
|
isYieldStatement = S.token(2).kind != SEMI;
|
||||||
break;
|
break;
|
||||||
|
case BANG: case TILDE:
|
||||||
|
isYieldStatement = S.token(1).kind != SEMI;
|
||||||
|
break;
|
||||||
case LPAREN:
|
case LPAREN:
|
||||||
int lookahead = 2;
|
int lookahead = 2;
|
||||||
int balance = 1;
|
int balance = 1;
|
||||||
|
|
|
@ -1432,7 +1432,7 @@ public class HtmlDocletWriter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitAttribute(AttributeTree node, Content c) {
|
public Boolean visitAttribute(AttributeTree node, Content c) {
|
||||||
StringBuilder sb = new StringBuilder(SPACER).append(node.getName());
|
StringBuilder sb = new StringBuilder(SPACER).append(node.getName().toString());
|
||||||
if (node.getValueKind() == ValueKind.EMPTY) {
|
if (node.getValueKind() == ValueKind.EMPTY) {
|
||||||
result.add(sb);
|
result.add(sb);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2050,18 +2050,18 @@ public class HtmlDocletWriter {
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (Element e: chain) {
|
for (Element e: chain) {
|
||||||
CharSequence name;
|
String name;
|
||||||
switch (e.getKind()) {
|
switch (e.getKind()) {
|
||||||
case MODULE:
|
case MODULE:
|
||||||
case PACKAGE:
|
case PACKAGE:
|
||||||
name = ((QualifiedNameable) e).getQualifiedName();
|
name = ((QualifiedNameable) e).getQualifiedName().toString();
|
||||||
if (name.length() == 0) {
|
if (name.length() == 0) {
|
||||||
name = "<unnamed>";
|
name = "<unnamed>";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
name = e.getSimpleName();
|
name = e.getSimpleName().toString();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ public class HtmlIds {
|
||||||
* @return the 1.4.x style anchor for the executable element
|
* @return the 1.4.x style anchor for the executable element
|
||||||
*/
|
*/
|
||||||
protected HtmlId forErasure(ExecutableElement executableElement) {
|
protected HtmlId forErasure(ExecutableElement executableElement) {
|
||||||
final StringBuilder buf = new StringBuilder(executableElement.getSimpleName());
|
final StringBuilder buf = new StringBuilder(executableElement.getSimpleName().toString());
|
||||||
buf.append("(");
|
buf.append("(");
|
||||||
List<? extends VariableElement> parameters = executableElement.getParameters();
|
List<? extends VariableElement> parameters = executableElement.getParameters();
|
||||||
boolean foundTypeVariable = false;
|
boolean foundTypeVariable = false;
|
||||||
|
@ -237,7 +237,7 @@ public class HtmlIds {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitTypeVariable(TypeVariable t, Void p) {
|
public Boolean visitTypeVariable(TypeVariable t, Void p) {
|
||||||
buf.append(utils.asTypeElement(t).getQualifiedName());
|
buf.append(utils.asTypeElement(t).getQualifiedName().toString());
|
||||||
foundTypeVariable = true;
|
foundTypeVariable = true;
|
||||||
return foundTypeVariable;
|
return foundTypeVariable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -70,17 +70,19 @@ public class Entity extends Content {
|
||||||
* @return the string with all of the HTML characters escaped
|
* @return the string with all of the HTML characters escaped
|
||||||
*/
|
*/
|
||||||
static String escapeHtmlChars(CharSequence s) {
|
static String escapeHtmlChars(CharSequence s) {
|
||||||
for (int i = 0; i < s.length(); i++) {
|
// Convert to string as CharSequence implementations can be slow - see JDK-8263321
|
||||||
char ch = s.charAt(i);
|
String str = s.toString();
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
char ch = str.charAt(i);
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
// only start building a new string if we need to
|
// only start building a new string if we need to
|
||||||
case '<': case '>': case '&':
|
case '<': case '>': case '&':
|
||||||
StringBuilder sb = new StringBuilder(s.subSequence(0, i));
|
StringBuilder sb = new StringBuilder(str.substring(0, i));
|
||||||
escapeHtmlChars(s, i, sb);
|
escapeHtmlChars(str, i, sb);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s.toString();
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,10 +93,10 @@ public class Entity extends Content {
|
||||||
* @param sb the string builder
|
* @param sb the string builder
|
||||||
*/
|
*/
|
||||||
static void escapeHtmlChars(CharSequence s, StringBuilder sb) {
|
static void escapeHtmlChars(CharSequence s, StringBuilder sb) {
|
||||||
escapeHtmlChars(s, 0, sb);
|
escapeHtmlChars(s.toString(), 0, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void escapeHtmlChars(CharSequence s, int start, StringBuilder sb) {
|
private static void escapeHtmlChars(String s, int start, StringBuilder sb) {
|
||||||
for (int i = start ; i < s.length(); i++) {
|
for (int i = start ; i < s.length(); i++) {
|
||||||
char ch = s.charAt(i);
|
char ch = s.charAt(i);
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class Text extends Content {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to construct FixedStringContent object.
|
* Constructs an immutable text object.
|
||||||
*
|
*
|
||||||
* @param content content for the object
|
* @param content content for the object
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -225,7 +225,7 @@ public class CommentHelper {
|
||||||
new SimpleDocTreeVisitor<Void, Void>() {
|
new SimpleDocTreeVisitor<Void, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void visitAttribute(AttributeTree node, Void p) {
|
public Void visitAttribute(AttributeTree node, Void p) {
|
||||||
sb.append(SPACER).append(node.getName());
|
sb.append(SPACER).append(node.getName().toString());
|
||||||
if (node.getValueKind() == ValueKind.EMPTY) {
|
if (node.getValueKind() == ValueKind.EMPTY) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ public class CommentHelper {
|
||||||
@Override
|
@Override
|
||||||
public Void visitEndElement(EndElementTree node, Void p) {
|
public Void visitEndElement(EndElementTree node, Void p) {
|
||||||
sb.append("</")
|
sb.append("</")
|
||||||
.append(node.getName())
|
.append(node.getName().toString())
|
||||||
.append(">");
|
.append(">");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ public class CommentHelper {
|
||||||
@Override
|
@Override
|
||||||
public Void visitStartElement(StartElementTree node, Void p) {
|
public Void visitStartElement(StartElementTree node, Void p) {
|
||||||
sb.append("<");
|
sb.append("<");
|
||||||
sb.append(node.getName());
|
sb.append(node.getName().toString());
|
||||||
node.getAttributes().forEach(dt -> dt.accept(this, null));
|
node.getAttributes().forEach(dt -> dt.accept(this, null));
|
||||||
sb.append(node.isSelfClosing() ? "/>" : ">");
|
sb.append(node.isSelfClosing() ? "/>" : ">");
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -2158,7 +2158,7 @@ public class Utils {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String visitType(TypeElement e, Void p) {
|
public String visitType(TypeElement e, Void p) {
|
||||||
StringBuilder sb = new StringBuilder(e.getSimpleName());
|
StringBuilder sb = new StringBuilder(e.getSimpleName().toString());
|
||||||
Element enclosed = e.getEnclosingElement();
|
Element enclosed = e.getEnclosingElement();
|
||||||
while (enclosed != null
|
while (enclosed != null
|
||||||
&& (enclosed.getKind().isClass() || enclosed.getKind().isInterface())) {
|
&& (enclosed.getKind().isClass() || enclosed.getKind().isInterface())) {
|
||||||
|
|
|
@ -27,9 +27,16 @@
|
||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
|
vmTestbase/jit/escape/AdaptiveBlocking/AdaptiveBlocking001/AdaptiveBlocking001.java 8260303 windows-x64
|
||||||
|
|
||||||
resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8220624 generic-all
|
resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8220624 generic-all
|
||||||
serviceability/sa/CDSJMapClstats.java 8220624 generic-all
|
serviceability/sa/CDSJMapClstats.java 8220624 generic-all
|
||||||
serviceability/sa/ClhsdbJhisto.java 8220624 generic-all
|
serviceability/sa/ClhsdbJhisto.java 8220624 generic-all
|
||||||
serviceability/sa/TestHeapDumpForLargeArray.java 8220624 generic-all
|
|
||||||
vmTestbase/jit/escape/AdaptiveBlocking/AdaptiveBlocking001/AdaptiveBlocking001.java 8260303 windows-x64
|
serviceability/sa/ClhsdbCDSCore.java 8268722 macosx-x64
|
||||||
serviceability/sa/TestJmapCore.java 8268283 linux-aarch64
|
serviceability/sa/ClhsdbFindPC.java#id1 8268722 macosx-x64
|
||||||
|
serviceability/sa/ClhsdbFindPC.java#id3 8268722 macosx-x64
|
||||||
|
serviceability/sa/ClhsdbPmap.java#id1 8268722 macosx-x64
|
||||||
|
serviceability/sa/ClhsdbPstack.java#id1 8268722 macosx-x64
|
||||||
|
serviceability/sa/TestJmapCore.java 8268722,8268283 macosx-x64,linux-aarch64
|
||||||
|
serviceability/sa/TestJmapCoreMetaspace.java 8268722 macosx-x64
|
||||||
|
|
|
@ -70,6 +70,8 @@ compiler/whitebox/MakeMethodNotCompilableTest.java 8265360 macosx-aarch64
|
||||||
|
|
||||||
compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-x64
|
compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-x64
|
||||||
|
|
||||||
|
compiler/intrinsics/VectorizedMismatchTest.java 8268482 windows-x64
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
# :hotspot_gc
|
# :hotspot_gc
|
||||||
|
|
|
@ -129,6 +129,7 @@ tier1_compiler_2 = \
|
||||||
tier1_compiler_3 = \
|
tier1_compiler_3 = \
|
||||||
compiler/intrinsics/ \
|
compiler/intrinsics/ \
|
||||||
compiler/jsr292/ \
|
compiler/jsr292/ \
|
||||||
|
compiler/locks/ \
|
||||||
compiler/loopopts/ \
|
compiler/loopopts/ \
|
||||||
compiler/macronodes/ \
|
compiler/macronodes/ \
|
||||||
compiler/memoryinitialization/ \
|
compiler/memoryinitialization/ \
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8268366
|
||||||
|
* @run main/othervm -Xbatch -XX:+TieredCompilation -XX:TieredStopAtLevel=1
|
||||||
|
* compiler.c1.TestLinearScanHasFPURegisters
|
||||||
|
*/
|
||||||
|
|
||||||
|
package compiler.c1;
|
||||||
|
|
||||||
|
public class TestLinearScanHasFPURegisters {
|
||||||
|
void test(String[] args) {
|
||||||
|
String arr[] = new String[4];
|
||||||
|
float f = -1;
|
||||||
|
try {
|
||||||
|
arr[0] = "-1"; // exception edge 1 with value -1
|
||||||
|
if (args.length > 1) {
|
||||||
|
f = 42;
|
||||||
|
arr[1] = "42"; // exception edge 2 with value 42
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// exception handler block with incoming phi for "f"
|
||||||
|
for (int i = 0; i < 1; ++i) {
|
||||||
|
f = f; // generates bytecodes, but no JIT IR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TestLinearScanHasFPURegisters t = new TestLinearScanHasFPURegisters();
|
||||||
|
for (int i = 0; i < 1000; ++i) {
|
||||||
|
t.test(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8268347
|
||||||
|
* @summary Nested locks optimization may create unbalanced monitor enter/exit code
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:-BackgroundCompilation
|
||||||
|
* -XX:CompileCommand=dontinline,TestNestedLocksElimination::foo
|
||||||
|
* -XX:CompileCommand=dontinline,TestNestedLocksElimination::getNext
|
||||||
|
* -XX:CompileCommand=dontinline,TestNestedLocksElimination::getHolder
|
||||||
|
* TestNestedLocksElimination
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class TestNestedLocksElimination {
|
||||||
|
|
||||||
|
private LinkedList<char[]> buffers = new LinkedList<>();
|
||||||
|
private boolean complete = false;
|
||||||
|
private int bufferSize;
|
||||||
|
|
||||||
|
void foo(char[] ca) {
|
||||||
|
// Don't inline dummy method
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't inline
|
||||||
|
char[] getNext(int length, int count) {
|
||||||
|
if (this.buffers.isEmpty()) {
|
||||||
|
return new char[100];
|
||||||
|
}
|
||||||
|
char[] b = (char[]) this.buffers.getFirst();
|
||||||
|
if (count >= 100) {
|
||||||
|
this.complete = true;
|
||||||
|
this.buffers.clear(); // empty
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized boolean isComplete() {
|
||||||
|
return this.complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized boolean availableSegment() {
|
||||||
|
return (buffers.isEmpty() == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't inline
|
||||||
|
TestNestedLocksElimination getHolder(TestNestedLocksElimination s1, TestNestedLocksElimination s2, int count) {
|
||||||
|
return (count & 7) == 0 ? s2 : s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test(TestNestedLocksElimination s1, TestNestedLocksElimination s2, int maxToSend) {
|
||||||
|
boolean isComplete = true;
|
||||||
|
boolean availableSegment = false;
|
||||||
|
int size = 0;
|
||||||
|
int count = 0;
|
||||||
|
do {
|
||||||
|
TestNestedLocksElimination s = getHolder(s1, s2, count++);
|
||||||
|
|
||||||
|
synchronized(s) {
|
||||||
|
isComplete = s.isComplete();
|
||||||
|
availableSegment = s.availableSegment();
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
size = 0;
|
||||||
|
while (size < maxToSend) {
|
||||||
|
char[] b = null;
|
||||||
|
// This is outer Lock region for object 's'.
|
||||||
|
// Locks from following inlined methods are "nested"
|
||||||
|
// because they reference the same object.
|
||||||
|
synchronized(s) {
|
||||||
|
b = s.getNext(maxToSend - size, count);
|
||||||
|
|
||||||
|
// The next is bi-morphic call with both calls inlined.
|
||||||
|
// But one is synchronized and the other is not.
|
||||||
|
// Class check for bi-morphic call is loop invariant
|
||||||
|
// and will trigger loop unswitching.
|
||||||
|
// Loop unswitching will create two versions of loop
|
||||||
|
// with gollowing calls inlinined in both versions.
|
||||||
|
|
||||||
|
isComplete = s.isComplete();
|
||||||
|
|
||||||
|
// The next synchronized method availableSegment() is
|
||||||
|
// inlined and its Lock will be "coarsened" with Unlock
|
||||||
|
// in version of loop with inlined synchronized method
|
||||||
|
// isComplete().
|
||||||
|
// Nested Lock Optimization will mark only this Unlock
|
||||||
|
// as nested (as part of "nested" pair lock/unlock).
|
||||||
|
// Locks elimination will remove "coarsened" Lock from
|
||||||
|
// availableSegment() method leaving unmatched unlock.
|
||||||
|
|
||||||
|
availableSegment = s.availableSegment();
|
||||||
|
}
|
||||||
|
foo(b);
|
||||||
|
size += b.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (availableSegment == true || isComplete == false);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int count = 0;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
TestNestedLocksElimination t = new TestNestedLocksElimination();
|
||||||
|
TestNestedLocksElimination s1 = new TestNestedLocksElimination();
|
||||||
|
TestNestedLocksElimination s2 = new TestNestedLocksEliminationSub();
|
||||||
|
|
||||||
|
char[] c = new char[100];
|
||||||
|
while (n++ < 20_000) {
|
||||||
|
s1.buffers.add(c);
|
||||||
|
s2.buffers.add(c);
|
||||||
|
count += t.test(s1, s2, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(" count: " + count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestNestedLocksEliminationSub extends TestNestedLocksElimination {
|
||||||
|
public boolean isComplete() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,13 +23,12 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8248268
|
* @bug 8248268 8268621
|
||||||
* @summary Verify general properties of the AES/KW/NoPadding,
|
* @summary Verify general properties of the AES/KW/NoPadding,
|
||||||
* AES/KW/PKCS5Padding, and AES/KWP/NoPadding.
|
* AES/KW/PKCS5Padding, and AES/KWP/NoPadding.
|
||||||
* @run main TestGeneral
|
* @run main TestGeneral
|
||||||
*/
|
*/
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
|
@ -37,7 +36,10 @@ import javax.crypto.spec.*;
|
||||||
|
|
||||||
public class TestGeneral {
|
public class TestGeneral {
|
||||||
|
|
||||||
private static final SecretKey KEY = new SecretKeySpec(new byte[16], "AES");;
|
private static final byte[] DATA_128 =
|
||||||
|
Arrays.copyOf("1234567890123456789012345678901234".getBytes(), 128);
|
||||||
|
private static final SecretKey KEY =
|
||||||
|
new SecretKeySpec(DATA_128, 0, 16, "AES");
|
||||||
private static final int KW_IV_LEN = 8;
|
private static final int KW_IV_LEN = 8;
|
||||||
private static final int KWP_IV_LEN = 4;
|
private static final int KWP_IV_LEN = 4;
|
||||||
private static final int MAX_KW_PKCS5PAD_LEN = 16; // 1-16
|
private static final int MAX_KW_PKCS5PAD_LEN = 16; // 1-16
|
||||||
|
@ -133,12 +135,27 @@ public class TestGeneral {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void testIv(Cipher c) throws Exception {
|
public static void testIv(Cipher c) throws Exception {
|
||||||
|
// get a fresh Cipher instance so we can test iv with pre-init state
|
||||||
|
Cipher c2 = Cipher.getInstance(c.getAlgorithm(), c.getProvider());
|
||||||
|
if (c2.getIV() != null) {
|
||||||
|
throw new RuntimeException("Expects null iv");
|
||||||
|
}
|
||||||
|
if (c2.getParameters() == null) {
|
||||||
|
throw new RuntimeException("Expects non-null default parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
c2.init(Cipher.ENCRYPT_MODE, KEY);
|
||||||
|
byte[] defIv2 = c2.getIV();
|
||||||
c.init(Cipher.ENCRYPT_MODE, KEY);
|
c.init(Cipher.ENCRYPT_MODE, KEY);
|
||||||
byte[] defIv = c.getIV();
|
byte[] defIv = c.getIV();
|
||||||
// try init w/ an iv w/ different length
|
if (!Arrays.equals(defIv, defIv2)) {
|
||||||
|
throw new RuntimeException("Failed default iv check");
|
||||||
|
}
|
||||||
|
// try init w/ an iv w/ invalid length
|
||||||
try {
|
try {
|
||||||
c.init(Cipher.ENCRYPT_MODE, KEY, new IvParameterSpec(defIv, 0,
|
c.init(Cipher.ENCRYPT_MODE, KEY, new IvParameterSpec(defIv, 0,
|
||||||
defIv.length/2));
|
defIv.length/2));
|
||||||
|
throw new RuntimeException("Invalid iv accepted");
|
||||||
} catch (InvalidAlgorithmParameterException iape) {
|
} catch (InvalidAlgorithmParameterException iape) {
|
||||||
System.out.println("Invalid IV rejected as expected");
|
System.out.println("Invalid IV rejected as expected");
|
||||||
}
|
}
|
||||||
|
@ -146,19 +163,23 @@ public class TestGeneral {
|
||||||
c.init(Cipher.ENCRYPT_MODE, KEY, new IvParameterSpec(defIv));
|
c.init(Cipher.ENCRYPT_MODE, KEY, new IvParameterSpec(defIv));
|
||||||
byte[] newIv = c.getIV();
|
byte[] newIv = c.getIV();
|
||||||
if (!Arrays.equals(newIv, defIv)) {
|
if (!Arrays.equals(newIv, defIv)) {
|
||||||
throw new RuntimeException("Failed iv check");
|
throw new RuntimeException("Failed set iv check");
|
||||||
|
}
|
||||||
|
byte[] newIv2 = c.getIV();
|
||||||
|
if (newIv == newIv2) {
|
||||||
|
throw new RuntimeException("Failed getIV copy check");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] argv) throws Exception {
|
public static void main(String[] argv) throws Exception {
|
||||||
// test all possible pad lengths, i.e. 1 - 16
|
byte[] data = DATA_128;
|
||||||
byte[] data = new byte[128];
|
|
||||||
new Random().nextBytes(data);
|
|
||||||
|
|
||||||
String ALGO = "AES/KW/PKCS5Padding";
|
String ALGO = "AES/KW/PKCS5Padding";
|
||||||
System.out.println("Testing " + ALGO);
|
System.out.println("Testing " + ALGO);
|
||||||
Cipher c = Cipher.getInstance(ALGO, "SunJCE");
|
Cipher c = Cipher.getInstance(ALGO, "SunJCE");
|
||||||
for (int i = 0; i < MAX_KW_PKCS5PAD_LEN; i++) {
|
|
||||||
|
// test all possible pad lengths, i.e. 1 - 16
|
||||||
|
for (int i = 1; i <= MAX_KW_PKCS5PAD_LEN; i++) {
|
||||||
testEnc(c, data, data.length - i, KW_IV_LEN, MAX_KW_PKCS5PAD_LEN);
|
testEnc(c, data, data.length - i, KW_IV_LEN, MAX_KW_PKCS5PAD_LEN);
|
||||||
testWrap(c, data, data.length - i, KW_IV_LEN, MAX_KW_PKCS5PAD_LEN);
|
testWrap(c, data, data.length - i, KW_IV_LEN, MAX_KW_PKCS5PAD_LEN);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +197,9 @@ public class TestGeneral {
|
||||||
ALGO = "AES/KWP/NoPadding";
|
ALGO = "AES/KWP/NoPadding";
|
||||||
System.out.println("Testing " + ALGO);
|
System.out.println("Testing " + ALGO);
|
||||||
c = Cipher.getInstance(ALGO, "SunJCE");
|
c = Cipher.getInstance(ALGO, "SunJCE");
|
||||||
for (int i = 0; i < MAX_KWP_PAD_LEN; i++) {
|
|
||||||
|
// test all possible pad lengths, i.e. 0 - 7
|
||||||
|
for (int i = 0; i <= MAX_KWP_PAD_LEN; i++) {
|
||||||
testEnc(c, data, data.length - i, KWP_IV_LEN, MAX_KWP_PAD_LEN);
|
testEnc(c, data, data.length - i, KWP_IV_LEN, MAX_KWP_PAD_LEN);
|
||||||
testWrap(c, data, data.length - i, KWP_IV_LEN, MAX_KWP_PAD_LEN);
|
testWrap(c, data, data.length - i, KWP_IV_LEN, MAX_KWP_PAD_LEN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,60 +23,100 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4162868 8130181 8242151
|
* @bug 4162868 8130181 8242151 8267397
|
||||||
* @modules java.base/sun.security.x509
|
* @modules java.base/sun.security.x509
|
||||||
* @modules java.base/sun.security.util
|
* @modules java.base/sun.security.util
|
||||||
* @run main/othervm ExtensibleAlgorithmId
|
* @run main/othervm ExtensibleAlgorithmId
|
||||||
* @summary Algorithm Name-to-OID mapping needs to be made extensible.
|
* @summary Check that AlgorithmId Name-to-OID mapping is extensible and
|
||||||
|
* up-to-date.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Run in othervm, coz AlgorithmId.oidTable is only initialized once
|
|
||||||
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import sun.security.x509.AlgorithmId;
|
import sun.security.x509.AlgorithmId;
|
||||||
|
|
||||||
public class ExtensibleAlgorithmId {
|
public class ExtensibleAlgorithmId {
|
||||||
|
|
||||||
|
private static void test(String alg, String expOid) throws Exception {
|
||||||
|
System.out.println("Testing " + alg + " and " + expOid );
|
||||||
|
try {
|
||||||
|
AlgorithmId algid = AlgorithmId.get(alg);
|
||||||
|
if (expOid == null) {
|
||||||
|
throw new Exception("Expected NSAE not thrown");
|
||||||
|
}
|
||||||
|
if (!expOid.equals(algid.getOID().toString())) {
|
||||||
|
throw new Exception("Oid mismatch, expected " + expOid +
|
||||||
|
", got " + algid.getOID().toString());
|
||||||
|
}
|
||||||
|
if (!alg.equals(algid.getName())) {
|
||||||
|
throw new Exception("Name mismatch, expected " + alg +
|
||||||
|
", got " + algid.getName());
|
||||||
|
}
|
||||||
|
// try AlgorithmId.get() using 'expOid' if (alg != expOid)
|
||||||
|
if (alg != expOid) {
|
||||||
|
algid = AlgorithmId.get(expOid);
|
||||||
|
if (!expOid.equals(algid.getOID().toString())) {
|
||||||
|
throw new Exception("Oid2 mismatch, expected " + expOid +
|
||||||
|
", got " + algid.getOID().toString());
|
||||||
|
}
|
||||||
|
if (!alg.equals(algid.getName())) {
|
||||||
|
throw new Exception("Name2 mismatch, expected " + alg +
|
||||||
|
", got " + algid.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(" => passed");
|
||||||
|
} catch (NoSuchAlgorithmException nsae) {
|
||||||
|
if (expOid != null) {
|
||||||
|
nsae.printStackTrace();
|
||||||
|
throw new Exception("Unexpected NSAE for " + alg);
|
||||||
|
}
|
||||||
|
System.out.println(" => expected NSAE thrown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
TestProvider p = new TestProvider();
|
TestProvider p = new TestProvider();
|
||||||
Security.addProvider(p);
|
String alias = "Alg.Alias.Signature.OID." + TestProvider.ALG_OID;
|
||||||
AlgorithmId algid = AlgorithmId.getAlgorithmId(TestProvider.ALG_NAME);
|
|
||||||
String oid = algid.getOID().toString();
|
|
||||||
if (!oid.equals(TestProvider.ALG_OID)) {
|
|
||||||
throw new Exception("Provider alias oid not used, found " + oid);
|
|
||||||
}
|
|
||||||
String name = algid.getName();
|
|
||||||
if (!name.equalsIgnoreCase(TestProvider.ALG_NAME)) {
|
|
||||||
throw new Exception("provider alias name not used, found " + name);
|
|
||||||
}
|
|
||||||
String alias = "Alg.Alias.Signature.OID." + oid;
|
|
||||||
String stdAlgName = p.getProperty(alias);
|
String stdAlgName = p.getProperty(alias);
|
||||||
if (stdAlgName == null ||
|
if (stdAlgName == null ||
|
||||||
!stdAlgName.equalsIgnoreCase(TestProvider.ALG_NAME)) {
|
!stdAlgName.equalsIgnoreCase(TestProvider.ALG_NAME)) {
|
||||||
throw new Exception("Wrong OID");
|
throw new Exception("Wrong OID");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scenario#1: test before adding TestProvider
|
||||||
|
System.out.println("Before adding test provider");
|
||||||
|
test(TestProvider.ALG_NAME, null);
|
||||||
|
test(TestProvider.ALG_OID, TestProvider.ALG_OID);
|
||||||
|
test(TestProvider.ALG_OID2, TestProvider.ALG_OID2);
|
||||||
|
|
||||||
|
Security.addProvider(p);
|
||||||
|
// scenario#2: test again after adding TestProvider
|
||||||
|
System.out.println("After adding test provider");
|
||||||
|
test(TestProvider.ALG_NAME, TestProvider.ALG_OID);
|
||||||
|
test(TestProvider.ALG_OID2, TestProvider.ALG_OID2);
|
||||||
|
|
||||||
|
Security.removeProvider(p.getName());
|
||||||
|
// scenario#3: test after removing TestProvider; should be same as
|
||||||
|
// scenario#1
|
||||||
|
System.out.println("After removing test provider");
|
||||||
|
test(TestProvider.ALG_NAME, null);
|
||||||
|
test(TestProvider.ALG_OID, TestProvider.ALG_OID);
|
||||||
|
test(TestProvider.ALG_OID2, TestProvider.ALG_OID2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TestProvider extends Provider {
|
static class TestProvider extends Provider {
|
||||||
|
|
||||||
static String ALG_OID = "1.2.3.4.5.6.7.8.9.0";
|
static String ALG_OID = "1.2.3.4.5.6.7.8.9.0";
|
||||||
|
static String ALG_OID2 = "0.2.7.6.5.4.3.2.1.0";
|
||||||
static String ALG_NAME = "XYZ";
|
static String ALG_NAME = "XYZ";
|
||||||
|
|
||||||
public TestProvider() {
|
public TestProvider() {
|
||||||
super("Dummy", "1.0", "XYZ algorithm");
|
super("Dummy", "1.0", "XYZ algorithm");
|
||||||
|
|
||||||
AccessController.doPrivileged(new PrivilegedAction() {
|
put("Signature." + ALG_NAME, "test.xyz");
|
||||||
public Object run() {
|
// preferred OID for name<->oid mapping
|
||||||
|
put("Alg.Alias.Signature.OID." + ALG_OID, ALG_NAME);
|
||||||
put("Signature." + ALG_NAME, "test.xyz");
|
put("Alg.Alias.Signature." + ALG_OID2, ALG_NAME);
|
||||||
// preferred OID
|
|
||||||
put("Alg.Alias.Signature.OID." + ALG_OID,
|
|
||||||
ALG_NAME);
|
|
||||||
put("Alg.Alias.Signature.9.8.7.6.5.4.3.2.1.0",
|
|
||||||
ALG_NAME);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8262891
|
* @bug 8262891 8268663
|
||||||
* @summary Check guards implementation.
|
* @summary Check guards implementation.
|
||||||
* @compile --enable-preview -source ${jdk.version} Guards.java
|
* @compile --enable-preview -source ${jdk.version} Guards.java
|
||||||
* @run main/othervm --enable-preview Guards
|
* @run main/othervm --enable-preview Guards
|
||||||
|
@ -43,6 +43,9 @@ public class Guards {
|
||||||
run(this::testBooleanSwitchExpression);
|
run(this::testBooleanSwitchExpression);
|
||||||
assertEquals("a", testPatternInGuard("a"));
|
assertEquals("a", testPatternInGuard("a"));
|
||||||
assertEquals(null, testPatternInGuard(1));
|
assertEquals(null, testPatternInGuard(1));
|
||||||
|
runIfTrue(this::typeGuardIfTrueIfStatement);
|
||||||
|
runIfTrue(this::typeGuardIfTrueSwitchExpression);
|
||||||
|
runIfTrue(this::typeGuardIfTrueSwitchStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run(Function<Object, String> convert) {
|
void run(Function<Object, String> convert) {
|
||||||
|
@ -52,6 +55,12 @@ public class Guards {
|
||||||
assertEquals("any", convert.apply(""));
|
assertEquals("any", convert.apply(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runIfTrue(Function<Object, String> convert) {
|
||||||
|
assertEquals("true", convert.apply(0));
|
||||||
|
assertEquals("second", convert.apply(2));
|
||||||
|
assertEquals("any", convert.apply(""));
|
||||||
|
}
|
||||||
|
|
||||||
String typeTestPatternSwitchTest(Object o) {
|
String typeTestPatternSwitchTest(Object o) {
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case Integer i && i == 0: return "zero";
|
case Integer i && i == 0: return "zero";
|
||||||
|
@ -84,6 +93,35 @@ public class Guards {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String typeGuardIfTrueSwitchStatement(Object o) {
|
||||||
|
Object o2 = "";
|
||||||
|
switch (o) {
|
||||||
|
case Integer i && i == 0 && i < 1 && o2 instanceof String s: o = s + String.valueOf(i); return "true";
|
||||||
|
case Integer i && i == 0 || i > 1: o = String.valueOf(i); return "second";
|
||||||
|
case Object x: return "any";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String typeGuardIfTrueSwitchExpression(Object o) {
|
||||||
|
Object o2 = "";
|
||||||
|
return switch (o) {
|
||||||
|
case Integer i && i == 0 && i < 1 && o2 instanceof String s: o = s + String.valueOf(i); yield "true";
|
||||||
|
case Integer i && i == 0 || i > 1: o = String.valueOf(i); yield "second";
|
||||||
|
case Object x: yield "any";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
String typeGuardIfTrueIfStatement(Object o) {
|
||||||
|
Object o2 = "";
|
||||||
|
if (o != null && o instanceof (Integer i && i == 0 && i < 1) && (o = i) != null && o2 instanceof String s) {
|
||||||
|
return s != null ? "true" : null;
|
||||||
|
} else if (o != null && o instanceof (Integer i && i == 0 || i > 1) && (o = i) != null) {
|
||||||
|
return "second";
|
||||||
|
} else {
|
||||||
|
return "any";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String testPatternInGuard(Object o) {
|
String testPatternInGuard(Object o) {
|
||||||
if (o instanceof (CharSequence cs && cs instanceof String s)) {
|
if (o instanceof (CharSequence cs && cs instanceof String s)) {
|
||||||
return s;
|
return s;
|
||||||
|
|
|
@ -190,4 +190,16 @@ public class SwitchErrors {
|
||||||
}
|
}
|
||||||
sealed class SealedNonAbstract permits A {}
|
sealed class SealedNonAbstract permits A {}
|
||||||
final class A extends SealedNonAbstract {}
|
final class A extends SealedNonAbstract {}
|
||||||
|
Object guardWithMatchingStatement(Object o1, Object o2) {
|
||||||
|
switch (o1) {
|
||||||
|
case String s && s.isEmpty() || o2 instanceof Number n: return n;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object guardWithMatchingExpression(Object o1, Object o2) {
|
||||||
|
return switch (o1) {
|
||||||
|
case String s && s.isEmpty() || o2 instanceof Number n -> n;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ SwitchErrors.java:166:18: compiler.err.flows.through.from.pattern
|
||||||
SwitchErrors.java:171:27: compiler.err.flows.through.to.pattern
|
SwitchErrors.java:171:27: compiler.err.flows.through.to.pattern
|
||||||
SwitchErrors.java:177:18: compiler.err.flows.through.to.pattern
|
SwitchErrors.java:177:18: compiler.err.flows.through.to.pattern
|
||||||
SwitchErrors.java:183:13: compiler.err.pattern.dominated
|
SwitchErrors.java:183:13: compiler.err.pattern.dominated
|
||||||
|
SwitchErrors.java:195:76: compiler.err.cant.resolve.location: kindname.variable, n, , , (compiler.misc.location: kindname.class, SwitchErrors, null)
|
||||||
|
SwitchErrors.java:201:71: compiler.err.cant.resolve.location: kindname.variable, n, , , (compiler.misc.location: kindname.class, SwitchErrors, null)
|
||||||
SwitchErrors.java:32:9: compiler.err.not.exhaustive.statement
|
SwitchErrors.java:32:9: compiler.err.not.exhaustive.statement
|
||||||
SwitchErrors.java:38:9: compiler.err.not.exhaustive.statement
|
SwitchErrors.java:38:9: compiler.err.not.exhaustive.statement
|
||||||
SwitchErrors.java:44:9: compiler.err.not.exhaustive.statement
|
SwitchErrors.java:44:9: compiler.err.not.exhaustive.statement
|
||||||
|
@ -41,4 +43,4 @@ SwitchErrors.java:127:9: compiler.err.not.exhaustive.statement
|
||||||
SwitchErrors.java:187:9: compiler.err.not.exhaustive.statement
|
SwitchErrors.java:187:9: compiler.err.not.exhaustive.statement
|
||||||
- compiler.note.preview.filename: SwitchErrors.java, DEFAULT
|
- compiler.note.preview.filename: SwitchErrors.java, DEFAULT
|
||||||
- compiler.note.preview.recompile
|
- compiler.note.preview.recompile
|
||||||
41 errors
|
43 errors
|
||||||
|
|
|
@ -27,7 +27,7 @@ import java.util.function.Function;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8262891
|
* @bug 8262891 8268333
|
||||||
* @summary Check behavior of pattern switches.
|
* @summary Check behavior of pattern switches.
|
||||||
* @compile --enable-preview -source ${jdk.version} Switches.java
|
* @compile --enable-preview -source ${jdk.version} Switches.java
|
||||||
* @run main/othervm --enable-preview Switches
|
* @run main/othervm --enable-preview Switches
|
||||||
|
@ -46,6 +46,8 @@ public class Switches {
|
||||||
assertTrue(testNullSwitch(""));
|
assertTrue(testNullSwitch(""));
|
||||||
runArrayTypeTest(this::testArrayTypeStatement);
|
runArrayTypeTest(this::testArrayTypeStatement);
|
||||||
runArrayTypeTest(this::testArrayTypeExpression);
|
runArrayTypeTest(this::testArrayTypeExpression);
|
||||||
|
runDefaultTest(this::testDefaultDoesNotDominateStatement);
|
||||||
|
runDefaultTest(this::testDefaultDoesNotDominateExpression);
|
||||||
runEnumTest(this::testEnumExpression1);
|
runEnumTest(this::testEnumExpression1);
|
||||||
runEnumTest(this::testEnumExpression2);
|
runEnumTest(this::testEnumExpression2);
|
||||||
runEnumTest(this::testEnumWithGuards1);
|
runEnumTest(this::testEnumWithGuards1);
|
||||||
|
@ -81,6 +83,13 @@ public class Switches {
|
||||||
assertEquals("", mapper.apply(1.0));
|
assertEquals("", mapper.apply(1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runDefaultTest(Function<Object, String> mapper) {
|
||||||
|
assertEquals("default", mapper.apply(new int[0]));
|
||||||
|
assertEquals("str6", mapper.apply("string"));
|
||||||
|
assertEquals("default", mapper.apply(1));
|
||||||
|
assertEquals("default", mapper.apply(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
void runEnumTest(Function<E, String> mapper) {
|
void runEnumTest(Function<E, String> mapper) {
|
||||||
assertEquals("a", mapper.apply(E.A));
|
assertEquals("a", mapper.apply(E.A));
|
||||||
assertEquals("b", mapper.apply(E.B));
|
assertEquals("b", mapper.apply(E.B));
|
||||||
|
@ -172,6 +181,22 @@ public class Switches {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String testDefaultDoesNotDominateStatement(Object o) {
|
||||||
|
String res;
|
||||||
|
switch (o) {
|
||||||
|
default -> res = "default";
|
||||||
|
case String str -> res = "str" + str.length();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
String testDefaultDoesNotDominateExpression(Object o) {
|
||||||
|
return switch (o) {
|
||||||
|
case default -> "default";
|
||||||
|
case String str -> "str" + str.length();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
int testStringWithConstant(String str) {
|
int testStringWithConstant(String str) {
|
||||||
switch (str) {
|
switch (str) {
|
||||||
case "A": return 1;
|
case "A": return 1;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* @test /nodynamiccopyright/
|
* @test /nodynamiccopyright/
|
||||||
* @bug 8206986 8222169 8224031 8240964 8267119
|
* @bug 8206986 8222169 8224031 8240964 8267119 8268670
|
||||||
* @summary Check expression switch works.
|
* @summary Check expression switch works.
|
||||||
* @compile/fail/ref=ExpressionSwitch-old.out -source 9 -Xlint:-options -XDrawDiagnostics ExpressionSwitch.java
|
* @compile/fail/ref=ExpressionSwitch-old.out -source 9 -Xlint:-options -XDrawDiagnostics ExpressionSwitch.java
|
||||||
* @compile ExpressionSwitch.java
|
* @compile ExpressionSwitch.java
|
||||||
|
@ -120,6 +120,26 @@ public class ExpressionSwitch {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int yieldUnaryNumberOperator(String s, int a) {
|
||||||
|
return switch (s) {
|
||||||
|
case "a": yield +a;
|
||||||
|
case "b": yield -a;
|
||||||
|
case "c": yield ~a; // intentionally repeated ~a, test the case clause
|
||||||
|
case "d": yield ++a;
|
||||||
|
case "e": yield --a;
|
||||||
|
case "f": yield a++;
|
||||||
|
case "g": yield a--;
|
||||||
|
default: yield ~a; // intentionally repeated ~a, test the default clause
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean yieldUnaryNotOperator(String s, boolean b) {
|
||||||
|
return switch (s) {
|
||||||
|
case "a": yield !b; // intentionally repeated !b, test the case clause
|
||||||
|
default: yield !b; // intentionally repeated !b, test the default clause
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void localClass(T t) {
|
private void localClass(T t) {
|
||||||
String good = "good";
|
String good = "good";
|
||||||
class L {
|
class L {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue