--- a/.hgtags Tue Feb 20 21:46:02 2018 +0100
+++ b/.hgtags Mon Feb 26 09:56:12 2018 +0100
@@ -470,3 +470,4 @@
4b62b815b4f49970b91a952929cf50115c263cb3 jdk-10+42
107413b070b92c88bde6230ceb4a19b579781068 jdk-10+43
dfa46cfe56346884a61efdc30dc50f7505d66761 jdk-11+1
+03ae177c26b016353e5ea1cab6ffd051dfa086ca jdk-11+2
--- a/make/Main.gmk Tue Feb 20 21:46:02 2018 +0100
+++ b/make/Main.gmk Mon Feb 26 09:56:12 2018 +0100
@@ -641,8 +641,11 @@
generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs
+ # If not already set, set the JVM variant target so that the JVM will be built.
+ JVM_MAIN_LIB_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-libs
+
# Building one JVM variant is enough to start building the other libs
- $(LIBS_TARGETS): hotspot-$(JVM_VARIANT_MAIN)-libs
+ $(LIBS_TARGETS): $(JVM_MAIN_LIB_TARGETS)
$(LAUNCHER_TARGETS): java.base-libs
@@ -719,8 +722,11 @@
java.base-jmod: jrtfs-jar $(filter-out java.base-jmod, $(JMOD_TARGETS))
endif
- # Building java.base-jmod requires all of hotspot to be built.
- java.base-jmod: hotspot
+ # If not already set, set the JVM target so that the JVM will be built.
+ JVM_MAIN_TARGETS ?= hotspot
+
+ # Building java.base-jmod requires all of VM (ie hotspot) to be built.
+ java.base-jmod: $(JVM_MAIN_TARGETS)
# Declare dependencies from <module>-jmod to all other module targets
# When creating a BUILDJDK, the java compilation has already been done by the
@@ -746,7 +752,7 @@
# in java.base-copy) and tzdb.dat (done in java.base-gendata) to the
# appropriate location otherwise jimage, jlink and jmod won't start. This
# also applies when creating the buildjdk.
- DEFAULT_JMOD_DEPS := java.base-libs java.base-copy java.base-gendata \
+ DEFAULT_JMOD_DEPS += java.base-libs java.base-copy java.base-gendata \
jdk.jlink-launchers
# When cross compiling and buildjdk is to be created, depend on creating the
# buildjdk instead of the default dependencies.
@@ -822,8 +828,11 @@
docs-reference-api-modulegraph: exploded-image buildtools-modules
+ # If not already set, then set the JVM specific docs targets
+ JVM_DOCS_TARGETS ?= hotspot-$(JVM_VARIANT_MAIN)-gensrc
+
# The gensrc steps for hotspot and jdk.jdi create html spec files.
- docs-jdk-specs: hotspot-$(JVM_VARIANT_MAIN)-gensrc jdk.jdi-gensrc \
+ docs-jdk-specs: $(JVM_DOCS_TARGETS) jdk.jdi-gensrc \
docs-jdk-index
docs-jdk-index: exploded-image buildtools-modules
@@ -890,8 +899,10 @@
################################################################################
# Virtual targets without recipes
+# If not already set, set the JVM specific tools targets
+JVM_TOOLS_TARGETS ?= buildtools-hotspot
buildtools: buildtools-langtools interim-langtools interim-rmic \
- buildtools-jdk buildtools-hotspot
+ buildtools-jdk $(JVM_TOOLS_TARGETS)
hotspot: $(HOTSPOT_VARIANT_TARGETS) hotspot-jsig
@@ -934,7 +945,7 @@
$(foreach m, $(ALL_COPY_MODULES), $(eval $m: $m-copy))
# Building java.base includes building all of hotspot.
-java.base: hotspot
+java.base: $(JVM_MAIN_TARGETS)
demos: demos-jdk
@@ -1001,10 +1012,15 @@
# This target builds the documentation image
docs-image: docs-jdk
+# If not already set, set the JVM specific targets to build the test image
+JVM_TEST_IMAGE_TARGETS ?= test-image-hotspot-jtreg-native test-image-hotspot-gtest
+
# This target builds the test image
-test-image: prepare-test-image test-image-hotspot-jtreg-native \
- test-image-jdk-jtreg-native test-image-failure-handler test-image-hotspot-gtest \
- test-image-demos-jdk
+test-image: prepare-test-image \
+ test-image-jdk-jtreg-native test-image-failure-handler \
+ test-image-demos-jdk $(JVM_TEST_IMAGE_TARGETS)
+
+################################################################################
# all-images builds all our deliverables as images.
all-images: product-images test-image docs-image
@@ -1143,6 +1159,8 @@
$(MAKESUPPORT_OUTPUTDIR)/main-targets.gmk
################################################################################
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, Main-post.gmk))
.PHONY: $(ALL_TARGETS)
--- a/make/autoconf/basics.m4 Tue Feb 20 21:46:02 2018 +0100
+++ b/make/autoconf/basics.m4 Mon Feb 26 09:56:12 2018 +0100
@@ -263,7 +263,7 @@
READLINK_TESTED=yes
fi
- if test "x$READLINK" != x && "x$READLINK_ISGNU" != x; then
+ if test "x$READLINK" != x && test "x$READLINK_ISGNU" != x; then
$1=`$READLINK -f [$]$1`
else
# Save the current directory for restoring afterwards
--- a/make/autoconf/version-numbers Tue Feb 20 21:46:02 2018 +0100
+++ b/make/autoconf/version-numbers Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
DEFAULT_VERSION_INTERIM=0
DEFAULT_VERSION_UPDATE=0
DEFAULT_VERSION_PATCH=0
-DEFAULT_VERSION_DATE=2018-03-20
+DEFAULT_VERSION_DATE=2018-09-18
DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
DEFAULT_VERSION_CLASSFILE_MINOR=0
--- a/make/common/TextFileProcessing.gmk Tue Feb 20 21:46:02 2018 +0100
+++ b/make/common/TextFileProcessing.gmk Mon Feb 26 09:56:12 2018 +0100
@@ -153,11 +153,11 @@
endif
# Convert the REPLACEMENTS syntax ( A => B ; C => D ; ...) to a sed command
- # line (-e "s/A/B/" -e "s/C/D/" ...), basically by replacing '=>' with '/'
- # and ';' with '/" -e "s/', and adjusting for edge cases.
- $1_REPLACEMENTS_COMMAND_LINE := $(SED) -e 's$$($1_SEP)$$(subst $$(SPACE);$$(SPACE),$$($1_SEP)' \
- -e 's$$($1_SEP),$$(subst $$(SPACE)=>$$(SPACE),$$($1_SEP),$$(subst $$(SPACE)=>$$(SPACE);$$(SPACE),$$($1_SEP)$$($1_SEP)' \
- -e 's$$($1_SEP),$$(strip $$($1_REPLACEMENTS)))))$$($1_SEP)'
+ # line (-e "s/A/B/g" -e "s/C/D/g" ...), basically by replacing '=>' with '/'
+ # and ';' with '/g" -e "s/', and adjusting for edge cases.
+ $1_REPLACEMENTS_COMMAND_LINE := $(SED) -e 's$$($1_SEP)$$(subst $$(SPACE);$$(SPACE),$$($1_SEP)g' \
+ -e 's$$($1_SEP),$$(subst $$(SPACE)=>$$(SPACE),$$($1_SEP),$$(subst $$(SPACE)=>$$(SPACE);$$(SPACE),$$($1_SEP)$$($1_SEP)g' \
+ -e 's$$($1_SEP),$$(strip $$($1_REPLACEMENTS)))))$$($1_SEP)g'
else
# We don't have any replacements, just pipe the file through cat.
$1_REPLACEMENTS_COMMAND_LINE := $(CAT)
--- a/make/conf/jib-profiles.js Tue Feb 20 21:46:02 2018 +0100
+++ b/make/conf/jib-profiles.js Mon Feb 26 09:56:12 2018 +0100
@@ -1090,7 +1090,7 @@
args = concat(args,
// This needs to be changed when we start building release candidates
// with-version-pre must be set to ea for 'ea' and empty for fcs build
- "--with-version-pre=",
+ "--with-version-pre=ea",
"--without-version-opt");
} else {
args = concat(args, "--with-version-opt=" + common.build_id);
--- a/make/devkit/createSolarisDevkit.sh Tue Feb 20 21:46:02 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# This script creates a devkit for building OpenJDK on Solaris by copying
-# part of a Solaris Studio installation and cretaing a sysroot by installing
-# a limited set of system packages. It is assumed that a suitable pkg
-# publisher is configured for the system where the script is executed.
-#
-# The Solaris Studio installation must contain at least these packages:
-# developer/solarisstudio-124/backend 12.4-1.0.6.0 i--
-# developer/solarisstudio-124/c++ 12.4-1.0.10.0 i--
-# developer/solarisstudio-124/cc 12.4-1.0.4.0 i--
-# developer/solarisstudio-124/library/c++-libs 12.4-1.0.10.0 i--
-# developer/solarisstudio-124/library/math-libs 12.4-1.0.0.1 i--
-# developer/solarisstudio-124/library/studio-gccrt 12.4-1.0.0.1 i--
-# developer/solarisstudio-124/studio-common 12.4-1.0.0.1 i--
-# developer/solarisstudio-124/studio-ja 12.4-1.0.0.1 i--
-# developer/solarisstudio-124/studio-legal 12.4-1.0.0.1 i--
-# developer/solarisstudio-124/studio-zhCN 12.4-1.0.0.1 i--
-# In particular backend 12.4-1.0.6.0 contains a critical patch for the sparc
-# version.
-#
-# erik.joelsson@oracle.com
-
-USAGE="$0 <Solaris Studio installation> <Path to gnu make binary>"
-
-if [ "$1" = "" ] || [ "$2" = "" ]; then
- echo $USAGE
- exit 1
-fi
-
-SOLARIS_STUDIO_VERSION=12u4
-SOLARIS_VERSION=11u1
-case `uname -p` in
- i*)
- ARCH=x86
- ;;
- sparc*)
- ARCH=sparc
- ;;
-esac
-
-SOLARIS_STUDIO_SRC=$1
-GNU_MAKE=$2
-
-SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
-BUILD_DIR="${SCRIPT_DIR}/../../build/devkit"
-
-DEVKIT_NAME=SS${SOLARIS_STUDIO_VERSION}-Solaris${SOLARIS_VERSION}
-DEVKIT_ROOT=${BUILD_DIR}/${DEVKIT_NAME}
-BUNDLE_NAME=${DEVKIT_NAME}.tar.gz
-BUNDLE=${BUILD_DIR}/${BUNDLE_NAME}
-INSTALL_ROOT=${BUILD_DIR}/install-root-$SOLARIS_VERSION
-INSTALL_ROOT_TOOLS=${BUILD_DIR}/install-root-tools-$SOLARIS_VERSION
-SYSROOT=${DEVKIT_ROOT}/sysroot
-SOLARIS_STUDIO_SUBDIR=SS${SOLARIS_STUDIO_VERSION}
-SOLARIS_STUDIO_DIR=${DEVKIT_ROOT}/${SOLARIS_STUDIO_SUBDIR}
-
-# Extract the publisher from the system
-if [ -z "${PUBLISHER_URI}" ]; then
- PUBLISHER_URI="$(pkg publisher solaris | grep URI | awk '{ print $3 }')"
-fi
-
-if [ ! -d $INSTALL_ROOT ]; then
- echo "Creating $INSTALL_ROOT and installing packages"
- pkg image-create $INSTALL_ROOT
- pkg -R $INSTALL_ROOT set-publisher -P -g ${PUBLISHER_URI} solaris
- pkg -R $INSTALL_ROOT install --accept $(cat solaris11.1-package-list.txt)
-else
- echo "Skipping installing packages"
-fi
-
-# Since we have implicitly been running 11.2 tools for a long time, we need
-# to pick them for the tools dir in the devkit. Create a separate install-root
-# for it.
-if [ ! -d $INSTALL_ROOT_TOOLS ]; then
- echo "Creating $INSTALL_ROOT_TOOLS and installing packages"
- pkg image-create $INSTALL_ROOT_TOOLS
- pkg -R $INSTALL_ROOT_TOOLS set-publisher -P -g ${PUBLISHER_URI} solaris
- sudo pkg -R $INSTALL_ROOT_TOOLS install --accept \
- entire@0.5.11-0.175.2.5.0.5.0 \
- system/linker \
- developer/base-developer-utilities \
- developer/gnu-binutils
-else
- echo "Skipping installing tools packages"
-fi
-
-if [ ! -d $SYSROOT ]; then
- echo "Copying from $INSTALL_ROOT to $SYSROOT"
- mkdir -p $SYSROOT
- cp -rH $INSTALL_ROOT/lib $SYSROOT/
- mkdir $SYSROOT/usr
- cp -rH $INSTALL_ROOT/usr/lib $SYSROOT/usr/
- cp -rH $INSTALL_ROOT/usr/include $SYSROOT/usr/
- pkg -R $INSTALL_ROOT list > $SYSROOT/pkg-list.txt
-else
- echo "Skipping copying to $SYSROOT"
-fi
-
-if [ ! -d $DEVKIT_ROOT/tools ]; then
- echo "Copying from $INSTALL_ROOT_TOOLS to $DEVKIT_ROOT/tools"
- # Some of the tools in sysroot are needed in the OpenJDK build. We need
- # to copy them into a tools dir, including their specific libraries.
- mkdir -p $DEVKIT_ROOT/tools/usr/bin/sparcv9 $DEVKIT_ROOT/tools/lib/sparcv9 \
- $DEVKIT_ROOT/tools/usr/gnu/bin
- cp $INSTALL_ROOT_TOOLS/usr/bin/{ar,nm,strip,ld,ldd} \
- $DEVKIT_ROOT/tools/usr/bin/
- cp $INSTALL_ROOT_TOOLS/usr/bin/sparcv9/{ar,nm,strip,ld,ldd} \
- $DEVKIT_ROOT/tools/usr/bin/sparcv9/
- cp $INSTALL_ROOT_TOOLS/usr/sbin/dtrace $DEVKIT_ROOT/tools/usr/bin/
- cp $INSTALL_ROOT_TOOLS/usr/sbin/sparcv9/dtrace $DEVKIT_ROOT/tools/usr/bin/sparcv9/
- cp -rH $INSTALL_ROOT_TOOLS/usr/gnu/bin/* $DEVKIT_ROOT/tools/usr/gnu/bin/
- cp $INSTALL_ROOT_TOOLS/lib/{libelf.so*,libld.so*,liblddbg.so*} \
- $DEVKIT_ROOT/tools/lib/
- cp $INSTALL_ROOT_TOOLS/lib/sparcv9/{libelf.so*,libld.so*,liblddbg.so*} \
- $DEVKIT_ROOT/tools/lib/sparcv9/
- for t in $(ls $DEVKIT_ROOT/tools/usr/gnu/bin); do
- if [ -f $DEVKIT_ROOT/tools/usr/gnu/bin/$t ]; then
- ln -s ../gnu/bin/$t $DEVKIT_ROOT/tools/usr/bin/g$t
- fi
- done
-else
- echo "Skipping copying to tools dir $DEVKIT_ROOT/tools"
-fi
-
-if [ ! -d $SOLARIS_STUDIO_DIR ]; then
- echo "Copying Solaris Studio from $SOLARIS_STUDIO_SRC"
- mkdir -p ${SOLARIS_STUDIO_DIR}
- cp -rH $SOLARIS_STUDIO_SRC/. ${SOLARIS_STUDIO_DIR}/
- # Solaris Studio 12.4 requires /lib/libmmheap.so.1 to run, but this lib is not
- # installed by default on all Solaris systems. Sneak it in from the sysroot to
- # make it run OOTB on more systems.
- cp $SYSROOT/lib/libmmheap.so.1 $SOLARIS_STUDIO_DIR/lib/compilers/sys/
-else
- echo "Skipping copying of Solaris Studio"
-fi
-
-echo "Copying gnu make to $DEVKIT_ROOT/bin"
-cp $GNU_MAKE $DEVKIT_ROOT/tools/usr/bin/
-if [ ! -e $DEVKIT_ROOT/tools/usr/bin/gmake ]; then
- ln -s make $DEVKIT_ROOT/tools/usr/bin/gmake
-fi
-
-# Create the devkit.info file
-echo Creating devkit.info
-INFO_FILE=$DEVKIT_ROOT/devkit.info
-rm -f $INFO_FILE
-echo "# This file describes to configure how to interpret the contents of this devkit" >> $INFO_FILE
-echo "DEVKIT_NAME=\"Solaris Studio $SOLARIS_STUDIO_VERSION - Solaris $SOLARIS_VERSION - $ARCH\"" >> $INFO_FILE
-echo "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/$SOLARIS_STUDIO_SUBDIR/bin:\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
-echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/tools/usr/bin\"" >> $INFO_FILE
-echo "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/sysroot\"" >> $INFO_FILE
-
-if [ ! -e $BUNDLE ]; then
- echo "Creating $BUNDLE from $DEVKIT_ROOT"
- cd $DEVKIT_ROOT/..
- tar zcf $BUNDLE $DEVKIT_NAME
-else
- echo "Skipping creation of $BUNDLE"
-fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/devkit/createSolarisDevkit12.4.sh Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,184 @@
+#!/bin/bash
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# This script creates a devkit for building OpenJDK on Solaris by copying
+# part of a Solaris Studio installation and cretaing a sysroot by installing
+# a limited set of system packages. It is assumed that a suitable pkg
+# publisher is configured for the system where the script is executed.
+#
+# The Solaris Studio installation must contain at least these packages:
+# developer/solarisstudio-124/backend 12.4-1.0.6.0 i--
+# developer/solarisstudio-124/c++ 12.4-1.0.10.0 i--
+# developer/solarisstudio-124/cc 12.4-1.0.4.0 i--
+# developer/solarisstudio-124/library/c++-libs 12.4-1.0.10.0 i--
+# developer/solarisstudio-124/library/math-libs 12.4-1.0.0.1 i--
+# developer/solarisstudio-124/library/studio-gccrt 12.4-1.0.0.1 i--
+# developer/solarisstudio-124/studio-common 12.4-1.0.0.1 i--
+# developer/solarisstudio-124/studio-ja 12.4-1.0.0.1 i--
+# developer/solarisstudio-124/studio-legal 12.4-1.0.0.1 i--
+# developer/solarisstudio-124/studio-zhCN 12.4-1.0.0.1 i--
+# In particular backend 12.4-1.0.6.0 contains a critical patch for the sparc
+# version.
+#
+# erik.joelsson@oracle.com
+
+USAGE="$0 <Solaris Studio installation> <Path to gnu make binary>"
+
+if [ "$1" = "" ] || [ "$2" = "" ]; then
+ echo $USAGE
+ exit 1
+fi
+
+SOLARIS_STUDIO_VERSION=12u4
+SOLARIS_VERSION=11u1
+case `uname -p` in
+ i*)
+ ARCH=x86
+ ;;
+ sparc*)
+ ARCH=sparc
+ ;;
+esac
+
+SOLARIS_STUDIO_SRC=$1
+GNU_MAKE=$2
+
+SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
+BUILD_DIR="${SCRIPT_DIR}/../../build/devkit"
+
+DEVKIT_NAME=SS${SOLARIS_STUDIO_VERSION}-Solaris${SOLARIS_VERSION}
+DEVKIT_ROOT=${BUILD_DIR}/${DEVKIT_NAME}
+BUNDLE_NAME=${DEVKIT_NAME}.tar.gz
+BUNDLE=${BUILD_DIR}/${BUNDLE_NAME}
+INSTALL_ROOT=${BUILD_DIR}/install-root-$SOLARIS_VERSION
+INSTALL_ROOT_TOOLS=${BUILD_DIR}/install-root-tools-$SOLARIS_VERSION
+SYSROOT=${DEVKIT_ROOT}/sysroot
+SOLARIS_STUDIO_SUBDIR=SS${SOLARIS_STUDIO_VERSION}
+SOLARIS_STUDIO_DIR=${DEVKIT_ROOT}/${SOLARIS_STUDIO_SUBDIR}
+
+# Extract the publisher from the system
+if [ -z "${PUBLISHER_URI}" ]; then
+ PUBLISHER_URI="$(pkg publisher solaris | grep URI | awk '{ print $3 }')"
+fi
+
+if [ ! -d $INSTALL_ROOT ]; then
+ echo "Creating $INSTALL_ROOT and installing packages"
+ pkg image-create $INSTALL_ROOT
+ pkg -R $INSTALL_ROOT set-publisher -P -g ${PUBLISHER_URI} solaris
+ pkg -R $INSTALL_ROOT install --accept $(cat solaris11.1-package-list.txt)
+else
+ echo "Skipping installing packages"
+fi
+
+# Since we have implicitly been running 11.2 tools for a long time, we need
+# to pick them for the tools dir in the devkit. Create a separate install-root
+# for it.
+if [ ! -d $INSTALL_ROOT_TOOLS ]; then
+ echo "Creating $INSTALL_ROOT_TOOLS and installing packages"
+ pkg image-create $INSTALL_ROOT_TOOLS
+ pkg -R $INSTALL_ROOT_TOOLS set-publisher -P -g ${PUBLISHER_URI} solaris
+ sudo pkg -R $INSTALL_ROOT_TOOLS install --accept \
+ entire@0.5.11-0.175.2.5.0.5.0 \
+ system/linker \
+ developer/base-developer-utilities \
+ developer/gnu-binutils
+else
+ echo "Skipping installing tools packages"
+fi
+
+if [ ! -d $SYSROOT ]; then
+ echo "Copying from $INSTALL_ROOT to $SYSROOT"
+ mkdir -p $SYSROOT
+ cp -rH $INSTALL_ROOT/lib $SYSROOT/
+ mkdir $SYSROOT/usr
+ cp -rH $INSTALL_ROOT/usr/lib $SYSROOT/usr/
+ cp -rH $INSTALL_ROOT/usr/include $SYSROOT/usr/
+ pkg -R $INSTALL_ROOT list > $SYSROOT/pkg-list.txt
+else
+ echo "Skipping copying to $SYSROOT"
+fi
+
+if [ ! -d $DEVKIT_ROOT/tools ]; then
+ echo "Copying from $INSTALL_ROOT_TOOLS to $DEVKIT_ROOT/tools"
+ # Some of the tools in sysroot are needed in the OpenJDK build. We need
+ # to copy them into a tools dir, including their specific libraries.
+ mkdir -p $DEVKIT_ROOT/tools/usr/bin/sparcv9 $DEVKIT_ROOT/tools/lib/sparcv9 \
+ $DEVKIT_ROOT/tools/usr/gnu/bin
+ cp $INSTALL_ROOT_TOOLS/usr/bin/{ar,nm,strip,ld,ldd} \
+ $DEVKIT_ROOT/tools/usr/bin/
+ cp $INSTALL_ROOT_TOOLS/usr/bin/sparcv9/{ar,nm,strip,ld,ldd} \
+ $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+ cp $INSTALL_ROOT_TOOLS/usr/sbin/dtrace $DEVKIT_ROOT/tools/usr/bin/
+ cp $INSTALL_ROOT_TOOLS/usr/sbin/sparcv9/dtrace $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+ cp -rH $INSTALL_ROOT_TOOLS/usr/gnu/bin/* $DEVKIT_ROOT/tools/usr/gnu/bin/
+ cp $INSTALL_ROOT_TOOLS/lib/{libelf.so*,libld.so*,liblddbg.so*} \
+ $DEVKIT_ROOT/tools/lib/
+ cp $INSTALL_ROOT_TOOLS/lib/sparcv9/{libelf.so*,libld.so*,liblddbg.so*} \
+ $DEVKIT_ROOT/tools/lib/sparcv9/
+ for t in $(ls $DEVKIT_ROOT/tools/usr/gnu/bin); do
+ if [ -f $DEVKIT_ROOT/tools/usr/gnu/bin/$t ]; then
+ ln -s ../gnu/bin/$t $DEVKIT_ROOT/tools/usr/bin/g$t
+ fi
+ done
+else
+ echo "Skipping copying to tools dir $DEVKIT_ROOT/tools"
+fi
+
+if [ ! -d $SOLARIS_STUDIO_DIR ]; then
+ echo "Copying Solaris Studio from $SOLARIS_STUDIO_SRC"
+ mkdir -p ${SOLARIS_STUDIO_DIR}
+ cp -rH $SOLARIS_STUDIO_SRC/. ${SOLARIS_STUDIO_DIR}/
+ # Solaris Studio 12.4 requires /lib/libmmheap.so.1 to run, but this lib is not
+ # installed by default on all Solaris systems. Sneak it in from the sysroot to
+ # make it run OOTB on more systems.
+ cp $SYSROOT/lib/libmmheap.so.1 $SOLARIS_STUDIO_DIR/lib/compilers/sys/
+else
+ echo "Skipping copying of Solaris Studio"
+fi
+
+echo "Copying gnu make to $DEVKIT_ROOT/bin"
+cp $GNU_MAKE $DEVKIT_ROOT/tools/usr/bin/
+if [ ! -e $DEVKIT_ROOT/tools/usr/bin/gmake ]; then
+ ln -s make $DEVKIT_ROOT/tools/usr/bin/gmake
+fi
+
+# Create the devkit.info file
+echo Creating devkit.info
+INFO_FILE=$DEVKIT_ROOT/devkit.info
+rm -f $INFO_FILE
+echo "# This file describes to configure how to interpret the contents of this devkit" >> $INFO_FILE
+echo "DEVKIT_NAME=\"Solaris Studio $SOLARIS_STUDIO_VERSION - Solaris $SOLARIS_VERSION - $ARCH\"" >> $INFO_FILE
+echo "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/$SOLARIS_STUDIO_SUBDIR/bin:\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
+echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/tools/usr/bin\"" >> $INFO_FILE
+echo "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/sysroot\"" >> $INFO_FILE
+
+if [ ! -e $BUNDLE ]; then
+ echo "Creating $BUNDLE from $DEVKIT_ROOT"
+ cd $DEVKIT_ROOT/..
+ tar zcf $BUNDLE $DEVKIT_NAME
+else
+ echo "Skipping creation of $BUNDLE"
+fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/devkit/createSolarisDevkit12.6.sh Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,167 @@
+#!/bin/bash
+#
+# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# 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.
+#
+
+# This script creates a devkit for building OpenJDK on Solaris by copying
+# part of a Solaris Studio installation and cretaing a sysroot by installing
+# a limited set of system packages. It is assumed that a suitable pkg
+# publisher is configured for the system where the script is executed.
+#
+# Note that you will need to be able to sudo to root to run the pkg install
+# part of this script. It should not affect the running system, but only
+# install in a separate temporary image.
+#
+# The Solaris Studio installation must contain at least these packages:
+# developer/developerstudio-126/backend 12.6-1.0.0.0 i--
+# developer/developerstudio-126/c++ 12.6-1.0.0.0 i--
+# developer/developerstudio-126/cc 12.6-1.0.0.0 i--
+# developer/developerstudio-126/dbx (solarisstudio) 12.6-1.0.0.0 i--
+# developer/developerstudio-126/library/c++-libs 12.6-1.0.0.0 i--
+# developer/developerstudio-126/library/math-libs 12.6-1.0.0.0 i--
+# developer/developerstudio-126/library/c-libs 12.6-1.0.0.0 i--
+# developer/developerstudio-126/library/studio-gccrt 12.6-1.0.0.0 i--
+# developer/developerstudio-126/studio-common 12.6-1.0.0.0 i--
+# developer/developerstudio-126/studio-ja 12.6-1.0.0.0 i--
+# developer/developerstudio-126/studio-legal 12.6-1.0.0.0 i--
+# developer/developerstudio-126/studio-zhCN 12.6-1.0.0.0 i--
+#
+# erik.joelsson@oracle.com
+
+USAGE="$0 <Solaris Studio installation>"
+
+if [ "$1" = "" ]; then
+ echo $USAGE
+ exit 1
+fi
+
+SOLARIS_STUDIO_VERSION=12u6
+SOLARIS_VERSION=11u3
+SOLARIS_ENTIRE_VERSION=0.5.11-0.175.3.20.0.6.0
+case `uname -p` in
+ i*)
+ ARCH=x86
+ ;;
+ sparc*)
+ ARCH=sparc
+ ;;
+esac
+
+SOLARIS_STUDIO_SRC=$1
+
+SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
+BUILD_DIR="${SCRIPT_DIR}/../../build/devkit"
+
+DEVKIT_NAME=SS${SOLARIS_STUDIO_VERSION}-Solaris${SOLARIS_VERSION}
+DEVKIT_ROOT=${BUILD_DIR}/${DEVKIT_NAME}
+BUNDLE_NAME=${DEVKIT_NAME}.tar.gz
+BUNDLE=${BUILD_DIR}/${BUNDLE_NAME}
+INSTALL_ROOT=${BUILD_DIR}/install-root-$SOLARIS_VERSION
+SYSROOT=${DEVKIT_ROOT}/sysroot
+SOLARIS_STUDIO_SUBDIR=SS${SOLARIS_STUDIO_VERSION}
+SOLARIS_STUDIO_DIR=${DEVKIT_ROOT}/${SOLARIS_STUDIO_SUBDIR}
+
+# Extract the publisher from the system
+if [ -z "${PUBLISHER_URI}" ]; then
+ PUBLISHER_URI="$(pkg publisher solaris | grep URI | awk '{ print $3 }')"
+fi
+
+if [ ! -d $INSTALL_ROOT ]; then
+ echo "Creating $INSTALL_ROOT and installing packages"
+ pkg image-create $INSTALL_ROOT
+ pkg -R $INSTALL_ROOT set-publisher -P -g ${PUBLISHER_URI} solaris
+ sudo pkg -R $INSTALL_ROOT install --accept entire@$SOLARIS_ENTIRE_VERSION \
+ system/install developer/gnu-binutils system/library/mmheap system/picl \
+ developer/assembler
+else
+ echo "Skipping installing packages"
+fi
+
+if [ ! -d $SYSROOT ]; then
+ echo "Copying from $INSTALL_ROOT to $SYSROOT"
+ mkdir -p $SYSROOT
+ cp -rH $INSTALL_ROOT/lib $SYSROOT/
+ mkdir $SYSROOT/usr
+ cp -rH $INSTALL_ROOT/usr/lib $SYSROOT/usr/
+ cp -rH $INSTALL_ROOT/usr/include $SYSROOT/usr/
+ pkg -R $INSTALL_ROOT list > $SYSROOT/pkg-list.txt
+else
+ echo "Skipping copying to $SYSROOT"
+fi
+
+if [ ! -d $DEVKIT_ROOT/tools ]; then
+ # Some of the tools in sysroot are needed in the OpenJDK build. We need
+ # to copy them into a tools dir, including their specific libraries.
+ mkdir -p $DEVKIT_ROOT/tools/usr/bin $DEVKIT_ROOT/tools/lib/sparcv9 \
+ $DEVKIT_ROOT/tools/usr/gnu/bin $DEVKIT_ROOT/tools/usr/bin/sparcv9
+ cp $INSTALL_ROOT/usr/bin/{as,ar,nm,strip,ld,pigz,ldd} \
+ $DEVKIT_ROOT/tools/usr/bin/
+ cp $INSTALL_ROOT/usr/sbin/dtrace $DEVKIT_ROOT/tools/usr/bin/
+ cp $INSTALL_ROOT/usr/sbin/sparcv9/dtrace $DEVKIT_ROOT/tools/usr/bin/sparcv9/
+ cp -rH $INSTALL_ROOT/usr/gnu/bin/* $DEVKIT_ROOT/tools/usr/gnu/bin/
+ cp $INSTALL_ROOT/lib/sparcv9/{libelf.so*,libld.so*,liblddbg.so*} $DEVKIT_ROOT/tools/lib/sparcv9/
+ for t in $(ls $DEVKIT_ROOT/tools/usr/gnu/bin); do
+ if [ -f $DEVKIT_ROOT/tools/usr/gnu/bin/$t ]; then
+ ln -s ../gnu/bin/$t $DEVKIT_ROOT/tools/usr/bin/g$t
+ fi
+ done
+else
+ echo "Skipping copying to tools dir $DEVKIT_ROOT/tools"
+fi
+
+if [ ! -d $SOLARIS_STUDIO_DIR ]; then
+ echo "Copying Solaris Studio from $SOLARIS_STUDIO_SRC"
+ mkdir -p ${SOLARIS_STUDIO_DIR}
+ cp -rH $SOLARIS_STUDIO_SRC/. ${SOLARIS_STUDIO_DIR}/
+ # Solaris Studio 12.6 requires libmmheap.so.1 and libsunmath.so.1 to run, but
+ # these libs are not installed by default on all Solaris systems.
+ # Sneak them in from the sysroot to make it run OOTB on more systems.
+ cp $SYSROOT/lib/libsunmath.so.1 $SOLARIS_STUDIO_DIR/lib/compilers/sys/
+ cp $SYSROOT/lib/sparcv9/libsunmath.so.1 $SOLARIS_STUDIO_DIR/lib/compilers/sys/sparcv9/
+ cp $SYSROOT/lib/libmmheap.so.1 $SOLARIS_STUDIO_DIR/lib/compilers/sys/
+ cp $SYSROOT/lib/sparcv9/libmmheap.so.1 $SOLARIS_STUDIO_DIR/lib/compilers/sys/sparcv9/
+else
+ echo "Skipping copying of Solaris Studio"
+fi
+
+# Create the devkit.info file
+echo Creating devkit.info
+INFO_FILE=$DEVKIT_ROOT/devkit.info
+rm -f $INFO_FILE
+echo "# This file describes to configure how to interpret the contents of this devkit" >> $INFO_FILE
+echo "DEVKIT_NAME=\"Solaris Studio $SOLARIS_STUDIO_VERSION - Solaris $SOLARIS_VERSION - $ARCH\"" >> $INFO_FILE
+echo "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/$SOLARIS_STUDIO_SUBDIR/bin:\$DEVKIT_ROOT/bin\"" >> $INFO_FILE
+echo "DEVKIT_EXTRA_PATH=\"\$DEVKIT_ROOT/tools/usr/bin\"" >> $INFO_FILE
+echo "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/sysroot\"" >> $INFO_FILE
+
+if [ ! -e $BUNDLE ]; then
+ GZIP=$(command -v pigz)
+ if [ -z "$GZIP" ]; then
+ GZIP="gzip"
+ fi
+ echo "Creating $BUNDLE from $DEVKIT_ROOT"
+ (cd $DEVKIT_ROOT && tar cf - . | $GZIP - > "$BUNDLE")
+else
+ echo "Skipping creation of $BUNDLE"
+fi
--- a/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk Tue Feb 20 21:46:02 2018 +0100
+++ b/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk Mon Feb 26 09:56:12 2018 +0100
@@ -123,7 +123,7 @@
$(GENSRC_DIR)/module-info.java.extra: $(GENSRC_DIR)/_gensrc_proc_done
($(CD) $(GENSRC_DIR)/META-INF/providers && \
p=""; \
- for i in $$($(LS)); do \
+ for i in $$($(LS) | $(SORT)); do \
c=$$($(CAT) $$i | $(TR) -d '\n\r'); \
if test x$$p != x$$c; then \
if test x$$p != x; then \
@@ -137,7 +137,7 @@
$(ECHO) " ;" >> $@; \
$(ECHO) "uses org.graalvm.compiler.options.OptionDescriptors;" >> $@; \
$(ECHO) "provides org.graalvm.compiler.options.OptionDescriptors with" >> $@; \
- for i in $$($(FIND) $(GENSRC_DIR) -name '*_OptionDescriptors.java'); do \
+ for i in $$($(FIND) $(GENSRC_DIR) -name '*_OptionDescriptors.java' | $(SORT)); do \
c=$$($(ECHO) $$i | $(SED) 's:.*/jdk\.internal\.vm\.compiler/\(.*\)\.java:\1:' | $(TR) '/' '.'); \
$(ECHO) " $$c," >> $@; \
done; \
--- a/make/mapfiles/libjava/mapfile-vers Tue Feb 20 21:46:02 2018 +0100
+++ b/make/mapfiles/libjava/mapfile-vers Mon Feb 26 09:56:12 2018 +0100
@@ -74,11 +74,12 @@
JNU_ThrowStringIndexOutOfBoundsException;
JNU_ToString;
- Java_java_io_FileDescriptor_cleanupClose0;
+ Java_java_io_FileCleanable_cleanupClose0;
Java_java_io_FileDescriptor_close0;
Java_java_io_FileDescriptor_initIDs;
Java_java_io_FileDescriptor_sync;
Java_java_io_FileDescriptor_getAppend;
+ Java_java_io_FileDescriptor_getHandle;
Java_java_io_FileInputStream_available0;
Java_java_io_FileInputStream_initIDs;
Java_java_io_FileInputStream_open0;
@@ -142,7 +143,6 @@
Java_java_lang_StackStreamFactory_checkStackWalkModes;
Java_java_lang_StackStreamFactory_00024AbstractStackWalker_callStackWalk;
Java_java_lang_StackStreamFactory_00024AbstractStackWalker_fetchStackFrames;
- Java_java_lang_Shutdown_runAllFinalizers;
Java_java_lang_StrictMath_IEEEremainder;
Java_java_lang_StrictMath_acos;
Java_java_lang_StrictMath_asin;
@@ -203,7 +203,6 @@
Java_java_lang_Runtime_freeMemory;
Java_java_lang_Runtime_maxMemory;
Java_java_lang_Runtime_gc;
- Java_java_lang_Runtime_runFinalization0;
Java_java_lang_Runtime_totalMemory;
Java_java_lang_Runtime_availableProcessors;
Java_java_lang_SecurityManager_getClassContext;
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -277,6 +277,8 @@
// Add in the index
add(result, result, tmp);
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
+ // The resulting oop is null if the reference is not yet resolved.
+ // It is Universe::the_null_sentinel() if the reference resolved to NULL via condy.
}
void InterpreterMacroAssembler::load_resolved_klass_at_offset(
@@ -399,6 +401,13 @@
str(val, Address(esp, Interpreter::expr_offset_in_bytes(n)));
}
+void InterpreterMacroAssembler::load_float(Address src) {
+ ldrs(v0, src);
+}
+
+void InterpreterMacroAssembler::load_double(Address src) {
+ ldrd(v0, src);
+}
void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
// set sender sp
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -158,6 +158,10 @@
void load_ptr(int n, Register val);
void store_ptr(int n, Register val);
+// Load float value from 'address'. The value is loaded onto the FPU register v0.
+ void load_float(Address src);
+ void load_double(Address src);
+
// Generate a subtype check: branch to ok_is_subtype if sub_klass is
// a subtype of super_klass.
void gen_subtype_check( Register sub_klass, Label &ok_is_subtype );
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -2056,9 +2056,14 @@
}
void MacroAssembler::unimplemented(const char* what) {
- char* b = new char[1024];
- jio_snprintf(b, 1024, "unimplemented: %s", what);
- stop(b);
+ const char* buf = NULL;
+ {
+ ResourceMark rm;
+ stringStream ss;
+ ss.print("unimplemented: %s", what);
+ buf = code_string(ss.as_string());
+ }
+ stop(buf);
}
// If a constant does not fit in an immediate field, generate some
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -370,7 +370,7 @@
void TemplateTable::ldc(bool wide)
{
transition(vtos, vtos);
- Label call_ldc, notFloat, notClass, Done;
+ Label call_ldc, notFloat, notClass, notInt, Done;
if (wide) {
__ get_unsigned_2_byte_index_at_bcp(r1, 1);
@@ -417,20 +417,19 @@
__ b(Done);
__ bind(notFloat);
-#ifdef ASSERT
- {
- Label L;
- __ cmp(r3, JVM_CONSTANT_Integer);
- __ br(Assembler::EQ, L);
- // String and Object are rewritten to fast_aldc
- __ stop("unexpected tag type in ldc");
- __ bind(L);
- }
-#endif
- // itos JVM_CONSTANT_Integer only
+
+ __ cmp(r3, JVM_CONSTANT_Integer);
+ __ br(Assembler::NE, notInt);
+
+ // itos
__ adds(r1, r2, r1, Assembler::LSL, 3);
__ ldrw(r0, Address(r1, base_offset));
__ push_i(r0);
+ __ b(Done);
+
+ __ bind(notInt);
+ condy_helper(Done);
+
__ bind(Done);
}
@@ -441,6 +440,8 @@
Register result = r0;
Register tmp = r1;
+ Register rarg = r2;
+
int index_size = wide ? sizeof(u2) : sizeof(u1);
Label resolved;
@@ -455,12 +456,27 @@
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
// first time invocation - must resolve first
- __ mov(tmp, (int)bytecode());
- __ call_VM(result, entry, tmp);
+ __ mov(rarg, (int)bytecode());
+ __ call_VM(result, entry, rarg);
__ bind(resolved);
+ { // Check for the null sentinel.
+ // If we just called the VM, that already did the mapping for us,
+ // but it's harmless to retry.
+ Label notNull;
+
+ // Stash null_sentinel address to get its value later
+ __ movptr(rarg, (uintptr_t)Universe::the_null_sentinel_addr());
+ __ ldr(tmp, Address(rarg));
+ __ cmp(result, tmp);
+ __ br(Assembler::NE, notNull);
+ __ mov(result, 0); // NULL object reference
+ __ bind(notNull);
+ }
+
if (VerifyOops) {
+ // Safe to call with 0 result
__ verify_oop(result);
}
}
@@ -468,7 +484,7 @@
void TemplateTable::ldc2_w()
{
transition(vtos, vtos);
- Label Long, Done;
+ Label notDouble, notLong, Done;
__ get_unsigned_2_byte_index_at_bcp(r0, 1);
__ get_cpool_and_tags(r1, r2);
@@ -479,22 +495,143 @@
__ lea(r2, Address(r2, r0, Address::lsl(0)));
__ load_unsigned_byte(r2, Address(r2, tags_offset));
__ cmpw(r2, (int)JVM_CONSTANT_Double);
- __ br(Assembler::NE, Long);
+ __ br(Assembler::NE, notDouble);
+
// dtos
__ lea (r2, Address(r1, r0, Address::lsl(3)));
__ ldrd(v0, Address(r2, base_offset));
__ push_d();
__ b(Done);
- __ bind(Long);
+ __ bind(notDouble);
+ __ cmpw(r2, (int)JVM_CONSTANT_Long);
+ __ br(Assembler::NE, notLong);
+
// ltos
__ lea(r0, Address(r1, r0, Address::lsl(3)));
__ ldr(r0, Address(r0, base_offset));
__ push_l();
+ __ b(Done);
+
+ __ bind(notLong);
+ condy_helper(Done);
__ bind(Done);
}
+void TemplateTable::condy_helper(Label& Done)
+{
+ Register obj = r0;
+ Register rarg = r1;
+ Register flags = r2;
+ Register off = r3;
+
+ address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
+
+ __ mov(rarg, (int) bytecode());
+ __ call_VM(obj, entry, rarg);
+
+ __ get_vm_result_2(flags, rthread);
+
+ // VMr = obj = base address to find primitive value to push
+ // VMr2 = flags = (tos, off) using format of CPCE::_flags
+ __ mov(off, flags);
+ __ andw(off, off, ConstantPoolCacheEntry::field_index_mask);
+
+ const Address field(obj, off);
+
+ // What sort of thing are we loading?
+ // x86 uses a shift and mask or wings it with a shift plus assert
+ // the mask is not needed. aarch64 just uses bitfield extract
+ __ ubfxw(flags, flags, ConstantPoolCacheEntry::tos_state_shift,
+ ConstantPoolCacheEntry::tos_state_bits);
+
+ switch (bytecode()) {
+ case Bytecodes::_ldc:
+ case Bytecodes::_ldc_w:
+ {
+ // tos in (itos, ftos, stos, btos, ctos, ztos)
+ Label notInt, notFloat, notShort, notByte, notChar, notBool;
+ __ cmpw(flags, itos);
+ __ br(Assembler::NE, notInt);
+ // itos
+ __ ldrw(r0, field);
+ __ push(itos);
+ __ b(Done);
+
+ __ bind(notInt);
+ __ cmpw(flags, ftos);
+ __ br(Assembler::NE, notFloat);
+ // ftos
+ __ load_float(field);
+ __ push(ftos);
+ __ b(Done);
+
+ __ bind(notFloat);
+ __ cmpw(flags, stos);
+ __ br(Assembler::NE, notShort);
+ // stos
+ __ load_signed_short(r0, field);
+ __ push(stos);
+ __ b(Done);
+
+ __ bind(notShort);
+ __ cmpw(flags, btos);
+ __ br(Assembler::NE, notByte);
+ // btos
+ __ load_signed_byte(r0, field);
+ __ push(btos);
+ __ b(Done);
+
+ __ bind(notByte);
+ __ cmpw(flags, ctos);
+ __ br(Assembler::NE, notChar);
+ // ctos
+ __ load_unsigned_short(r0, field);
+ __ push(ctos);
+ __ b(Done);
+
+ __ bind(notChar);
+ __ cmpw(flags, ztos);
+ __ br(Assembler::NE, notBool);
+ // ztos
+ __ load_signed_byte(r0, field);
+ __ push(ztos);
+ __ b(Done);
+
+ __ bind(notBool);
+ break;
+ }
+
+ case Bytecodes::_ldc2_w:
+ {
+ Label notLong, notDouble;
+ __ cmpw(flags, ltos);
+ __ br(Assembler::NE, notLong);
+ // ltos
+ __ ldr(r0, field);
+ __ push(ltos);
+ __ b(Done);
+
+ __ bind(notLong);
+ __ cmpw(flags, dtos);
+ __ br(Assembler::NE, notDouble);
+ // dtos
+ __ load_double(field);
+ __ push(dtos);
+ __ b(Done);
+
+ __ bind(notDouble);
+ break;
+ }
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ __ stop("bad ldc/condy");
+}
+
void TemplateTable::locals_index(Register reg, int offset)
{
__ ldrb(reg, at_bcp(offset));
--- a/src/hotspot/cpu/ppc/copy_ppc.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/ppc/copy_ppc.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -32,11 +32,11 @@
// Inline functions for memory copy and fill.
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -52,7 +52,7 @@
}
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -70,25 +70,25 @@
}
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
// Template for atomic, element-wise copy.
template <class T>
-static void copy_conjoint_atomic(T* from, T* to, size_t count) {
+static void copy_conjoint_atomic(const T* from, T* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -104,44 +104,44 @@
}
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
// TODO: contribute optimized version.
copy_conjoint_atomic<jshort>(from, to, count);
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
// TODO: contribute optimized version.
copy_conjoint_atomic<jint>(from, to, count);
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
copy_conjoint_atomic<jlong>(from, to, count);
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
copy_conjoint_atomic<oop>(from, to, count);
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_bytes_atomic(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
// TODO: contribute optimized version.
- pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
+ pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
// TODO: contribute optimized version.
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
--- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -492,6 +492,8 @@
// Add in the index.
add(result, tmp, result);
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, is_null);
+ // The resulting oop is null if the reference is not yet resolved.
+ // It is Universe::the_null_sentinel() if the reference resolved to NULL via condy.
}
// load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -314,7 +314,7 @@
Rcpool = R3_ARG1;
transition(vtos, vtos);
- Label notInt, notClass, exit;
+ Label notInt, notFloat, notClass, exit;
__ get_cpool_and_tags(Rcpool, Rscratch2); // Set Rscratch2 = &tags.
if (wide) { // Read index.
@@ -356,13 +356,16 @@
__ align(32, 12);
__ bind(notInt);
-#ifdef ASSERT
- // String and Object are rewritten to fast_aldc
__ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float);
- __ asm_assert_eq("unexpected type", 0x8765);
-#endif
+ __ bne(CCR0, notFloat);
__ lfsx(F15_ftos, Rcpool, Rscratch1);
__ push(ftos);
+ __ b(exit);
+
+ __ align(32, 12);
+ // assume the tag is for condy; if not, the VM runtime will tell us
+ __ bind(notFloat);
+ condy_helper(exit);
__ align(32, 12);
__ bind(exit);
@@ -380,6 +383,19 @@
// non-null object (CallSite, etc.)
__ get_cache_index_at_bcp(Rscratch, 1, index_size); // Load index.
__ load_resolved_reference_at_index(R17_tos, Rscratch, &is_null);
+
+ // Convert null sentinel to NULL.
+ int simm16_rest = __ load_const_optimized(Rscratch, Universe::the_null_sentinel_addr(), R0, true);
+ __ ld(Rscratch, simm16_rest, Rscratch);
+ __ cmpld(CCR0, R17_tos, Rscratch);
+ if (VM_Version::has_isel()) {
+ __ isel_0(R17_tos, CCR0, Assembler::equal);
+ } else {
+ Label not_sentinel;
+ __ bne(CCR0, not_sentinel);
+ __ li(R17_tos, 0);
+ __ bind(not_sentinel);
+ }
__ verify_oop(R17_tos);
__ dispatch_epilog(atos, Bytecodes::length_for(bytecode()));
@@ -395,7 +411,7 @@
void TemplateTable::ldc2_w() {
transition(vtos, vtos);
- Label Llong, Lexit;
+ Label not_double, not_long, exit;
Register Rindex = R11_scratch1,
Rcpool = R12_scratch2,
@@ -410,23 +426,129 @@
__ addi(Rtag, Rtag, tags_offset);
__ lbzx(Rtag, Rtag, Rindex);
-
__ sldi(Rindex, Rindex, LogBytesPerWord);
+
__ cmpdi(CCR0, Rtag, JVM_CONSTANT_Double);
- __ bne(CCR0, Llong);
- // A double can be placed at word-aligned locations in the constant pool.
- // Check out Conversions.java for an example.
- // Also ConstantPool::header_size() is 20, which makes it very difficult
- // to double-align double on the constant pool. SG, 11/7/97
+ __ bne(CCR0, not_double);
__ lfdx(F15_ftos, Rcpool, Rindex);
__ push(dtos);
- __ b(Lexit);
-
- __ bind(Llong);
+ __ b(exit);
+
+ __ bind(not_double);
+ __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Long);
+ __ bne(CCR0, not_long);
__ ldx(R17_tos, Rcpool, Rindex);
__ push(ltos);
-
- __ bind(Lexit);
+ __ b(exit);
+
+ __ bind(not_long);
+ condy_helper(exit);
+
+ __ align(32, 12);
+ __ bind(exit);
+}
+
+void TemplateTable::condy_helper(Label& Done) {
+ const Register obj = R31;
+ const Register off = R11_scratch1;
+ const Register flags = R12_scratch2;
+ const Register rarg = R4_ARG2;
+ __ li(rarg, (int)bytecode());
+ call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg);
+ __ get_vm_result_2(flags);
+
+ // VMr = obj = base address to find primitive value to push
+ // VMr2 = flags = (tos, off) using format of CPCE::_flags
+ __ andi(off, flags, ConstantPoolCacheEntry::field_index_mask);
+
+ // What sort of thing are we loading?
+ __ rldicl(flags, flags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+
+ switch (bytecode()) {
+ case Bytecodes::_ldc:
+ case Bytecodes::_ldc_w:
+ {
+ // tos in (itos, ftos, stos, btos, ctos, ztos)
+ Label notInt, notFloat, notShort, notByte, notChar, notBool;
+ __ cmplwi(CCR0, flags, itos);
+ __ bne(CCR0, notInt);
+ // itos
+ __ lwax(R17_tos, obj, off);
+ __ push(itos);
+ __ b(Done);
+
+ __ bind(notInt);
+ __ cmplwi(CCR0, flags, ftos);
+ __ bne(CCR0, notFloat);
+ // ftos
+ __ lfsx(F15_ftos, obj, off);
+ __ push(ftos);
+ __ b(Done);
+
+ __ bind(notFloat);
+ __ cmplwi(CCR0, flags, stos);
+ __ bne(CCR0, notShort);
+ // stos
+ __ lhax(R17_tos, obj, off);
+ __ push(stos);
+ __ b(Done);
+
+ __ bind(notShort);
+ __ cmplwi(CCR0, flags, btos);
+ __ bne(CCR0, notByte);
+ // btos
+ __ lbzx(R17_tos, obj, off);
+ __ extsb(R17_tos, R17_tos);
+ __ push(btos);
+ __ b(Done);
+
+ __ bind(notByte);
+ __ cmplwi(CCR0, flags, ctos);
+ __ bne(CCR0, notChar);
+ // ctos
+ __ lhzx(R17_tos, obj, off);
+ __ push(ctos);
+ __ b(Done);
+
+ __ bind(notChar);
+ __ cmplwi(CCR0, flags, ztos);
+ __ bne(CCR0, notBool);
+ // ztos
+ __ lbzx(R17_tos, obj, off);
+ __ push(ztos);
+ __ b(Done);
+
+ __ bind(notBool);
+ break;
+ }
+
+ case Bytecodes::_ldc2_w:
+ {
+ Label notLong, notDouble;
+ __ cmplwi(CCR0, flags, ltos);
+ __ bne(CCR0, notLong);
+ // ltos
+ __ ldx(R17_tos, obj, off);
+ __ push(ltos);
+ __ b(Done);
+
+ __ bind(notLong);
+ __ cmplwi(CCR0, flags, dtos);
+ __ bne(CCR0, notDouble);
+ // dtos
+ __ lfdx(F15_ftos, obj, off);
+ __ push(dtos);
+ __ b(Done);
+
+ __ bind(notDouble);
+ break;
+ }
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ __ stop("bad ldc/condy");
}
// Get the locals index located in the bytecode stream at bcp + offset.
--- a/src/hotspot/cpu/s390/copy_s390.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/s390/copy_s390.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -73,7 +73,7 @@
#undef USE_INLINE_ASM
-static void copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -89,7 +89,7 @@
}
}
-static void copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -105,7 +105,7 @@
}
}
-static bool has_destructive_overlap(char* from, char* to, size_t byte_count) {
+static bool has_destructive_overlap(const char* from, char* to, size_t byte_count) {
return (from < to) && ((to-from) < (ptrdiff_t)byte_count);
}
@@ -662,7 +662,7 @@
// D I S J O I N T C O P Y I N G //
//*************************************//
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
// JVM2008: very frequent, some tests frequent.
// Copy HeapWord (=DW) aligned storage. Use MVCLE in inline-asm code.
@@ -740,13 +740,13 @@
#endif
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
// JVM2008: < 4k calls.
assert(((((size_t)from) & 0x07L) | (((size_t)to) & 0x07L)) == 0, "No atomic copy w/o aligned data");
pd_aligned_disjoint_words(from, to, count); // Rare calls -> just delegate.
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
// JVM2008: very rare.
pd_aligned_disjoint_words(from, to, count); // Rare calls -> just delegate.
}
@@ -756,7 +756,7 @@
// C O N J O I N T C O P Y I N G //
//*************************************//
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
// JVM2008: between some and lower end of frequent.
#ifdef USE_INLINE_ASM
@@ -836,13 +836,13 @@
#endif
}
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
// Just delegate. HeapWords are optimally aligned anyway.
pd_aligned_conjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
#ifdef USE_INLINE_ASM
size_t count_in = count;
@@ -866,16 +866,16 @@
// C O N J O I N T A T O M I C C O P Y I N G //
//**************************************************//
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
// Call arraycopy stubs to do the job.
pd_conjoint_bytes(from, to, count); // bytes are always accessed atomically.
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
#ifdef USE_INLINE_ASM
size_t count_in = count;
- if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerShort)) {
+ if (has_destructive_overlap((const char*)from, (char*)to, count_in*BytesPerShort)) {
// Use optimizations from shared code where no z-specific optimization exists.
copy_conjoint_jshorts_atomic(from, to, count);
} else {
@@ -890,11 +890,11 @@
#endif
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
#ifdef USE_INLINE_ASM
size_t count_in = count;
- if (has_destructive_overlap((char*)from, (char*)to, count_in*BytesPerInt)) {
+ if (has_destructive_overlap((const char*)from, (char*)to, count_in*BytesPerInt)) {
switch (count_in) {
case 4: COPY4_ATOMIC_4(to,from)
return;
@@ -922,7 +922,7 @@
#endif
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
#ifdef USE_INLINE_ASM
size_t count_in = count;
@@ -970,11 +970,11 @@
}
}
else
- pd_aligned_disjoint_words((HeapWord*)from, (HeapWord*)to, count_in); // rare calls -> just delegate.
+ pd_aligned_disjoint_words((const HeapWord*)from, (HeapWord*)to, count_in); // rare calls -> just delegate.
#endif
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
#ifdef USE_INLINE_ASM
size_t count_in = count;
@@ -1011,24 +1011,24 @@
#endif
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_bytes_atomic(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
//**********************************************//
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -389,6 +389,8 @@
#endif
z_agr(result, index); // Address of indexed array element.
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
+ // The resulting oop is null if the reference is not yet resolved.
+ // It is Universe::the_null_sentinel() if the reference resolved to NULL via condy.
}
// load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -450,7 +450,7 @@
void TemplateTable::ldc(bool wide) {
transition(vtos, vtos);
- Label call_ldc, notFloat, notClass, Done;
+ Label call_ldc, notFloat, notClass, notInt, Done;
const Register RcpIndex = Z_tmp_1;
const Register Rtags = Z_ARG2;
@@ -500,22 +500,17 @@
__ z_bru(Done);
__ bind(notFloat);
-#ifdef ASSERT
- {
- Label L;
-
- __ z_cli(0, Raddr_type, JVM_CONSTANT_Integer);
- __ z_bre(L);
- // String and Object are rewritten to fast_aldc.
- __ stop("unexpected tag type in ldc");
-
- __ bind(L);
- }
-#endif
+ __ z_cli(0, Raddr_type, JVM_CONSTANT_Integer);
+ __ z_brne(notInt);
// itos
__ mem2reg_opt(Z_tos, Address(Z_tmp_2, RcpOffset, base_offset), false);
__ push_i(Z_tos);
+ __ z_bru(Done);
+
+ // assume the tag is for condy; if not, the VM runtime will tell us
+ __ bind(notInt);
+ condy_helper(Done);
__ bind(Done);
}
@@ -528,15 +523,23 @@
const Register index = Z_tmp_2;
int index_size = wide ? sizeof(u2) : sizeof(u1);
- Label L_resolved;
+ Label L_do_resolve, L_resolved;
// We are resolved if the resolved reference cache entry contains a
// non-null object (CallSite, etc.).
__ get_cache_index_at_bcp(index, 1, index_size); // Load index.
__ load_resolved_reference_at_index(Z_tos, index);
__ z_ltgr(Z_tos, Z_tos);
+ __ z_bre(L_do_resolve);
+
+ // Convert null sentinel to NULL.
+ __ load_const_optimized(Z_R1_scratch, (intptr_t)Universe::the_null_sentinel_addr());
+ __ z_cg(Z_tos, Address(Z_R1_scratch));
__ z_brne(L_resolved);
-
+ __ clear_reg(Z_tos);
+ __ z_bru(L_resolved);
+
+ __ bind(L_do_resolve);
// First time invocation - must resolve first.
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
__ load_const_optimized(Z_ARG1, (int)bytecode());
@@ -548,7 +551,7 @@
void TemplateTable::ldc2_w() {
transition(vtos, vtos);
- Label Long, Done;
+ Label notDouble, notLong, Done;
// Z_tmp_1 = index of cp entry
__ get_2_byte_integer_at_bcp(Z_tmp_1, 1, InterpreterMacroAssembler::Unsigned);
@@ -566,21 +569,132 @@
// Check type.
__ z_cli(0, Z_tos, JVM_CONSTANT_Double);
- __ z_brne(Long);
-
+ __ z_brne(notDouble);
// dtos
__ mem2freg_opt(Z_ftos, Address(Z_tmp_2, Z_tmp_1, base_offset));
__ push_d();
__ z_bru(Done);
- __ bind(Long);
+ __ bind(notDouble);
+ __ z_cli(0, Z_tos, JVM_CONSTANT_Long);
+ __ z_brne(notLong);
// ltos
__ mem2reg_opt(Z_tos, Address(Z_tmp_2, Z_tmp_1, base_offset));
__ push_l();
+ __ z_bru(Done);
+
+ __ bind(notLong);
+ condy_helper(Done);
__ bind(Done);
}
+void TemplateTable::condy_helper(Label& Done) {
+ const Register obj = Z_tmp_1;
+ const Register off = Z_tmp_2;
+ const Register flags = Z_ARG1;
+ const Register rarg = Z_ARG2;
+ __ load_const_optimized(rarg, (int)bytecode());
+ call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg);
+ __ get_vm_result_2(flags);
+
+ // VMr = obj = base address to find primitive value to push
+ // VMr2 = flags = (tos, off) using format of CPCE::_flags
+ assert(ConstantPoolCacheEntry::field_index_mask == 0xffff, "or use other instructions");
+ __ z_llghr(off, flags);
+ const Address field(obj, off);
+
+ // What sort of thing are we loading?
+ __ z_srl(flags, ConstantPoolCacheEntry::tos_state_shift);
+ // Make sure we don't need to mask flags for tos_state after the above shift.
+ ConstantPoolCacheEntry::verify_tos_state_shift();
+
+ switch (bytecode()) {
+ case Bytecodes::_ldc:
+ case Bytecodes::_ldc_w:
+ {
+ // tos in (itos, ftos, stos, btos, ctos, ztos)
+ Label notInt, notFloat, notShort, notByte, notChar, notBool;
+ __ z_cghi(flags, itos);
+ __ z_brne(notInt);
+ // itos
+ __ z_l(Z_tos, field);
+ __ push(itos);
+ __ z_bru(Done);
+
+ __ bind(notInt);
+ __ z_cghi(flags, ftos);
+ __ z_brne(notFloat);
+ // ftos
+ __ z_le(Z_ftos, field);
+ __ push(ftos);
+ __ z_bru(Done);
+
+ __ bind(notFloat);
+ __ z_cghi(flags, stos);
+ __ z_brne(notShort);
+ // stos
+ __ z_lh(Z_tos, field);
+ __ push(stos);
+ __ z_bru(Done);
+
+ __ bind(notShort);
+ __ z_cghi(flags, btos);
+ __ z_brne(notByte);
+ // btos
+ __ z_lb(Z_tos, field);
+ __ push(btos);
+ __ z_bru(Done);
+
+ __ bind(notByte);
+ __ z_cghi(flags, ctos);
+ __ z_brne(notChar);
+ // ctos
+ __ z_llh(Z_tos, field);
+ __ push(ctos);
+ __ z_bru(Done);
+
+ __ bind(notChar);
+ __ z_cghi(flags, ztos);
+ __ z_brne(notBool);
+ // ztos
+ __ z_lb(Z_tos, field);
+ __ push(ztos);
+ __ z_bru(Done);
+
+ __ bind(notBool);
+ break;
+ }
+
+ case Bytecodes::_ldc2_w:
+ {
+ Label notLong, notDouble;
+ __ z_cghi(flags, ltos);
+ __ z_brne(notLong);
+ // ltos
+ __ z_lg(Z_tos, field);
+ __ push(ltos);
+ __ z_bru(Done);
+
+ __ bind(notLong);
+ __ z_cghi(flags, dtos);
+ __ z_brne(notDouble);
+ // dtos
+ __ z_ld(Z_ftos, field);
+ __ push(dtos);
+ __ z_bru(Done);
+
+ __ bind(notDouble);
+ break;
+ }
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ __ stop("bad ldc/condy");
+}
+
void TemplateTable::locals_index(Register reg, int offset) {
__ z_llgc(reg, at_bcp(offset));
__ z_lcgr(reg);
--- a/src/hotspot/cpu/sparc/copy_sparc.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/sparc/copy_sparc.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,11 +27,11 @@
// Inline functions for memory copy and fill.
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -47,7 +47,7 @@
}
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -65,23 +65,23 @@
}
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -97,7 +97,7 @@
}
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -113,12 +113,12 @@
}
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
// Do better than this: inline memmove body NEEDS CLEANUP
if (from > to) {
while (count-- > 0) {
@@ -135,24 +135,24 @@
}
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_bytes_atomic(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1411,9 +1411,14 @@
void MacroAssembler::unimplemented(const char* what) {
- char* b = new char[1024];
- jio_snprintf(b, 1024, "unimplemented: %s", what);
- stop(b);
+ const char* buf = NULL;
+ {
+ ResourceMark rm;
+ stringStream ss;
+ ss.print("unimplemented: %s", what);
+ buf = code_string(ss.as_string());
+ }
+ stop(buf);
}
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -3660,9 +3660,14 @@
}
void MacroAssembler::unimplemented(const char* what) {
- char* b = new char[1024];
- jio_snprintf(b, 1024, "unimplemented: %s", what);
- stop(b);
+ const char* buf = NULL;
+ {
+ ResourceMark rm;
+ stringStream ss;
+ ss.print("unimplemented: %s", what);
+ buf = code_string(ss.as_string());
+ }
+ stop(buf);
}
#ifdef _LP64
--- a/src/hotspot/cpu/zero/copy_zero.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/cpu/zero/copy_zero.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -28,11 +28,11 @@
// Inline functions for memory copy and fill.
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
memmove(to, from, count * HeapWordSize);
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -49,7 +49,7 @@
}
}
-static void pd_disjoint_words_atomic(HeapWord* from,
+static void pd_disjoint_words_atomic(const HeapWord* from,
HeapWord* to,
size_t count) {
switch (count) {
@@ -70,73 +70,73 @@
}
}
-static void pd_aligned_conjoint_words(HeapWord* from,
+static void pd_aligned_conjoint_words(const HeapWord* from,
HeapWord* to,
size_t count) {
memmove(to, from, count * HeapWordSize);
}
-static void pd_aligned_disjoint_words(HeapWord* from,
+static void pd_aligned_disjoint_words(const HeapWord* from,
HeapWord* to,
size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
memmove(to, from, count);
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
memmove(to, from, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
_Copy_conjoint_jshorts_atomic(from, to, count);
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
_Copy_conjoint_jints_atomic(from, to, count);
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
_Copy_conjoint_jlongs_atomic(from, to, count);
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
#ifdef _LP64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#else
assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size");
- _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ _Copy_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
#endif // _LP64
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from,
+static void pd_arrayof_conjoint_bytes(const HeapWord* from,
HeapWord* to,
size_t count) {
_Copy_arrayof_conjoint_bytes(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from,
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from,
HeapWord* to,
size_t count) {
_Copy_arrayof_conjoint_jshorts(from, to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from,
+static void pd_arrayof_conjoint_jints(const HeapWord* from,
HeapWord* to,
size_t count) {
_Copy_arrayof_conjoint_jints(from, to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from,
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from,
HeapWord* to,
size_t count) {
_Copy_arrayof_conjoint_jlongs(from, to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from,
+static void pd_arrayof_conjoint_oops(const HeapWord* from,
HeapWord* to,
size_t count) {
#ifdef _LP64
--- a/src/hotspot/os/linux/decoder_linux.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os/linux/decoder_linux.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include "jvm.h"
#include "utilities/decoder_elf.hpp"
+#include "utilities/elfFile.hpp"
#include <cxxabi.h>
@@ -50,3 +51,38 @@
return false;
}
+// Returns true if the elf file is marked NOT to require an executable stack,
+// or if the file could not be opened.
+// Returns false if the elf file requires an executable stack, the stack flag
+// is not set at all, or if the file can not be read.
+bool ElfFile::specifies_noexecstack(const char* filepath) {
+ if (filepath == NULL) return true;
+
+ FILE* file = fopen(filepath, "r");
+ if (file == NULL) return true;
+
+ // AARCH64 defaults to noexecstack. All others default to execstack.
+ bool result = AARCH64_ONLY(true) NOT_AARCH64(false);
+
+ // Read file header
+ Elf_Ehdr head;
+ if (fread(&head, sizeof(Elf_Ehdr), 1, file) == 1 &&
+ is_elf_file(head) &&
+ fseek(file, head.e_phoff, SEEK_SET) == 0) {
+
+ // Read program header table
+ Elf_Phdr phdr;
+ for (int index = 0; index < head.e_phnum; index ++) {
+ if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, file) != 1) {
+ result = false;
+ break;
+ }
+ if (phdr.p_type == PT_GNU_STACK) {
+ result = (phdr.p_flags == (PF_R | PF_W));
+ break;
+ }
+ }
+ }
+ fclose(file);
+ return result;
+}
--- a/src/hotspot/os/windows/globals_windows.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os/windows/globals_windows.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,7 @@
notproduct, \
range, \
constraint, \
- writeable) \
- \
- product(bool, UseUTCFileTimestamp, true, \
- "Adjust the timestamp returned from stat() to be UTC")
+ writeable)
//
--- a/src/hotspot/os_cpu/bsd_x86/copy_bsd_x86.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os_cpu/bsd_x86/copy_bsd_x86.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
#ifndef OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
(void)memmove(to, from, count * HeapWordSize);
#else
@@ -70,7 +70,7 @@
#endif // AMD64
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
switch (count) {
case 8: to[7] = from[7];
@@ -108,7 +108,7 @@
#endif // AMD64
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
switch (count) {
case 8: to[7] = from[7];
@@ -132,15 +132,15 @@
#endif // AMD64
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_words(from, to, count);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
#ifdef AMD64
(void)memmove(to, from, count);
#else
@@ -219,25 +219,25 @@
#endif // AMD64
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
_Copy_conjoint_jshorts_atomic(from, to, count);
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
#ifdef AMD64
_Copy_conjoint_jints_atomic(from, to, count);
#else
assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size");
// pd_conjoint_words is word-atomic in this implementation.
- pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
+ pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#endif // AMD64
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
#ifdef AMD64
_Copy_conjoint_jlongs_atomic(from, to, count);
#else
@@ -262,47 +262,47 @@
#endif // AMD64
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#else
assert(HeapWordSize == BytesPerOop, "heapwords and oops must be the same size");
// pd_conjoint_words is word-atomic in this implementation.
- pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
+ pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_bytes(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jshorts(from, to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
_Copy_arrayof_conjoint_jints(from, to, count);
#else
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
_Copy_arrayof_conjoint_jlongs(from, to, count);
#else
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
_Copy_arrayof_conjoint_jlongs(from, to, count);
#else
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
#endif // AMD64
}
--- a/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os_cpu/linux_aarch64/copy_linux_aarch64.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -99,7 +99,7 @@
: "memory", "cc"); \
}
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
__asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory");
if (__builtin_expect(count <= 8, 1)) {
COPY_SMALL(from, to, count);
@@ -108,7 +108,7 @@
_Copy_conjoint_words(from, to, count);
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
if (__builtin_constant_p(count)) {
memcpy(to, from, count * sizeof(HeapWord));
return;
@@ -121,7 +121,7 @@
_Copy_disjoint_words(from, to, count);
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
__asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory");
if (__builtin_expect(count <= 8, 1)) {
COPY_SMALL(from, to, count);
@@ -130,56 +130,56 @@
_Copy_disjoint_words(from, to, count);
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_words(from, to, count);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
_Copy_conjoint_jshorts_atomic(from, to, count);
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
_Copy_conjoint_jints_atomic(from, to, count);
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
_Copy_conjoint_jlongs_atomic(from, to, count);
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_bytes(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jshorts(from, to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jints(from, to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jlongs(from, to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
assert(!UseCompressedOops, "foo!");
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
_Copy_arrayof_conjoint_jlongs(from, to, count);
--- a/src/hotspot/os_cpu/linux_arm/copy_linux_arm.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os_cpu/linux_arm/copy_linux_arm.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
#ifndef OS_CPU_LINUX_ARM_VM_COPY_LINUX_ARM_INLINE_HPP
#define OS_CPU_LINUX_ARM_VM_COPY_LINUX_ARM_INLINE_HPP
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AARCH64
_Copy_conjoint_words(from, to, count * HeapWordSize);
#else
@@ -34,7 +34,7 @@
#endif
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AARCH64
_Copy_disjoint_words(from, to, count * HeapWordSize);
#else
@@ -42,27 +42,27 @@
#endif // AARCH64
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_words(from, to, count);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
memmove(to, from, count);
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
#ifdef AARCH64
_Copy_conjoint_jshorts_atomic(from, to, count * BytesPerShort);
#else
@@ -70,58 +70,58 @@
#endif
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
#ifdef AARCH64
_Copy_conjoint_jints_atomic(from, to, count * BytesPerInt);
#else
assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size");
// pd_conjoint_words is word-atomic in this implementation.
- pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
+ pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#endif
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
#ifdef AARCH64
assert(HeapWordSize == BytesPerLong, "64-bit architecture");
- pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
+ pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#else
_Copy_conjoint_jlongs_atomic(to, from, count * BytesPerLong);
#endif
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
#ifdef AARCH64
if (UseCompressedOops) {
assert(BytesPerHeapOop == BytesPerInt, "compressed oops");
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
} else {
assert(BytesPerHeapOop == BytesPerLong, "64-bit architecture");
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
#else
assert(BytesPerHeapOop == BytesPerInt, "32-bit architecture");
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
#endif
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_bytes_atomic((void*)from, (void*)to, count);
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_bytes_atomic((const void*)from, (void*)to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
#endif // OS_CPU_LINUX_ARM_VM_COPY_LINUX_ARM_INLINE_HPP
--- a/src/hotspot/os_cpu/linux_x86/copy_linux_x86.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os_cpu/linux_x86/copy_linux_x86.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
#ifndef OS_CPU_LINUX_X86_VM_COPY_LINUX_X86_INLINE_HPP
#define OS_CPU_LINUX_X86_VM_COPY_LINUX_X86_INLINE_HPP
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
(void)memmove(to, from, count * HeapWordSize);
#else
@@ -70,7 +70,7 @@
#endif // AMD64
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
switch (count) {
case 8: to[7] = from[7];
@@ -108,7 +108,7 @@
#endif // AMD64
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
switch (count) {
case 8: to[7] = from[7];
@@ -132,15 +132,15 @@
#endif // AMD64
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_conjoint_words(from, to, count);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
#ifdef AMD64
(void)memmove(to, from, count);
#else
@@ -219,25 +219,25 @@
#endif // AMD64
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
_Copy_conjoint_jshorts_atomic(from, to, count);
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
#ifdef AMD64
_Copy_conjoint_jints_atomic(from, to, count);
#else
assert(HeapWordSize == BytesPerInt, "heapwords and jints must be the same size");
// pd_conjoint_words is word-atomic in this implementation.
- pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
+ pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#endif // AMD64
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
#ifdef AMD64
_Copy_conjoint_jlongs_atomic(from, to, count);
#else
@@ -262,47 +262,47 @@
#endif // AMD64
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#else
assert(HeapWordSize == BytesPerOop, "heapwords and oops must be the same size");
// pd_conjoint_words is word-atomic in this implementation.
- pd_conjoint_words((HeapWord*)from, (HeapWord*)to, count);
+ pd_conjoint_words((const HeapWord*)from, (HeapWord*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_bytes(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jshorts(from, to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
_Copy_arrayof_conjoint_jints(from, to, count);
#else
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
_Copy_arrayof_conjoint_jlongs(from, to, count);
#else
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
_Copy_arrayof_conjoint_jlongs(from, to, count);
#else
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
#endif // AMD64
}
--- a/src/hotspot/os_cpu/solaris_x86/copy_solaris_x86.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os_cpu/solaris_x86/copy_solaris_x86.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
#ifndef OS_CPU_SOLARIS_X86_VM_COPY_SOLARIS_X86_INLINE_HPP
#define OS_CPU_SOLARIS_X86_VM_COPY_SOLARIS_X86_INLINE_HPP
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifndef AMD64
(void)memcpy(to, from, count * HeapWordSize);
#else
@@ -50,7 +50,7 @@
#endif // AMD64
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -68,15 +68,15 @@
}
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
#ifdef AMD64
(void)memmove(to, from, count);
#else
@@ -84,53 +84,53 @@
#endif // AMD64
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
_Copy_conjoint_jshorts_atomic(from, to, count);
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
_Copy_conjoint_jints_atomic(from, to, count);
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
// Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't.
_Copy_conjoint_jlongs_atomic(from, to, count);
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ _Copy_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#else
- _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ _Copy_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_bytes(from, to, count);
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jshorts(from, to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
_Copy_arrayof_conjoint_jints(from, to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
_Copy_arrayof_conjoint_jlongs(from, to, count);
#else
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
#endif // AMD64
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
_Copy_arrayof_conjoint_jlongs(from, to, count);
--- a/src/hotspot/os_cpu/windows_x86/copy_windows_x86.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/os_cpu/windows_x86/copy_windows_x86.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
#ifndef OS_CPU_WINDOWS_X86_VM_COPY_WINDOWS_X86_INLINE_HPP
#define OS_CPU_WINDOWS_X86_VM_COPY_WINDOWS_X86_INLINE_HPP
-static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
switch (count) {
case 8: to[7] = from[7];
@@ -50,7 +50,7 @@
#endif // AMD64
}
-static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
switch (count) {
case 8: to[7] = from[7];
case 7: to[6] = from[6];
@@ -68,23 +68,23 @@
}
}
-static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
(void)memmove(to, from, count * HeapWordSize);
}
-static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
pd_disjoint_words(from, to, count);
}
-static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes(const void* from, void* to, size_t count) {
(void)memmove(to, from, count);
}
-static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
-static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -100,7 +100,7 @@
}
}
-static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
if (from > to) {
while (count-- > 0) {
// Copy forwards
@@ -116,10 +116,10 @@
}
}
-static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
#ifdef AMD64
assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
#else
// Guarantee use of fild/fistp or xmm regs via some asm code, because compilers won't.
__asm {
@@ -149,7 +149,7 @@
#endif // AMD64
}
-static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
// Do better than this: inline memmove body NEEDS CLEANUP
if (from > to) {
while (count-- > 0) {
@@ -166,7 +166,7 @@
}
}
-static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
+static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
pd_conjoint_bytes_atomic(from, to, count);
#else
@@ -174,20 +174,20 @@
#endif // AMD64
}
-static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jshorts_atomic((jshort*)from, (jshort*)to, count);
+static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count);
}
-static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
-static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count);
}
-static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
- pd_conjoint_oops_atomic((oop*)from, (oop*)to, count);
+static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
+ pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count);
}
#endif // OS_CPU_WINDOWS_X86_VM_COPY_WINDOWS_X86_INLINE_HPP
--- a/src/hotspot/share/classfile/compactHashtable.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/classfile/compactHashtable.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -146,27 +146,23 @@
cht->init(base_address, _num_entries, _num_buckets,
_compact_buckets->data(), _compact_entries->data());
- if (log_is_enabled(Info, cds, hashtables)) {
- ResourceMark rm;
- LogMessage(cds, hashtables) msg;
- stringStream info_stream;
-
+ LogMessage(cds, hashtables) msg;
+ if (msg.is_info()) {
double avg_cost = 0.0;
if (_num_entries > 0) {
avg_cost = double(table_bytes)/double(_num_entries);
}
- info_stream.print_cr("Shared %s table stats -------- base: " PTR_FORMAT,
+ msg.info("Shared %s table stats -------- base: " PTR_FORMAT,
table_name, (intptr_t)base_address);
- info_stream.print_cr("Number of entries : %9d", _num_entries);
- info_stream.print_cr("Total bytes used : %9d", table_bytes);
- info_stream.print_cr("Average bytes per entry : %9.3f", avg_cost);
- info_stream.print_cr("Average bucket size : %9.3f", summary.avg());
- info_stream.print_cr("Variance of bucket size : %9.3f", summary.variance());
- info_stream.print_cr("Std. dev. of bucket size: %9.3f", summary.sd());
- info_stream.print_cr("Empty buckets : %9d", _num_empty_buckets);
- info_stream.print_cr("Value_Only buckets : %9d", _num_value_only_buckets);
- info_stream.print_cr("Other buckets : %9d", _num_other_buckets);
- msg.info("%s", info_stream.as_string());
+ msg.info("Number of entries : %9d", _num_entries);
+ msg.info("Total bytes used : %9d", table_bytes);
+ msg.info("Average bytes per entry : %9.3f", avg_cost);
+ msg.info("Average bucket size : %9.3f", summary.avg());
+ msg.info("Variance of bucket size : %9.3f", summary.variance());
+ msg.info("Std. dev. of bucket size: %9.3f", summary.sd());
+ msg.info("Empty buckets : %9d", _num_empty_buckets);
+ msg.info("Value_Only buckets : %9d", _num_value_only_buckets);
+ msg.info("Other buckets : %9d", _num_other_buckets);
}
}
--- a/src/hotspot/share/classfile/vmSymbols.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/classfile/vmSymbols.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -358,7 +358,6 @@
template(reference_lock_name, "lock") \
template(reference_discovered_name, "discovered") \
template(run_finalization_name, "runFinalization") \
- template(run_finalizers_on_exit_name, "runFinalizersOnExit") \
template(dispatchUncaughtException_name, "dispatchUncaughtException") \
template(loadClass_name, "loadClass") \
template(loadClassInternal_name, "loadClassInternal") \
--- a/src/hotspot/share/code/compiledMethod.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/code/compiledMethod.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -439,11 +439,11 @@
}
void CompiledMethod::set_unloading_clock(unsigned char unloading_clock) {
- OrderAccess::release_store((volatile jubyte*)&_unloading_clock, unloading_clock);
+ OrderAccess::release_store(&_unloading_clock, unloading_clock);
}
unsigned char CompiledMethod::unloading_clock() {
- return (unsigned char)OrderAccess::load_acquire((volatile jubyte*)&_unloading_clock);
+ return OrderAccess::load_acquire(&_unloading_clock);
}
// Processing of oop references should have been sufficient to keep
--- a/src/hotspot/share/code/dependencyContext.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/code/dependencyContext.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -270,5 +270,5 @@
#endif //PRODUCT
int nmethodBucket::decrement() {
- return Atomic::add(-1, (volatile int *)&_count);
+ return Atomic::sub(1, &_count);
}
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,10 +75,6 @@
// supports. Caller does not hold the Heap_lock on entry.
void collect(GCCause::Cause cause);
- bool card_mark_must_follow_store() const {
- return true;
- }
-
void stop();
void safepoint_synchronize_begin();
void safepoint_synchronize_end();
--- a/src/hotspot/share/gc/g1/collectionSetChooser.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/collectionSetChooser.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -138,7 +138,7 @@
G1PrintRegionLivenessInfoClosure cl("Post-Sorting");
for (uint i = 0; i < _end; ++i) {
HeapRegion* r = regions_at(i);
- cl.doHeapRegion(r);
+ cl.do_heap_region(r);
}
}
verify();
@@ -220,7 +220,7 @@
_g1h(G1CollectedHeap::heap()),
_cset_updater(hrSorted, true /* parallel */, chunk_size) { }
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
// Do we have any marking information for this region?
if (r->is_marked()) {
// We will skip any region that's currently used as an old GC
--- a/src/hotspot/share/gc/g1/g1Allocator.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1Allocator.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -134,9 +134,6 @@
_old_is_full = true;
}
-G1PLAB::G1PLAB(size_t gclab_word_size) :
- PLAB(gclab_word_size), _retired(true) { }
-
size_t G1Allocator::unsafe_max_tlab_alloc(AllocationContext_t context) {
// Return the remaining space in the cur alloc region, but not less than
// the min TLAB size.
@@ -253,7 +250,7 @@
if ((required_in_plab <= plab_word_size) &&
may_throw_away_buffer(required_in_plab, plab_word_size)) {
- G1PLAB* alloc_buf = alloc_buffer(dest, context);
+ PLAB* alloc_buf = alloc_buffer(dest, context);
alloc_buf->retire();
size_t actual_plab_size = 0;
@@ -304,7 +301,7 @@
void G1DefaultPLABAllocator::flush_and_retire_stats() {
for (uint state = 0; state < InCSetState::Num; state++) {
- G1PLAB* const buf = _alloc_buffers[state];
+ PLAB* const buf = _alloc_buffers[state];
if (buf != NULL) {
G1EvacStats* stats = _g1h->alloc_buffer_stats(state);
buf->flush_and_retire_stats(stats);
@@ -318,7 +315,7 @@
wasted = 0;
undo_wasted = 0;
for (uint state = 0; state < InCSetState::Num; state++) {
- G1PLAB * const buf = _alloc_buffers[state];
+ PLAB * const buf = _alloc_buffers[state];
if (buf != NULL) {
wasted += buf->waste();
undo_wasted += buf->undo_waste();
--- a/src/hotspot/share/gc/g1/g1Allocator.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1Allocator.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -178,39 +178,6 @@
}
};
-class G1PLAB: public PLAB {
-private:
- bool _retired;
-
-public:
- G1PLAB(size_t gclab_word_size);
- virtual ~G1PLAB() {
- guarantee(_retired, "Allocation buffer has not been retired");
- }
-
- // The amount of space in words wasted within the PLAB including
- // waste due to refills and alignment.
- size_t wasted() const { return _wasted; }
-
- virtual void set_buf(HeapWord* buf, size_t word_size) {
- PLAB::set_buf(buf, word_size);
- _retired = false;
- }
-
- virtual void retire() {
- if (_retired) {
- return;
- }
- PLAB::retire();
- _retired = true;
- }
-
- virtual void flush_and_retire_stats(PLABStats* stats) {
- PLAB::flush_and_retire_stats(stats);
- _retired = true;
- }
-};
-
// Manages the PLABs used during garbage collection. Interface for allocation from PLABs.
// Needs to handle multiple contexts, extra alignment in any "survivor" area and some
// statistics.
@@ -231,7 +198,7 @@
size_t _direct_allocated[InCSetState::Num];
virtual void flush_and_retire_stats() = 0;
- virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
+ virtual PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
// Calculate the survivor space object alignment in bytes. Returns that or 0 if
// there are no restrictions on survivor alignment.
@@ -292,14 +259,14 @@
// The default PLAB allocator for G1. Keeps the current (single) PLAB for survivor
// and old generation allocation.
class G1DefaultPLABAllocator : public G1PLABAllocator {
- G1PLAB _surviving_alloc_buffer;
- G1PLAB _tenured_alloc_buffer;
- G1PLAB* _alloc_buffers[InCSetState::Num];
+ PLAB _surviving_alloc_buffer;
+ PLAB _tenured_alloc_buffer;
+ PLAB* _alloc_buffers[InCSetState::Num];
public:
G1DefaultPLABAllocator(G1Allocator* _allocator);
- virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
+ virtual PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
assert(dest.is_valid(),
"Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value());
assert(_alloc_buffers[dest.value()] != NULL,
--- a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -47,7 +47,7 @@
inline HeapWord* G1PLABAllocator::plab_allocate(InCSetState dest,
size_t word_sz,
AllocationContext_t context) {
- G1PLAB* buffer = alloc_buffer(dest, context);
+ PLAB* buffer = alloc_buffer(dest, context);
if (_survivor_alignment_bytes == 0 || !dest.is_young()) {
return buffer->allocate(word_sz);
} else {
--- a/src/hotspot/share/gc/g1/g1CardCounts.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CardCounts.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -144,7 +144,7 @@
HeapRegionClosure(), _card_counts(card_counts) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
_card_counts->clear_region(r);
return false;
}
--- a/src/hotspot/share/gc/g1/g1CardLiveData.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CardLiveData.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -285,7 +285,7 @@
_mark_bitmap(mark_bitmap),
_cm(cm) { }
- bool doHeapRegion(HeapRegion* hr) {
+ bool do_heap_region(HeapRegion* hr) {
size_t marked_bytes = _helper.mark_marked_during_marking(_mark_bitmap, hr);
if (marked_bytes > 0) {
hr->add_to_marked_bytes(marked_bytes);
@@ -352,7 +352,7 @@
_helper(live_data, g1h->reserved_region().start()),
_gc_timestamp_at_create(live_data->gc_timestamp_at_create()) { }
- bool doHeapRegion(HeapRegion* hr) {
+ bool do_heap_region(HeapRegion* hr) {
if (has_been_reclaimed(hr)) {
_helper.reset_live_data(hr);
}
@@ -478,7 +478,7 @@
int failures() const { return _failures; }
- bool doHeapRegion(HeapRegion* hr) {
+ bool do_heap_region(HeapRegion* hr) {
int failures = 0;
// Walk the marking bitmap for this region and set the corresponding bits
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1010,7 +1010,7 @@
private:
G1HRPrinter* _hr_printer;
public:
- bool doHeapRegion(HeapRegion* hr) {
+ bool do_heap_region(HeapRegion* hr) {
assert(!hr->is_young(), "not expecting to find young regions");
_hr_printer->post_compaction(hr);
return false;
@@ -1573,7 +1573,6 @@
}
jint G1CollectedHeap::initialize() {
- CollectedHeap::pre_initialize();
os::enable_vtime();
// Necessary to satisfy locking discipline assertions.
@@ -1917,7 +1916,7 @@
CheckGCTimeStampsHRClosure(unsigned gc_time_stamp) :
_gc_time_stamp(gc_time_stamp), _failures(false) { }
- virtual bool doHeapRegion(HeapRegion* hr) {
+ virtual bool do_heap_region(HeapRegion* hr) {
unsigned region_gc_time_stamp = hr->get_gc_time_stamp();
if (_gc_time_stamp != region_gc_time_stamp) {
log_error(gc, verify)("Region " HR_FORMAT " has GC time stamp = %d, expected %d", HR_FORMAT_PARAMS(hr),
@@ -1969,7 +1968,7 @@
size_t _used;
public:
SumUsedClosure() : _used(0) {}
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
_used += r->used();
return false;
}
@@ -2188,7 +2187,7 @@
ObjectClosure* _cl;
public:
IterateObjectClosureRegionClosure(ObjectClosure* cl) : _cl(cl) {}
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (!r->is_continues_humongous()) {
r->object_iterate(_cl);
}
@@ -2303,7 +2302,7 @@
outputStream* _st;
public:
PrintRegionClosure(outputStream* st) : _st(st) {}
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
r->print_on(_st);
return false;
}
@@ -2422,7 +2421,7 @@
size_t _occupied_sum;
public:
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
HeapRegionRemSet* hrrs = r->rem_set();
size_t occupied = hrrs->occupied();
_occupied_sum += occupied;
@@ -2669,7 +2668,7 @@
_dcq(&JavaThread::dirty_card_queue_set()) {
}
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
if (!r->is_starts_humongous()) {
return false;
}
@@ -2745,7 +2744,7 @@
class VerifyRegionRemSetClosure : public HeapRegionClosure {
public:
- bool doHeapRegion(HeapRegion* hr) {
+ bool do_heap_region(HeapRegion* hr) {
if (!hr->is_archive() && !hr->is_continues_humongous()) {
hr->verify_rem_set();
}
@@ -2815,7 +2814,7 @@
public:
G1PrintCollectionSetClosure(G1HRPrinter* hr_printer) : HeapRegionClosure(), _hr_printer(hr_printer) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
_hr_printer->cset(r);
return false;
}
@@ -4505,7 +4504,7 @@
_local_free_list("Local Region List for CSet Freeing") {
}
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
assert(r->in_collection_set(), "Region %u should be in collection set.", r->hrm_index());
@@ -4628,7 +4627,7 @@
public:
G1PrepareFreeCollectionSetClosure(WorkItem* work_items) : HeapRegionClosure(), _cur_idx(0), _work_items(work_items) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
_work_items[_cur_idx++] = WorkItem(r);
return false;
}
@@ -4762,7 +4761,7 @@
_free_region_list(free_region_list), _humongous_objects_reclaimed(0), _humongous_regions_reclaimed(0), _freed_bytes(0) {
}
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
if (!r->is_starts_humongous()) {
return false;
}
@@ -4897,7 +4896,7 @@
class G1AbandonCollectionSetClosure : public HeapRegionClosure {
public:
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
assert(r->in_collection_set(), "Region %u must have been in collection set", r->hrm_index());
G1CollectedHeap::heap()->clear_in_cset(r);
r->set_young_index_in_cset(-1);
@@ -4967,7 +4966,7 @@
bool _success;
public:
NoYoungRegionsClosure() : _success(true) { }
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (r->is_young()) {
log_error(gc, verify)("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
p2i(r->bottom()), p2i(r->end()));
@@ -4997,7 +4996,7 @@
public:
TearDownRegionSetsClosure(HeapRegionSet* old_set) : _old_set(old_set) { }
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (r->is_old()) {
_old_set->remove(r);
} else if(r->is_young()) {
@@ -5065,7 +5064,7 @@
}
}
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (r->is_empty()) {
// Add free regions to the free list
r->set_free();
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1197,7 +1197,7 @@
}
// Iterate over heap regions, in address order, terminating the
- // iteration early if the "doHeapRegion" method returns "true".
+ // iteration early if the "do_heap_region" method returns "true".
void heap_region_iterate(HeapRegionClosure* blk) const;
// Return the region with the given index. It assumes the index is valid.
@@ -1272,36 +1272,8 @@
size_t max_tlab_size() const;
size_t unsafe_max_tlab_alloc(Thread* ignored) const;
- // Can a compiler initialize a new object without store barriers?
- // This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint. If such permission
- // is granted for this heap type, the compiler promises to call
- // defer_store_barrier() below on any slow path allocation of
- // a new object for which such initializing store barriers will
- // have been elided. G1, like CMS, allows this, but should be
- // ready to provide a compensating write barrier as necessary
- // if that storage came out of a non-young region. The efficiency
- // of this implementation depends crucially on being able to
- // answer very efficiently in constant time whether a piece of
- // storage in the heap comes from a young region or not.
- // See ReduceInitialCardMarks.
- virtual bool can_elide_tlab_store_barriers() const {
- return true;
- }
-
- virtual bool card_mark_must_follow_store() const {
- return true;
- }
-
inline bool is_in_young(const oop obj);
- // We don't need barriers for initializing stores to objects
- // in the young gen: for the SATB pre-barrier, there is no
- // pre-value that needs to be remembered; for the remembered-set
- // update logging post-barrier, we don't maintain remembered set
- // information for young gen objects.
- virtual inline bool can_elide_initializing_store_barrier(oop new_obj);
-
// Returns "true" iff the given word_size is "very large".
static bool is_humongous(size_t word_size) {
// Note this has to be strictly greater-than as the TLABs
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -241,15 +241,6 @@
return heap_region_containing(obj)->is_young();
}
-// We don't need barriers for initializing stores to objects
-// in the young gen: for the SATB pre-barrier, there is no
-// pre-value that needs to be remembered; for the remembered-set
-// update logging post-barrier, we don't maintain remembered set
-// information for young gen objects.
-inline bool G1CollectedHeap::can_elide_initializing_store_barrier(oop new_obj) {
- return is_in_young(new_obj);
-}
-
inline bool G1CollectedHeap::is_obj_dead(const oop obj) const {
if (obj == NULL) {
return false;
--- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -186,9 +186,9 @@
do {
HeapRegion* r = G1CollectedHeap::heap()->region_at(_collection_set_regions[cur_pos]);
- bool result = cl->doHeapRegion(r);
+ bool result = cl->do_heap_region(r);
if (result) {
- cl->incomplete();
+ cl->set_incomplete();
return;
}
cur_pos++;
@@ -292,7 +292,7 @@
public:
G1VerifyYoungAgesClosure() : HeapRegionClosure(), _valid(true) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
guarantee(r->is_young(), "Region must be young but is %s", r->get_type_str());
SurvRateGroup* group = r->surv_rate_group();
@@ -332,7 +332,7 @@
public:
G1PrintCollectionSetClosure(outputStream* st) : HeapRegionClosure(), _st(st) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
assert(r->in_collection_set(), "Region %u should be in collection set", r->hrm_index());
_st->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
HR_FORMAT_PARAMS(r),
@@ -524,7 +524,7 @@
FREE_C_HEAP_ARRAY(int, _heap_region_indices);
}
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
const int idx = r->young_index_in_cset();
assert(idx > -1, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -591,7 +591,7 @@
G1ClearBitmapHRClosure(G1CMBitMap* bitmap, G1ConcurrentMark* cm) : HeapRegionClosure(), _cm(cm), _bitmap(bitmap) {
}
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
size_t const chunk_size_in_words = G1ClearBitMapTask::chunk_size() / HeapWordSize;
HeapWord* cur = r->bottom();
@@ -638,7 +638,7 @@
}
bool is_complete() {
- return _cl.complete();
+ return _cl.is_complete();
}
};
@@ -694,7 +694,7 @@
CheckBitmapClearHRClosure(G1CMBitMap* bitmap) : _bitmap(bitmap) {
}
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
// This closure can be called concurrently to the mutator, so we must make sure
// that the result of the getNextMarkedWordAddress() call is compared to the
// value passed to it as limit to detect any found bits.
@@ -707,12 +707,12 @@
bool G1ConcurrentMark::next_mark_bitmap_is_clear() {
CheckBitmapClearHRClosure cl(_next_mark_bitmap);
_g1h->heap_region_iterate(&cl);
- return cl.complete();
+ return cl.is_complete();
}
class NoteStartOfMarkHRClosure: public HeapRegionClosure {
public:
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
r->note_start_of_marking();
return false;
}
@@ -1094,7 +1094,7 @@
const uint old_regions_removed() { return _old_regions_removed; }
const uint humongous_regions_removed() { return _humongous_regions_removed; }
- bool doHeapRegion(HeapRegion *hr) {
+ bool do_heap_region(HeapRegion *hr) {
_g1->reset_gc_time_stamps(hr);
hr->note_end_of_marking();
@@ -1135,7 +1135,7 @@
G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
&hrrs_cleanup_task);
_g1h->heap_region_par_iterate_from_worker_offset(&g1_note_end, &_hrclaimer, worker_id);
- assert(g1_note_end.complete(), "Shouldn't have yielded!");
+ assert(g1_note_end.is_complete(), "Shouldn't have yielded!");
// Now update the lists
_g1h->remove_from_old_sets(g1_note_end.old_regions_removed(), g1_note_end.humongous_regions_removed());
@@ -2922,7 +2922,7 @@
"(bytes)", "(bytes)");
}
-bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
+bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) {
const char* type = r->get_type_str();
HeapWord* bottom = r->bottom();
HeapWord* end = r->end();
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -848,7 +848,7 @@
// The header and footer are printed in the constructor and
// destructor respectively.
G1PrintRegionLivenessInfoClosure(const char* phase_name);
- virtual bool doHeapRegion(HeapRegion* r);
+ virtual bool do_heap_region(HeapRegion* r);
~G1PrintRegionLivenessInfoClosure();
};
--- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -220,7 +220,7 @@
return rspc.marked_bytes();
}
- bool doHeapRegion(HeapRegion *hr) {
+ bool do_heap_region(HeapRegion *hr) {
assert(!hr->is_pinned(), "Unexpected pinned region at index %u", hr->hrm_index());
assert(hr->in_collection_set(), "bad CS");
--- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -56,7 +56,7 @@
_bitmap(bitmap),
_worker_id(worker_id) { }
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
G1AdjustAndRebuildClosure cl(_worker_id);
if (r->is_humongous()) {
oop obj = oop(r->humongous_start_region()->bottom());
--- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -40,7 +40,7 @@
G1ResetHumongousClosure(G1CMBitMap* bitmap) :
_bitmap(bitmap) { }
- bool doHeapRegion(HeapRegion* current) {
+ bool do_heap_region(HeapRegion* current) {
if (current->is_humongous()) {
if (current->is_starts_humongous()) {
oop obj = oop(current->bottom());
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -37,7 +37,7 @@
#include "logging/log.hpp"
#include "utilities/ticks.inline.hpp"
-bool G1FullGCPrepareTask::G1CalculatePointersClosure::doHeapRegion(HeapRegion* hr) {
+bool G1FullGCPrepareTask::G1CalculatePointersClosure::do_heap_region(HeapRegion* hr) {
if (hr->is_humongous()) {
oop obj = oop(hr->humongous_start_region()->bottom());
if (_bitmap->is_marked(obj)) {
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -67,7 +67,7 @@
G1FullGCCompactionPoint* cp);
void update_sets();
- bool doHeapRegion(HeapRegion* hr);
+ bool do_heap_region(HeapRegion* hr);
bool freed_regions();
};
--- a/src/hotspot/share/gc/g1/g1HeapTransition.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -58,7 +58,7 @@
class DetailedUsageClosure: public HeapRegionClosure {
public:
DetailedUsage _usage;
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (r->is_old()) {
_usage._old_used += r->used();
_usage._old_region_count++;
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -273,7 +273,7 @@
G1CollectedHeap* _g1h;
public:
VerifyArchivePointerRegionClosure(G1CollectedHeap* g1h) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
if (r->is_archive()) {
VerifyObjectInArchiveRegionClosure verify_oop_pointers(r, false);
r->object_iterate(&verify_oop_pointers);
@@ -306,7 +306,7 @@
return _failures;
}
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
// For archive regions, verify there are no heap pointers to
// non-pinned regions. For all others, verify liveness info.
if (r->is_closed_archive()) {
@@ -498,7 +498,7 @@
_old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
_old_count(), _humongous_count(), _free_count(){ }
- bool doHeapRegion(HeapRegion* hr) {
+ bool do_heap_region(HeapRegion* hr) {
if (hr->is_young()) {
// TODO
} else if (hr->is_humongous()) {
@@ -608,7 +608,7 @@
public:
G1VerifyCardTableCleanup(G1HeapVerifier* verifier, G1SATBCardTableModRefBS* ct_bs)
: _verifier(verifier), _ct_bs(ct_bs) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
if (r->is_survivor()) {
_verifier->verify_dirty_region(r);
} else {
@@ -654,7 +654,7 @@
G1HeapVerifier* _verifier;
public:
G1VerifyDirtyYoungListClosure(G1HeapVerifier* verifier) : HeapRegionClosure(), _verifier(verifier) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
_verifier->verify_dirty_region(r);
return false;
}
@@ -721,7 +721,7 @@
bool failures() { return _failures; }
- virtual bool doHeapRegion(HeapRegion* hr) {
+ virtual bool do_heap_region(HeapRegion* hr) {
bool result = _verifier->verify_bitmaps(_caller, hr);
if (!result) {
_failures = true;
@@ -744,7 +744,7 @@
public:
G1CheckCSetFastTableClosure() : HeapRegionClosure(), _failures(false) { }
- virtual bool doHeapRegion(HeapRegion* hr) {
+ virtual bool do_heap_region(HeapRegion* hr) {
uint i = hr->hrm_index();
InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i);
if (hr->is_humongous()) {
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -206,7 +206,7 @@
oop const old, size_t word_sz, uint age,
HeapWord * const obj_ptr,
const AllocationContext_t context) const {
- G1PLAB* alloc_buf = _plab_allocator->alloc_buffer(dest_state, context);
+ PLAB* alloc_buf = _plab_allocator->alloc_buffer(dest_state, context);
if (alloc_buf->contains(obj_ptr)) {
_g1h->_gc_tracer_stw->report_promotion_in_new_plab_event(old->klass(), word_sz, age,
dest_state.value() == InCSetState::Old,
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,7 @@
public:
G1ResetScanTopClosure(HeapWord** scan_top) : _scan_top(scan_top) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
uint hrm_index = r->hrm_index();
if (!r->in_collection_set() && r->is_old_or_humongous()) {
_scan_top[hrm_index] = r->top();
@@ -204,7 +204,7 @@
if (_iter_states[region] != Unclaimed) {
return false;
}
- jint res = Atomic::cmpxchg(Claimed, (jint*)(&_iter_states[region]), Unclaimed);
+ G1RemsetIterState res = Atomic::cmpxchg(Claimed, &_iter_states[region], Unclaimed);
return (res == Unclaimed);
}
@@ -214,7 +214,7 @@
if (iter_is_complete(region)) {
return false;
}
- jint res = Atomic::cmpxchg(Complete, (jint*)(&_iter_states[region]), Claimed);
+ G1RemsetIterState res = Atomic::cmpxchg(Complete, &_iter_states[region], Claimed);
return (res == Claimed);
}
@@ -349,7 +349,7 @@
_scan_state->add_dirty_region(region_idx_for_card);
}
-bool G1ScanRSForRegionClosure::doHeapRegion(HeapRegion* r) {
+bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
assert(r->in_collection_set(), "should only be called on elements of CS.");
uint region_idx = r->hrm_index();
@@ -522,7 +522,7 @@
_g1h(G1CollectedHeap::heap()),
_live_data(live_data) { }
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (!r->is_continues_humongous()) {
r->rem_set()->scrub(_live_data);
}
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -176,7 +176,7 @@
CodeBlobClosure* code_root_cl,
uint worker_i);
- bool doHeapRegion(HeapRegion* r);
+ bool do_heap_region(HeapRegion* r);
double strong_code_root_scan_time_sec() {
return _strong_code_root_scan_time_sec;
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -252,7 +252,7 @@
_max_rs_mem_sz(0), _max_code_root_mem_sz(0)
{}
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
HeapRegionRemSet* hrrs = r->rem_set();
// HeapRegionRemSet::mem_size() includes the
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -131,6 +131,7 @@
}
void G1SATBCardTableLoggingModRefBS::initialize(G1RegionToSpaceMapper* mapper) {
+ initialize_deferred_card_mark_barriers();
mapper->set_mapping_changed_listener(&_listener);
_byte_map_size = mapper->reserved().byte_size();
@@ -213,3 +214,14 @@
}
}
}
+
+bool G1SATBCardTableModRefBS::is_in_young(oop obj) const {
+ volatile jbyte* p = byte_for((void*)obj);
+ return *p == g1_young_card_val();
+}
+
+void G1SATBCardTableLoggingModRefBS::flush_deferred_barriers(JavaThread* thread) {
+ CardTableModRefBS::flush_deferred_barriers(thread);
+ thread->satb_mark_queue().flush();
+ thread->dirty_card_queue().flush();
+}
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,6 +92,8 @@
jbyte val = _byte_map[card_index];
return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
}
+
+ virtual bool is_in_young(oop obj) const;
};
template<>
@@ -145,13 +147,19 @@
// above no longer applies.
void invalidate(MemRegion mr);
- void write_region_work(MemRegion mr) { invalidate(mr); }
+ void write_region(MemRegion mr) { invalidate(mr); }
void write_ref_array_work(MemRegion mr) { invalidate(mr); }
template <DecoratorSet decorators, typename T>
void write_ref_field_post(T* field, oop new_val);
void write_ref_field_post_slow(volatile jbyte* byte);
+ virtual void flush_deferred_barriers(JavaThread* thread);
+
+ virtual bool card_mark_must_follow_store() const {
+ return true;
+ }
+
// Callbacks for runtime accesses.
template <DecoratorSet decorators, typename BarrierSetT = G1SATBCardTableLoggingModRefBS>
class AccessBarrier: public ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT> {
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -30,7 +30,7 @@
template <DecoratorSet decorators, typename T>
inline void G1SATBCardTableModRefBS::write_ref_field_pre(T* field) {
- if (HasDecorator<decorators, ARRAYCOPY_DEST_NOT_INITIALIZED>::value ||
+ if (HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value ||
HasDecorator<decorators, AS_NO_KEEPALIVE>::value) {
return;
}
--- a/src/hotspot/share/gc/g1/g1YoungRemSetSamplingThread.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1YoungRemSetSamplingThread.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -79,7 +79,7 @@
G1YoungRemSetSamplingClosure(SuspendibleThreadSetJoiner* sts) :
HeapRegionClosure(), _sts(sts), _regions_visited(0), _sampled_rs_lengths(0) { }
- virtual bool doHeapRegion(HeapRegion* r) {
+ virtual bool do_heap_region(HeapRegion* r) {
size_t rs_length = r->rem_set()->occupied();
_sampled_rs_lengths += rs_length;
@@ -114,7 +114,7 @@
G1CollectionSet* g1cs = g1h->collection_set();
g1cs->iterate(&cl);
- if (cl.complete()) {
+ if (cl.is_complete()) {
g1p->revise_young_list_target_length_if_necessary(cl.sampled_rs_lengths());
}
}
--- a/src/hotspot/share/gc/g1/heapRegion.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -719,23 +719,23 @@
};
// HeapRegionClosure is used for iterating over regions.
-// Terminates the iteration when the "doHeapRegion" method returns "true".
+// Terminates the iteration when the "do_heap_region" method returns "true".
class HeapRegionClosure : public StackObj {
friend class HeapRegionManager;
friend class G1CollectionSet;
- bool _complete;
- void incomplete() { _complete = false; }
+ bool _is_complete;
+ void set_incomplete() { _is_complete = false; }
public:
- HeapRegionClosure(): _complete(true) {}
+ HeapRegionClosure(): _is_complete(true) {}
// Typically called on each region until it returns true.
- virtual bool doHeapRegion(HeapRegion* r) = 0;
+ virtual bool do_heap_region(HeapRegion* r) = 0;
// True after iteration if the closure was applied to all heap regions
// and returned "false" in all cases.
- bool complete() { return _complete; }
+ bool is_complete() { return _is_complete; }
};
#endif // SHARE_VM_GC_G1_HEAPREGION_HPP
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -242,9 +242,9 @@
continue;
}
guarantee(at(i) != NULL, "Tried to access region %u that has a NULL HeapRegion*", i);
- bool res = blk->doHeapRegion(at(i));
+ bool res = blk->do_heap_region(at(i));
if (res) {
- blk->incomplete();
+ blk->set_incomplete();
return;
}
}
@@ -353,7 +353,7 @@
if (!hrclaimer->claim_region(index)) {
continue;
}
- bool res = blk->doHeapRegion(r);
+ bool res = blk->do_heap_region(r);
if (res) {
return;
}
--- a/src/hotspot/share/gc/g1/heapRegionManager.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -236,8 +236,8 @@
// and not free, and return the number of regions newly committed in commit_count.
bool allocate_containing_regions(MemRegion range, size_t* commit_count, WorkGang* pretouch_workers);
- // Apply blk->doHeapRegion() on all committed regions in address order,
- // terminating the iteration early if doHeapRegion() returns true.
+ // Apply blk->do_heap_region() on all committed regions in address order,
+ // terminating the iteration early if do_heap_region() returns true.
void iterate(HeapRegionClosure* blk) const;
void par_iterate(HeapRegionClosure* blk, HeapRegionClaimer* hrclaimer, const uint start_index) const;
--- a/src/hotspot/share/gc/parallel/cardTableExtension.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/parallel/cardTableExtension.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
#include "gc/parallel/cardTableExtension.hpp"
#include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/objectStartArray.inline.hpp"
-#include "gc/parallel/parallelScavengeHeap.hpp"
+#include "gc/parallel/parallelScavengeHeap.inline.hpp"
#include "gc/parallel/psPromotionManager.inline.hpp"
#include "gc/parallel/psScavenge.hpp"
#include "gc/parallel/psTasks.hpp"
@@ -677,3 +677,7 @@
}
return min_start;
}
+
+bool CardTableExtension::is_in_young(oop obj) const {
+ return ParallelScavengeHeap::heap()->is_in_young(obj);
+}
--- a/src/hotspot/share/gc/parallel/cardTableExtension.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/parallel/cardTableExtension.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -108,6 +108,13 @@
}
#endif // ASSERT
+
+ // ReduceInitialCardMarks support
+ virtual bool is_in_young(oop obj) const;
+
+ virtual bool card_mark_must_follow_store() const {
+ return false;
+ }
};
template<>
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,8 +57,6 @@
GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
jint ParallelScavengeHeap::initialize() {
- CollectedHeap::pre_initialize();
-
const size_t heap_size = _collector_policy->max_heap_byte_size();
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
@@ -490,13 +488,6 @@
CollectedHeap::resize_all_tlabs();
}
-bool ParallelScavengeHeap::can_elide_initializing_store_barrier(oop new_obj) {
- // We don't need barriers for stores to objects in the
- // young gen and, a fortiori, for initializing stores to
- // objects therein.
- return is_in_young(new_obj);
-}
-
// This method is used by System.gc() and JVMTI.
void ParallelScavengeHeap::collect(GCCause::Cause cause) {
assert(!Heap_lock->owned_by_self(),
@@ -719,4 +710,3 @@
memory_pools.append(_old_pool);
return memory_pools;
}
-
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -205,21 +205,6 @@
size_t tlab_used(Thread* thr) const;
size_t unsafe_max_tlab_alloc(Thread* thr) const;
- // Can a compiler initialize a new object without store barriers?
- // This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint.
- virtual bool can_elide_tlab_store_barriers() const {
- return true;
- }
-
- virtual bool card_mark_must_follow_store() const {
- return false;
- }
-
- // Return true if we don't we need a store barrier for
- // initializing stores to an object at this address.
- virtual bool can_elide_initializing_store_barrier(oop new_obj);
-
void object_iterate(ObjectClosure* cl);
void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); }
--- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -538,7 +538,7 @@
{
assert(_dc_and_los < dc_claimed, "already claimed");
assert(_dc_and_los >= dc_one, "count would go negative");
- Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los);
+ Atomic::add(dc_mask, &_dc_and_los);
}
inline HeapWord* ParallelCompactData::RegionData::data_location() const
@@ -578,7 +578,7 @@
inline void ParallelCompactData::RegionData::add_live_obj(size_t words)
{
assert(words <= (size_t)los_mask - live_obj_size(), "overflow");
- Atomic::add((int) words, (volatile int*) &_dc_and_los);
+ Atomic::add(static_cast<region_sz_t>(words), &_dc_and_los);
}
inline void ParallelCompactData::RegionData::set_highest_ref(HeapWord* addr)
--- a/src/hotspot/share/gc/serial/serialHeap.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/serial/serialHeap.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,10 +61,6 @@
virtual bool is_in_closed_subset(const void* p) const {
return is_in(p);
}
-
- virtual bool card_mark_must_follow_store() const {
- return false;
- }
};
#endif // SHARE_VM_GC_CMS_CMSHEAP_HPP
--- a/src/hotspot/share/gc/shared/barrierSet.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -32,6 +32,8 @@
#include "oops/oopsHierarchy.hpp"
#include "utilities/fakeRttiSupport.hpp"
+class JavaThread;
+
// This class provides the interface between a barrier implementation and
// the rest of the system.
@@ -107,19 +109,19 @@
static void static_write_ref_array_pre(HeapWord* start, size_t count);
static void static_write_ref_array_post(HeapWord* start, size_t count);
+ // Support for optimizing compilers to call the barrier set on slow path allocations
+ // that did not enter a TLAB. Used for e.g. ReduceInitialCardMarks.
+ // The allocation is safe to use iff it returns true. If not, the slow-path allocation
+ // is redone until it succeeds. This can e.g. prevent allocations from the slow path
+ // to be in old.
+ virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {}
+ virtual void flush_deferred_barriers(JavaThread* thread) {}
+ virtual void make_parsable(JavaThread* thread) {}
+
protected:
virtual void write_ref_array_work(MemRegion mr) = 0;
public:
- // (For efficiency reasons, this operation is specialized for certain
- // barrier types. Semantically, it should be thought of as a call to the
- // virtual "_work" function below, which must implement the barrier.)
- void write_region(MemRegion mr);
-
-protected:
- virtual void write_region_work(MemRegion mr) = 0;
-
-public:
// Inform the BarrierSet that the the covered heap region that starts
// with "base" has been changed to have the given size (possibly from 0,
// for initialization.)
--- a/src/hotspot/share/gc/shared/barrierSet.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/barrierSet.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,8 +52,4 @@
write_ref_array_work(MemRegion(aligned_start, aligned_end));
}
-inline void BarrierSet::write_region(MemRegion mr) {
- write_region_work(mr);
-}
-
#endif // SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
#include "logging/log.hpp"
#include "memory/virtualspace.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/thread.hpp"
#include "services/memTracker.hpp"
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
@@ -61,7 +62,8 @@
_committed(NULL),
_cur_covered_regions(0),
_byte_map(NULL),
- byte_map_base(NULL)
+ byte_map_base(NULL),
+ _defer_initial_card_mark(false)
{
assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");
@@ -75,6 +77,7 @@
}
void CardTableModRefBS::initialize() {
+ initialize_deferred_card_mark_barriers();
_guard_index = cards_required(_whole_heap.word_size()) - 1;
_last_valid_index = _guard_index - 1;
@@ -521,3 +524,112 @@
st->print_cr("Card table byte_map: [" INTPTR_FORMAT "," INTPTR_FORMAT "] byte_map_base: " INTPTR_FORMAT,
p2i(_byte_map), p2i(_byte_map + _byte_map_size), p2i(byte_map_base));
}
+
+// Helper for ReduceInitialCardMarks. For performance,
+// compiled code may elide card-marks for initializing stores
+// to a newly allocated object along the fast-path. We
+// compensate for such elided card-marks as follows:
+// (a) Generational, non-concurrent collectors, such as
+// GenCollectedHeap(ParNew,DefNew,Tenured) and
+// ParallelScavengeHeap(ParallelGC, ParallelOldGC)
+// need the card-mark if and only if the region is
+// in the old gen, and do not care if the card-mark
+// succeeds or precedes the initializing stores themselves,
+// so long as the card-mark is completed before the next
+// scavenge. For all these cases, we can do a card mark
+// at the point at which we do a slow path allocation
+// in the old gen, i.e. in this call.
+// (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires
+// in addition that the card-mark for an old gen allocated
+// object strictly follow any associated initializing stores.
+// In these cases, the memRegion remembered below is
+// used to card-mark the entire region either just before the next
+// slow-path allocation by this thread or just before the next scavenge or
+// CMS-associated safepoint, whichever of these events happens first.
+// (The implicit assumption is that the object has been fully
+// initialized by this point, a fact that we assert when doing the
+// card-mark.)
+// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
+// G1 concurrent marking is in progress an SATB (pre-write-)barrier
+// is used to remember the pre-value of any store. Initializing
+// stores will not need this barrier, so we need not worry about
+// compensating for the missing pre-barrier here. Turning now
+// to the post-barrier, we note that G1 needs a RS update barrier
+// which simply enqueues a (sequence of) dirty cards which may
+// optionally be refined by the concurrent update threads. Note
+// that this barrier need only be applied to a non-young write,
+// but, like in CMS, because of the presence of concurrent refinement
+// (much like CMS' precleaning), must strictly follow the oop-store.
+// Thus, using the same protocol for maintaining the intended
+// invariants turns out, serendepitously, to be the same for both
+// G1 and CMS.
+//
+// For any future collector, this code should be reexamined with
+// that specific collector in mind, and the documentation above suitably
+// extended and updated.
+void CardTableModRefBS::on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {
+ if (!ReduceInitialCardMarks) {
+ return;
+ }
+ // If a previous card-mark was deferred, flush it now.
+ flush_deferred_card_mark_barrier(thread);
+ if (new_obj->is_typeArray() || is_in_young(new_obj)) {
+ // Arrays of non-references don't need a post-barrier.
+ // The deferred_card_mark region should be empty
+ // following the flush above.
+ assert(thread->deferred_card_mark().is_empty(), "Error");
+ } else {
+ MemRegion mr((HeapWord*)new_obj, new_obj->size());
+ assert(!mr.is_empty(), "Error");
+ if (_defer_initial_card_mark) {
+ // Defer the card mark
+ thread->set_deferred_card_mark(mr);
+ } else {
+ // Do the card mark
+ write_region(mr);
+ }
+ }
+}
+
+void CardTableModRefBS::initialize_deferred_card_mark_barriers() {
+ // Used for ReduceInitialCardMarks (when COMPILER2 or JVMCI is used);
+ // otherwise remains unused.
+#if defined(COMPILER2) || INCLUDE_JVMCI
+ _defer_initial_card_mark = is_server_compilation_mode_vm() && ReduceInitialCardMarks && can_elide_tlab_store_barriers()
+ && (DeferInitialCardMark || card_mark_must_follow_store());
+#else
+ assert(_defer_initial_card_mark == false, "Who would set it?");
+#endif
+}
+
+void CardTableModRefBS::flush_deferred_card_mark_barrier(JavaThread* thread) {
+#if defined(COMPILER2) || INCLUDE_JVMCI
+ MemRegion deferred = thread->deferred_card_mark();
+ if (!deferred.is_empty()) {
+ assert(_defer_initial_card_mark, "Otherwise should be empty");
+ {
+ // Verify that the storage points to a parsable object in heap
+ DEBUG_ONLY(oop old_obj = oop(deferred.start());)
+ assert(!is_in_young(old_obj),
+ "Else should have been filtered in on_slowpath_allocation_exit()");
+ assert(oopDesc::is_oop(old_obj, true), "Not an oop");
+ assert(deferred.word_size() == (size_t)(old_obj->size()),
+ "Mismatch: multiple objects?");
+ }
+ write_region(deferred);
+ // "Clear" the deferred_card_mark field
+ thread->set_deferred_card_mark(MemRegion());
+ }
+ assert(thread->deferred_card_mark().is_empty(), "invariant");
+#else
+ assert(!_defer_initial_card_mark, "Should be false");
+ assert(thread->deferred_card_mark().is_empty(), "Should be empty");
+#endif
+}
+
+void CardTableModRefBS::flush_deferred_barriers(JavaThread* thread) {
+ // The deferred store barriers must all have been flushed to the
+ // card-table (or other remembered set structure) before GC starts
+ // processing the card-table (or other remembered set).
+ flush_deferred_card_mark_barrier(thread);
+}
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,10 @@
CT_MR_BS_last_reserved = 16
};
+ // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2
+ // or INCLUDE_JVMCI is being used
+ bool _defer_initial_card_mark;
+
// a word's worth (row) of clean card values
static const intptr_t clean_card_row = (intptr_t)(-1);
@@ -180,8 +184,8 @@
CardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti);
~CardTableModRefBS();
- protected:
- void write_region_work(MemRegion mr) {
+ public:
+ void write_region(MemRegion mr) {
dirty_MemRegion(mr);
}
@@ -314,6 +318,49 @@
void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN;
void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
+ // ReduceInitialCardMarks
+ void initialize_deferred_card_mark_barriers();
+
+ // If the CollectedHeap was asked to defer a store barrier above,
+ // this informs it to flush such a deferred store barrier to the
+ // remembered set.
+ void flush_deferred_card_mark_barrier(JavaThread* thread);
+
+ // Can a compiler initialize a new object without store barriers?
+ // This permission only extends from the creation of a new object
+ // via a TLAB up to the first subsequent safepoint. If such permission
+ // is granted for this heap type, the compiler promises to call
+ // defer_store_barrier() below on any slow path allocation of
+ // a new object for which such initializing store barriers will
+ // have been elided. G1, like CMS, allows this, but should be
+ // ready to provide a compensating write barrier as necessary
+ // if that storage came out of a non-young region. The efficiency
+ // of this implementation depends crucially on being able to
+ // answer very efficiently in constant time whether a piece of
+ // storage in the heap comes from a young region or not.
+ // See ReduceInitialCardMarks.
+ virtual bool can_elide_tlab_store_barriers() const {
+ return true;
+ }
+
+ // If a compiler is eliding store barriers for TLAB-allocated objects,
+ // we will be informed of a slow-path allocation by a call
+ // to on_slowpath_allocation_exit() below. Such a call precedes the
+ // initialization of the object itself, and no post-store-barriers will
+ // be issued. Some heap types require that the barrier strictly follows
+ // the initializing stores. (This is currently implemented by deferring the
+ // barrier until the next slow-path allocation or gc-related safepoint.)
+ // This interface answers whether a particular barrier type needs the card
+ // mark to be thus strictly sequenced after the stores.
+ virtual bool card_mark_must_follow_store() const = 0;
+
+ virtual bool is_in_young(oop obj) const = 0;
+
+ virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
+ virtual void flush_deferred_barriers(JavaThread* thread);
+
+ virtual void make_parsable(JavaThread* thread) { flush_deferred_card_mark_barrier(thread); }
+
template <DecoratorSet decorators, typename BarrierSetT = CardTableModRefBS>
class AccessBarrier: public ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT> {};
};
--- a/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,3 +121,6 @@
}
}
+bool CardTableModRefBSForCTRS::is_in_young(oop obj) const {
+ return GenCollectedHeap::heap()->is_in_young(obj);
+}
--- a/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBSForCTRS.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,12 @@
void set_CTRS(CardTableRS* rs) { _rs = rs; }
+ virtual bool card_mark_must_follow_store() const {
+ return UseConcMarkSweepGC;
+ }
+
+ virtual bool is_in_young(oop obj) const;
+
private:
CardTableRS* _rs;
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -177,8 +177,7 @@
_total_collections(0),
_total_full_collections(0),
_gc_cause(GCCause::_no_gc),
- _gc_lastcause(GCCause::_no_gc),
- _defer_initial_card_mark(false) // strengthened by subclass in pre_initialize() below.
+ _gc_lastcause(GCCause::_no_gc)
{
const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
const size_t elements_per_word = HeapWordSize / sizeof(jint);
@@ -239,17 +238,6 @@
BarrierSet::set_bs(barrier_set);
}
-void CollectedHeap::pre_initialize() {
- // Used for ReduceInitialCardMarks (when COMPILER2 is used);
- // otherwise remains unused.
-#if COMPILER2_OR_JVMCI
- _defer_initial_card_mark = is_server_compilation_mode_vm() && ReduceInitialCardMarks && can_elide_tlab_store_barriers()
- && (DeferInitialCardMark || card_mark_must_follow_store());
-#else
- assert(_defer_initial_card_mark == false, "Who would set it?");
-#endif
-}
-
#ifndef PRODUCT
void CollectedHeap::check_for_bad_heap_word_value(HeapWord* addr, size_t size) {
if (CheckMemoryInitialization && ZapUnusedHeapArea) {
@@ -333,28 +321,6 @@
return obj;
}
-void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) {
- MemRegion deferred = thread->deferred_card_mark();
- if (!deferred.is_empty()) {
- assert(_defer_initial_card_mark, "Otherwise should be empty");
- {
- // Verify that the storage points to a parsable object in heap
- DEBUG_ONLY(oop old_obj = oop(deferred.start());)
- assert(is_in(old_obj), "Not in allocated heap");
- assert(!can_elide_initializing_store_barrier(old_obj),
- "Else should have been filtered in new_store_pre_barrier()");
- assert(oopDesc::is_oop(old_obj, true), "Not an oop");
- assert(deferred.word_size() == (size_t)(old_obj->size()),
- "Mismatch: multiple objects?");
- }
- BarrierSet* bs = barrier_set();
- bs->write_region(deferred);
- // "Clear" the deferred_card_mark field
- thread->set_deferred_card_mark(MemRegion());
- }
- assert(thread->deferred_card_mark().is_empty(), "invariant");
-}
-
size_t CollectedHeap::max_tlab_size() const {
// TLABs can't be bigger than we can fill with a int[Integer.MAX_VALUE].
// This restriction could be removed by enabling filling with multiple arrays.
@@ -370,72 +336,6 @@
return align_down(max_int_size, MinObjAlignment);
}
-// Helper for ReduceInitialCardMarks. For performance,
-// compiled code may elide card-marks for initializing stores
-// to a newly allocated object along the fast-path. We
-// compensate for such elided card-marks as follows:
-// (a) Generational, non-concurrent collectors, such as
-// GenCollectedHeap(ParNew,DefNew,Tenured) and
-// ParallelScavengeHeap(ParallelGC, ParallelOldGC)
-// need the card-mark if and only if the region is
-// in the old gen, and do not care if the card-mark
-// succeeds or precedes the initializing stores themselves,
-// so long as the card-mark is completed before the next
-// scavenge. For all these cases, we can do a card mark
-// at the point at which we do a slow path allocation
-// in the old gen, i.e. in this call.
-// (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires
-// in addition that the card-mark for an old gen allocated
-// object strictly follow any associated initializing stores.
-// In these cases, the memRegion remembered below is
-// used to card-mark the entire region either just before the next
-// slow-path allocation by this thread or just before the next scavenge or
-// CMS-associated safepoint, whichever of these events happens first.
-// (The implicit assumption is that the object has been fully
-// initialized by this point, a fact that we assert when doing the
-// card-mark.)
-// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
-// G1 concurrent marking is in progress an SATB (pre-write-)barrier
-// is used to remember the pre-value of any store. Initializing
-// stores will not need this barrier, so we need not worry about
-// compensating for the missing pre-barrier here. Turning now
-// to the post-barrier, we note that G1 needs a RS update barrier
-// which simply enqueues a (sequence of) dirty cards which may
-// optionally be refined by the concurrent update threads. Note
-// that this barrier need only be applied to a non-young write,
-// but, like in CMS, because of the presence of concurrent refinement
-// (much like CMS' precleaning), must strictly follow the oop-store.
-// Thus, using the same protocol for maintaining the intended
-// invariants turns out, serendepitously, to be the same for both
-// G1 and CMS.
-//
-// For any future collector, this code should be reexamined with
-// that specific collector in mind, and the documentation above suitably
-// extended and updated.
-oop CollectedHeap::new_store_pre_barrier(JavaThread* thread, oop new_obj) {
- // If a previous card-mark was deferred, flush it now.
- flush_deferred_store_barrier(thread);
- if (can_elide_initializing_store_barrier(new_obj) ||
- new_obj->is_typeArray()) {
- // Arrays of non-references don't need a pre-barrier.
- // The deferred_card_mark region should be empty
- // following the flush above.
- assert(thread->deferred_card_mark().is_empty(), "Error");
- } else {
- MemRegion mr((HeapWord*)new_obj, new_obj->size());
- assert(!mr.is_empty(), "Error");
- if (_defer_initial_card_mark) {
- // Defer the card mark
- thread->set_deferred_card_mark(mr);
- } else {
- // Do the card mark
- BarrierSet* bs = barrier_set();
- bs->write_region(mr);
- }
- }
- return new_obj;
-}
-
size_t CollectedHeap::filler_array_hdr_size() {
return align_object_offset(arrayOopDesc::header_size(T_INT)); // align to Long
}
@@ -538,24 +438,16 @@
" otherwise concurrent mutator activity may make heap "
" unparsable again");
const bool use_tlab = UseTLAB;
- const bool deferred = _defer_initial_card_mark;
// The main thread starts allocating via a TLAB even before it
// has added itself to the threads list at vm boot-up.
JavaThreadIteratorWithHandle jtiwh;
assert(!use_tlab || jtiwh.length() > 0,
"Attempt to fill tlabs before main thread has been added"
" to threads list is doomed to failure!");
+ BarrierSet *bs = barrier_set();
for (; JavaThread *thread = jtiwh.next(); ) {
if (use_tlab) thread->tlab().make_parsable(retire_tlabs);
-#if COMPILER2_OR_JVMCI
- // The deferred store barriers must all have been flushed to the
- // card-table (or other remembered set structure) before GC starts
- // processing the card-table (or other remembered set).
- if (deferred) flush_deferred_store_barrier(thread);
-#else
- assert(!deferred, "Should be false");
- assert(thread->deferred_card_mark().is_empty(), "Should be empty");
-#endif
+ bs->make_parsable(thread);
}
}
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,10 +101,6 @@
GCHeapLog* _gc_heap_log;
- // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2
- // or INCLUDE_JVMCI is being used
- bool _defer_initial_card_mark;
-
MemRegion _reserved;
protected:
@@ -129,13 +125,6 @@
// Constructor
CollectedHeap();
- // Do common initializations that must follow instance construction,
- // for example, those needing virtual calls.
- // This code could perhaps be moved into initialize() but would
- // be slightly more awkward because we want the latter to be a
- // pure virtual.
- void pre_initialize();
-
// Create a new tlab. All TLAB allocations must go through this.
virtual HeapWord* allocate_new_tlab(size_t size);
@@ -408,45 +397,6 @@
return 0;
}
- // Can a compiler initialize a new object without store barriers?
- // This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint. If such permission
- // is granted for this heap type, the compiler promises to call
- // defer_store_barrier() below on any slow path allocation of
- // a new object for which such initializing store barriers will
- // have been elided.
- virtual bool can_elide_tlab_store_barriers() const = 0;
-
- // If a compiler is eliding store barriers for TLAB-allocated objects,
- // there is probably a corresponding slow path which can produce
- // an object allocated anywhere. The compiler's runtime support
- // promises to call this function on such a slow-path-allocated
- // object before performing initializations that have elided
- // store barriers. Returns new_obj, or maybe a safer copy thereof.
- virtual oop new_store_pre_barrier(JavaThread* thread, oop new_obj);
-
- // Answers whether an initializing store to a new object currently
- // allocated at the given address doesn't need a store
- // barrier. Returns "true" if it doesn't need an initializing
- // store barrier; answers "false" if it does.
- virtual bool can_elide_initializing_store_barrier(oop new_obj) = 0;
-
- // If a compiler is eliding store barriers for TLAB-allocated objects,
- // we will be informed of a slow-path allocation by a call
- // to new_store_pre_barrier() above. Such a call precedes the
- // initialization of the object itself, and no post-store-barriers will
- // be issued. Some heap types require that the barrier strictly follows
- // the initializing stores. (This is currently implemented by deferring the
- // barrier until the next slow-path allocation or gc-related safepoint.)
- // This interface answers whether a particular heap type needs the card
- // mark to be thus strictly sequenced after the stores.
- virtual bool card_mark_must_follow_store() const = 0;
-
- // If the CollectedHeap was asked to defer a store barrier above,
- // this informs it to flush such a deferred store barrier to the
- // remembered set.
- virtual void flush_deferred_store_barrier(JavaThread* thread);
-
// Perform a collection of the heap; intended for use in implementing
// "System.gc". This probably implies as full a collection as the
// "CollectedHeap" supports.
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,8 +71,6 @@
}
jint GenCollectedHeap::initialize() {
- CollectedHeap::pre_initialize();
-
// While there are no constraints in the GC code that HeapWordSize
// be any particular value, there are multiple other areas in the
// system which believe this to be true (e.g. oop->object_size in some
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -270,22 +270,6 @@
virtual size_t unsafe_max_tlab_alloc(Thread* thr) const;
virtual HeapWord* allocate_new_tlab(size_t size);
- // Can a compiler initialize a new object without store barriers?
- // This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint.
- virtual bool can_elide_tlab_store_barriers() const {
- return true;
- }
-
- // We don't need barriers for stores to objects in the
- // young gen and, a fortiori, for initializing stores to
- // objects therein. This applies to DefNew+Tenured and ParNew+CMS
- // only and may need to be re-examined in case other
- // kinds of collectors are implemented in the future.
- virtual bool can_elide_initializing_store_barrier(oop new_obj) {
- return is_in_young(new_obj);
- }
-
// The "requestor" generation is performing some garbage collection
// action for which it would be useful to have scratch space. The
// requestor promises to allocate no more than "max_alloc_words" in any
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
// Causes all refs in "mr" to be assumed to be modified.
virtual void invalidate(MemRegion mr) = 0;
+ virtual void write_region(MemRegion mr) = 0;
// The caller guarantees that "mr" contains no references. (Perhaps it's
// objects have been moved elsewhere.)
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,7 @@
if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
// Optimized covariant case
bs->write_ref_array_pre(dst, (int)length,
- HasDecorator<decorators, ARRAYCOPY_DEST_NOT_INITIALIZED>::value);
+ HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value);
Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
bs->write_ref_array((HeapWord*)dst, length);
} else {
--- a/src/hotspot/share/gc/shared/plab.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/plab.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,6 @@
// Initializes the buffer to be empty, but with the given "word_sz".
// Must get initialized with "set_buf" for an allocation to succeed.
PLAB(size_t word_sz);
- virtual ~PLAB() {}
static size_t size_required_for_allocation(size_t word_size) { return word_size + AlignmentReserve; }
@@ -120,7 +119,7 @@
}
// Sets the space of the buffer to be [buf, space+word_sz()).
- virtual void set_buf(HeapWord* buf, size_t new_word_sz) {
+ void set_buf(HeapWord* buf, size_t new_word_sz) {
assert(new_word_sz > AlignmentReserve, "Too small");
_word_sz = new_word_sz;
@@ -136,11 +135,11 @@
// Flush allocation statistics into the given PLABStats supporting ergonomic
// sizing of PLAB's and retire the current buffer. To be called at the end of
// GC.
- virtual void flush_and_retire_stats(PLABStats* stats);
+ void flush_and_retire_stats(PLABStats* stats);
// Fills in the unallocated portion of the buffer with a garbage object and updates
// statistics. To be called during GC.
- virtual void retire();
+ void retire();
};
// PLAB book-keeping.
--- a/src/hotspot/share/gc/shared/taskqueue.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/taskqueue.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -153,7 +153,7 @@
ParallelTaskTerminator::offer_termination(TerminatorTerminator* terminator) {
assert(_n_threads > 0, "Initialization is incorrect");
assert(_offered_termination < _n_threads, "Invariant");
- Atomic::inc((int *)&_offered_termination);
+ Atomic::inc(&_offered_termination);
uint yield_count = 0;
// Number of hard spin loops done since last yield
@@ -228,7 +228,7 @@
#endif
if (peek_in_queue_set() ||
(terminator != NULL && terminator->should_exit_termination())) {
- Atomic::dec((int *)&_offered_termination);
+ Atomic::dec(&_offered_termination);
assert(_offered_termination < _n_threads, "Invariant");
return false;
}
--- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -205,7 +205,7 @@
#if !(defined SPARC || defined IA32 || defined AMD64)
OrderAccess::fence();
#endif
- uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom);
+ uint localBot = OrderAccess::load_acquire(&_bottom);
uint n_elems = size(localBot, oldAge.top());
if (n_elems == 0) {
return false;
--- a/src/hotspot/share/gc/shared/workgroup.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/gc/shared/workgroup.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -157,7 +157,7 @@
// Wait for the coordinator to dispatch a task.
_start_semaphore->wait();
- uint num_started = (uint) Atomic::add(1, (volatile jint*)&_started);
+ uint num_started = Atomic::add(1u, &_started);
// Subtract one to get a zero-indexed worker id.
uint worker_id = num_started - 1;
@@ -168,7 +168,7 @@
void worker_done_with_task() {
// Mark that the worker is done with the task.
// The worker is not allowed to read the state variables after this line.
- uint not_finished = (uint) Atomic::add(-1, (volatile jint*)&_not_finished);
+ uint not_finished = Atomic::sub(1u, &_not_finished);
// The last worker signals to the coordinator that all work is completed.
if (not_finished == 0) {
@@ -439,7 +439,7 @@
#ifdef ASSERT
if (!res) {
assert(_claimed < _n_tasks, "Too many tasks claimed; missing clear?");
- Atomic::inc((volatile jint*) &_claimed);
+ Atomic::inc(&_claimed);
}
#endif
return res;
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -116,10 +116,7 @@
oop obj = ik->allocate_instance(CHECK);
thread->set_vm_result(obj);
JRT_BLOCK_END;
-
- if (ReduceInitialCardMarks) {
- new_store_pre_barrier(thread);
- }
+ SharedRuntime::on_slowpath_allocation_exit(thread);
JRT_END
JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
@@ -151,29 +148,9 @@
}
}
JRT_BLOCK_END;
-
- if (ReduceInitialCardMarks) {
- new_store_pre_barrier(thread);
- }
+ SharedRuntime::on_slowpath_allocation_exit(thread);
JRT_END
-void JVMCIRuntime::new_store_pre_barrier(JavaThread* thread) {
- // After any safepoint, just before going back to compiled code,
- // we inform the GC that we will be doing initializing writes to
- // this object in the future without emitting card-marks, so
- // GC may take any compensating steps.
- // NOTE: Keep this code consistent with GraphKit::store_barrier.
-
- oop new_obj = thread->vm_result();
- if (new_obj == NULL) return;
-
- assert(Universe::heap()->can_elide_tlab_store_barriers(),
- "compiler must check this first");
- // GC may decide to give back a safer copy of new_obj.
- new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj);
- thread->set_vm_result(new_obj);
-}
-
JRT_ENTRY(void, JVMCIRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
assert(klass->is_klass(), "not a class");
assert(rank >= 1, "rank must be nonzero");
--- a/src/hotspot/share/jvmci/jvmciRuntime.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciRuntime.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -154,7 +154,6 @@
static void write_barrier_pre(JavaThread* thread, oopDesc* obj);
static void write_barrier_post(JavaThread* thread, void* card);
static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child);
- static void new_store_pre_barrier(JavaThread* thread);
// used to throw exceptions from compiled JVMCI code
static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message);
--- a/src/hotspot/share/logging/logTag.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/logging/logTag.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -60,6 +60,7 @@
LOG_TAG(cset) \
LOG_TAG(data) \
LOG_TAG(datacreation) \
+ LOG_TAG(decoder) \
LOG_TAG(defaultmethods) \
LOG_TAG(dump) \
LOG_TAG(ergo) \
--- a/src/hotspot/share/memory/allocation.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/memory/allocation.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -38,9 +38,9 @@
inline void inc_stat_counter(volatile julong* dest, julong add_value) {
#if defined(SPARC) || defined(X86)
// Sparc and X86 have atomic jlong (8 bytes) instructions
- julong value = Atomic::load((volatile jlong*)dest);
+ julong value = Atomic::load(dest);
value += add_value;
- Atomic::store((jlong)value, (volatile jlong*)dest);
+ Atomic::store(value, dest);
#else
// possible word-tearing during load/store
*dest += add_value;
--- a/src/hotspot/share/memory/filemap.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/memory/filemap.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -410,14 +410,11 @@
// Write the FileMapInfo information to the file.
void FileMapInfo::open_for_write() {
- _full_path = Arguments::GetSharedArchivePath();
- if (log_is_enabled(Info, cds)) {
- ResourceMark rm;
- LogMessage(cds) msg;
- stringStream info_stream;
- info_stream.print_cr("Dumping shared data to file: ");
- info_stream.print_cr(" %s", _full_path);
- msg.info("%s", info_stream.as_string());
+ _full_path = Arguments::GetSharedArchivePath();
+ LogMessage(cds) msg;
+ if (msg.is_info()) {
+ msg.info("Dumping shared data to file: ");
+ msg.info(" %s", _full_path);
}
#ifdef _WINDOWS // On Windows, need WRITE permission to remove the file.
--- a/src/hotspot/share/memory/metaspace.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -4372,7 +4372,7 @@
// ChunkManagerReturnTest stresses taking/returning chunks from the ChunkManager. It takes and
// returns chunks from/to the ChunkManager while keeping track of the expected ChunkManager
// content.
-class ChunkManagerReturnTestImpl {
+class ChunkManagerReturnTestImpl : public CHeapObj<mtClass> {
VirtualSpaceNode _vsn;
ChunkManager _cm;
--- a/src/hotspot/share/memory/metaspaceShared.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -883,13 +883,11 @@
const char *sep = "--------------------+---------------------------+---------------------------+--------------------------";
const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %";
- ResourceMark rm;
LogMessage(cds) msg;
- stringStream info_stream;
- info_stream.print_cr("Detailed metadata info (excluding od/st regions; rw stats include md/mc regions):");
- info_stream.print_cr("%s", hdr);
- info_stream.print_cr("%s", sep);
+ msg.info("Detailed metadata info (excluding od/st regions; rw stats include md/mc regions):");
+ msg.info("%s", hdr);
+ msg.info("%s", sep);
for (int type = 0; type < int(_number_of_types); type ++) {
const char *name = type_name((Type)type);
int ro_count = _counts[RO][type];
@@ -903,7 +901,7 @@
double rw_perc = percent_of(rw_bytes, rw_all);
double perc = percent_of(bytes, ro_all + rw_all);
- info_stream.print_cr(fmt_stats, name,
+ msg.info(fmt_stats, name,
ro_count, ro_bytes, ro_perc,
rw_count, rw_bytes, rw_perc,
count, bytes, perc);
@@ -921,8 +919,8 @@
double all_rw_perc = percent_of(all_rw_bytes, rw_all);
double all_perc = percent_of(all_bytes, ro_all + rw_all);
- info_stream.print_cr("%s", sep);
- info_stream.print_cr(fmt_stats, "Total",
+ msg.info("%s", sep);
+ msg.info(fmt_stats, "Total",
all_ro_count, all_ro_bytes, all_ro_perc,
all_rw_count, all_rw_bytes, all_rw_perc,
all_count, all_bytes, all_perc);
@@ -930,7 +928,6 @@
assert(all_ro_bytes == ro_all, "everything should have been counted");
assert(all_rw_bytes == rw_all, "everything should have been counted");
- msg.info("%s", info_stream.as_string());
#undef fmt_stats
}
--- a/src/hotspot/share/memory/universe.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/memory/universe.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -542,32 +542,6 @@
#undef assert_pll_locked
#undef assert_pll_ownership
-
-static bool has_run_finalizers_on_exit = false;
-
-void Universe::run_finalizers_on_exit() {
- if (has_run_finalizers_on_exit) return;
- has_run_finalizers_on_exit = true;
-
- // Called on VM exit. This ought to be run in a separate thread.
- log_trace(ref)("Callback to run finalizers on exit");
- {
- PRESERVE_EXCEPTION_MARK;
- Klass* finalizer_klass = SystemDictionary::Finalizer_klass();
- JavaValue result(T_VOID);
- JavaCalls::call_static(
- &result,
- finalizer_klass,
- vmSymbols::run_finalizers_on_exit_name(),
- vmSymbols::void_method_signature(),
- THREAD
- );
- // Ignore any pending exceptions
- CLEAR_PENDING_EXCEPTION;
- }
-}
-
-
// initialize_vtable could cause gc if
// 1) we specified true to initialize_vtable and
// 2) this ran after gc was enabled
--- a/src/hotspot/share/memory/universe.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/memory/universe.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -464,9 +464,6 @@
static bool should_fill_in_stack_trace(Handle throwable);
static void check_alignment(uintx size, uintx alignment, const char* name);
- // Finalizer support.
- static void run_finalizers_on_exit();
-
// Iteration
// Apply "f" to the addresses of all the direct heap pointers maintained
--- a/src/hotspot/share/oops/access.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/oops/access.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -155,6 +155,8 @@
// - Accesses on narrowOop* translate to encoded/decoded memory accesses without runtime checks
// - Accesses on HeapWord* translate to a runtime check choosing one of the above
// - Accesses on other types translate to raw memory accesses without runtime checks
+// * AS_DEST_NOT_INITIALIZED: This property can be important to e.g. SATB barriers by
+// marking that the previous value is uninitialized nonsense rather than a real value.
// * AS_NO_KEEPALIVE: The barrier is used only on oop references and will not keep any involved objects
// alive, regardless of the type of reference being accessed. It will however perform the memory access
// in a consistent way w.r.t. e.g. concurrent compaction, so that the right field is being accessed,
@@ -164,10 +166,12 @@
// responsibility of performing the access and what barriers to be performed to the GC. This is the default.
// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
// decorator for enabling primitive barriers is enabled for the build.
-const DecoratorSet AS_RAW = UCONST64(1) << 11;
-const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 12;
-const DecoratorSet AS_NORMAL = UCONST64(1) << 13;
-const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_NO_KEEPALIVE | AS_NORMAL;
+const DecoratorSet AS_RAW = UCONST64(1) << 11;
+const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 12;
+const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 13;
+const DecoratorSet AS_NORMAL = UCONST64(1) << 14;
+const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_DEST_NOT_INITIALIZED |
+ AS_NO_KEEPALIVE | AS_NORMAL;
// === Reference Strength Decorators ===
// These decorators only apply to accesses on oop-like types (oop/narrowOop).
@@ -178,10 +182,10 @@
// * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
// This could for example come from the unsafe API.
// * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
-const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 14;
-const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 15;
-const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 16;
-const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 17;
+const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 15;
+const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 16;
+const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
+const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
@@ -196,23 +200,21 @@
// * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
// but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
// implies that it is also an IN_ROOT.
-const DecoratorSet IN_HEAP = UCONST64(1) << 18;
-const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 19;
-const DecoratorSet IN_ROOT = UCONST64(1) << 20;
-const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 21;
-const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 22;
+const DecoratorSet IN_HEAP = UCONST64(1) << 19;
+const DecoratorSet IN_HEAP_ARRAY = UCONST64(1) << 20;
+const DecoratorSet IN_ROOT = UCONST64(1) << 21;
+const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 22;
+const DecoratorSet IN_ARCHIVE_ROOT = UCONST64(1) << 23;
const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_HEAP_ARRAY |
IN_ROOT | IN_CONCURRENT_ROOT |
IN_ARCHIVE_ROOT;
// == Value Decorators ==
// * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 23;
+const DecoratorSet OOP_NOT_NULL = UCONST64(1) << 24;
const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
// == Arraycopy Decorators ==
-// * ARRAYCOPY_DEST_NOT_INITIALIZED: This property can be important to e.g. SATB barriers by
-// marking that the previous value uninitialized nonsense rather than a real value.
// * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source
// are not guaranteed to be subclasses of the class of the destination array. This requires
// a check-cast barrier during the copying operation. If this is not set, it is assumed
@@ -222,14 +224,12 @@
// * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
// * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
// * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
-const DecoratorSet ARRAYCOPY_DEST_NOT_INITIALIZED = UCONST64(1) << 24;
const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 25;
const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 26;
const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 27;
const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 28;
const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 29;
-const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_DEST_NOT_INITIALIZED |
- ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
+const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
@@ -343,8 +343,8 @@
template <DecoratorSet expected_mo_decorators>
static void verify_primitive_decorators() {
- const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE) | IN_HEAP |
- IN_HEAP_ARRAY;
+ const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE ^ AS_DEST_NOT_INITIALIZED) |
+ IN_HEAP | IN_HEAP_ARRAY;
verify_decorators<expected_mo_decorators | primitive_decorators>();
}
--- a/src/hotspot/share/oops/access.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/oops/access.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1060,6 +1060,7 @@
const DecoratorSet barrier_strength_decorators = decorators & AS_DECORATOR_MASK;
STATIC_ASSERT(barrier_strength_decorators == 0 || ( // make sure barrier strength decorators are disjoint if set
(barrier_strength_decorators ^ AS_NO_KEEPALIVE) == 0 ||
+ (barrier_strength_decorators ^ AS_DEST_NOT_INITIALIZED) == 0 ||
(barrier_strength_decorators ^ AS_RAW) == 0 ||
(barrier_strength_decorators ^ AS_NORMAL) == 0
));
--- a/src/hotspot/share/opto/callnode.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/callnode.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1441,8 +1441,10 @@
if (!allow_new_nodes) return NULL;
// Create a cast which is control dependent on the initialization to
// propagate the fact that the array length must be positive.
+ InitializeNode* init = initialization();
+ assert(init != NULL, "initialization not found");
length = new CastIINode(length, narrow_length_type);
- length->set_req(0, initialization()->proj_out_or_null(0));
+ length->set_req(0, init->proj_out_or_null(0));
}
}
--- a/src/hotspot/share/opto/graphKit.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/graphKit.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -3861,7 +3861,7 @@
if (use_ReduceInitialCardMarks()
&& obj == just_allocated_object(control())) {
// We can skip marks on a freshly-allocated object in Eden.
- // Keep this code in sync with new_store_pre_barrier() in runtime.cpp.
+ // Keep this code in sync with new_deferred_store_barrier() in runtime.cpp.
// That routine informs GC to take appropriate compensating steps,
// upon a slow-path allocation, so as to make this card-mark
// elision safe.
@@ -4159,7 +4159,7 @@
* as part of the allocation in the case the allocated object is not located
* in the nursery, this would happen for humongous objects. This is similar to
* how CMS is required to handle this case, see the comments for the method
- * CollectedHeap::new_store_pre_barrier and OptoRuntime::new_store_pre_barrier.
+ * CardTableModRefBS::on_allocation_slowpath_exit and OptoRuntime::new_deferred_store_barrier.
* A deferred card mark is required for these objects and handled in the above
* mentioned methods.
*
@@ -4249,7 +4249,7 @@
if (use_ReduceInitialCardMarks() && obj == just_allocated_object(control())) {
// We can skip marks on a freshly-allocated object in Eden.
- // Keep this code in sync with new_store_pre_barrier() in runtime.cpp.
+ // Keep this code in sync with new_deferred_store_barrier() in runtime.cpp.
// That routine informs GC to take appropriate compensating steps,
// upon a slow-path allocation, so as to make this card-mark
// elision safe.
--- a/src/hotspot/share/opto/graphKit.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/graphKit.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -755,8 +755,10 @@
Node* just_allocated_object(Node* current_control);
static bool use_ReduceInitialCardMarks() {
- return (ReduceInitialCardMarks
- && Universe::heap()->can_elide_tlab_store_barriers());
+ BarrierSet *bs = Universe::heap()->barrier_set();
+ return bs->is_a(BarrierSet::CardTableModRef)
+ && barrier_set_cast<CardTableModRefBS>(bs)->can_elide_tlab_store_barriers()
+ && ReduceInitialCardMarks;
}
// Sync Ideal and Graph kits.
--- a/src/hotspot/share/opto/loopnode.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/loopnode.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -2347,7 +2347,7 @@
tty->print(" ");
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
- Node* entry = _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl);
+ Node* entry = _head->is_Loop() ? _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl) : _head->in(LoopNode::EntryControl);
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
if (predicate != NULL ) {
tty->print(" limit_check");
@@ -2398,7 +2398,7 @@
if (Verbose) {
tty->print(" body={"); _body.dump_simple(); tty->print(" }");
}
- if (_head->as_Loop()->is_strip_mined()) {
+ if (_head->is_Loop() && _head->as_Loop()->is_strip_mined()) {
tty->print(" strip_mined");
}
tty->cr();
--- a/src/hotspot/share/opto/loopopts.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/loopopts.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -693,7 +693,9 @@
Node* PhaseIdealLoop::try_move_store_before_loop(Node* n, Node *n_ctrl) {
// Store has to be first in the loop body
IdealLoopTree *n_loop = get_loop(n_ctrl);
- if (n->is_Store() && n_loop != _ltree_root && n_loop->is_loop() && n->in(0) != NULL) {
+ if (n->is_Store() && n_loop != _ltree_root &&
+ n_loop->is_loop() && n_loop->_head->is_Loop() &&
+ n->in(0) != NULL) {
Node* address = n->in(MemNode::Address);
Node* value = n->in(MemNode::ValueIn);
Node* mem = n->in(MemNode::Memory);
--- a/src/hotspot/share/opto/runtime.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/runtime.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -194,23 +194,6 @@
// We failed the fast-path allocation. Now we need to do a scavenge or GC
// and try allocation again.
-void OptoRuntime::new_store_pre_barrier(JavaThread* thread) {
- // After any safepoint, just before going back to compiled code,
- // we inform the GC that we will be doing initializing writes to
- // this object in the future without emitting card-marks, so
- // GC may take any compensating steps.
- // NOTE: Keep this code consistent with GraphKit::store_barrier.
-
- oop new_obj = thread->vm_result();
- if (new_obj == NULL) return;
-
- assert(Universe::heap()->can_elide_tlab_store_barriers(),
- "compiler must check this first");
- // GC may decide to give back a safer copy of new_obj.
- new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj);
- thread->set_vm_result(new_obj);
-}
-
// object allocation
JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(Klass* klass, JavaThread* thread))
JRT_BLOCK;
@@ -244,10 +227,8 @@
deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION);
JRT_BLOCK_END;
- if (GraphKit::use_ReduceInitialCardMarks()) {
- // inform GC that we won't do card marks for initializing writes.
- new_store_pre_barrier(thread);
- }
+ // inform GC that we won't do card marks for initializing writes.
+ SharedRuntime::on_slowpath_allocation_exit(thread);
JRT_END
@@ -284,10 +265,8 @@
thread->set_vm_result(result);
JRT_BLOCK_END;
- if (GraphKit::use_ReduceInitialCardMarks()) {
- // inform GC that we won't do card marks for initializing writes.
- new_store_pre_barrier(thread);
- }
+ // inform GC that we won't do card marks for initializing writes.
+ SharedRuntime::on_slowpath_allocation_exit(thread);
JRT_END
// array allocation without zeroing
@@ -314,10 +293,9 @@
thread->set_vm_result(result);
JRT_BLOCK_END;
- if (GraphKit::use_ReduceInitialCardMarks()) {
- // inform GC that we won't do card marks for initializing writes.
- new_store_pre_barrier(thread);
- }
+
+ // inform GC that we won't do card marks for initializing writes.
+ SharedRuntime::on_slowpath_allocation_exit(thread);
oop result = thread->vm_result();
if ((len > 0) && (result != NULL) &&
--- a/src/hotspot/share/opto/runtime.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/opto/runtime.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -163,10 +163,6 @@
static void new_array_C(Klass* array_klass, int len, JavaThread *thread);
static void new_array_nozero_C(Klass* array_klass, int len, JavaThread *thread);
- // Post-slow-path-allocation, pre-initializing-stores step for
- // implementing ReduceInitialCardMarks
- static void new_store_pre_barrier(JavaThread* thread);
-
// Allocate storage for a multi-dimensional arrays
// Note: needs to be fixed for arbitrary number of dimensions
static void multianewarray2_C(Klass* klass, int len1, int len2, JavaThread *thread);
--- a/src/hotspot/share/prims/whitebox.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -60,6 +60,7 @@
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/exceptions.hpp"
+#include "utilities/elfFile.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_CDS
#include "prims/cdsoffsets.hpp"
@@ -528,7 +529,7 @@
size_t total_memory() { return _total_memory; }
size_t total_memory_to_free() { return _total_memory_to_free; }
- bool doHeapRegion(HeapRegion* r) {
+ bool do_heap_region(HeapRegion* r) {
if (r->is_old()) {
size_t prev_live = r->marked_bytes();
size_t live = r->live_bytes();
@@ -1911,6 +1912,13 @@
os::print_os_info(tty);
WB_END
+// Elf decoder
+WB_ENTRY(void, WB_DisableElfSectionCache(JNIEnv* env))
+#if !defined(_WINDOWS) && !defined(__APPLE__)
+ ElfFile::_do_not_cache_elf_section = true;
+#endif
+WB_END
+
#define CC (char*)
@@ -2125,6 +2133,7 @@
(void*)&WB_CheckLibSpecifiesNoexecstack},
{CC"isContainerized", CC"()Z", (void*)&WB_IsContainerized },
{CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo },
+ {CC"disableElfSectionCache", CC"()V", (void*)&WB_DisableElfSectionCache },
};
--- a/src/hotspot/share/runtime/arguments.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -537,6 +537,7 @@
{ "SharedReadOnlySize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
{ "SharedMiscDataSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
{ "SharedMiscCodeSize", JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
+ { "UseUTCFileTimestamp", JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
--- a/src/hotspot/share/runtime/fieldDescriptor.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/fieldDescriptor.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -201,6 +201,12 @@
}
// Print a hint as to the underlying integer representation. This can be wrong for
// pointers on an LP64 machine
+#ifdef _LP64
+ if ((ft == T_OBJECT || ft == T_ARRAY) && UseCompressedOops) {
+ st->print(" (%x)", obj->int_field(offset()));
+ }
+ else // <- intended
+#endif
if (ft == T_LONG || ft == T_DOUBLE LP64_ONLY(|| !is_java_primitive(ft)) ) {
st->print(" (%x %x)", obj->int_field(offset()), obj->int_field(offset()+sizeof(jint)));
} else if (as_int < 0 || as_int > 9) {
--- a/src/hotspot/share/runtime/os.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/os.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -85,7 +85,7 @@
julong os::free_bytes = 0; // # of bytes freed
#endif
-static juint cur_malloc_words = 0; // current size for MallocMaxTestWords
+static size_t cur_malloc_words = 0; // current size for MallocMaxTestWords
void os_init_globals() {
// Called from init_globals().
@@ -629,12 +629,12 @@
//
static bool has_reached_max_malloc_test_peak(size_t alloc_size) {
if (MallocMaxTestWords > 0) {
- jint words = (jint)(alloc_size / BytesPerWord);
+ size_t words = (alloc_size / BytesPerWord);
if ((cur_malloc_words + words) > MallocMaxTestWords) {
return true;
}
- Atomic::add(words, (volatile jint *)&cur_malloc_words);
+ Atomic::add(words, &cur_malloc_words);
}
return false;
}
@@ -1826,8 +1826,7 @@
os::SuspendResume::State os::SuspendResume::switch_state(os::SuspendResume::State from,
os::SuspendResume::State to)
{
- os::SuspendResume::State result =
- (os::SuspendResume::State) Atomic::cmpxchg((jint) to, (jint *) &_state, (jint) from);
+ os::SuspendResume::State result = Atomic::cmpxchg(to, &_state, from);
if (result == from) {
// success
return to;
--- a/src/hotspot/share/runtime/os.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/os.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -27,6 +27,8 @@
#include "jvm.h"
#include "jvmtifiles/jvmti.h"
+#include "metaprogramming/isRegisteredEnum.hpp"
+#include "metaprogramming/integralConstant.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/handles.hpp"
#include "utilities/macros.hpp"
@@ -907,11 +909,11 @@
class SuspendedThreadTask {
public:
SuspendedThreadTask(Thread* thread) : _thread(thread), _done(false) {}
- virtual ~SuspendedThreadTask() {}
void run();
bool is_done() { return _done; }
virtual void do_task(const SuspendedThreadTaskContext& context) = 0;
protected:
+ ~SuspendedThreadTask() {}
private:
void internal_do_task();
Thread* _thread;
@@ -1006,6 +1008,10 @@
};
+#ifndef _WINDOWS
+template<> struct IsRegisteredEnum<os::SuspendResume::State> : public TrueType {};
+#endif // !_WINDOWS
+
// Note that "PAUSE" is almost always used with synchronization
// so arguably we should provide Atomic::SpinPause() instead
// of the global SpinPause() with C linkage.
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3169,3 +3169,16 @@
}
return activation;
}
+
+void SharedRuntime::on_slowpath_allocation_exit(JavaThread* thread) {
+ // After any safepoint, just before going back to compiled code,
+ // we inform the GC that we will be doing initializing writes to
+ // this object in the future without emitting card-marks, so
+ // GC may take any compensating steps.
+
+ oop new_obj = thread->vm_result();
+ if (new_obj == NULL) return;
+
+ BarrierSet *bs = Universe::heap()->barrier_set();
+ bs->on_slowpath_allocation_exit(thread, new_obj);
+}
--- a/src/hotspot/share/runtime/sharedRuntime.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -211,6 +211,10 @@
static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, CompiledMethod* nm, int deopt_reason);
#endif
+ // Post-slow-path-allocation, pre-initializing-stores step for
+ // implementing e.g. ReduceInitialCardMarks
+ static void on_slowpath_allocation_exit(JavaThread* thread);
+
static void enable_stack_reserved_zone(JavaThread* thread);
static frame look_for_reserved_stack_annotated_method(JavaThread* thread, frame fr);
--- a/src/hotspot/share/runtime/stubRoutines.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/stubRoutines.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -418,7 +418,7 @@
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT
assert(count != 0, "count should be non-zero");
- HeapAccess<ARRAYCOPY_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, (HeapWord*)src, (HeapWord*)dest, count);
+ HeapAccess<AS_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, (HeapWord*)src, (HeapWord*)dest, count);
JRT_END
JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count))
@@ -462,7 +462,7 @@
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT
assert(count != 0, "count should be non-zero");
- HeapAccess<ARRAYCOPY_ARRAYOF | ARRAYCOPY_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, src, dest, count);
+ HeapAccess<ARRAYCOPY_ARRAYOF | AS_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, src, dest, count);
JRT_END
address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) {
--- a/src/hotspot/share/runtime/thread.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/thread.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1994,20 +1994,10 @@
JvmtiExport::cleanup_thread(this);
}
- // We must flush any deferred card marks before removing a thread from
- // the list of active threads.
- Universe::heap()->flush_deferred_store_barrier(this);
- assert(deferred_card_mark().is_empty(), "Should have been flushed");
-
-#if INCLUDE_ALL_GCS
- // We must flush the G1-related buffers before removing a thread
- // from the list of active threads. We must do this after any deferred
- // card marks have been flushed (above) so that any entries that are
- // added to the thread's dirty card queue as a result are not lost.
- if (UseG1GC) {
- flush_barrier_queues();
- }
-#endif // INCLUDE_ALL_GCS
+ // We must flush any deferred card marks and other various GC barrier
+ // related buffers (e.g. G1 SATB buffer and G1 dirty card queue buffer)
+ // before removing a thread from the list of active threads.
+ BarrierSet::barrier_set()->flush_deferred_barriers(this);
log_info(os, thread)("JavaThread %s (tid: " UINTX_FORMAT ").",
exit_type == JavaThread::normal_exit ? "exiting" : "detaching",
@@ -4202,10 +4192,9 @@
// SystemDictionary::resolve_or_null will return null if there was
// an exception. If we cannot load the Shutdown class, just don't
// call Shutdown.shutdown() at all. This will mean the shutdown hooks
- // and finalizers (if runFinalizersOnExit is set) won't be run.
- // Note that if a shutdown hook was registered or runFinalizersOnExit
- // was called, the Shutdown class would have already been loaded
- // (Runtime.addShutdownHook and runFinalizersOnExit will load it).
+ // won't be run. Note that if a shutdown hook was registered,
+ // the Shutdown class would have already been loaded
+ // (Runtime.addShutdownHook will load it).
JavaValue result(T_VOID);
JavaCalls::call_static(&result,
shutdown_klass,
@@ -4228,7 +4217,7 @@
// + Wait until we are the last non-daemon thread to execute
// <-- every thing is still working at this moment -->
// + Call java.lang.Shutdown.shutdown(), which will invoke Java level
-// shutdown hooks, run finalizers if finalization-on-exit
+// shutdown hooks
// + Call before_exit(), prepare for VM exit
// > run VM level shutdown hooks (they are registered through JVM_OnExit(),
// currently the only user of this mechanism is File.deleteOnExit())
--- a/src/hotspot/share/runtime/thread.inline.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/thread.inline.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,24 +30,18 @@
#include "runtime/thread.hpp"
inline void Thread::set_suspend_flag(SuspendFlags f) {
- assert(sizeof(jint) == sizeof(_suspend_flags), "size mismatch");
uint32_t flags;
do {
flags = _suspend_flags;
}
- while (Atomic::cmpxchg((jint)(flags | f),
- (volatile jint*)&_suspend_flags,
- (jint)flags) != (jint)flags);
+ while (Atomic::cmpxchg((flags | f), &_suspend_flags, flags) != flags);
}
inline void Thread::clear_suspend_flag(SuspendFlags f) {
- assert(sizeof(jint) == sizeof(_suspend_flags), "size mismatch");
uint32_t flags;
do {
flags = _suspend_flags;
}
- while (Atomic::cmpxchg((jint)(flags & ~f),
- (volatile jint*)&_suspend_flags,
- (jint)flags) != (jint)flags);
+ while (Atomic::cmpxchg((flags & ~f), &_suspend_flags, flags) != flags);
}
inline void Thread::set_has_async_exception() {
--- a/src/hotspot/share/runtime/vmStructs.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/runtime/vmStructs.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -466,6 +466,7 @@
nonstatic_field(CardGeneration, _capacity_at_prologue, size_t) \
nonstatic_field(CardGeneration, _used_at_prologue, size_t) \
\
+ nonstatic_field(CardTableModRefBS, _defer_initial_card_mark, bool) \
nonstatic_field(CardTableModRefBS, _whole_heap, const MemRegion) \
nonstatic_field(CardTableModRefBS, _guard_index, const size_t) \
nonstatic_field(CardTableModRefBS, _last_valid_index, const size_t) \
@@ -482,7 +483,6 @@
\
nonstatic_field(CollectedHeap, _reserved, MemRegion) \
nonstatic_field(CollectedHeap, _barrier_set, BarrierSet*) \
- nonstatic_field(CollectedHeap, _defer_initial_card_mark, bool) \
nonstatic_field(CollectedHeap, _is_gc_active, bool) \
nonstatic_field(CollectedHeap, _total_collections, unsigned int) \
\
--- a/src/hotspot/share/services/mallocSiteTable.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/services/mallocSiteTable.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -151,7 +151,7 @@
~AccessLock() {
if (_lock_state == SharedLock) {
- Atomic::dec((volatile jint*)_lock);
+ Atomic::dec(_lock);
}
}
// Acquire shared lock.
@@ -159,7 +159,7 @@
inline bool sharedLock() {
jint res = Atomic::add(1, _lock);
if (res < 0) {
- Atomic::add(-1, _lock);
+ Atomic::dec(_lock);
return false;
}
_lock_state = SharedLock;
--- a/src/hotspot/share/services/mallocTracker.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/services/mallocTracker.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,8 +66,6 @@
assert(_size >= sz, "deallocation > allocated");
Atomic::dec(&_count);
if (sz > 0) {
- // unary minus operator applied to unsigned type, result still unsigned
- #pragma warning(suppress: 4146)
Atomic::sub(sz, &_size);
}
}
--- a/src/hotspot/share/services/threadService.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/services/threadService.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -120,7 +120,7 @@
}
void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
- Atomic::dec((jint*) &_exiting_threads_count);
+ Atomic::dec(&_exiting_threads_count);
if (thread->is_hidden_from_external_view() ||
thread->is_jvmti_agent_thread()) {
@@ -131,17 +131,17 @@
if (daemon) {
_daemon_threads_count->set_value(_daemon_threads_count->get_value() - 1);
- Atomic::dec((jint*) &_exiting_daemon_threads_count);
+ Atomic::dec(&_exiting_daemon_threads_count);
}
}
void ThreadService::current_thread_exiting(JavaThread* jt) {
assert(jt == JavaThread::current(), "Called by current thread");
- Atomic::inc((jint*) &_exiting_threads_count);
+ Atomic::inc(&_exiting_threads_count);
oop threadObj = jt->threadObj();
if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
- Atomic::inc((jint*) &_exiting_daemon_threads_count);
+ Atomic::inc(&_exiting_daemon_threads_count);
}
}
--- a/src/hotspot/share/utilities/copy.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/copy.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,10 +29,8 @@
// Copy bytes; larger units are filled atomically if everything is aligned.
-void Copy::conjoint_memory_atomic(void* from, void* to, size_t size) {
- address src = (address) from;
- address dst = (address) to;
- uintptr_t bits = (uintptr_t) src | (uintptr_t) dst | (uintptr_t) size;
+void Copy::conjoint_memory_atomic(const void* from, void* to, size_t size) {
+ uintptr_t bits = (uintptr_t) from | (uintptr_t) to | (uintptr_t) size;
// (Note: We could improve performance by ignoring the low bits of size,
// and putting a short cleanup loop after each bulk copy loop.
@@ -43,14 +41,14 @@
// which may or may not want to include such optimizations.)
if (bits % sizeof(jlong) == 0) {
- Copy::conjoint_jlongs_atomic((jlong*) src, (jlong*) dst, size / sizeof(jlong));
+ Copy::conjoint_jlongs_atomic((const jlong*) from, (jlong*) to, size / sizeof(jlong));
} else if (bits % sizeof(jint) == 0) {
- Copy::conjoint_jints_atomic((jint*) src, (jint*) dst, size / sizeof(jint));
+ Copy::conjoint_jints_atomic((const jint*) from, (jint*) to, size / sizeof(jint));
} else if (bits % sizeof(jshort) == 0) {
- Copy::conjoint_jshorts_atomic((jshort*) src, (jshort*) dst, size / sizeof(jshort));
+ Copy::conjoint_jshorts_atomic((const jshort*) from, (jshort*) to, size / sizeof(jshort));
} else {
// Not aligned, so no need to be atomic.
- Copy::conjoint_jbytes((void*) src, (void*) dst, size);
+ Copy::conjoint_jbytes((const void*) from, (void*) to, size);
}
}
--- a/src/hotspot/share/utilities/copy.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/copy.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,28 +31,28 @@
// Assembly code for platforms that need it.
extern "C" {
- void _Copy_conjoint_words(HeapWord* from, HeapWord* to, size_t count);
- void _Copy_disjoint_words(HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_conjoint_words(const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_disjoint_words(const HeapWord* from, HeapWord* to, size_t count);
- void _Copy_conjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count);
- void _Copy_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_conjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count);
- void _Copy_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count);
- void _Copy_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count);
- void _Copy_conjoint_bytes(void* from, void* to, size_t count);
+ void _Copy_conjoint_bytes(const void* from, void* to, size_t count);
- void _Copy_conjoint_bytes_atomic (void* from, void* to, size_t count);
- void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count);
- void _Copy_conjoint_jints_atomic (jint* from, jint* to, size_t count);
- void _Copy_conjoint_jlongs_atomic (jlong* from, jlong* to, size_t count);
- void _Copy_conjoint_oops_atomic (oop* from, oop* to, size_t count);
+ void _Copy_conjoint_bytes_atomic (const void* from, void* to, size_t count);
+ void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count);
+ void _Copy_conjoint_jints_atomic (const jint* from, jint* to, size_t count);
+ void _Copy_conjoint_jlongs_atomic (const jlong* from, jlong* to, size_t count);
+ void _Copy_conjoint_oops_atomic (const oop* from, oop* to, size_t count);
- void _Copy_arrayof_conjoint_bytes (HeapWord* from, HeapWord* to, size_t count);
- void _Copy_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count);
- void _Copy_arrayof_conjoint_jints (HeapWord* from, HeapWord* to, size_t count);
- void _Copy_arrayof_conjoint_jlongs (HeapWord* from, HeapWord* to, size_t count);
- void _Copy_arrayof_conjoint_oops (HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_arrayof_conjoint_bytes (const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_arrayof_conjoint_jints (const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_arrayof_conjoint_jlongs (const HeapWord* from, HeapWord* to, size_t count);
+ void _Copy_arrayof_conjoint_oops (const HeapWord* from, HeapWord* to, size_t count);
}
class Copy : AllStatic {
@@ -87,33 +87,33 @@
// HeapWords
// Word-aligned words, conjoint, not atomic on each word
- static void conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ static void conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogHeapWordSize);
pd_conjoint_words(from, to, count);
}
// Word-aligned words, disjoint, not atomic on each word
- static void disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ static void disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogHeapWordSize);
assert_disjoint(from, to, count);
pd_disjoint_words(from, to, count);
}
// Word-aligned words, disjoint, atomic on each word
- static void disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
+ static void disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogHeapWordSize);
assert_disjoint(from, to, count);
pd_disjoint_words_atomic(from, to, count);
}
// Object-aligned words, conjoint, not atomic on each word
- static void aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ static void aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_aligned(from, to);
pd_aligned_conjoint_words(from, to, count);
}
// Object-aligned words, disjoint, not atomic on each word
- static void aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ static void aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_aligned(from, to);
assert_disjoint(from, to, count);
pd_aligned_disjoint_words(from, to, count);
@@ -122,77 +122,77 @@
// bytes, jshorts, jints, jlongs, oops
// bytes, conjoint, not atomic on each byte (not that it matters)
- static void conjoint_jbytes(void* from, void* to, size_t count) {
+ static void conjoint_jbytes(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
// bytes, conjoint, atomic on each byte (not that it matters)
- static void conjoint_jbytes_atomic(void* from, void* to, size_t count) {
+ static void conjoint_jbytes_atomic(const void* from, void* to, size_t count) {
pd_conjoint_bytes(from, to, count);
}
// jshorts, conjoint, atomic on each jshort
- static void conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+ static void conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
assert_params_ok(from, to, LogBytesPerShort);
pd_conjoint_jshorts_atomic(from, to, count);
}
// jints, conjoint, atomic on each jint
- static void conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+ static void conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
assert_params_ok(from, to, LogBytesPerInt);
pd_conjoint_jints_atomic(from, to, count);
}
// jlongs, conjoint, atomic on each jlong
- static void conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+ static void conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
assert_params_ok(from, to, LogBytesPerLong);
pd_conjoint_jlongs_atomic(from, to, count);
}
// oops, conjoint, atomic on each oop
- static void conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+ static void conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
assert_params_ok(from, to, LogBytesPerHeapOop);
pd_conjoint_oops_atomic(from, to, count);
}
// overloaded for UseCompressedOops
- static void conjoint_oops_atomic(narrowOop* from, narrowOop* to, size_t count) {
+ static void conjoint_oops_atomic(const narrowOop* from, narrowOop* to, size_t count) {
assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong");
assert_params_ok(from, to, LogBytesPerInt);
- pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+ pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
}
// Copy a span of memory. If the span is an integral number of aligned
// longs, words, or ints, copy those units atomically.
// The largest atomic transfer unit is 8 bytes, or the largest power
// of two which divides all of from, to, and size, whichever is smaller.
- static void conjoint_memory_atomic(void* from, void* to, size_t size);
+ static void conjoint_memory_atomic(const void* from, void* to, size_t size);
// bytes, conjoint array, atomic on each byte (not that it matters)
- static void arrayof_conjoint_jbytes(HeapWord* from, HeapWord* to, size_t count) {
+ static void arrayof_conjoint_jbytes(const HeapWord* from, HeapWord* to, size_t count) {
pd_arrayof_conjoint_bytes(from, to, count);
}
// jshorts, conjoint array, atomic on each jshort
- static void arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
+ static void arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogBytesPerShort);
pd_arrayof_conjoint_jshorts(from, to, count);
}
// jints, conjoint array, atomic on each jint
- static void arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
+ static void arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogBytesPerInt);
pd_arrayof_conjoint_jints(from, to, count);
}
// jlongs, conjoint array, atomic on each jlong
- static void arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
+ static void arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogBytesPerLong);
pd_arrayof_conjoint_jlongs(from, to, count);
}
// oops, conjoint array, atomic on each oop
- static void arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
+ static void arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
assert_params_ok(from, to, LogBytesPerHeapOop);
pd_arrayof_conjoint_oops(from, to, count);
}
@@ -200,7 +200,7 @@
// Known overlap methods
// Copy word-aligned words from higher to lower addresses, not atomic on each word
- inline static void conjoint_words_to_lower(HeapWord* from, HeapWord* to, size_t byte_count) {
+ inline static void conjoint_words_to_lower(const HeapWord* from, HeapWord* to, size_t byte_count) {
// byte_count is in bytes to check its alignment
assert_params_ok(from, to, LogHeapWordSize);
assert_byte_count_ok(byte_count, HeapWordSize);
@@ -214,7 +214,7 @@
}
// Copy word-aligned words from lower to higher addresses, not atomic on each word
- inline static void conjoint_words_to_higher(HeapWord* from, HeapWord* to, size_t byte_count) {
+ inline static void conjoint_words_to_higher(const HeapWord* from, HeapWord* to, size_t byte_count) {
// byte_count is in bytes to check its alignment
assert_params_ok(from, to, LogHeapWordSize);
assert_byte_count_ok(byte_count, HeapWordSize);
@@ -305,7 +305,7 @@
}
private:
- static bool params_disjoint(HeapWord* from, HeapWord* to, size_t count) {
+ static bool params_disjoint(const HeapWord* from, HeapWord* to, size_t count) {
if (from < to) {
return pointer_delta(to, from) >= count;
}
@@ -314,14 +314,14 @@
// These methods raise a fatal if they detect a problem.
- static void assert_disjoint(HeapWord* from, HeapWord* to, size_t count) {
+ static void assert_disjoint(const HeapWord* from, HeapWord* to, size_t count) {
#ifdef ASSERT
if (!params_disjoint(from, to, count))
basic_fatal("source and dest overlap");
#endif
}
- static void assert_params_ok(void* from, void* to, intptr_t log_align) {
+ static void assert_params_ok(const void* from, void* to, intptr_t log_align) {
#ifdef ASSERT
if (mask_bits((uintptr_t)from, right_n_bits(log_align)) != 0)
basic_fatal("not aligned");
@@ -336,7 +336,7 @@
basic_fatal("not word aligned");
#endif
}
- static void assert_params_aligned(HeapWord* from, HeapWord* to) {
+ static void assert_params_aligned(const HeapWord* from, HeapWord* to) {
#ifdef ASSERT
if (mask_bits((uintptr_t)from, BytesPerLong-1) != 0)
basic_fatal("not long aligned");
--- a/src/hotspot/share/utilities/decoder.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/decoder.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,12 +33,10 @@
class AbstractDecoder : public CHeapObj<mtInternal> {
public:
- virtual ~AbstractDecoder() {}
-
// status code for decoding native C frame
enum decoder_status {
not_available = -10, // real decoder is not available
- no_error = 0, // successfully decoded frames
+ no_error = 0, // no error encountered
out_of_memory, // out of memory
file_invalid, // invalid elf file
file_not_found, // could not found symbol file (on windows), such as jvm.pdb or jvm.map
@@ -46,6 +44,12 @@
helper_init_error // SymInitialize failed (Windows only)
};
+protected:
+ decoder_status _decoder_status;
+
+public:
+ virtual ~AbstractDecoder() {}
+
// decode an pc address to corresponding function name and an offset from the beginning of
// the function
//
@@ -68,11 +72,8 @@
}
static bool is_error(decoder_status status) {
- return (status > 0);
+ return (status > no_error);
}
-
-protected:
- decoder_status _decoder_status;
};
// Do nothing decoder
@@ -96,10 +97,8 @@
virtual bool demangle(const char* symbol, char* buf, int buflen) {
return false;
}
-
};
-
class Decoder : AllStatic {
public:
static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL, bool demangle = true);
--- a/src/hotspot/share/utilities/elfFile.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfFile.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,60 +31,150 @@
#include <limits.h>
#include <new>
+#include "logging/log.hpp"
#include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
#include "utilities/elfFuncDescTable.hpp"
#include "utilities/elfStringTable.hpp"
#include "utilities/elfSymbolTable.hpp"
+#include "utilities/ostream.hpp"
+// For test only, disable elf section cache and force to read from file directly.
+bool ElfFile::_do_not_cache_elf_section = false;
+
+ElfSection::ElfSection(FILE* fd, const Elf_Shdr& hdr) : _section_data(NULL) {
+ _stat = load_section(fd, hdr);
+}
+
+ElfSection::~ElfSection() {
+ if (_section_data != NULL) {
+ os::free(_section_data);
+ }
+}
+
+NullDecoder::decoder_status ElfSection::load_section(FILE* const fd, const Elf_Shdr& shdr) {
+ memcpy((void*)&_section_hdr, (const void*)&shdr, sizeof(shdr));
+
+ if (ElfFile::_do_not_cache_elf_section) {
+ log_debug(decoder)("Elf section cache is disabled");
+ return NullDecoder::no_error;
+ }
+
+ _section_data = os::malloc(shdr.sh_size, mtInternal);
+ // No enough memory for caching. It is okay, we can try to read from
+ // file instead.
+ if (_section_data == NULL) return NullDecoder::no_error;
-ElfFile::ElfFile(const char* filepath) {
- assert(filepath, "null file path");
- memset(&m_elfHdr, 0, sizeof(m_elfHdr));
- m_string_tables = NULL;
- m_symbol_tables = NULL;
- m_funcDesc_table = NULL;
- m_next = NULL;
- m_status = NullDecoder::no_error;
+ MarkedFileReader mfd(fd);
+ if (mfd.has_mark() &&
+ mfd.set_position(shdr.sh_offset) &&
+ mfd.read(_section_data, shdr.sh_size)) {
+ return NullDecoder::no_error;
+ } else {
+ os::free(_section_data);
+ _section_data = NULL;
+ return NullDecoder::file_invalid;
+ }
+}
+
+bool FileReader::read(void* buf, size_t size) {
+ assert(buf != NULL, "no buffer");
+ assert(size > 0, "no space");
+ return fread(buf, size, 1, _fd) == 1;
+}
+
+int FileReader::read_buffer(void* buf, size_t size) {
+ assert(buf != NULL, "no buffer");
+ assert(size > 0, "no space");
+ return fread(buf, 1, size, _fd);
+}
+
+bool FileReader::set_position(long offset) {
+ return fseek(_fd, offset, SEEK_SET) == 0;
+}
+
+MarkedFileReader::MarkedFileReader(FILE* fd) : FileReader(fd) {
+ _marked_pos = ftell(fd);
+}
+
+MarkedFileReader::~MarkedFileReader() {
+ if (_marked_pos != -1) {
+ set_position(_marked_pos);
+ }
+}
+
+ElfFile::ElfFile(const char* filepath) :
+ _string_tables(NULL), _symbol_tables(NULL), _funcDesc_table(NULL),
+ _next(NULL), _status(NullDecoder::no_error),
+ _shdr_string_table(NULL), _file(NULL), _filepath(NULL) {
+ memset(&_elfHdr, 0, sizeof(_elfHdr));
int len = strlen(filepath) + 1;
- m_filepath = (const char*)os::malloc(len * sizeof(char), mtInternal);
- if (m_filepath != NULL) {
- strcpy((char*)m_filepath, filepath);
- m_file = fopen(filepath, "r");
- if (m_file != NULL) {
- load_tables();
- } else {
- m_status = NullDecoder::file_not_found;
- }
- } else {
- m_status = NullDecoder::out_of_memory;
+ _filepath = (char*)os::malloc(len * sizeof(char), mtInternal);
+ if (_filepath == NULL) {
+ _status = NullDecoder::out_of_memory;
+ return;
+ }
+ strcpy(_filepath, filepath);
+
+ _status = parse_elf(filepath);
+
+ // we no longer need section header string table
+ if (_shdr_string_table != NULL) {
+ delete _shdr_string_table;
+ _shdr_string_table = NULL;
}
}
ElfFile::~ElfFile() {
- if (m_string_tables != NULL) {
- delete m_string_tables;
+ if (_shdr_string_table != NULL) {
+ delete _shdr_string_table;
}
- if (m_symbol_tables != NULL) {
- delete m_symbol_tables;
+ cleanup_tables();
+
+ if (_file != NULL) {
+ fclose(_file);
+ }
+
+ if (_filepath != NULL) {
+ os::free((void*)_filepath);
}
- if (m_file != NULL) {
- fclose(m_file);
+ if (_next != NULL) {
+ delete _next;
+ }
+}
+
+void ElfFile::cleanup_tables() {
+ if (_string_tables != NULL) {
+ delete _string_tables;
+ _string_tables = NULL;
+ }
+
+ if (_symbol_tables != NULL) {
+ delete _symbol_tables;
+ _symbol_tables = NULL;
}
- if (m_filepath != NULL) {
- os::free((void*)m_filepath);
+ if (_funcDesc_table != NULL) {
+ delete _funcDesc_table;
+ _funcDesc_table = NULL;
}
+}
- if (m_next != NULL) {
- delete m_next;
+NullDecoder::decoder_status ElfFile::parse_elf(const char* filepath) {
+ assert(filepath, "null file path");
+
+ _file = fopen(filepath, "r");
+ if (_file != NULL) {
+ return load_tables();
+ } else {
+ return NullDecoder::file_not_found;
}
-};
-
+}
//Check elf header to ensure the file is valid.
bool ElfFile::is_elf_file(Elf_Ehdr& hdr) {
@@ -96,116 +186,134 @@
ELFDATANONE != hdr.e_ident[EI_DATA]);
}
-bool ElfFile::load_tables() {
- assert(m_file, "file not open");
- assert(!NullDecoder::is_error(m_status), "already in error");
+NullDecoder::decoder_status ElfFile::load_tables() {
+ assert(_file, "file not open");
+ assert(!NullDecoder::is_error(_status), "already in error");
+ FileReader freader(fd());
// read elf file header
- if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
- m_status = NullDecoder::file_invalid;
- return false;
+ if (!freader.read(&_elfHdr, sizeof(_elfHdr))) {
+ return NullDecoder::file_invalid;
}
- if (!is_elf_file(m_elfHdr)) {
- m_status = NullDecoder::file_invalid;
- return false;
+ // Check signature
+ if (!is_elf_file(_elfHdr)) {
+ return NullDecoder::file_invalid;
}
// walk elf file's section headers, and load string tables
Elf_Shdr shdr;
- if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
- if (NullDecoder::is_error(m_status)) return false;
+ if (!freader.set_position(_elfHdr.e_shoff)) {
+ return NullDecoder::file_invalid;
+ }
- for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
- if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
- m_status = NullDecoder::file_invalid;
- return false;
- }
- if (shdr.sh_type == SHT_STRTAB) {
- // string tables
- ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
- if (table == NULL) {
- m_status = NullDecoder::out_of_memory;
- return false;
- }
- add_string_table(table);
- } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
- // symbol tables
- ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
- if (table == NULL) {
- m_status = NullDecoder::out_of_memory;
- return false;
- }
- add_symbol_table(table);
- }
+ for (int index = 0; index < _elfHdr.e_shnum; index ++) {
+ if (!freader.read(&shdr, sizeof(shdr))) {
+ return NullDecoder::file_invalid;
}
-#if defined(PPC64) && !defined(ABI_ELFv2)
- // Now read the .opd section wich contains the PPC64 function descriptor table.
- // The .opd section is only available on PPC64 (see for example:
- // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
- // so this code should do no harm on other platforms but because of performance reasons we only
- // execute it on PPC64 platforms.
- // Notice that we can only find the .opd section after we have successfully read in the string
- // tables in the previous loop, because we need to query the name of each section which is
- // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx).
-
- // Reset the file pointer
- if (fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
- return false;
+ if (shdr.sh_type == SHT_STRTAB) {
+ // string tables
+ ElfStringTable* table = new (std::nothrow) ElfStringTable(fd(), shdr, index);
+ if (table == NULL) {
+ return NullDecoder::out_of_memory;
+ }
+ if (index == _elfHdr.e_shstrndx) {
+ assert(_shdr_string_table == NULL, "Only set once");
+ _shdr_string_table = table;
+ } else {
+ add_string_table(table);
+ }
+ } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
+ // symbol tables
+ ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(fd(), shdr);
+ if (table == NULL) {
+ return NullDecoder::out_of_memory;
+ }
+ add_symbol_table(table);
}
- for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
- if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
- m_status = NullDecoder::file_invalid;
- return false;
- }
- if (m_elfHdr.e_shstrndx != SHN_UNDEF && shdr.sh_type == SHT_PROGBITS) {
- ElfStringTable* string_table = get_string_table(m_elfHdr.e_shstrndx);
- if (string_table == NULL) {
- m_status = NullDecoder::file_invalid;
- return false;
- }
- char buf[8]; // '8' is enough because we only want to read ".opd"
- if (string_table->string_at(shdr.sh_name, buf, sizeof(buf)) && !strncmp(".opd", buf, 4)) {
- m_funcDesc_table = new (std::nothrow) ElfFuncDescTable(m_file, shdr, index);
- if (m_funcDesc_table == NULL) {
- m_status = NullDecoder::out_of_memory;
- return false;
- }
- break;
- }
+ }
+#if defined(PPC64) && !defined(ABI_ELFv2)
+ // Now read the .opd section wich contains the PPC64 function descriptor table.
+ // The .opd section is only available on PPC64 (see for example:
+ // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
+ // so this code should do no harm on other platforms but because of performance reasons we only
+ // execute it on PPC64 platforms.
+ // Notice that we can only find the .opd section after we have successfully read in the string
+ // tables in the previous loop, because we need to query the name of each section which is
+ // contained in one of the string tables (i.e. the one with the index m_elfHdr.e_shstrndx).
+
+ // Reset the file pointer
+ int sect_index = section_by_name(".opd", shdr);
+
+ if (sect_index == -1) {
+ return NullDecoder::file_invalid;
+ }
+
+ _funcDesc_table = new (std::nothrow) ElfFuncDescTable(_file, shdr, sect_index);
+ if (_funcDesc_table == NULL) {
+ return NullDecoder::out_of_memory;
+ }
+#endif
+ return NullDecoder::no_error;
+}
+
+int ElfFile::section_by_name(const char* name, Elf_Shdr& hdr) {
+ assert(name != NULL, "No section name");
+ size_t len = strlen(name) + 1;
+ ResourceMark rm;
+ char* buf = NEW_RESOURCE_ARRAY(char, len);
+ if (buf == NULL) {
+ return -1;
+ }
+
+ assert(_shdr_string_table != NULL, "Section header string table should be loaded");
+ ElfStringTable* const table = _shdr_string_table;
+ MarkedFileReader mfd(fd());
+ if (!mfd.has_mark() || !mfd.set_position(_elfHdr.e_shoff)) return -1;
+
+ int sect_index = -1;
+ for (int index = 0; index < _elfHdr.e_shnum; index ++) {
+ if (!mfd.read((void*)&hdr, sizeof(hdr))) {
+ break;
+ }
+ if (table->string_at(hdr.sh_name, buf, len)) {
+ if (strncmp(buf, name, len) == 0) {
+ sect_index = index;
+ break;
}
}
-#endif
-
}
- return true;
+ return sect_index;
}
bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
// something already went wrong, just give up
- if (NullDecoder::is_error(m_status)) {
+ if (NullDecoder::is_error(_status)) {
return false;
}
- ElfSymbolTable* symbol_table = m_symbol_tables;
+
int string_table_index;
int pos_in_string_table;
int off = INT_MAX;
bool found_symbol = false;
+ ElfSymbolTable* symbol_table = _symbol_tables;
+
while (symbol_table != NULL) {
- if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, m_funcDesc_table)) {
+ if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off, _funcDesc_table)) {
found_symbol = true;
break;
}
- symbol_table = symbol_table->m_next;
+ symbol_table = symbol_table->next();
}
- if (!found_symbol) return false;
+ if (!found_symbol) {
+ return false;
+ }
ElfStringTable* string_table = get_string_table(string_table_index);
if (string_table == NULL) {
- m_status = NullDecoder::file_invalid;
+ _status = NullDecoder::file_invalid;
return false;
}
if (offset) *offset = off;
@@ -213,74 +321,31 @@
return string_table->string_at(pos_in_string_table, buf, buflen);
}
-
void ElfFile::add_symbol_table(ElfSymbolTable* table) {
- if (m_symbol_tables == NULL) {
- m_symbol_tables = table;
+ if (_symbol_tables == NULL) {
+ _symbol_tables = table;
} else {
- table->m_next = m_symbol_tables;
- m_symbol_tables = table;
+ table->set_next(_symbol_tables);
+ _symbol_tables = table;
}
}
void ElfFile::add_string_table(ElfStringTable* table) {
- if (m_string_tables == NULL) {
- m_string_tables = table;
+ if (_string_tables == NULL) {
+ _string_tables = table;
} else {
- table->m_next = m_string_tables;
- m_string_tables = table;
+ table->set_next(_string_tables);
+ _string_tables = table;
}
}
ElfStringTable* ElfFile::get_string_table(int index) {
- ElfStringTable* p = m_string_tables;
+ ElfStringTable* p = _string_tables;
while (p != NULL) {
if (p->index() == index) return p;
- p = p->m_next;
+ p = p->next();
}
return NULL;
}
-#ifdef LINUX
-bool ElfFile::specifies_noexecstack(const char* filepath) {
- // Returns true if the elf file is marked NOT to require an executable stack,
- // or if the file could not be opened.
- // Returns false if the elf file requires an executable stack, the stack flag
- // is not set at all, or if the file can not be read.
- if (filepath == NULL) return true;
-
- FILE* file = fopen(filepath, "r");
- if (file == NULL) return true;
-
- // AARCH64 defaults to noexecstack. All others default to execstack.
-#ifdef AARCH64
- bool result = true;
-#else
- bool result = false;
-#endif
-
- // Read file header
- Elf_Ehdr head;
- if (fread(&head, sizeof(Elf_Ehdr), 1, file) == 1 &&
- is_elf_file(head) &&
- fseek(file, head.e_phoff, SEEK_SET) == 0) {
-
- // Read program header table
- Elf_Phdr phdr;
- for (int index = 0; index < head.e_phnum; index ++) {
- if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, file) != 1) {
- result = false;
- break;
- }
- if (phdr.p_type == PT_GNU_STACK) {
- result = (phdr.p_flags == (PF_R | PF_W));
- break;
- }
- }
- }
- fclose(file);
- return result;
-}
-#endif // LINUX
-
#endif // !_WINDOWS && !__APPLE__
--- a/src/hotspot/share/utilities/elfFile.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfFile.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,6 @@
typedef Elf32_Off Elf_Off;
typedef Elf32_Addr Elf_Addr;
-
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Phdr Elf_Phdr;
@@ -72,46 +71,126 @@
#include "memory/allocation.hpp"
#include "utilities/decoder.hpp"
-
class ElfStringTable;
class ElfSymbolTable;
class ElfFuncDescTable;
+// ELF section, may or may not have cached data
+class ElfSection VALUE_OBJ_CLASS_SPEC {
+private:
+ Elf_Shdr _section_hdr;
+ void* _section_data;
+ NullDecoder::decoder_status _stat;
+public:
+ ElfSection(FILE* fd, const Elf_Shdr& hdr);
+ ~ElfSection();
-// On Solaris/Linux platforms, libjvm.so does contain all private symbols.
+ NullDecoder::decoder_status status() const { return _stat; }
+
+ const Elf_Shdr* section_header() const { return &_section_hdr; }
+ const void* section_data() const { return (const void*)_section_data; }
+private:
+ // load this section.
+ // it return no_error, when it fails to cache the section data due to lack of memory
+ NullDecoder::decoder_status load_section(FILE* const file, const Elf_Shdr& hdr);
+};
+
+class FileReader : public StackObj {
+protected:
+ FILE* const _fd;
+public:
+ FileReader(FILE* const fd) : _fd(fd) {};
+ bool read(void* buf, size_t size);
+ int read_buffer(void* buf, size_t size);
+ bool set_position(long offset);
+};
+
+// Mark current position, so we can get back to it after
+// reads.
+class MarkedFileReader : public FileReader {
+private:
+ long _marked_pos;
+public:
+ MarkedFileReader(FILE* const fd);
+ ~MarkedFileReader();
+
+ bool has_mark() const { return _marked_pos >= 0; }
+};
+
// ElfFile is basically an elf file parser, which can lookup the symbol
// that is the nearest to the given address.
// Beware, this code is called from vm error reporting code, when vm is already
// in "error" state, so there are scenarios, lookup will fail. We want this
// part of code to be very defensive, and bait out if anything went wrong.
-
class ElfFile: public CHeapObj<mtInternal> {
friend class ElfDecoder;
- public:
+
+private:
+ // link ElfFiles
+ ElfFile* _next;
+
+ // Elf file
+ char* _filepath;
+ FILE* _file;
+
+ // Elf header
+ Elf_Ehdr _elfHdr;
+
+ // symbol tables
+ ElfSymbolTable* _symbol_tables;
+
+ // regular string tables
+ ElfStringTable* _string_tables;
+
+ // section header string table, used for finding section name
+ ElfStringTable* _shdr_string_table;
+
+ // function descriptors table
+ ElfFuncDescTable* _funcDesc_table;
+
+ NullDecoder::decoder_status _status;
+
+public:
ElfFile(const char* filepath);
~ElfFile();
bool decode(address addr, char* buf, int buflen, int* offset);
- const char* filepath() {
- return m_filepath;
+
+ const char* filepath() const {
+ return _filepath;
+ }
+
+ bool same_elf_file(const char* filepath) const {
+ assert(filepath != NULL, "null file path");
+ return (_filepath != NULL && !strcmp(filepath, _filepath));
}
- bool same_elf_file(const char* filepath) {
- assert(filepath, "null file path");
- assert(m_filepath, "already out of memory");
- return (m_filepath && !strcmp(filepath, m_filepath));
+ NullDecoder::decoder_status get_status() const {
+ return _status;
}
- NullDecoder::decoder_status get_status() {
- return m_status;
- }
-
- private:
+ // Returns true if the elf file is marked NOT to require an executable stack,
+ // or if the file could not be opened.
+ // Returns false if the elf file requires an executable stack, the stack flag
+ // is not set at all, or if the file can not be read.
+ // On systems other than linux it always returns false.
+ static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; });
+private:
// sanity check, if the file is a real elf file
static bool is_elf_file(Elf_Ehdr&);
- // load string tables from the elf file
- bool load_tables();
+ // parse this elf file
+ NullDecoder::decoder_status parse_elf(const char* filename);
+
+ // load string, symbol and function descriptor tables from the elf file
+ NullDecoder::decoder_status load_tables();
+
+ ElfFile* next() const { return _next; }
+ void set_next(ElfFile* file) { _next = file; }
+
+ // find a section by name, return section index
+ // if there is no such section, return -1
+ int section_by_name(const char* name, Elf_Shdr& hdr);
// string tables are stored in a linked list
void add_string_table(ElfStringTable* table);
@@ -122,39 +201,15 @@
// return a string table at specified section index
ElfStringTable* get_string_table(int index);
-protected:
- ElfFile* next() const { return m_next; }
- void set_next(ElfFile* file) { m_next = file; }
- public:
- // Returns true if the elf file is marked NOT to require an executable stack,
- // or if the file could not be opened.
- // Returns false if the elf file requires an executable stack, the stack flag
- // is not set at all, or if the file can not be read.
- // On systems other than linux it always returns false.
- static bool specifies_noexecstack(const char* filepath) NOT_LINUX({ return false; });
-
- protected:
- ElfFile* m_next;
+ FILE* const fd() const { return _file; }
- private:
- // file
- const char* m_filepath;
- FILE* m_file;
-
- // Elf header
- Elf_Ehdr m_elfHdr;
+ // Cleanup string, symbol and function descriptor tables
+ void cleanup_tables();
- // symbol tables
- ElfSymbolTable* m_symbol_tables;
-
- // string tables
- ElfStringTable* m_string_tables;
-
- // function descriptors table
- ElfFuncDescTable* m_funcDesc_table;
-
- NullDecoder::decoder_status m_status;
+public:
+ // For whitebox test
+ static bool _do_not_cache_elf_section;
};
#endif // !_WINDOWS && !__APPLE__
--- a/src/hotspot/share/utilities/elfFuncDescTable.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfFuncDescTable.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -30,7 +30,8 @@
#include "memory/allocation.inline.hpp"
#include "utilities/elfFuncDescTable.hpp"
-ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) {
+ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) :
+ _file(file), _index(index), _section(file, shdr) {
assert(file, "null file handle");
// The actual function address (i.e. function entry point) is always the
// first value in the function descriptor (on IA64 and PPC64 they look as follows):
@@ -39,62 +40,33 @@
// Unfortunately 'shdr.sh_entsize' doesn't always seem to contain this size (it's zero on PPC64) so we can't assert
// assert(IA64_ONLY(2) PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries");
- m_funcDescs = NULL;
- m_file = file;
- m_index = index;
- m_status = NullDecoder::no_error;
-
- // try to load the function descriptor table
- long cur_offset = ftell(file);
- if (cur_offset != -1) {
- // call malloc so we can back up if memory allocation fails.
- m_funcDescs = (address*)os::malloc(shdr.sh_size, mtInternal);
- if (m_funcDescs) {
- if (fseek(file, shdr.sh_offset, SEEK_SET) ||
- fread((void*)m_funcDescs, shdr.sh_size, 1, file) != 1 ||
- fseek(file, cur_offset, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
- os::free(m_funcDescs);
- m_funcDescs = NULL;
- }
- }
- if (!NullDecoder::is_error(m_status)) {
- memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
- }
- } else {
- m_status = NullDecoder::file_invalid;
- }
+ _status = _section.status();
}
ElfFuncDescTable::~ElfFuncDescTable() {
- if (m_funcDescs != NULL) {
- os::free(m_funcDescs);
- }
}
address ElfFuncDescTable::lookup(Elf_Word index) {
- if (NullDecoder::is_error(m_status)) {
+ if (NullDecoder::is_error(_status)) {
return NULL;
}
- if (m_funcDescs != NULL) {
- if (m_shdr.sh_size > 0 && m_shdr.sh_addr <= index && index <= m_shdr.sh_addr + m_shdr.sh_size) {
- // Notice that 'index' is a byte-offset into the function descriptor table.
- return m_funcDescs[(index - m_shdr.sh_addr) / sizeof(address)];
- }
+ address* func_descs = cached_func_descs();
+ const Elf_Shdr* shdr = _section.section_header();
+ if (!(shdr->sh_size > 0 && shdr->sh_addr <= index && index <= shdr->sh_addr + shdr->sh_size)) {
+ // don't put the whole decoder in error mode if we just tried a wrong index
return NULL;
+ }
+
+ if (func_descs != NULL) {
+ return func_descs[(index - shdr->sh_addr) / sizeof(address)];
} else {
- long cur_pos;
+ MarkedFileReader mfd(_file);
address addr;
- if (!(m_shdr.sh_size > 0 && m_shdr.sh_addr <= index && index <= m_shdr.sh_addr + m_shdr.sh_size)) {
- // don't put the whole decoder in error mode if we just tried a wrong index
- return NULL;
- }
- if ((cur_pos = ftell(m_file)) == -1 ||
- fseek(m_file, m_shdr.sh_offset + index - m_shdr.sh_addr, SEEK_SET) ||
- fread(&addr, sizeof(addr), 1, m_file) != 1 ||
- fseek(m_file, cur_pos, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
+ if (!mfd.has_mark() ||
+ !mfd.set_position(shdr->sh_offset + index - shdr->sh_addr) ||
+ !mfd.read((void*)&addr, sizeof(addr))) {
+ _status = NullDecoder::file_invalid;
return NULL;
}
return addr;
--- a/src/hotspot/share/utilities/elfFuncDescTable.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfFuncDescTable.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -116,32 +116,31 @@
class ElfFuncDescTable: public CHeapObj<mtInternal> {
friend class ElfFile;
- public:
+private:
+ // holds the complete function descriptor section if
+ // we can allocate enough memory
+ ElfSection _section;
+
+ // file contains string table
+ FILE* const _file;
+
+ // The section index of this function descriptor (i.e. '.opd') section in the ELF file
+ const int _index;
+
+ NullDecoder::decoder_status _status;
+public:
ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index);
~ElfFuncDescTable();
// return the function address for the function descriptor at 'index' or NULL on error
address lookup(Elf_Word index);
- int get_index() { return m_index; };
-
- NullDecoder::decoder_status get_status() { return m_status; };
-
- protected:
- // holds the complete function descriptor section if
- // we can allocate enough memory
- address* m_funcDescs;
+ int get_index() const { return _index; };
- // file contains string table
- FILE* m_file;
+ NullDecoder::decoder_status get_status() const { return _status; };
- // section header
- Elf_Shdr m_shdr;
-
- // The section index of this function descriptor (i.e. '.opd') section in the ELF file
- int m_index;
-
- NullDecoder::decoder_status m_status;
+private:
+ address* cached_func_descs() const { return (address*)_section.section_data(); }
};
#endif // !_WINDOWS && !__APPLE__
--- a/src/hotspot/share/utilities/elfStringTable.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfStringTable.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,58 +33,44 @@
// We will try to load whole string table into memory if we can.
// Otherwise, fallback to more expensive file operation.
-ElfStringTable::ElfStringTable(FILE* file, Elf_Shdr shdr, int index) {
- assert(file, "null file handle");
- m_table = NULL;
- m_index = index;
- m_next = NULL;
- m_file = file;
- m_status = NullDecoder::no_error;
-
- // try to load the string table
- long cur_offset = ftell(file);
- m_table = (char*)os::malloc(sizeof(char) * shdr.sh_size, mtInternal);
- if (m_table != NULL) {
- // if there is an error, mark the error
- if (fseek(file, shdr.sh_offset, SEEK_SET) ||
- fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
- fseek(file, cur_offset, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
- os::free((void*)m_table);
- m_table = NULL;
- }
- } else {
- memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
- }
+ElfStringTable::ElfStringTable(FILE* const file, Elf_Shdr& shdr, int index) :
+ _section(file, shdr), _index(index), _fd(file), _next(NULL) {
+ _status = _section.status();
}
ElfStringTable::~ElfStringTable() {
- if (m_table != NULL) {
- os::free((void*)m_table);
- }
-
- if (m_next != NULL) {
- delete m_next;
+ if (_next != NULL) {
+ delete _next;
}
}
-bool ElfStringTable::string_at(int pos, char* buf, int buflen) {
- if (NullDecoder::is_error(m_status)) {
+bool ElfStringTable::string_at(size_t pos, char* buf, int buflen) {
+ if (NullDecoder::is_error(get_status())) {
+ return false;
+ }
+
+ assert(buflen > 0, "no buffer");
+ if (pos >= _section.section_header()->sh_size) {
return false;
}
- if (m_table != NULL) {
- jio_snprintf(buf, buflen, "%s", (const char*)(m_table + pos));
+
+ const char* data = (const char*)_section.section_data();
+ if (data != NULL) {
+ jio_snprintf(buf, buflen, "%s", data + pos);
return true;
- } else {
- long cur_pos = ftell(m_file);
- if (cur_pos == -1 ||
- fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
- fread(buf, 1, buflen, m_file) <= 0 ||
- fseek(m_file, cur_pos, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
+ } else { // no cache data, read from file instead
+ const Elf_Shdr* const shdr = _section.section_header();
+ MarkedFileReader mfd(_fd);
+ if (mfd.has_mark() &&
+ mfd.set_position(shdr->sh_offset + pos) &&
+ mfd.read((void*)buf, size_t(buflen))) {
+ buf[buflen - 1] = '\0';
+ return true;
+ } else {
+ // put it in error state to avoid retry
+ _status = NullDecoder::file_invalid;
return false;
}
- return true;
}
}
--- a/src/hotspot/share/utilities/elfStringTable.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfStringTable.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,37 +37,36 @@
// one blob. Otherwise, it will load string from file when requested.
class ElfStringTable: CHeapObj<mtInternal> {
friend class ElfFile;
- public:
- ElfStringTable(FILE* file, Elf_Shdr shdr, int index);
+private:
+ ElfStringTable* _next;
+ int _index; // section index
+ ElfSection _section;
+ FILE* const _fd;
+ NullDecoder::decoder_status _status;
+
+public:
+ ElfStringTable(FILE* const file, Elf_Shdr& shdr, int index);
~ElfStringTable();
// section index
- int index() { return m_index; };
+ int index() const { return _index; };
// get string at specified offset
- bool string_at(int offset, char* buf, int buflen);
+ bool string_at(size_t offset, char* buf, int buflen);
// get status code
- NullDecoder::decoder_status get_status() { return m_status; };
-
- protected:
- ElfStringTable* m_next;
-
- // section index
- int m_index;
+ NullDecoder::decoder_status get_status() const {
+ return _status;
+ }
- // holds complete string table if can
- // allocate enough memory
- const char* m_table;
+private:
+ void set_next(ElfStringTable* next) {
+ _next = next;
+ }
- // file contains string table
- FILE* m_file;
-
- // section header
- Elf_Shdr m_shdr;
-
- // error code
- NullDecoder::decoder_status m_status;
+ ElfStringTable* next() const {
+ return _next;
+ }
};
#endif // !_WINDOWS && !__APPLE__
--- a/src/hotspot/share/utilities/elfSymbolTable.cpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfSymbolTable.cpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,48 +30,26 @@
#include "utilities/elfFuncDescTable.hpp"
#include "utilities/elfSymbolTable.hpp"
-ElfSymbolTable::ElfSymbolTable(FILE* file, Elf_Shdr shdr) {
- assert(file, "null file handle");
- m_symbols = NULL;
- m_next = NULL;
- m_file = file;
- m_status = NullDecoder::no_error;
+ElfSymbolTable::ElfSymbolTable(FILE* const file, Elf_Shdr& shdr) :
+ _section(file, shdr), _fd(file), _next(NULL) {
+ assert(file != NULL, "null file handle");
+ _status = _section.status();
- // try to load the string table
- long cur_offset = ftell(file);
- if (cur_offset != -1) {
- // call malloc so we can back up if memory allocation fails.
- m_symbols = (Elf_Sym*)os::malloc(shdr.sh_size, mtInternal);
- if (m_symbols) {
- if (fseek(file, shdr.sh_offset, SEEK_SET) ||
- fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
- fseek(file, cur_offset, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
- os::free(m_symbols);
- m_symbols = NULL;
- }
- }
- if (!NullDecoder::is_error(m_status)) {
- memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
- }
- } else {
- m_status = NullDecoder::file_invalid;
+ if (_section.section_header()->sh_size % sizeof(Elf_Sym) != 0) {
+ _status = NullDecoder::file_invalid;
}
}
ElfSymbolTable::~ElfSymbolTable() {
- if (m_symbols != NULL) {
- os::free(m_symbols);
- }
-
- if (m_next != NULL) {
- delete m_next;
+ if (_next != NULL) {
+ delete _next;
}
}
bool ElfSymbolTable::compare(const Elf_Sym* sym, address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable) {
if (STT_FUNC == ELF_ST_TYPE(sym->st_info)) {
Elf_Word st_size = sym->st_size;
+ const Elf_Shdr* shdr = _section.section_header();
address sym_addr;
if (funcDescTable != NULL && funcDescTable->get_index() == sym->st_shndx) {
// We need to go another step trough the function descriptor table (currently PPC64 only)
@@ -82,7 +60,7 @@
if (sym_addr <= addr && (Elf_Word)(addr - sym_addr) < st_size) {
*offset = (int)(addr - sym_addr);
*posIndex = sym->st_name;
- *stringtableIndex = m_shdr.sh_link;
+ *stringtableIndex = shdr->sh_link;
return true;
}
}
@@ -94,39 +72,39 @@
assert(posIndex, "null string table offset pointer");
assert(offset, "null offset pointer");
- if (NullDecoder::is_error(m_status)) {
+ if (NullDecoder::is_error(get_status())) {
return false;
}
size_t sym_size = sizeof(Elf_Sym);
- assert((m_shdr.sh_size % sym_size) == 0, "check size");
- int count = m_shdr.sh_size / sym_size;
- if (m_symbols != NULL) {
+ int count = _section.section_header()->sh_size / sym_size;
+ Elf_Sym* symbols = (Elf_Sym*)_section.section_data();
+
+ if (symbols != NULL) {
for (int index = 0; index < count; index ++) {
- if (compare(&m_symbols[index], addr, stringtableIndex, posIndex, offset, funcDescTable)) {
+ if (compare(&symbols[index], addr, stringtableIndex, posIndex, offset, funcDescTable)) {
return true;
}
}
} else {
- long cur_pos;
- if ((cur_pos = ftell(m_file)) == -1 ||
- fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
- m_status = NullDecoder::file_invalid;
+ MarkedFileReader mfd(_fd);
+
+ if (!mfd.has_mark() || !mfd.set_position(_section.section_header()->sh_offset)) {
+ _status = NullDecoder::file_invalid;
return false;
}
Elf_Sym sym;
for (int index = 0; index < count; index ++) {
- if (fread(&sym, sym_size, 1, m_file) == 1) {
- if (compare(&sym, addr, stringtableIndex, posIndex, offset, funcDescTable)) {
- return true;
- }
- } else {
- m_status = NullDecoder::file_invalid;
+ if (!mfd.read((void*)&sym, sizeof(sym))) {
+ _status = NullDecoder::file_invalid;
return false;
}
+
+ if (compare(&sym, addr, stringtableIndex, posIndex, offset, funcDescTable)) {
+ return true;
+ }
}
- fseek(m_file, cur_pos, SEEK_SET);
}
return false;
}
--- a/src/hotspot/share/utilities/elfSymbolTable.hpp Tue Feb 20 21:46:02 2018 +0100
+++ b/src/hotspot/share/utilities/elfSymbolTable.hpp Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,29 +40,27 @@
*/
class ElfSymbolTable: public CHeapObj<mtInternal> {
friend class ElfFile;
- public:
- ElfSymbolTable(FILE* file, Elf_Shdr shdr);
+private:
+ ElfSymbolTable* _next;
+
+ // file contains string table
+ FILE* const _fd;
+
+ // corresponding section
+ ElfSection _section;
+
+ NullDecoder::decoder_status _status;
+public:
+ ElfSymbolTable(FILE* const file, Elf_Shdr& shdr);
~ElfSymbolTable();
// search the symbol that is nearest to the specified address.
bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable);
- NullDecoder::decoder_status get_status() { return m_status; };
-
- protected:
- ElfSymbolTable* m_next;
-
- // holds a complete symbol table section if
- // can allocate enough memory
- Elf_Sym* m_symbols;
-
- // file contains string table
- FILE* m_file;
-
- // section header
- Elf_Shdr m_shdr;
-
- NullDecoder::decoder_status m_status;
+ NullDecoder::decoder_status get_status() const { return _status; };
+private:
+ ElfSymbolTable* next() const { return _next; }
+ void set_next(ElfSymbolTable* next) { _next = next; }
bool compare(const Elf_Sym* sym, address addr, int* stringtableIndex, int* posIndex, int* offset, ElfFuncDescTable* funcDescTable);
};
--- a/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/BlockCipherParamsCore.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -115,7 +115,7 @@
* Returns a formatted string describing the parameters.
*/
public String toString() {
- String LINE_SEP = System.getProperty("line.separator");
+ String LINE_SEP = System.lineSeparator();
String ivString = LINE_SEP + " iv:" + LINE_SEP + "[";
HexDumpEncoder encoder = new HexDumpEncoder();
--- a/src/java.base/share/classes/com/sun/crypto/provider/DHParameters.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DHParameters.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -129,7 +129,7 @@
* Returns a formatted string describing the parameters.
*/
protected String engineToString() {
- String LINE_SEP = System.getProperty("line.separator");
+ String LINE_SEP = System.lineSeparator();
StringBuilder sb
= new StringBuilder("SunJCE Diffie-Hellman Parameters:"
--- a/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
*
*
* @see DHPrivateKey
- * @see java.security.KeyAgreement
+ * @see javax.crypto.KeyAgreement
*/
final class DHPublicKey implements PublicKey,
javax.crypto.interfaces.DHPublicKey, Serializable {
@@ -258,7 +258,7 @@
}
public String toString() {
- String LINE_SEP = System.getProperty("line.separator");
+ String LINE_SEP = System.lineSeparator();
StringBuilder sb
= new StringBuilder("SunJCE Diffie-Hellman Public Key:"
--- a/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/GCMParameters.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,7 +134,7 @@
* Returns a formatted string describing the parameters.
*/
protected String engineToString() {
- String LINE_SEP = System.getProperty("line.separator");
+ String LINE_SEP = System.lineSeparator();
HexDumpEncoder encoder = new HexDumpEncoder();
StringBuilder sb
= new StringBuilder(LINE_SEP + " iv:" + LINE_SEP + "["
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBEParameters.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBEParameters.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -135,7 +135,7 @@
* Returns a formatted string describing the parameters.
*/
protected String engineToString() {
- String LINE_SEP = System.getProperty("line.separator");
+ String LINE_SEP = System.lineSeparator();
String saltString = LINE_SEP + " salt:" + LINE_SEP + "[";
HexDumpEncoder encoder = new HexDumpEncoder();
saltString += encoder.encodeBuffer(salt);
--- a/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/RC2Parameters.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -214,7 +214,7 @@
* Returns a formatted string describing the parameters.
*/
protected String engineToString() {
- String LINE_SEP = System.getProperty("line.separator");
+ String LINE_SEP = System.lineSeparator();
HexDumpEncoder encoder = new HexDumpEncoder();
StringBuilder sb
= new StringBuilder(LINE_SEP + " iv:" + LINE_SEP + "["
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/io/FileCleanable.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.io;
+
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.ref.CleanerFactory;
+import jdk.internal.ref.PhantomCleanable;
+
+import java.lang.ref.Cleaner;
+
+/**
+ * Cleanable for a FileDescriptor when it becomes phantom reachable.
+ * For regular fds on Unix and regular handles on Windows
+ * register a cleanup if fd != -1 or handle != -1.
+ * <p>
+ * Subclassed from {@code PhantomCleanable} so that {@code clear} can be
+ * called to disable the cleanup when the handle is closed by any means other
+ * than calling {@link FileDescriptor#close}.
+ * Otherwise, it might incorrectly close the handle after it has been reused.
+ */
+final class FileCleanable extends PhantomCleanable<FileDescriptor> {
+
+ // Access to FileDescriptor private fields;
+ // avoids making fd and handle package private
+ private static final JavaIOFileDescriptorAccess fdAccess =
+ SharedSecrets.getJavaIOFileDescriptorAccess();
+
+ /*
+ * Raw close of the file fd and/or handle.
+ * Used only for last chance cleanup.
+ */
+ private static native void cleanupClose0(int fd, long handle) throws IOException;
+
+ // The raw fd to close
+ private final int fd;
+
+ // The handle to close
+ private final long handle;
+
+ /**
+ * Register a Cleanable with the FileDescriptor
+ * if the FileDescriptor is non-null and valid.
+ * @implNote
+ * A exception (OutOfMemoryException) will leave the FileDescriptor
+ * having allocated resources and leak the fd/handle.
+ *
+ * @param fdo the FileDescriptor; may be null
+ */
+ static void register(FileDescriptor fdo) {
+ if (fdo != null && fdo.valid()) {
+ int fd = fdAccess.get(fdo);
+ long handle = fdAccess.getHandle(fdo);
+ fdo.registerCleanup(new FileCleanable(fdo, CleanerFactory.cleaner(), fd, handle));
+ }
+ }
+
+ /**
+ * Unregister a Cleanable from the FileDescriptor.
+ * @param fdo the FileDescriptor; may be null
+ */
+ static void unregister(FileDescriptor fdo) {
+ if (fdo != null) {
+ fdo.unregisterCleanup();
+ }
+ }
+
+ /**
+ * Constructor for a phantom cleanable reference.
+ *
+ * @param obj the object to monitor
+ * @param cleaner the cleaner
+ * @param fd file descriptor to close
+ * @param handle handle to close
+ */
+ private FileCleanable(FileDescriptor obj, Cleaner cleaner, int fd, long handle) {
+ super(obj, cleaner);
+ this.fd = fd;
+ this.handle = handle;
+ }
+
+ /**
+ * Close the native handle or fd.
+ */
+ @Override
+ protected void performCleanup() {
+ try {
+ cleanupClose0(fd, handle);
+ } catch (IOException ioe) {
+ throw new UncheckedIOException("close", ioe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/io/FileDescriptor.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,369 @@
+/*
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.io;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import jdk.internal.misc.JavaIOFileDescriptorAccess;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.ref.PhantomCleanable;
+
+/**
+ * Instances of the file descriptor class serve as an opaque handle
+ * to the underlying machine-specific structure representing an open
+ * file, an open socket, or another source or sink of bytes.
+ * The main practical use for a file descriptor is to create a
+ * {@link FileInputStream} or {@link FileOutputStream} to contain it.
+ * <p>
+ * Applications should not create their own file descriptors.
+ *
+ * @author Pavani Diwanji
+ * @since 1.0
+ */
+public final class FileDescriptor {
+
+ private int fd;
+
+ private long handle;
+
+ private Closeable parent;
+ private List<Closeable> otherParents;
+ private boolean closed;
+
+ /**
+ * true, if file is opened for appending.
+ */
+ private boolean append;
+
+ static {
+ initIDs();
+ }
+
+ // Set up JavaIOFileDescriptorAccess in SharedSecrets
+ static {
+ SharedSecrets.setJavaIOFileDescriptorAccess(
+ new JavaIOFileDescriptorAccess() {
+ public void set(FileDescriptor fdo, int fd) {
+ fdo.set(fd);
+ }
+
+ public int get(FileDescriptor fdo) {
+ return fdo.fd;
+ }
+
+ public void setAppend(FileDescriptor fdo, boolean append) {
+ fdo.append = append;
+ }
+
+ public boolean getAppend(FileDescriptor fdo) {
+ return fdo.append;
+ }
+
+ public void close(FileDescriptor fdo) throws IOException {
+ fdo.close();
+ }
+
+ /* Register for a normal FileCleanable fd/handle cleanup. */
+ public void registerCleanup(FileDescriptor fdo) {
+ FileCleanable.register(fdo);
+ }
+
+ /* Register a custom PhantomCleanup. */
+ public void registerCleanup(FileDescriptor fdo,
+ PhantomCleanable<FileDescriptor> cleanup) {
+ fdo.registerCleanup(cleanup);
+ }
+
+ public void unregisterCleanup(FileDescriptor fdo) {
+ fdo.unregisterCleanup();
+ }
+
+ public void setHandle(FileDescriptor fdo, long handle) {
+ fdo.setHandle(handle);
+ }
+
+ public long getHandle(FileDescriptor fdo) {
+ return fdo.handle;
+ }
+ }
+ );
+ }
+
+ /**
+ * Cleanup in case FileDescriptor is not explicitly closed.
+ */
+ private PhantomCleanable<FileDescriptor> cleanup;
+
+ /**
+ * Constructs an (invalid) FileDescriptor object.
+ * The fd or handle is set later.
+ */
+ public FileDescriptor() {
+ fd = -1;
+ handle = -1;
+ }
+
+ /**
+ * Used for standard input, output, and error only.
+ * For Windows the corresponding handle is initialized.
+ * For Unix the append mode is cached.
+ * @param fd the raw fd number (0, 1, 2)
+ */
+ private FileDescriptor(int fd) {
+ this.fd = fd;
+ this.handle = getHandle(fd);
+ this.append = getAppend(fd);
+ }
+
+ /**
+ * A handle to the standard input stream. Usually, this file
+ * descriptor is not used directly, but rather via the input stream
+ * known as {@code System.in}.
+ *
+ * @see java.lang.System#in
+ */
+ public static final FileDescriptor in = new FileDescriptor(0);
+
+ /**
+ * A handle to the standard output stream. Usually, this file
+ * descriptor is not used directly, but rather via the output stream
+ * known as {@code System.out}.
+ * @see java.lang.System#out
+ */
+ public static final FileDescriptor out = new FileDescriptor(1);
+
+ /**
+ * A handle to the standard error stream. Usually, this file
+ * descriptor is not used directly, but rather via the output stream
+ * known as {@code System.err}.
+ *
+ * @see java.lang.System#err
+ */
+ public static final FileDescriptor err = new FileDescriptor(2);
+
+ /**
+ * Tests if this file descriptor object is valid.
+ *
+ * @return {@code true} if the file descriptor object represents a
+ * valid, open file, socket, or other active I/O connection;
+ * {@code false} otherwise.
+ */
+ public boolean valid() {
+ return (handle != -1) || (fd != -1);
+ }
+
+ /**
+ * Force all system buffers to synchronize with the underlying
+ * device. This method returns after all modified data and
+ * attributes of this FileDescriptor have been written to the
+ * relevant device(s). In particular, if this FileDescriptor
+ * refers to a physical storage medium, such as a file in a file
+ * system, sync will not return until all in-memory modified copies
+ * of buffers associated with this FileDescriptor have been
+ * written to the physical medium.
+ *
+ * sync is meant to be used by code that requires physical
+ * storage (such as a file) to be in a known state For
+ * example, a class that provided a simple transaction facility
+ * might use sync to ensure that all changes to a file caused
+ * by a given transaction were recorded on a storage medium.
+ *
+ * sync only affects buffers downstream of this FileDescriptor. If
+ * any in-memory buffering is being done by the application (for
+ * example, by a BufferedOutputStream object), those buffers must
+ * be flushed into the FileDescriptor (for example, by invoking
+ * OutputStream.flush) before that data will be affected by sync.
+ *
+ * @exception SyncFailedException
+ * Thrown when the buffers cannot be flushed,
+ * or because the system cannot guarantee that all the
+ * buffers have been synchronized with physical media.
+ * @since 1.1
+ */
+ public native void sync() throws SyncFailedException;
+
+ /* This routine initializes JNI field offsets for the class */
+ private static native void initIDs();
+
+ /*
+ * On Windows return the handle for the standard streams.
+ */
+ private static native long getHandle(int d);
+
+ /**
+ * Returns true, if the file was opened for appending.
+ */
+ private static native boolean getAppend(int fd);
+
+ /**
+ * Set the fd.
+ * Used on Unix and for sockets on Windows and Unix.
+ * If setting to -1, clear the cleaner.
+ * The {@link #registerCleanup} method should be called for new fds.
+ * @param fd the raw fd or -1 to indicate closed
+ */
+ @SuppressWarnings("unchecked")
+ synchronized void set(int fd) {
+ if (fd == -1 && cleanup != null) {
+ cleanup.clear();
+ cleanup = null;
+ }
+ this.fd = fd;
+ }
+
+ /**
+ * Set the handle.
+ * Used on Windows for regular files.
+ * If setting to -1, clear the cleaner.
+ * The {@link #registerCleanup} method should be called for new handles.
+ * @param handle the handle or -1 to indicate closed
+ */
+ @SuppressWarnings("unchecked")
+ void setHandle(long handle) {
+ if (handle == -1 && cleanup != null) {
+ cleanup.clear();
+ cleanup = null;
+ }
+ this.handle = handle;
+ }
+
+ /**
+ * Register a cleanup for the current handle.
+ * Used directly in java.io and indirectly via fdAccess.
+ * The cleanup should be registered after the handle is set in the FileDescriptor.
+ * @param cleanable a PhantomCleanable to register
+ */
+ @SuppressWarnings("unchecked")
+ synchronized void registerCleanup(PhantomCleanable<FileDescriptor> cleanable) {
+ Objects.requireNonNull(cleanable, "cleanable");
+ if (cleanup != null) {
+ cleanup.clear();
+ }
+ cleanup = cleanable;
+ }
+
+ /**
+ * Unregister a cleanup for the current raw fd or handle.
+ * Used directly in java.io and indirectly via fdAccess.
+ * Normally {@link #close()} should be used except in cases where
+ * it is certain the caller will close the raw fd and the cleanup
+ * must not close the raw fd. {@link #unregisterCleanup()} must be
+ * called before the raw fd is closed to prevent a race that makes
+ * it possible for the fd to be reallocated to another use and later
+ * the cleanup might be invoked.
+ */
+ synchronized void unregisterCleanup() {
+ if (cleanup != null) {
+ cleanup.clear();
+ }
+ cleanup = null;
+ }
+
+ /**
+ * Close the raw file descriptor or handle, if it has not already been closed.
+ * The native code sets the fd and handle to -1.
+ * Clear the cleaner so the close does not happen twice.
+ * Package private to allow it to be used in java.io.
+ * @throws IOException if close fails
+ */
+ @SuppressWarnings("unchecked")
+ synchronized void close() throws IOException {
+ unregisterCleanup();
+ close0();
+ }
+
+ /*
+ * Close the raw file descriptor or handle, if it has not already been closed
+ * and set the fd and handle to -1.
+ */
+ private native void close0() throws IOException;
+
+ /*
+ * Package private methods to track referents.
+ * If multiple streams point to the same FileDescriptor, we cycle
+ * through the list of all referents and call close()
+ */
+
+ /**
+ * Attach a Closeable to this FD for tracking.
+ * parent reference is added to otherParents when
+ * needed to make closeAll simpler.
+ */
+ synchronized void attach(Closeable c) {
+ if (parent == null) {
+ // first caller gets to do this
+ parent = c;
+ } else if (otherParents == null) {
+ otherParents = new ArrayList<>();
+ otherParents.add(parent);
+ otherParents.add(c);
+ } else {
+ otherParents.add(c);
+ }
+ }
+
+ /**
+ * Cycle through all Closeables sharing this FD and call
+ * close() on each one.
+ *
+ * The caller closeable gets to call close0().
+ */
+ @SuppressWarnings("try")
+ synchronized void closeAll(Closeable releaser) throws IOException {
+ if (!closed) {
+ closed = true;
+ IOException ioe = null;
+ try (releaser) {
+ if (otherParents != null) {
+ for (Closeable referent : otherParents) {
+ try {
+ referent.close();
+ } catch(IOException x) {
+ if (ioe == null) {
+ ioe = x;
+ } else {
+ ioe.addSuppressed(x);
+ }
+ }
+ }
+ }
+ } catch(IOException ex) {
+ /*
+ * If releaser close() throws IOException
+ * add other exceptions as suppressed.
+ */
+ if (ioe != null)
+ ex.addSuppressed(ioe);
+ ioe = ex;
+ } finally {
+ if (ioe != null)
+ throw ioe;
+ }
+ }
+ }
+}
--- a/src/java.base/share/classes/java/io/FileInputStream.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/io/FileInputStream.java Mon Feb 26 09:56:12 2018 +0100
@@ -25,7 +25,6 @@
package java.io;
-import java.lang.reflect.Method;
import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;
@@ -158,7 +157,7 @@
open(name);
altFinalizer = AltFinalizer.get(this);
if (altFinalizer == null) {
- fd.registerCleanup(); // open set the fd, register the cleanup
+ FileCleanable.register(fd); // open set the fd, register the cleanup
}
}
--- a/src/java.base/share/classes/java/io/FileOutputStream.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/io/FileOutputStream.java Mon Feb 26 09:56:12 2018 +0100
@@ -25,7 +25,6 @@
package java.io;
-import java.lang.reflect.Method;
import java.nio.channels.FileChannel;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
@@ -238,7 +237,7 @@
open(name, append);
altFinalizer = AltFinalizer.get(this);
if (altFinalizer == null) {
- fd.registerCleanup(); // open set the fd, register the cleanup
+ FileCleanable.register(fd); // open sets the fd, register the cleanup
}
}
--- a/src/java.base/share/classes/java/io/RandomAccessFile.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/io/RandomAccessFile.java Mon Feb 26 09:56:12 2018 +0100
@@ -257,7 +257,7 @@
fd.attach(this);
path = name;
open(name, imode);
- fd.registerCleanup(); // open sets the fd, register the cleanup
+ FileCleanable.register(fd); // open sets the fd, register the cleanup
}
/**
--- a/src/java.base/share/classes/java/lang/ClassLoader.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java Mon Feb 26 09:56:12 2018 +0100
@@ -1922,7 +1922,7 @@
case 3:
String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
throw new IllegalStateException(msg);
- case 4:
+ default:
// system fully initialized
assert VM.isBooted() && scl != null;
SecurityManager sm = System.getSecurityManager();
@@ -1930,8 +1930,6 @@
checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl;
- default:
- throw new InternalError("should not reach here");
}
}
--- a/src/java.base/share/classes/java/lang/Runtime.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Runtime.java Mon Feb 26 09:56:12 2018 +0100
@@ -35,6 +35,8 @@
import java.util.List;
import java.util.Optional;
import java.util.StringTokenizer;
+
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
@@ -77,18 +79,14 @@
* serves as a status code; by convention, a nonzero status code indicates
* abnormal termination.
*
- * <p> The virtual machine's shutdown sequence consists of two phases. In
- * the first phase all registered {@link #addShutdownHook shutdown hooks},
- * if any, are started in some unspecified order and allowed to run
- * concurrently until they finish. In the second phase all uninvoked
- * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit}
- * has been enabled. Once this is done the virtual machine {@link #halt halts}.
+ * <p> All registered {@linkplain #addShutdownHook shutdown hooks}, if any,
+ * are started in some unspecified order and allowed to run concurrently
+ * until they finish. Once this is done the virtual machine
+ * {@linkplain #halt halts}.
*
- * <p> If this method is invoked after the virtual machine has begun its
- * shutdown sequence then if shutdown hooks are being run this method will
- * block indefinitely. If shutdown hooks have already been run and on-exit
- * finalization has been enabled then this method halts the virtual machine
- * with the given status code if the status is nonzero; otherwise, it
+ * <p> If this method is invoked after all shutdown hooks have already
+ * been run and the status is nonzero then this method halts the
+ * virtual machine with the given status code. Otherwise, this method
* blocks indefinitely.
*
* <p> The {@link System#exit(int) System.exit} method is the
@@ -107,7 +105,6 @@
* @see java.lang.SecurityManager#checkExit(int)
* @see #addShutdownHook
* @see #removeShutdownHook
- * @see #runFinalizersOnExit
* @see #halt(int)
*/
public void exit(int status) {
@@ -140,10 +137,9 @@
* thread. When the virtual machine begins its shutdown sequence it will
* start all registered shutdown hooks in some unspecified order and let
* them run concurrently. When all the hooks have finished it will then
- * run all uninvoked finalizers if finalization-on-exit has been enabled.
- * Finally, the virtual machine will halt. Note that daemon threads will
- * continue to run during the shutdown sequence, as will non-daemon threads
- * if shutdown was initiated by invoking the {@link #exit exit} method.
+ * halt. Note that daemon threads will continue to run during the shutdown
+ * sequence, as will non-daemon threads if shutdown was initiated by
+ * invoking the {@link #exit exit} method.
*
* <p> Once the shutdown sequence has begun it can be stopped only by
* invoking the {@link #halt halt} method, which forcibly
@@ -253,10 +249,9 @@
*
* <p> This method should be used with extreme caution. Unlike the
* {@link #exit exit} method, this method does not cause shutdown
- * hooks to be started and does not run uninvoked finalizers if
- * finalization-on-exit has been enabled. If the shutdown sequence has
- * already been initiated then this method does not wait for any running
- * shutdown hooks or finalizers to finish their work.
+ * hooks to be started. If the shutdown sequence has already been
+ * initiated then this method does not wait for any running
+ * shutdown hooks to finish their work.
*
* @param status
* Termination status. By convention, a nonzero status code
@@ -284,46 +279,6 @@
}
/**
- * Enable or disable finalization on exit; doing so specifies that the
- * finalizers of all objects that have finalizers that have not yet been
- * automatically invoked are to be run before the Java runtime exits.
- * By default, finalization on exit is disabled.
- *
- * <p>If there is a security manager,
- * its {@code checkExit} method is first called
- * with 0 as its argument to ensure the exit is allowed.
- * This could result in a SecurityException.
- *
- * @param value true to enable finalization on exit, false to disable
- * @deprecated This method is inherently unsafe. It may result in
- * finalizers being called on live objects while other threads are
- * concurrently manipulating those objects, resulting in erratic
- * behavior or deadlock.
- * This method is subject to removal in a future version of Java SE.
- *
- * @throws SecurityException
- * if a security manager exists and its {@code checkExit}
- * method doesn't allow the exit.
- *
- * @see java.lang.Runtime#exit(int)
- * @see java.lang.Runtime#gc()
- * @see java.lang.SecurityManager#checkExit(int)
- * @since 1.1
- */
- @Deprecated(since="1.2", forRemoval=true)
- public static void runFinalizersOnExit(boolean value) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- try {
- security.checkExit(0);
- } catch (SecurityException e) {
- throw new SecurityException("runFinalizersOnExit");
- }
- }
- Shutdown.setRunFinalizersOnExit(value);
- }
-
- /**
* Executes the specified string command in a separate process.
*
* <p>This is a convenience method. An invocation of the form
@@ -702,9 +657,6 @@
*/
public native void gc();
- /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */
- private static native void runFinalization0();
-
/**
* Runs the finalization methods of any objects pending finalization.
* Calling this method suggests that the Java virtual machine expend
@@ -724,7 +676,7 @@
* @see java.lang.Object#finalize()
*/
public void runFinalization() {
- runFinalization0();
+ SharedSecrets.getJavaLangRefAccess().runFinalization();
}
/**
--- a/src/java.base/share/classes/java/lang/Shutdown.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Shutdown.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,35 +26,33 @@
package java.lang;
+import jdk.internal.misc.VM;
+
/**
* Package-private utility class containing data structures and logic
* governing the virtual-machine shutdown sequence.
*
* @author Mark Reinhold
* @since 1.3
+ *
+ * @see java.io.Console
+ * @see ApplicationShutdownHooks
+ * @see java.io.DeleteOnExitHook
*/
class Shutdown {
- /* Shutdown state */
- private static final int RUNNING = 0;
- private static final int HOOKS = 1;
- private static final int FINALIZERS = 2;
- private static int state = RUNNING;
-
- /* Should we run all finalizers upon exit? */
- private static boolean runFinalizersOnExit = false;
-
// The system shutdown hooks are registered with a predefined slot.
// The list of shutdown hooks is as follows:
// (0) Console restore hook
- // (1) Application hooks
+ // (1) ApplicationShutdownHooks that invokes all registered application
+ // shutdown hooks and waits until they finish
// (2) DeleteOnExit hook
private static final int MAX_SYSTEM_HOOKS = 10;
private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
// the index of the currently running shutdown hook to the hooks array
- private static int currentRunningHook = 0;
+ private static int currentRunningHook = -1;
/* The preceding static fields are protected by this lock */
private static class Lock { };
@@ -63,17 +61,9 @@
/* Lock object for the native halt method */
private static Object haltLock = new Lock();
- /* Invoked by Runtime.runFinalizersOnExit */
- static void setRunFinalizersOnExit(boolean run) {
- synchronized (lock) {
- runFinalizersOnExit = run;
- }
- }
-
-
/**
- * Add a new shutdown hook. Checks the shutdown state and the hook itself,
- * but does not do any security checks.
+ * Add a new system shutdown hook. Checks the shutdown state and
+ * the hook itself, but does not do any security checks.
*
* The registerShutdownInProgress parameter should be false except
* registering the DeleteOnExitHook since the first file may
@@ -92,15 +82,18 @@
* already passes the given slot
*/
static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
+ if (slot < 0 || slot >= MAX_SYSTEM_HOOKS) {
+ throw new IllegalArgumentException("Invalid slot: " + slot);
+ }
synchronized (lock) {
if (hooks[slot] != null)
throw new InternalError("Shutdown hook at slot " + slot + " already registered");
if (!registerShutdownInProgress) {
- if (state > RUNNING)
+ if (currentRunningHook >= 0)
throw new IllegalStateException("Shutdown in progress");
} else {
- if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook))
+ if (VM.isShutdown() || slot <= currentRunningHook)
throw new IllegalStateException("Shutdown in progress");
}
@@ -108,9 +101,23 @@
}
}
- /* Run all registered shutdown hooks
+ /* Run all system shutdown hooks.
+ *
+ * The system shutdown hooks are run in the thread synchronized on
+ * Shutdown.class. Other threads calling Runtime::exit, Runtime::halt
+ * or JNI DestroyJavaVM will block indefinitely.
+ *
+ * ApplicationShutdownHooks is registered as one single hook that starts
+ * all application shutdown hooks and waits until they finish.
*/
private static void runHooks() {
+ synchronized (lock) {
+ /* Guard against the possibility of a daemon thread invoking exit
+ * after DestroyJavaVM initiates the shutdown sequence
+ */
+ if (VM.isShutdown()) return;
+ }
+
for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
try {
Runnable hook;
@@ -121,13 +128,16 @@
hook = hooks[i];
}
if (hook != null) hook.run();
- } catch(Throwable t) {
+ } catch (Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
+
+ // set shutdown state
+ VM.shutdown();
}
/* The halt method is synchronized on the halt lock
@@ -142,74 +152,22 @@
static native void halt0(int status);
- /* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */
- private static native void runAllFinalizers();
-
-
- /* The actual shutdown sequence is defined here.
- *
- * If it weren't for runFinalizersOnExit, this would be simple -- we'd just
- * run the hooks and then halt. Instead we need to keep track of whether
- * we're running hooks or finalizers. In the latter case a finalizer could
- * invoke exit(1) to cause immediate termination, while in the former case
- * any further invocations of exit(n), for any n, simply stall. Note that
- * if on-exit finalizers are enabled they're run iff the shutdown is
- * initiated by an exit(0); they're never run on exit(n) for n != 0 or in
- * response to SIGINT, SIGTERM, etc.
- */
- private static void sequence() {
- synchronized (lock) {
- /* Guard against the possibility of a daemon thread invoking exit
- * after DestroyJavaVM initiates the shutdown sequence
- */
- if (state != HOOKS) return;
- }
- runHooks();
- boolean rfoe;
- synchronized (lock) {
- state = FINALIZERS;
- rfoe = runFinalizersOnExit;
- }
- if (rfoe) runAllFinalizers();
- }
-
-
/* Invoked by Runtime.exit, which does all the security checks.
* Also invoked by handlers for system-provided termination events,
* which should pass a nonzero status code.
*/
static void exit(int status) {
- boolean runMoreFinalizers = false;
synchronized (lock) {
- if (status != 0) runFinalizersOnExit = false;
- switch (state) {
- case RUNNING: /* Initiate shutdown */
- state = HOOKS;
- break;
- case HOOKS: /* Stall and halt */
- break;
- case FINALIZERS:
- if (status != 0) {
- /* Halt immediately on nonzero status */
- halt(status);
- } else {
- /* Compatibility with old behavior:
- * Run more finalizers and then halt
- */
- runMoreFinalizers = runFinalizersOnExit;
- }
- break;
+ if (status != 0 && VM.isShutdown()) {
+ /* Halt immediately on nonzero status */
+ halt(status);
}
}
- if (runMoreFinalizers) {
- runAllFinalizers();
- halt(status);
- }
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
- sequence();
+ runHooks();
halt(status);
}
}
@@ -220,18 +178,8 @@
* actually halt the VM.
*/
static void shutdown() {
- synchronized (lock) {
- switch (state) {
- case RUNNING: /* Initiate shutdown */
- state = HOOKS;
- break;
- case HOOKS: /* Stall and then return */
- case FINALIZERS:
- break;
- }
- }
synchronized (Shutdown.class) {
- sequence();
+ runHooks();
}
}
--- a/src/java.base/share/classes/java/lang/System.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/System.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1766,38 +1766,6 @@
}
/**
- * Enable or disable finalization on exit; doing so specifies that the
- * finalizers of all objects that have finalizers that have not yet been
- * automatically invoked are to be run before the Java runtime exits.
- * By default, finalization on exit is disabled.
- *
- * <p>If there is a security manager,
- * its <code>checkExit</code> method is first called
- * with 0 as its argument to ensure the exit is allowed.
- * This could result in a SecurityException.
- *
- * @deprecated This method is inherently unsafe. It may result in
- * finalizers being called on live objects while other threads are
- * concurrently manipulating those objects, resulting in erratic
- * behavior or deadlock.
- * This method is subject to removal in a future version of Java SE.
- * @param value indicating enabling or disabling of finalization
- * @throws SecurityException
- * if a security manager exists and its <code>checkExit</code>
- * method doesn't allow the exit.
- *
- * @see java.lang.Runtime#exit(int)
- * @see java.lang.Runtime#gc()
- * @see java.lang.SecurityManager#checkExit(int)
- * @since 1.1
- */
- @Deprecated(since="1.2", forRemoval=true)
- @SuppressWarnings("removal")
- public static void runFinalizersOnExit(boolean value) {
- Runtime.runFinalizersOnExit(value);
- }
-
- /**
* Loads the native library specified by the filename argument. The filename
* argument must be an absolute path name.
*
--- a/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/doc-files/threadPrimitiveDeprecation.html Mon Feb 26 09:56:12 2018 +0100
@@ -1,6 +1,6 @@
<!doctype html>
<!--
- Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -346,19 +346,6 @@
the manner of <code>Thread.suspend</code>. (In fact, it is roughly
equivalent to <code>Thread.suspend</code> without the possibility
of a subsequent <code>Thread.resume</code>.)
-<hr>
-<h3>Why is <code>Runtime.runFinalizersOnExit</code>
-deprecated?</h3>
-Because it is inherently unsafe. It may result in finalizers being
-called on live objects while other threads are concurrently
-manipulating those objects, resulting in erratic behavior or
-deadlock. While this problem could be prevented if the class whose
-objects are being finalized were coded to "defend against" this
-call, most programmers do <i>not</i> defend against it. They assume
-that an object is dead at the time that its finalizer is called.
-<p>Further, the call is not "thread-safe" in the sense that it sets
-a VM-global flag. This forces <i>every</i> class with a finalizer
-to defend against the finalization of live objects!</p>
<p><!-- Body text ends here --></p>
</body>
</html>
--- a/src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java Mon Feb 26 09:56:12 2018 +0100
@@ -37,6 +37,7 @@
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
final class BootstrapMethodInvoker {
+
/**
* Factored code for invoking a bootstrap method for invokedynamic
* or a dynamic constant.
@@ -76,14 +77,30 @@
bootstrapMethod = null;
}
try {
+ // As an optimization we special case various known BSMs,
+ // such as LambdaMetafactory::metafactory and
+ // StringConcatFactory::makeConcatWithConstants.
+ //
+ // By providing static type information or even invoking
+ // exactly, we avoid emitting code to perform runtime
+ // checking.
info = maybeReBox(info);
if (info == null) {
// VM is allowed to pass up a null meaning no BSM args
- result = bootstrapMethod.invoke(caller, name, type);
+ result = invoke(bootstrapMethod, caller, name, type);
}
else if (!info.getClass().isArray()) {
// VM is allowed to pass up a single BSM arg directly
- result = bootstrapMethod.invoke(caller, name, type, info);
+
+ // Call to StringConcatFactory::makeConcatWithConstants
+ // with empty constant arguments?
+ if (isStringConcatFactoryBSM(bootstrapMethod.type())) {
+ result = (CallSite)bootstrapMethod
+ .invokeExact(caller, name, (MethodType)type,
+ (String)info, new Object[0]);
+ } else {
+ result = invoke(bootstrapMethod, caller, name, type, info);
+ }
}
else if (info.getClass() == int[].class) {
// VM is allowed to pass up a pair {argc, index}
@@ -103,51 +120,52 @@
// VM is allowed to pass up a full array of resolved BSM args
Object[] argv = (Object[]) info;
maybeReBoxElements(argv);
- switch (argv.length) {
- case 0:
- result = bootstrapMethod.invoke(caller, name, type);
- break;
- case 1:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0]);
- break;
- case 2:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1]);
- break;
- case 3:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2]);
- break;
- case 4:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2], argv[3]);
- break;
- case 5:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2], argv[3], argv[4]);
- break;
- case 6:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
- break;
- default:
- final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
- final int MAX_SAFE_SIZE = MethodType.MAX_MH_ARITY / 2 - NON_SPREAD_ARG_COUNT;
- if (argv.length >= MAX_SAFE_SIZE) {
- // to be on the safe side, use invokeWithArguments which handles jumbo lists
- Object[] newargv = new Object[NON_SPREAD_ARG_COUNT + argv.length];
- newargv[0] = caller;
- newargv[1] = name;
- newargv[2] = type;
- System.arraycopy(argv, 0, newargv, NON_SPREAD_ARG_COUNT, argv.length);
- result = bootstrapMethod.invokeWithArguments(newargv);
+
+ MethodType bsmType = bootstrapMethod.type();
+ if (isLambdaMetafactoryIndyBSM(bsmType) && argv.length == 3) {
+ result = (CallSite)bootstrapMethod
+ .invokeExact(caller, name, (MethodType)type, (MethodType)argv[0],
+ (MethodHandle)argv[1], (MethodType)argv[2]);
+ } else if (isLambdaMetafactoryCondyBSM(bsmType) && argv.length == 3) {
+ result = bootstrapMethod
+ .invokeExact(caller, name, (Class<?>)type, (MethodType)argv[0],
+ (MethodHandle)argv[1], (MethodType)argv[2]);
+ } else if (isStringConcatFactoryBSM(bsmType) && argv.length >= 1) {
+ String recipe = (String)argv[0];
+ Object[] shiftedArgs = Arrays.copyOfRange(argv, 1, argv.length);
+ result = (CallSite)bootstrapMethod.invokeExact(caller, name, (MethodType)type, recipe, shiftedArgs);
+ } else {
+ switch (argv.length) {
+ case 0:
+ result = invoke(bootstrapMethod, caller, name, type);
+ break;
+ case 1:
+ result = invoke(bootstrapMethod, caller, name, type,
+ argv[0]);
break;
- }
- MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
- MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
- MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
- result = spreader.invokeExact(typedBSM, (Object) caller, (Object) name, type, argv);
+ case 2:
+ result = invoke(bootstrapMethod, caller, name, type,
+ argv[0], argv[1]);
+ break;
+ case 3:
+ result = invoke(bootstrapMethod, caller, name, type,
+ argv[0], argv[1], argv[2]);
+ break;
+ case 4:
+ result = invoke(bootstrapMethod, caller, name, type,
+ argv[0], argv[1], argv[2], argv[3]);
+ break;
+ case 5:
+ result = invoke(bootstrapMethod, caller, name, type,
+ argv[0], argv[1], argv[2], argv[3], argv[4]);
+ break;
+ case 6:
+ result = invoke(bootstrapMethod, caller, name, type,
+ argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+ break;
+ default:
+ result = invokeWithManyArguments(bootstrapMethod, caller, name, type, argv);
+ }
}
}
if (resultType.isPrimitive()) {
@@ -175,6 +193,132 @@
}
}
+ // If we don't provide static type information for type, we'll generate runtime
+ // checks. Let's try not to...
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller,
+ String name, Object type) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type);
+ }
+ }
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller,
+ String name, Object type, Object arg0) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type, arg0);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type, arg0);
+ }
+ }
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller, String name,
+ Object type, Object arg0, Object arg1) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type, arg0, arg1);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type, arg0, arg1);
+ }
+ }
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller, String name,
+ Object type, Object arg0, Object arg1,
+ Object arg2) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type, arg0, arg1, arg2);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type, arg0, arg1, arg2);
+ }
+ }
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller, String name,
+ Object type, Object arg0, Object arg1,
+ Object arg2, Object arg3) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type, arg0, arg1, arg2, arg3);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller,
+ String name, Object type, Object arg0, Object arg1,
+ Object arg2, Object arg3, Object arg4) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type, arg0, arg1, arg2, arg3, arg4);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type, arg0, arg1, arg2, arg3, arg4);
+ }
+ }
+
+ private static Object invoke(MethodHandle bootstrapMethod, Lookup caller,
+ String name, Object type, Object arg0, Object arg1,
+ Object arg2, Object arg3, Object arg4, Object arg5) throws Throwable {
+ if (type instanceof Class) {
+ return bootstrapMethod.invoke(caller, name, (Class<?>)type, arg0, arg1, arg2, arg3, arg4, arg5);
+ } else {
+ return bootstrapMethod.invoke(caller, name, (MethodType)type, arg0, arg1, arg2, arg3, arg4, arg5);
+ }
+ }
+
+ private static Object invokeWithManyArguments(MethodHandle bootstrapMethod, Lookup caller,
+ String name, Object type, Object[] argv) throws Throwable {
+ final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
+ final int MAX_SAFE_SIZE = MethodType.MAX_MH_ARITY / 2 - NON_SPREAD_ARG_COUNT;
+ if (argv.length >= MAX_SAFE_SIZE) {
+ // to be on the safe side, use invokeWithArguments which handles jumbo lists
+ Object[] newargv = new Object[NON_SPREAD_ARG_COUNT + argv.length];
+ newargv[0] = caller;
+ newargv[1] = name;
+ newargv[2] = type;
+ System.arraycopy(argv, 0, newargv, NON_SPREAD_ARG_COUNT, argv.length);
+ return bootstrapMethod.invokeWithArguments(newargv);
+ } else {
+ MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+ MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+ MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+ return spreader.invokeExact(typedBSM, (Object) caller, (Object) name, type, argv);
+ }
+ }
+
+ private static final MethodType LMF_INDY_MT = MethodType.methodType(CallSite.class,
+ Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
+
+ private static final MethodType LMF_CONDY_MT = MethodType.methodType(Object.class,
+ Lookup.class, String.class, Class.class, MethodType.class, MethodHandle.class, MethodType.class);
+
+ private static final MethodType SCF_MT = MethodType.methodType(CallSite.class,
+ Lookup.class, String.class, MethodType.class, String.class, Object[].class);
+
+ /**
+ * @return true iff the BSM method type exactly matches
+ * {@see java.lang.invoke.StringConcatFactory#makeConcatWithConstants(MethodHandles.Lookup,
+ * String,MethodType,String,Object...))}
+ */
+ private static boolean isStringConcatFactoryBSM(MethodType bsmType) {
+ return bsmType == SCF_MT;
+ }
+
+ /**
+ * @return true iff the BSM method type exactly matches
+ * {@see java.lang.invoke.LambdaMetafactory#metafactory(
+ * MethodHandles.Lookup,String,Class,MethodType,MethodHandle,MethodType)}
+ */
+ private static boolean isLambdaMetafactoryCondyBSM(MethodType bsmType) {
+ return bsmType == LMF_CONDY_MT;
+ }
+
+ /**
+ * @return true iff the BSM method type exactly matches
+ * {@see java.lang.invoke.LambdaMetafactory#metafactory(
+ * MethodHandles.Lookup,String,MethodType,MethodType,MethodHandle,MethodType)}
+ */
+ private static boolean isLambdaMetafactoryIndyBSM(MethodType bsmType) {
+ return bsmType == LMF_INDY_MT;
+ }
+
/** The JVM produces java.lang.Integer values to box
* CONSTANT_Integer boxes but does not intern them.
* Let's intern them. This is slightly wrong for
--- a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Mon Feb 26 09:56:12 2018 +0100
@@ -242,6 +242,12 @@
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
+ // LambdaMetafactory bootstrap methods are startup sensitive, and may be
+ // special cased in java.lang.invokeBootstrapMethodInvoker to ensure
+ // methods are invoked with exact type information to avoid generating
+ // code for runtime checks. Take care any changes or additions here are
+ // reflected there as appropriate.
+
/**
* Facilitates the creation of simple "function objects" that implement one
* or more interfaces by delegation to a provided {@link MethodHandle},
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -643,10 +643,7 @@
static boolean canBeCalledVirtual(MemberName mem) {
assert(mem.isInvocable());
- Class<?> defc = mem.getDeclaringClass();
switch (mem.getName()) {
- case "checkMemberAccess":
- return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
case "getContextClassLoader":
return canBeCalledVirtual(mem, java.lang.Thread.class);
}
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Mon Feb 26 09:56:12 2018 +0100
@@ -373,6 +373,12 @@
}
}
+ // StringConcatFactory bootstrap methods are startup sensitive, and may be
+ // special cased in java.lang.invokeBootstrapMethodInvoker to ensure
+ // methods are invoked with exact type information to avoid generating
+ // code for runtime checks. Take care any changes or additions here are
+ // reflected there as appropriate.
+
/**
* Facilitates the creation of optimized String concatenation methods, that
* can be used to efficiently concatenate a known number of arguments of
--- a/src/java.base/share/classes/java/lang/ref/Finalizer.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,7 @@
new Finalizer(finalizee);
}
- private void deregisterAndRunFinalizer(JavaLangAccess jla) {
+ private void runFinalizer(JavaLangAccess jla) {
synchronized (lock) {
if (this.next == this) // already finalized
return;
@@ -80,17 +80,14 @@
this.prev = null;
this.next = this; // mark as finalized
}
- runFinalizer(jla);
- }
- private void runFinalizer(JavaLangAccess jla) {
try {
Object finalizee = this.get();
if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
jla.invokeFinalize(finalizee);
- /* Clear stack slot containing this variable, to decrease
- the chances of false retention with a conservative GC */
+ // Clear stack slot containing this variable, to decrease
+ // the chances of false retention with a conservative GC
finalizee = null;
}
} catch (Throwable x) { }
@@ -98,17 +95,14 @@
}
/* Create a privileged secondary finalizer thread in the system thread
- group for the given Runnable, and wait for it to complete.
-
- This method is used by both runFinalization and runFinalizersOnExit.
- The former method invokes all pending finalizers, while the latter
- invokes all uninvoked finalizers if on-exit finalization has been
- enabled.
-
- These two methods could have been implemented by offloading their work
- to the regular finalizer thread and waiting for that thread to finish.
- The advantage of creating a fresh thread, however, is that it insulates
- invokers of these methods from a stalled or deadlocked finalizer thread.
+ * group for the given Runnable, and wait for it to complete.
+ *
+ * This method is used by runFinalization.
+ *
+ * It could have been implemented by offloading the work to the
+ * regular finalizer thread and waiting for that thread to finish.
+ * The advantage of creating a fresh thread, however, is that it insulates
+ * invokers of that method from a stalled or deadlocked finalizer thread.
*/
private static void forkSecondaryFinalizer(final Runnable proc) {
AccessController.doPrivileged(
@@ -144,40 +138,11 @@
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true;
for (Finalizer f; (f = (Finalizer)queue.poll()) != null; )
- f.deregisterAndRunFinalizer(jla);
+ f.runFinalizer(jla);
}
});
}
- /* Invoked by java.lang.Shutdown */
- static void runAllFinalizers() {
- if (VM.initLevel() == 0) {
- return;
- }
-
- forkSecondaryFinalizer(new Runnable() {
- private volatile boolean running;
- public void run() {
- // in case of recursive call to run()
- if (running)
- return;
- final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
- running = true;
- for (;;) {
- // "pollFirst" from unfinalized
- Finalizer f;
- synchronized (lock) {
- f = unfinalized;
- if (f == null) break;
- unfinalized = f.next;
- if (unfinalized != null)
- unfinalized.prev = null;
- f.next = f; // mark as finalized
- }
- f.runFinalizer(jla);
- }}});
- }
-
private static class FinalizerThread extends Thread {
private volatile boolean running;
FinalizerThread(ThreadGroup g) {
@@ -203,7 +168,7 @@
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
- f.deregisterAndRunFinalizer(jla);
+ f.runFinalizer(jla);
} catch (InterruptedException x) {
// ignore and continue
}
--- a/src/java.base/share/classes/java/lang/ref/Reference.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ref/Reference.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -235,6 +235,11 @@
{
return Reference.waitForReferenceProcessing();
}
+
+ @Override
+ public void runFinalization() {
+ Finalizer.runFinalization();
+ }
});
}
--- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package java.lang.reflect;
import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandle;
import java.security.AccessController;
import jdk.internal.misc.VM;
@@ -180,6 +181,7 @@
* @revised 9
* @spec JPMS
*/
+ @CallerSensitive // overrides in Method/Field/Constructor are @CS
public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
setAccessible0(flag);
@@ -276,14 +278,17 @@
// do nothing, needs to be overridden by Constructor, Method, Field
}
-
- void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
+ final void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
checkCanSetAccessible(caller, declaringClass, true);
}
private boolean checkCanSetAccessible(Class<?> caller,
Class<?> declaringClass,
boolean throwExceptionIfDenied) {
+ if (caller == MethodHandle.class) {
+ throw new IllegalCallerException(); // should not happen
+ }
+
Module callerModule = caller.getModule();
Module declaringModule = declaringClass.getModule();
--- a/src/java.base/share/classes/java/net/SocketCleanable.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/net/SocketCleanable.java Mon Feb 26 09:56:12 2018 +0100
@@ -36,20 +36,21 @@
/**
- * Cleanup for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
+ * Cleanable for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
* Create a cleanup if the raw fd != -1. Windows closes sockets using the fd.
* Subclassed from {@code PhantomCleanable} so that {@code clear} can be
* called to disable the cleanup when the socket fd is closed by any means
* other than calling {@link FileDescriptor#close}.
- * Otherwise, it would incorrectly close the handle or fd after it has been reused.
+ * Otherwise, it might incorrectly close the handle or fd after it has been reused.
*/
-final class SocketCleanable extends PhantomCleanable<Object> {
+final class SocketCleanable extends PhantomCleanable<FileDescriptor> {
- // Access to FileDescriptor internals
+ // Access to FileDescriptor private fields
private static final JavaIOFileDescriptorAccess fdAccess =
SharedSecrets.getJavaIOFileDescriptorAccess();
// Native function to call NET_SocketClose(fd)
+ // Used only for last chance cleanup.
private static native void cleanupClose0(int fd) throws IOException;
// The raw fd to close
@@ -62,12 +63,10 @@
* @param fdo the FileDescriptor; may be null
*/
static void register(FileDescriptor fdo) {
- if (fdo != null) {
+ if (fdo != null && fdo.valid()) {
int fd = fdAccess.get(fdo);
- if (fd != -1) {
- fdAccess.registerCleanup(fdo,
- new SocketCleanable(fdo, CleanerFactory.cleaner(), fd));
- }
+ fdAccess.registerCleanup(fdo,
+ new SocketCleanable(fdo, CleanerFactory.cleaner(), fd));
}
}
@@ -88,7 +87,7 @@
* @param cleaner the cleaner
* @param fd file descriptor to close
*/
- private SocketCleanable(Object obj, Cleaner cleaner, int fd) {
+ private SocketCleanable(FileDescriptor obj, Cleaner cleaner, int fd) {
super(obj, cleaner);
this.fd = fd;
}
--- a/src/java.base/share/classes/java/util/Currency.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/util/Currency.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.spi.CurrencyNameProvider;
+import java.util.stream.Collectors;
import sun.util.locale.provider.CalendarDataUtility;
import sun.util.locale.provider.LocaleServiceProviderPool;
import sun.util.logging.PlatformLogger;
@@ -77,7 +78,10 @@
* JP=JPZ,999,0
* </code>
* <p>
- * will supersede the currency data for Japan.
+ * will supersede the currency data for Japan. If JPZ is one of the existing
+ * ISO 4217 currency code referred by other countries, the existing
+ * JPZ currency data is updated with the given numeric code and minor
+ * unit value.
*
* <p>
* <code>
@@ -93,6 +97,11 @@
* country code entries exist, the behavior of the Currency information for that
* {@code Currency} is undefined and the remainder of entries in file are processed.
* <p>
+ * If multiple property entries with same currency code but different numeric code
+ * and/or minor unit are encountered, those entries are ignored and the remainder
+ * of entries in file are processed.
+ *
+ * <p>
* It is recommended to use {@link java.math.BigDecimal} class while dealing
* with {@code Currency} or monetary values as it provides better handling of floating
* point numbers and their operations.
@@ -237,19 +246,17 @@
try (FileReader fr = new FileReader(propFile)) {
props.load(fr);
}
- Set<String> keys = props.stringPropertyNames();
Pattern propertiesPattern =
- Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
- "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
- "\\d{2}:\\d{2})?");
- for (String key : keys) {
- replaceCurrencyData(propertiesPattern,
- key.toUpperCase(Locale.ROOT),
- props.getProperty(key).toUpperCase(Locale.ROOT));
- }
+ Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" +
+ "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" +
+ "\\d{2}:\\d{2})?");
+ List<CurrencyProperty> currencyEntries
+ = getValidCurrencyData(props, propertiesPattern);
+ currencyEntries.forEach(Currency::replaceCurrencyData);
}
} catch (IOException e) {
- info("currency.properties is ignored because of an IOException", e);
+ CurrencyProperty.info("currency.properties is ignored"
+ + " because of an IOException", e);
}
return null;
}
@@ -769,71 +776,111 @@
}
/**
- * Replaces currency data found in the currencydata.properties file
+ * Parse currency data found in the properties file (that
+ * java.util.currency.data designates) to a List of CurrencyProperty
+ * instances. Also, remove invalid entries and the multiple currency
+ * code inconsistencies.
*
- * @param pattern regex pattern for the properties
- * @param ctry country code
- * @param curdata currency data. This is a comma separated string that
- * consists of "three-letter alphabet code", "three-digit numeric code",
- * and "one-digit (0-9) default fraction digit".
- * For example, "JPZ,392,0".
- * An optional UTC date can be appended to the string (comma separated)
- * to allow a currency change take effect after date specified.
- * For example, "JP=JPZ,999,0,2014-01-01T00:00:00" has no effect unless
- * UTC time is past 1st January 2014 00:00:00 GMT.
+ * @param props properties containing currency data
+ * @param pattern regex pattern for the properties entry
+ * @return list of parsed property entries
*/
- private static void replaceCurrencyData(Pattern pattern, String ctry, String curdata) {
+ private static List<CurrencyProperty> getValidCurrencyData(Properties props,
+ Pattern pattern) {
+
+ Set<String> keys = props.stringPropertyNames();
+ List<CurrencyProperty> propertyEntries = new ArrayList<>();
- if (ctry.length() != 2) {
- // ignore invalid country code
- info("currency.properties entry for " + ctry +
- " is ignored because of the invalid country code.", null);
- return;
- }
+ // remove all invalid entries and parse all valid currency properties
+ // entries to a group of CurrencyProperty, classified by currency code
+ Map<String, List<CurrencyProperty>> currencyCodeGroup = keys.stream()
+ .map(k -> CurrencyProperty
+ .getValidEntry(k.toUpperCase(Locale.ROOT),
+ props.getProperty(k).toUpperCase(Locale.ROOT),
+ pattern)).flatMap(o -> o.stream())
+ .collect(Collectors.groupingBy(entry -> entry.currencyCode));
- Matcher m = pattern.matcher(curdata);
- if (!m.find() || (m.group(4) == null && countOccurrences(curdata, ',') >= 3)) {
- // format is not recognized. ignore the data
- // if group(4) date string is null and we've 4 values, bad date value
- info("currency.properties entry for " + ctry +
- " ignored because the value format is not recognized.", null);
- return;
- }
-
- try {
- if (m.group(4) != null && !isPastCutoverDate(m.group(4))) {
- info("currency.properties entry for " + ctry +
- " ignored since cutover date has not passed :" + curdata, null);
- return;
+ // check each group for inconsistencies
+ currencyCodeGroup.forEach((curCode, list) -> {
+ boolean inconsistent = CurrencyProperty
+ .containsInconsistentInstances(list);
+ if (inconsistent) {
+ list.forEach(prop -> CurrencyProperty.info("The property"
+ + " entry for " + prop.country + " is inconsistent."
+ + " Ignored.", null));
+ } else {
+ propertyEntries.addAll(list);
}
- } catch (ParseException ex) {
- info("currency.properties entry for " + ctry +
- " ignored since exception encountered :" + ex.getMessage(), null);
- return;
- }
+ });
+
+ return propertyEntries;
+ }
- String code = m.group(1);
- int numeric = Integer.parseInt(m.group(2));
+ /**
+ * Replaces currency data found in the properties file that
+ * java.util.currency.data designates. This method is invoked for
+ * each valid currency entry.
+ *
+ * @param prop CurrencyProperty instance of the valid property entry
+ */
+ private static void replaceCurrencyData(CurrencyProperty prop) {
+
+
+ String ctry = prop.country;
+ String code = prop.currencyCode;
+ int numeric = prop.numericCode;
+ int fraction = prop.fraction;
int entry = numeric << NUMERIC_CODE_SHIFT;
- int fraction = Integer.parseInt(m.group(3));
- if (fraction > SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS) {
- info("currency.properties entry for " + ctry +
- " ignored since the fraction is more than " +
- SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS + ":" + curdata, null);
- return;
- }
int index = SpecialCaseEntry.indexOf(code, fraction, numeric);
- /* if a country switches from simple case to special case or
+
+ // If a new entry changes the numeric code/dfd of an existing
+ // currency code, update it in the sc list at the respective
+ // index and also change it in the other currencies list and
+ // main table (if that currency code is also used as a
+ // simple case).
+
+ // If all three components do not match with the new entry,
+ // but the currency code exists in the special case list
+ // update the sc entry with the new entry
+ int scCurrencyCodeIndex = -1;
+ if (index == -1) {
+ scCurrencyCodeIndex = SpecialCaseEntry.currencyCodeIndex(code);
+ if (scCurrencyCodeIndex != -1) {
+ //currency code exists in sc list, then update the old entry
+ specialCasesList.set(scCurrencyCodeIndex,
+ new SpecialCaseEntry(code, fraction, numeric));
+
+ // also update the entry in other currencies list
+ OtherCurrencyEntry oe = OtherCurrencyEntry.findEntry(code);
+ if (oe != null) {
+ int oIndex = otherCurrenciesList.indexOf(oe);
+ otherCurrenciesList.set(oIndex, new OtherCurrencyEntry(
+ code, fraction, numeric));
+ }
+ }
+ }
+
+ /* If a country switches from simple case to special case or
* one special case to other special case which is not present
- * in the sc arrays then insert the new entry in special case arrays
+ * in the sc arrays then insert the new entry in special case arrays.
+ * If an entry with given currency code exists, update with the new
+ * entry.
*/
if (index == -1 && (ctry.charAt(0) != code.charAt(0)
|| ctry.charAt(1) != code.charAt(1))) {
- specialCasesList.add(new SpecialCaseEntry(code, fraction, numeric));
- index = specialCasesList.size() - 1;
+ if(scCurrencyCodeIndex == -1) {
+ specialCasesList.add(new SpecialCaseEntry(code, fraction,
+ numeric));
+ index = specialCasesList.size() - 1;
+ } else {
+ index = scCurrencyCodeIndex;
+ }
+
+ // update the entry in main table if it exists as a simple case
+ updateMainTableEntry(code, fraction, numeric);
}
if (index == -1) {
@@ -848,32 +895,29 @@
setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
}
- private static boolean isPastCutoverDate(String s) throws ParseException {
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
- format.setTimeZone(TimeZone.getTimeZone("UTC"));
- format.setLenient(false);
- long time = format.parse(s.trim()).getTime();
- return System.currentTimeMillis() > time;
-
- }
+ // update the entry in maintable for any simple case found, if a new
+ // entry as a special case updates the entry in sc list with
+ // existing currency code
+ private static void updateMainTableEntry(String code, int fraction,
+ int numeric) {
+ // checking the existence of currency code in mainTable
+ int tableEntry = getMainTableEntry(code.charAt(0), code.charAt(1));
+ int entry = numeric << NUMERIC_CODE_SHIFT;
+ if ((tableEntry & COUNTRY_TYPE_MASK) == SIMPLE_CASE_COUNTRY_MASK
+ && tableEntry != INVALID_COUNTRY_ENTRY
+ && code.charAt(2) - 'A' == (tableEntry
+ & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK)) {
- private static int countOccurrences(String value, char match) {
- int count = 0;
- for (char c : value.toCharArray()) {
- if (c == match) {
- ++count;
- }
- }
- return count;
- }
-
- private static void info(String message, Throwable t) {
- PlatformLogger logger = PlatformLogger.getLogger("java.util.Currency");
- if (logger.isLoggable(PlatformLogger.Level.INFO)) {
- if (t != null) {
- logger.info(message, t);
- } else {
- logger.info(message);
+ int numericCode = (tableEntry & NUMERIC_CODE_MASK)
+ >> NUMERIC_CODE_SHIFT;
+ int defaultFractionDigits = (tableEntry
+ & SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_MASK)
+ >> SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT;
+ if (numeric != numericCode || fraction != defaultFractionDigits) {
+ // update the entry in main table
+ entry |= (fraction << SIMPLE_CASE_COUNTRY_DEFAULT_DIGITS_SHIFT)
+ | (code.charAt(2) - 'A');
+ setMainTableEntry(code.charAt(0), code.charAt(1), entry);
}
}
}
@@ -959,6 +1003,25 @@
return fractionAndNumericCode;
}
+ // get the index based on currency code
+ private static int currencyCodeIndex(String code) {
+ int size = specialCasesList.size();
+ for (int index = 0; index < size; index++) {
+ SpecialCaseEntry scEntry = specialCasesList.get(index);
+ if (scEntry.oldCurrency.equals(code) && (scEntry.cutOverTime == Long.MAX_VALUE
+ || System.currentTimeMillis() < scEntry.cutOverTime)) {
+ //consider only when there is no new currency or cutover time is not passed
+ return index;
+ } else if (scEntry.newCurrency.equals(code)
+ && System.currentTimeMillis() >= scEntry.cutOverTime) {
+ //consider only if the cutover time is passed
+ return index;
+ }
+ }
+ return -1;
+ }
+
+
// convert the special case entry to sc arrays index
private static int toIndex(int tableEntry) {
return (tableEntry & SPECIAL_CASE_COUNTRY_INDEX_MASK) - SPECIAL_CASE_COUNTRY_INDEX_DELTA;
@@ -999,6 +1062,136 @@
}
+
+ /*
+ * Used to represent an entry of the properties file that
+ * java.util.currency.data designates
+ *
+ * - country: country representing the currency entry
+ * - currencyCode: currency code
+ * - fraction: default fraction digit
+ * - numericCode: numeric code
+ * - date: cutover date
+ */
+ private static class CurrencyProperty {
+ final private String country;
+ final private String currencyCode;
+ final private int fraction;
+ final private int numericCode;
+ final private String date;
+
+ private CurrencyProperty(String country, String currencyCode,
+ int fraction, int numericCode, String date) {
+ this.country = country;
+ this.currencyCode = currencyCode;
+ this.fraction = fraction;
+ this.numericCode = numericCode;
+ this.date = date;
+ }
+
+ /**
+ * Check the valid currency data and create/return an Optional instance
+ * of CurrencyProperty
+ *
+ * @param ctry country representing the currency data
+ * @param curData currency data of the given {@code ctry}
+ * @param pattern regex pattern for the properties entry
+ * @return Optional containing CurrencyProperty instance, If valid;
+ * empty otherwise
+ */
+ private static Optional<CurrencyProperty> getValidEntry(String ctry,
+ String curData,
+ Pattern pattern) {
+
+ CurrencyProperty prop = null;
+
+ if (ctry.length() != 2) {
+ // Invalid country code. Ignore the entry.
+ } else {
+
+ prop = parseProperty(ctry, curData, pattern);
+ // if the property entry failed any of the below checked
+ // criteria it is ignored
+ if (prop == null
+ || (prop.date == null && curData.chars()
+ .map(c -> c == ',' ? 1 : 0).sum() >= 3)) {
+ // format is not recognized. ignore the data if date
+ // string is null and we've 4 values, bad date value
+ prop = null;
+ } else if (prop.fraction
+ > SIMPLE_CASE_COUNTRY_MAX_DEFAULT_DIGITS) {
+ prop = null;
+ } else {
+ try {
+ if (prop.date != null
+ && !isPastCutoverDate(prop.date)) {
+ prop = null;
+ }
+ } catch (ParseException ex) {
+ prop = null;
+ }
+ }
+ }
+
+ if (prop == null) {
+ info("The property entry for " + ctry + " is invalid."
+ + " Ignored.", null);
+ }
+
+ return Optional.ofNullable(prop);
+ }
+
+ /*
+ * Parse properties entry and return CurrencyProperty instance
+ */
+ private static CurrencyProperty parseProperty(String ctry,
+ String curData, Pattern pattern) {
+ Matcher m = pattern.matcher(curData);
+ if (!m.find()) {
+ return null;
+ } else {
+ return new CurrencyProperty(ctry, m.group(1),
+ Integer.parseInt(m.group(3)),
+ Integer.parseInt(m.group(2)), m.group(4));
+ }
+ }
+
+ /**
+ * Checks if the given list contains multiple inconsistent currency instances
+ */
+ private static boolean containsInconsistentInstances(
+ List<CurrencyProperty> list) {
+ int numCode = list.get(0).numericCode;
+ int fractionDigit = list.get(0).fraction;
+ return list.stream().anyMatch(prop -> prop.numericCode != numCode
+ || prop.fraction != fractionDigit);
+ }
+
+ private static boolean isPastCutoverDate(String s)
+ throws ParseException {
+ SimpleDateFormat format = new SimpleDateFormat(
+ "yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
+ format.setTimeZone(TimeZone.getTimeZone("UTC"));
+ format.setLenient(false);
+ long time = format.parse(s.trim()).getTime();
+ return System.currentTimeMillis() > time;
+
+ }
+
+ private static void info(String message, Throwable t) {
+ PlatformLogger logger = PlatformLogger
+ .getLogger("java.util.Currency");
+ if (logger.isLoggable(PlatformLogger.Level.INFO)) {
+ if (t != null) {
+ logger.info(message, t);
+ } else {
+ logger.info(message);
+ }
+ }
+ }
+
+ }
+
}
--- a/src/java.base/share/classes/java/util/Formatter.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/util/Formatter.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -284,11 +284,11 @@
* {@code 'A'}, and {@code 'T'}) are the same as those for the corresponding
* lower-case conversion characters except that the result is converted to
* upper case according to the rules of the prevailing {@link java.util.Locale
- * Locale}. The result is equivalent to the following invocation of {@link
- * String#toUpperCase(Locale)}
- *
- * <pre>
- * out.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)) </pre>
+ * Locale}. If there is no explicit locale specified, either at the
+ * construction of the instance or as a parameter to its method
+ * invocation, then the {@link java.util.Locale.Category#FORMAT default locale}
+ * is used.
+ *
*
* <table class="striped">
* <caption style="display:none">genConv</caption>
@@ -709,11 +709,10 @@
* {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the
* corresponding lower-case conversion characters except that the result is
* converted to upper case according to the rules of the prevailing {@link
- * java.util.Locale Locale}. The result is equivalent to the following
- * invocation of {@link String#toUpperCase(Locale)}
- *
- * <pre>
- * out.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)) </pre>
+ * java.util.Locale Locale}. If there is no explicit locale specified,
+ * either at the construction of the instance or as a parameter to its method
+ * invocation, then the {@link java.util.Locale.Category#FORMAT default locale}
+ * is used.
*
* <h4><a id="dgen">General</a></h4>
*
@@ -2897,16 +2896,16 @@
break;
case Conversion.CHARACTER:
case Conversion.CHARACTER_UPPER:
- printCharacter(arg);
+ printCharacter(arg, l);
break;
case Conversion.BOOLEAN:
- printBoolean(arg);
+ printBoolean(arg, l);
break;
case Conversion.STRING:
printString(arg, l);
break;
case Conversion.HASHCODE:
- printHashCode(arg);
+ printHashCode(arg, l);
break;
case Conversion.LINE_SEPARATOR:
a.append(System.lineSeparator());
@@ -2921,7 +2920,7 @@
private void printInteger(Object arg, Locale l) throws IOException {
if (arg == null)
- print("null");
+ print("null", l);
else if (arg instanceof Byte)
print(((Byte)arg).byteValue(), l);
else if (arg instanceof Short)
@@ -2938,7 +2937,7 @@
private void printFloat(Object arg, Locale l) throws IOException {
if (arg == null)
- print("null");
+ print("null", l);
else if (arg instanceof Float)
print(((Float)arg).floatValue(), l);
else if (arg instanceof Double)
@@ -2951,7 +2950,7 @@
private void printDateTime(Object arg, Locale l) throws IOException {
if (arg == null) {
- print("null");
+ print("null", l);
return;
}
Calendar cal = null;
@@ -2982,9 +2981,9 @@
print(cal, c, l);
}
- private void printCharacter(Object arg) throws IOException {
+ private void printCharacter(Object arg, Locale l) throws IOException {
if (arg == null) {
- print("null");
+ print("null", l);
return;
}
String s = null;
@@ -3011,7 +3010,7 @@
} else {
failConversion(c, arg);
}
- print(s);
+ print(s, l);
}
private void printString(Object arg, Locale l) throws IOException {
@@ -3024,13 +3023,13 @@
if (f.contains(Flags.ALTERNATE))
failMismatch(Flags.ALTERNATE, 's');
if (arg == null)
- print("null");
+ print("null", l);
else
- print(arg.toString());
+ print(arg.toString(), l);
}
}
- private void printBoolean(Object arg) throws IOException {
+ private void printBoolean(Object arg, Locale l) throws IOException {
String s;
if (arg != null)
s = ((arg instanceof Boolean)
@@ -3038,24 +3037,29 @@
: Boolean.toString(true));
else
s = Boolean.toString(false);
- print(s);
+ print(s, l);
}
- private void printHashCode(Object arg) throws IOException {
+ private void printHashCode(Object arg, Locale l) throws IOException {
String s = (arg == null
? "null"
: Integer.toHexString(arg.hashCode()));
- print(s);
+ print(s, l);
}
- private void print(String s) throws IOException {
+ private void print(String s, Locale l) throws IOException {
if (precision != -1 && precision < s.length())
s = s.substring(0, precision);
if (f.contains(Flags.UPPERCASE))
- s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT));
+ s = toUpperCaseWithLocale(s, l);
appendJustified(a, s);
}
+ private String toUpperCaseWithLocale(String s, Locale l) {
+ return s.toUpperCase(Objects.requireNonNullElse(l,
+ Locale.getDefault(Locale.Category.FORMAT)));
+ }
+
private Appendable appendJustified(Appendable a, CharSequence cs) throws IOException {
if (width == -1) {
return a.append(cs);
@@ -3276,7 +3280,7 @@
trailingZeros(sb, width - len);
}
if (f.contains(Flags.UPPERCASE))
- s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT));
+ s = toUpperCaseWithLocale(s, l);
sb.append(s);
}
@@ -3351,7 +3355,7 @@
trailingZeros(sb, width - len);
}
if (f.contains(Flags.UPPERCASE))
- s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT));
+ s = toUpperCaseWithLocale(s, l);
sb.append(s);
}
@@ -3950,7 +3954,7 @@
// justify based on width
if (f.contains(Flags.UPPERCASE)) {
- appendJustified(a, sb.toString().toUpperCase(Locale.getDefault(Locale.Category.FORMAT)));
+ appendJustified(a, toUpperCaseWithLocale(sb.toString(), l));
} else {
appendJustified(a, sb);
}
@@ -4132,8 +4136,7 @@
StringBuilder tsb = new StringBuilder();
print(tsb, t, DateTime.AM_PM, l);
- sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l,
- Locale.getDefault(Locale.Category.FORMAT))));
+ sb.append(toUpperCaseWithLocale(tsb.toString(), l));
break;
}
case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
@@ -4171,7 +4174,7 @@
print(sb, t, c, l);
// justify based on width
if (f.contains(Flags.UPPERCASE)) {
- appendJustified(a, sb.toString().toUpperCase(Locale.getDefault(Locale.Category.FORMAT)));
+ appendJustified(a, toUpperCaseWithLocale(sb.toString(), l));
} else {
appendJustified(a, sb);
}
@@ -4373,8 +4376,7 @@
// this may be in wrong place for some locales
StringBuilder tsb = new StringBuilder();
print(tsb, t, DateTime.AM_PM, l);
- sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l,
- Locale.getDefault(Locale.Category.FORMAT))));
+ sb.append(toUpperCaseWithLocale(tsb.toString(), l));
break;
}
case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
--- a/src/java.base/share/classes/java/util/jar/Attributes.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/util/jar/Attributes.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,16 @@
package java.util.jar;
-import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Comparator;
import java.util.LinkedHashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import java.util.Collection;
-import java.util.AbstractSet;
-import java.util.Iterator;
-import java.util.Locale;
+
import sun.util.logging.PlatformLogger;
-import java.util.Comparator;
/**
* The Attributes class maps Manifest attribute names to associated string
--- a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,6 @@
package java.util.regex;
-import sun.security.action.GetPropertyAction;
-
-
/**
* Unchecked exception thrown to indicate a syntax error in a
* regular-expression pattern.
@@ -93,9 +90,6 @@
return pattern;
}
- private static final String nl =
- GetPropertyAction.privilegedGetProperty("line.separator");
-
/**
* Returns a multi-line string containing the description of the syntax
* error and its index, the erroneous regular-expression pattern, and a
@@ -110,10 +104,10 @@
sb.append(" near index ");
sb.append(index);
}
- sb.append(nl);
+ sb.append(System.lineSeparator());
sb.append(pattern);
if (index >= 0) {
- sb.append(nl);
+ sb.append(System.lineSeparator());
for (int i = 0; i < index; i++) sb.append(' ');
sb.append('^');
}
--- a/src/java.base/share/classes/jdk/internal/misc/JavaIOFileDescriptorAccess.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaIOFileDescriptorAccess.java Mon Feb 26 09:56:12 2018 +0100
@@ -40,7 +40,7 @@
public boolean getAppend(FileDescriptor fdo);
public void close(FileDescriptor fdo) throws IOException;
public void registerCleanup(FileDescriptor fdo);
- public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanable);
+ public void registerCleanup(FileDescriptor fdo, PhantomCleanable<FileDescriptor> cleanable);
public void unregisterCleanup(FileDescriptor fdo);
// Only valid on Windows
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,4 +36,11 @@
* {@link java.lang.ref.Reference}s, {@code false} otherwise.
*/
boolean waitForReferenceProcessing() throws InterruptedException;
+
+ /**
+ * Runs the finalization methods of any objects pending finalization.
+ *
+ * Invoked by Runtime.runFinalization()
+ */
+ void runFinalization();
}
--- a/src/java.base/share/classes/jdk/internal/misc/VM.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/VM.java Mon Feb 26 09:56:12 2018 +0100
@@ -27,9 +27,7 @@
import static java.lang.Thread.State.*;
import java.util.Map;
-import java.util.HashMap;
import java.util.Properties;
-import java.util.Collections;
public class VM {
@@ -38,6 +36,8 @@
private static final int MODULE_SYSTEM_INITED = 2;
private static final int SYSTEM_LOADER_INITIALIZING = 3;
private static final int SYSTEM_BOOTED = 4;
+ private static final int SYSTEM_SHUTDOWN = 5;
+
// 0, 1, 2, ...
private static volatile int initLevel;
@@ -52,7 +52,7 @@
*/
public static void initLevel(int value) {
synchronized (lock) {
- if (value <= initLevel || value > SYSTEM_BOOTED)
+ if (value <= initLevel || value > SYSTEM_SHUTDOWN)
throw new InternalError("Bad level: " + value);
initLevel = value;
lock.notifyAll();
@@ -94,6 +94,23 @@
return initLevel >= SYSTEM_BOOTED;
}
+ /**
+ * Set shutdown state. Shutdown completes when all registered shutdown
+ * hooks have been run.
+ *
+ * @see java.lang.Shutdown
+ */
+ public static void shutdown() {
+ initLevel(SYSTEM_SHUTDOWN);
+ }
+
+ /**
+ * Returns {@code true} if the VM has been shutdown
+ */
+ public static boolean isShutdown() {
+ return initLevel == SYSTEM_SHUTDOWN;
+ }
+
// A user-settable upper limit on the maximum amount of allocatable direct
// buffer memory. This value may be changed during VM initialization if
// "java" is launched with "-XX:MaxDirectMemorySize=<size>".
--- a/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLStreamWriterImpl.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,8 +75,7 @@
//pretty print by default
private boolean _doIndent = true;
//The system line separator for writing out line breaks.
- private char[] _lineSep =
- System.getProperty("line.separator").toCharArray();
+ private char[] _lineSep = System.lineSeparator().toCharArray();
public XMLStreamWriterImpl(OutputStream os) throws XMLStreamException {
this(os, XMLStreamWriter.DEFAULT_CHARSET);
--- a/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLWriter.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/XMLWriter.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -123,7 +123,7 @@
}
private void nl() throws XMLStreamException {
- String lineEnd = System.getProperty("line.separator");
+ String lineEnd = System.lineSeparator();
try {
_writer.write(lineEnd);
} catch (IOException e) {
--- a/src/java.base/share/native/libjava/Runtime.c Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/native/libjava/Runtime.c Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,19 +65,6 @@
JVM_GC();
}
-JNIEXPORT void JNICALL
-Java_java_lang_Runtime_runFinalization0(JNIEnv *env, jobject this)
-{
- jclass cl;
- jmethodID mid;
-
- if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer"))
- && (mid = (*env)->GetStaticMethodID(env, cl,
- "runFinalization", "()V"))) {
- (*env)->CallStaticVoidMethod(env, cl, mid);
- }
-}
-
JNIEXPORT jint JNICALL
Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
{
--- a/src/java.base/share/native/libjava/Shutdown.c Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/native/libjava/Shutdown.c Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,17 +35,3 @@
{
JVM_Halt(code);
}
-
-
-JNIEXPORT void JNICALL
-Java_java_lang_Shutdown_runAllFinalizers(JNIEnv *env, jclass ignored)
-{
- jclass cl;
- jmethodID mid;
-
- if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer"))
- && (mid = (*env)->GetStaticMethodID(env, cl,
- "runAllFinalizers", "()V"))) {
- (*env)->CallStaticVoidMethod(env, cl, mid);
- }
-}
--- a/src/java.base/share/native/libjava/System.c Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/share/native/libjava/System.c Mon Feb 26 09:56:12 2018 +0100
@@ -125,7 +125,6 @@
#define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
#endif
-static int fmtdefault; // boolean value
jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,
char *platformDispVal, char *platformFmtVal,
jmethodID putID, jmethodID getPropID) {
@@ -141,16 +140,9 @@
const char *baseVal = "";
/* user.xxx base property */
- if (fmtdefault) {
- if (platformFmtVal) {
- PUTPROP(props, baseKey, platformFmtVal);
- baseVal = platformFmtVal;
- }
- } else {
- if (platformDispVal) {
- PUTPROP(props, baseKey, platformDispVal);
- baseVal = platformDispVal;
- }
+ if (platformDispVal) {
+ PUTPROP(props, baseKey, platformDispVal);
+ baseVal = platformDispVal;
}
/* user.xxx.display property */
@@ -402,16 +394,6 @@
ret = JVM_InitProperties(env, props);
- /* Check the compatibility flag */
- GETPROP(props, "sun.locale.formatasdefault", jVMVal);
- if (jVMVal) {
- const char * val = (*env)->GetStringUTFChars(env, jVMVal, 0);
- CHECK_NULL_RETURN(val, NULL);
- fmtdefault = !strcmp(val, "true");
- (*env)->ReleaseStringUTFChars(env, jVMVal, val);
- (*env)->DeleteLocalRef(env, jVMVal);
- }
-
/* reconstruct i18n related properties */
fillI18nProps(env, props, "user.language", sprops->display_language,
sprops->format_language, putID, getPropID);
@@ -430,11 +412,7 @@
*/
PUTPROP(props, "file.encoding", sprops->encoding);
#else
- if (fmtdefault) {
- PUTPROP(props, "file.encoding", sprops->encoding);
- } else {
- PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
- }
+ PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
#endif
} else {
(*env)->DeleteLocalRef(env, jVMVal);
--- a/src/java.base/unix/classes/java/io/FileDescriptor.java Tue Feb 20 21:46:02 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.io;
-
-import java.lang.ref.Cleaner;
-import java.util.ArrayList;
-import java.util.List;
-
-import jdk.internal.misc.JavaIOFileDescriptorAccess;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.ref.CleanerFactory;
-import jdk.internal.ref.PhantomCleanable;
-
-/**
- * Instances of the file descriptor class serve as an opaque handle
- * to the underlying machine-specific structure representing an open
- * file, an open socket, or another source or sink of bytes.
- * The main practical use for a file descriptor is to create a
- * {@link FileInputStream} or {@link FileOutputStream} to contain it.
- * <p>
- * Applications should not create their own file descriptors.
- *
- * @author Pavani Diwanji
- * @since 1.0
- */
-public final class FileDescriptor {
-
- private int fd;
-
- private Closeable parent;
- private List<Closeable> otherParents;
- private boolean closed;
-
- /**
- * true, if file is opened for appending.
- */
- private boolean append;
-
- static {
- initIDs();
- }
-
- // Set up JavaIOFileDescriptorAccess in SharedSecrets
- static {
- SharedSecrets.setJavaIOFileDescriptorAccess(
- new JavaIOFileDescriptorAccess() {
- public void set(FileDescriptor fdo, int fd) {
- fdo.set(fd);
- }
-
- public int get(FileDescriptor fdo) {
- return fdo.fd;
- }
-
- public void setAppend(FileDescriptor fdo, boolean append) {
- fdo.append = append;
- }
-
- public boolean getAppend(FileDescriptor fdo) {
- return fdo.append;
- }
-
- public void close(FileDescriptor fdo) throws IOException {
- fdo.close();
- }
-
- public void registerCleanup(FileDescriptor fdo) {
- fdo.registerCleanup();
- }
-
- public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanup) {
- fdo.registerCleanup(cleanup);
- }
-
- public void unregisterCleanup(FileDescriptor fdo) {
- fdo.unregisterCleanup();
- }
-
- public void setHandle(FileDescriptor fdo, long handle) {
- throw new UnsupportedOperationException();
- }
-
- public long getHandle(FileDescriptor fdo) {
- throw new UnsupportedOperationException();
- }
- }
- );
- }
-
- /**
- * Cleanup in case FileDescriptor is not explicitly closed.
- */
- private PhantomCleanable<Object> cleanup;
-
- /**
- * Constructs an (invalid) FileDescriptor
- * object.
- */
- public FileDescriptor() {
- fd = -1;
- }
-
- private FileDescriptor(int fd) {
- this.fd = fd;
- this.append = getAppend(fd);
- }
-
- /**
- * A handle to the standard input stream. Usually, this file
- * descriptor is not used directly, but rather via the input stream
- * known as {@code System.in}.
- *
- * @see java.lang.System#in
- */
- public static final FileDescriptor in = new FileDescriptor(0);
-
- /**
- * A handle to the standard output stream. Usually, this file
- * descriptor is not used directly, but rather via the output stream
- * known as {@code System.out}.
- * @see java.lang.System#out
- */
- public static final FileDescriptor out = new FileDescriptor(1);
-
- /**
- * A handle to the standard error stream. Usually, this file
- * descriptor is not used directly, but rather via the output stream
- * known as {@code System.err}.
- *
- * @see java.lang.System#err
- */
- public static final FileDescriptor err = new FileDescriptor(2);
-
- /**
- * Tests if this file descriptor object is valid.
- *
- * @return {@code true} if the file descriptor object represents a
- * valid, open file, socket, or other active I/O connection;
- * {@code false} otherwise.
- */
- public boolean valid() {
- return fd != -1;
- }
-
- /**
- * Force all system buffers to synchronize with the underlying
- * device. This method returns after all modified data and
- * attributes of this FileDescriptor have been written to the
- * relevant device(s). In particular, if this FileDescriptor
- * refers to a physical storage medium, such as a file in a file
- * system, sync will not return until all in-memory modified copies
- * of buffers associated with this FileDescriptor have been
- * written to the physical medium.
- *
- * sync is meant to be used by code that requires physical
- * storage (such as a file) to be in a known state For
- * example, a class that provided a simple transaction facility
- * might use sync to ensure that all changes to a file caused
- * by a given transaction were recorded on a storage medium.
- *
- * sync only affects buffers downstream of this FileDescriptor. If
- * any in-memory buffering is being done by the application (for
- * example, by a BufferedOutputStream object), those buffers must
- * be flushed into the FileDescriptor (for example, by invoking
- * OutputStream.flush) before that data will be affected by sync.
- *
- * @exception SyncFailedException
- * Thrown when the buffers cannot be flushed,
- * or because the system cannot guarantee that all the
- * buffers have been synchronized with physical media.
- * @since 1.1
- */
- public native void sync() throws SyncFailedException;
-
- /* This routine initializes JNI field offsets for the class */
- private static native void initIDs();
-
- /**
- * Set the fd.
- * If setting to -1, clear the cleaner.
- * The {@link #registerCleanup()} method should be called for new fds.
- * @param fd the fd or -1 to indicate closed
- */
- @SuppressWarnings("unchecked")
- synchronized void set(int fd) {
- if (fd == -1 && cleanup != null) {
- cleanup.clear();
- cleanup = null;
- }
- this.fd = fd;
- }
-
- /**
- * Register a cleanup for the current handle.
- * Used directly in java.io and indirectly via fdAccess.
- * The cleanup should be registered after the handle is set in the FileDescriptor.
- */
- @SuppressWarnings("unchecked")
- void registerCleanup() {
- registerCleanup(null);
- }
-
- /**
- * Register a cleanup for the current handle.
- * Used directly in java.io and indirectly via fdAccess.
- * The cleanup should be registered after the handle is set in the FileDescriptor.
- * @param newCleanable a PhantomCleanable to register
- */
- @SuppressWarnings("unchecked")
- synchronized void registerCleanup(PhantomCleanable<Object> newCleanable) {
- if (cleanup != null) {
- cleanup.clear();
- }
- cleanup = (newCleanable == null) ? FDCleanup.create(this) : newCleanable;
- }
-
- /**
- * Unregister a cleanup for the current raw fd.
- * Used directly in java.io and indirectly via fdAccess.
- * Normally {@link #close()} should be used except in cases where
- * it is certain the caller will close the raw fd and the cleanup
- * must not close the raw fd. {@link #unregisterCleanup()} must be
- * called before the raw fd is closed to prevent a race that makes
- * it possible for the fd to be reallocated to another use and later
- * the cleanup might be invoked.
- */
- synchronized void unregisterCleanup() {
- if (cleanup != null) {
- cleanup.clear();
- }
- cleanup = null;
- }
-
- /**
- * Returns true, if the file was opened for appending.
- */
- private static native boolean getAppend(int fd);
-
- /**
- * Close the raw file descriptor or handle, if it has not already been closed
- * and set the fd and handle to -1.
- * Clear the cleaner so the close does not happen twice.
- * Package private to allow it to be used in java.io.
- * @throws IOException if close fails
- */
- @SuppressWarnings("unchecked")
- synchronized void close() throws IOException {
- if (cleanup != null) {
- cleanup.clear();
- cleanup = null;
- }
- close0();
- }
-
- /*
- * Close the raw file descriptor or handle, if it has not already been closed
- * and set the fd and handle to -1.
- */
- private native void close0() throws IOException;
-
- /*
- * Raw close of the file descriptor.
- * Used only for last chance cleanup.
- */
- private static native void cleanupClose0(int fd) throws IOException;
-
- /*
- * Package private methods to track referents.
- * If multiple streams point to the same FileDescriptor, we cycle
- * through the list of all referents and call close()
- */
-
- /**
- * Attach a Closeable to this FD for tracking.
- * parent reference is added to otherParents when
- * needed to make closeAll simpler.
- */
- synchronized void attach(Closeable c) {
- if (parent == null) {
- // first caller gets to do this
- parent = c;
- } else if (otherParents == null) {
- otherParents = new ArrayList<>();
- otherParents.add(parent);
- otherParents.add(c);
- } else {
- otherParents.add(c);
- }
- }
-
- /**
- * Cycle through all Closeables sharing this FD and call
- * close() on each one.
- *
- * The caller closeable gets to call close0().
- */
- @SuppressWarnings("try")
- synchronized void closeAll(Closeable releaser) throws IOException {
- if (!closed) {
- closed = true;
- IOException ioe = null;
- try (releaser) {
- if (otherParents != null) {
- for (Closeable referent : otherParents) {
- try {
- referent.close();
- } catch(IOException x) {
- if (ioe == null) {
- ioe = x;
- } else {
- ioe.addSuppressed(x);
- }
- }
- }
- }
- } catch(IOException ex) {
- /*
- * If releaser close() throws IOException
- * add other exceptions as suppressed.
- */
- if (ioe != null)
- ex.addSuppressed(ioe);
- ioe = ex;
- } finally {
- if (ioe != null)
- throw ioe;
- }
- }
- }
-
- /**
- * Cleanup for a FileDescriptor when it becomes phantom reachable.
- * Create a cleanup if fd != -1.
- * Subclassed from {@code PhantomCleanable} so that {@code clear} can be
- * called to disable the cleanup when the fd is closed by any means other
- * than calling {@link FileDescriptor#close}.
- * Otherwise, it may close the native fd after it has been reused.
- */
- static final class FDCleanup extends PhantomCleanable<Object> {
- private final int fd;
-
- static FDCleanup create(FileDescriptor fdo) {
- return fdo.fd == -1
- ? null
- : new FDCleanup(fdo, CleanerFactory.cleaner(), fdo.fd);
- }
-
- /**
- * Constructor for a phantom cleanable reference.
- * @param obj the object to monitor
- * @param cleaner the cleaner
- * @param fd file descriptor to close
- */
- private FDCleanup(Object obj, Cleaner cleaner, int fd) {
- super(obj, cleaner);
- this.fd = fd;
- }
-
- /**
- * Close the native fd.
- */
- @Override
- protected void performCleanup() {
- try {
- cleanupClose0(fd);
- } catch (IOException ioe) {
- throw new UncheckedIOException("close", ioe);
- }
- }
- }
-}
--- a/src/java.base/unix/classes/java/io/UnixFileSystem.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/unix/classes/java/io/UnixFileSystem.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,12 +34,14 @@
private final char slash;
private final char colon;
private final String javaHome;
+ private final String userDir;
public UnixFileSystem() {
Properties props = GetPropertyAction.privilegedGetProperties();
slash = props.getProperty("file.separator").charAt(0);
colon = props.getProperty("path.separator").charAt(0);
javaHome = props.getProperty("java.home");
+ userDir = props.getProperty("user.dir");
}
@@ -128,7 +130,11 @@
public String resolve(File f) {
if (isAbsolute(f)) return f.getPath();
- return resolve(System.getProperty("user.dir"), f.getPath());
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPropertyAccess("user.dir");
+ }
+ return resolve(userDir, f.getPath());
}
// Caches for canonicalization results to improve startup performance.
--- a/src/java.base/unix/native/libjava/FileDescriptor_md.c Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/unix/native/libjava/FileDescriptor_md.c Mon Feb 26 09:56:12 2018 +0100
@@ -64,6 +64,10 @@
JNU_ThrowByName(env, "java/io/SyncFailedException", "sync failed");
}
}
+JNIEXPORT jlong JNICALL
+Java_java_io_FileDescriptor_getHandle(JNIEnv *env, jclass fdClass, jint fd) {
+ return -1;
+}
JNIEXPORT jboolean JNICALL
Java_java_io_FileDescriptor_getAppend(JNIEnv *env, jclass fdClass, jint fd) {
@@ -71,17 +75,17 @@
return ((flags & O_APPEND) == 0) ? JNI_FALSE : JNI_TRUE;
}
+// instance method close0 for FileDescriptor
JNIEXPORT void JNICALL
-Java_java_io_FileDescriptor_cleanupClose0(JNIEnv *env, jclass fdClass, jint fd) {
+Java_java_io_FileDescriptor_close0(JNIEnv *env, jobject this) {
+ fileDescriptorClose(env, this);
+}
+
+JNIEXPORT void JNICALL
+Java_java_io_FileCleanable_cleanupClose0(JNIEnv *env, jclass fdClass, jint fd, jlong unused) {
if (fd != -1) {
if (close(fd) == -1) {
JNU_ThrowIOExceptionWithLastError(env, "close failed");
}
}
}
-
-// instance method close0 for FileDescriptor
-JNIEXPORT void JNICALL
-Java_java_io_FileDescriptor_close0(JNIEnv *env, jobject this) {
- fileDescriptorClose(env, this);
-}
--- a/src/java.base/windows/classes/java/io/FileDescriptor.java Tue Feb 20 21:46:02 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,400 +0,0 @@
-/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.io;
-
-import java.lang.ref.Cleaner;
-import java.util.ArrayList;
-import java.util.List;
-
-import jdk.internal.misc.JavaIOFileDescriptorAccess;
-import jdk.internal.misc.SharedSecrets;
-import jdk.internal.ref.CleanerFactory;
-import jdk.internal.ref.PhantomCleanable;
-
-/**
- * Instances of the file descriptor class serve as an opaque handle
- * to the underlying machine-specific structure representing an open
- * file, an open socket, or another source or sink of bytes.
- * The main practical use for a file descriptor is to create a
- * {@link FileInputStream} or {@link FileOutputStream} to contain it.
- * <p>
- * Applications should not create their own file descriptors.
- *
- * @author Pavani Diwanji
- * @since 1.0
- */
-public final class FileDescriptor {
-
- private int fd;
-
- private long handle;
-
- private Closeable parent;
- private List<Closeable> otherParents;
- private boolean closed;
-
- /**
- * true, if file is opened for appending.
- */
- private boolean append;
-
- static {
- initIDs();
- }
-
- // Set up JavaIOFileDescriptorAccess in SharedSecrets
- static {
- SharedSecrets.setJavaIOFileDescriptorAccess(
- new JavaIOFileDescriptorAccess() {
- public void set(FileDescriptor fdo, int fd) {
- fdo.fd = fd;
- }
-
- public int get(FileDescriptor fdo) {
- return fdo.fd;
- }
-
- public void setAppend(FileDescriptor fdo, boolean append) {
- fdo.append = append;
- }
-
- public boolean getAppend(FileDescriptor fdo) {
- return fdo.append;
- }
-
- public void close(FileDescriptor fdo) throws IOException {
- fdo.close();
- }
-
- public void registerCleanup(FileDescriptor fdo) {
- fdo.registerCleanup(null);
- }
-
- public void registerCleanup(FileDescriptor fdo, PhantomCleanable<Object> cleanup) {
- fdo.registerCleanup(cleanup);
- }
-
- public void unregisterCleanup(FileDescriptor fdo) {
- fdo.unregisterCleanup();
- }
-
- public void setHandle(FileDescriptor fdo, long handle) {
- fdo.setHandle(handle);
- }
-
- public long getHandle(FileDescriptor fdo) {
- return fdo.handle;
- }
- }
- );
- }
-
- /**
- * Cleanup in case FileDescriptor is not explicitly closed.
- */
- private PhantomCleanable<Object> cleanup;
-
- /**
- * Constructs an (invalid) FileDescriptor
- * object.
- */
- public FileDescriptor() {
- fd = -1;
- handle = -1;
- }
-
- /**
- * A handle to the standard input stream. Usually, this file
- * descriptor is not used directly, but rather via the input stream
- * known as {@code System.in}.
- *
- * @see java.lang.System#in
- */
- public static final FileDescriptor in = standardStream(0);
-
- /**
- * A handle to the standard output stream. Usually, this file
- * descriptor is not used directly, but rather via the output stream
- * known as {@code System.out}.
- * @see java.lang.System#out
- */
- public static final FileDescriptor out = standardStream(1);
-
- /**
- * A handle to the standard error stream. Usually, this file
- * descriptor is not used directly, but rather via the output stream
- * known as {@code System.err}.
- *
- * @see java.lang.System#err
- */
- public static final FileDescriptor err = standardStream(2);
-
- /**
- * Tests if this file descriptor object is valid.
- *
- * @return {@code true} if the file descriptor object represents a
- * valid, open file, socket, or other active I/O connection;
- * {@code false} otherwise.
- */
- public boolean valid() {
- return (handle != -1) || (fd != -1);
- }
-
- /**
- * Force all system buffers to synchronize with the underlying
- * device. This method returns after all modified data and
- * attributes of this FileDescriptor have been written to the
- * relevant device(s). In particular, if this FileDescriptor
- * refers to a physical storage medium, such as a file in a file
- * system, sync will not return until all in-memory modified copies
- * of buffers associated with this FileDescriptor have been
- * written to the physical medium.
- *
- * sync is meant to be used by code that requires physical
- * storage (such as a file) to be in a known state For
- * example, a class that provided a simple transaction facility
- * might use sync to ensure that all changes to a file caused
- * by a given transaction were recorded on a storage medium.
- *
- * sync only affects buffers downstream of this FileDescriptor. If
- * any in-memory buffering is being done by the application (for
- * example, by a BufferedOutputStream object), those buffers must
- * be flushed into the FileDescriptor (for example, by invoking
- * OutputStream.flush) before that data will be affected by sync.
- *
- * @exception SyncFailedException
- * Thrown when the buffers cannot be flushed,
- * or because the system cannot guarantee that all the
- * buffers have been synchronized with physical media.
- * @since 1.1
- */
- public native void sync() throws SyncFailedException;
-
- /* This routine initializes JNI field offsets for the class */
- private static native void initIDs();
-
- private static FileDescriptor standardStream(int fd) {
- FileDescriptor desc = new FileDescriptor();
- desc.handle = getHandle(fd);
- return desc;
- }
-
- private static native long getHandle(int d);
-
- /**
- * Set the handle.
- * If setting to -1, clear the cleaner.
- * The {@link #registerCleanup()} method should be called for new handles.
- * @param handle the handle or -1 to indicate closed
- */
- @SuppressWarnings("unchecked")
- void setHandle(long handle) {
- if (handle == -1 && cleanup != null) {
- cleanup.clear();
- cleanup = null;
- }
- this.handle = handle;
- }
-
- /**
- * Register a cleanup for the current handle.
- * Used directly in java.io and indirectly via fdAccess.
- * The cleanup should be registered after the handle is set in the FileDescriptor.
- */
- @SuppressWarnings("unchecked")
- void registerCleanup() {
- registerCleanup(null);
- }
-
- /**
- * Register a cleanup for the current handle.
- * Used directly in java.io and indirectly via fdAccess.
- * The cleanup should be registered after the handle is set in the FileDescriptor.
- * @param newCleanable a PhantomCleanable to register
- */
- @SuppressWarnings("unchecked")
- synchronized void registerCleanup(PhantomCleanable<Object> newCleanable) {
- if (cleanup != null) {
- cleanup.clear();
- }
- cleanup = (newCleanable == null) ? FDCleanup.create(this) : newCleanable;
- }
-
- /**
- * Unregister a cleanup for the current raw fd.
- * Used directly in java.io and indirectly via fdAccess.
- * Normally {@link #close()} should be used except in cases where
- * it is certain the caller will close the raw fd and the cleanup
- * must not close the raw fd. {@link #unregisterCleanup()} must be
- * called before the raw fd is closed to prevent a race that makes
- * it possible for the fd to be reallocated to another use and later
- * the cleanup might be invoked.
- */
- synchronized void unregisterCleanup() {
- if (cleanup != null) {
- cleanup.clear();
- }
- cleanup = null;
- }
-
- /**
- * Close the raw file descriptor or handle, if it has not already been closed
- * and set the fd and handle to -1.
- * Clear the cleaner so the close does not happen twice.
- * Package private to allow it to be used in java.io.
- * @throws IOException if close fails
- */
- @SuppressWarnings("unchecked")
- synchronized void close() throws IOException {
- if (cleanup != null) {
- cleanup.clear();
- cleanup = null;
- }
- close0();
- }
-
- /*
- * Close the raw file descriptor or handle, if it has not already been closed
- * and set the fd and handle to -1.
- */
- private native void close0() throws IOException;
-
- /*
- * Raw close of the file handle.
- * Used only for last chance cleanup.
- */
- private static native void cleanupClose0(long handle) throws IOException;
-
- /*
- * Package private methods to track referents.
- * If multiple streams point to the same FileDescriptor, we cycle
- * through the list of all referents and call close()
- */
-
- /**
- * Attach a Closeable to this FD for tracking.
- * parent reference is added to otherParents when
- * needed to make closeAll simpler.
- */
- synchronized void attach(Closeable c) {
- if (parent == null) {
- // first caller gets to do this
- parent = c;
- } else if (otherParents == null) {
- otherParents = new ArrayList<>();
- otherParents.add(parent);
- otherParents.add(c);
- } else {
- otherParents.add(c);
- }
- }
-
- /**
- * Cycle through all Closeables sharing this FD and call
- * close() on each one.
- *
- * The caller closeable gets to call close0().
- */
- @SuppressWarnings("try")
- synchronized void closeAll(Closeable releaser) throws IOException {
- if (!closed) {
- closed = true;
- IOException ioe = null;
- try (releaser) {
- if (otherParents != null) {
- for (Closeable referent : otherParents) {
- try {
- referent.close();
- } catch(IOException x) {
- if (ioe == null) {
- ioe = x;
- } else {
- ioe.addSuppressed(x);
- }
- }
- }
- }
- } catch(IOException ex) {
- /*
- * If releaser close() throws IOException
- * add other exceptions as suppressed.
- */
- if (ioe != null)
- ex.addSuppressed(ioe);
- ioe = ex;
- } finally {
- if (ioe != null)
- throw ioe;
- }
- }
- }
-
- /**
- * Cleanup for a FileDescriptor when it becomes phantom reachable.
- * Create a cleanup if handle != -1.
- * Windows closes files using handles and sockets via the fd.
- * Network FileDescriptors using socket fd must provide their
- * own PhantomCleanable to {@link #registerCleanup}.
- * This implementation only clears thehandles.
- * <p>
- * Subclassed from {@code PhantomCleanable} so that {@code clear} can be
- * called to disable the cleanup when the handle is closed by any means other
- * than calling {@link FileDescriptor#close}.
- * Otherwise, it may incorrectly close the handle after it has been reused.
- */
- static final class FDCleanup extends PhantomCleanable<Object> {
- private final long handle;
-
- static FDCleanup create(FileDescriptor fdo) {
- return fdo.handle == -1L
- ? null
- : new FDCleanup(fdo, CleanerFactory.cleaner(), fdo.handle);
- }
-
- /**
- * Constructor for a phantom cleanable reference.
- * @param obj the object to monitor
- * @param cleaner the cleaner
- * @param handle file handle to close
- */
- private FDCleanup(Object obj, Cleaner cleaner, long handle) {
- super(obj, cleaner);
- this.handle = handle;
- }
-
- /**
- * Close the native handle.
- */
- @Override
- protected void performCleanup() {
- try {
- cleanupClose0(handle);
- } catch (IOException ioe) {
- throw new UncheckedIOException("close", ioe);
- }
- }
- }
-}
--- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,12 +43,14 @@
private final char slash;
private final char altSlash;
private final char semicolon;
+ private final String userDir;
public WinNTFileSystem() {
Properties props = GetPropertyAction.privilegedGetProperties();
slash = props.getProperty("file.separator").charAt(0);
semicolon = props.getProperty("path.separator").charAt(0);
altSlash = (this.slash == '\\') ? '/' : '\\';
+ userDir = props.getProperty("user.dir");
}
private boolean isSlash(char c) {
@@ -347,7 +349,11 @@
private String getUserPath() {
/* For both compatibility and security,
we must look this up every time */
- return normalize(System.getProperty("user.dir"));
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPropertyAccess("user.dir");
+ }
+ return normalize(userDir);
}
private String getDrive(String path) {
--- a/src/java.base/windows/native/libjava/FileDescriptor_md.c Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.base/windows/native/libjava/FileDescriptor_md.c Mon Feb 26 09:56:12 2018 +0100
@@ -56,11 +56,6 @@
CHECK_NULL(IO_append_fdID = (*env)->GetFieldID(env, fdClass, "append", "Z"));
}
-JNIEXPORT jlong JNICALL
-Java_java_io_FileDescriptor_getHandle(JNIEnv *env, jclass fdClass, jint fd) {
- SET_HANDLE(fd);
-}
-
/**************************************************************
* File Descriptor
*/
@@ -73,13 +68,14 @@
}
}
-JNIEXPORT void JNICALL
-Java_java_io_FileDescriptor_cleanupClose0(JNIEnv *env, jclass fdClass, jlong handle) {
- if (handle != -1) {
- if (CloseHandle((HANDLE)handle) == -1) {
- JNU_ThrowIOExceptionWithLastError(env, "close failed");
- }
- }
+JNIEXPORT jlong JNICALL
+Java_java_io_FileDescriptor_getHandle(JNIEnv *env, jclass fdClass, jint fd) {
+ SET_HANDLE(fd);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_FileDescriptor_getAppend(JNIEnv *env, jclass fdClass, jint fd) {
+ return JNI_FALSE;
}
// instance method close0 for FileDescriptor
@@ -87,3 +83,12 @@
Java_java_io_FileDescriptor_close0(JNIEnv *env, jobject this) {
fileDescriptorClose(env, this);
}
+
+JNIEXPORT void JNICALL
+Java_java_io_FileCleanable_cleanupClose0(JNIEnv *env, jclass fdClass, jint unused, jlong handle) {
+ if (handle != -1) {
+ if (CloseHandle((HANDLE)handle) == -1) {
+ JNU_ThrowIOExceptionWithLastError(env, "close failed");
+ }
+ }
+}
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthList.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthList.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,9 @@
private final LinkedList<AuthTimeWithHash> entries;
private final int lifespan;
+ // entries.getLast().ctime, updated after each cleanup.
+ private volatile int oldestTime = Integer.MIN_VALUE;
+
/**
* Constructs a AuthList.
*/
@@ -67,11 +70,13 @@
* Puts the authenticator timestamp into the cache in descending order,
* and throw an exception if it's already there.
*/
- public void put(AuthTimeWithHash t, KerberosTime currentTime)
+ public synchronized void put(AuthTimeWithHash t, KerberosTime currentTime)
throws KrbApErrException {
if (entries.isEmpty()) {
entries.addFirst(t);
+ oldestTime = t.ctime;
+ return;
} else {
AuthTimeWithHash temp = entries.getFirst();
int cmp = temp.compareTo(t);
@@ -106,24 +111,26 @@
// let us cleanup while we are here
long timeLimit = currentTime.getSeconds() - lifespan;
- ListIterator<AuthTimeWithHash> it = entries.listIterator(0);
- AuthTimeWithHash temp = null;
- int index = -1;
- while (it.hasNext()) {
- // search expired timestamps.
- temp = it.next();
- if (temp.ctime < timeLimit) {
- index = entries.indexOf(temp);
- break;
+
+ // Only trigger a cleanup when the earliest entry is
+ // lifespan + 5 sec ago. This ensures a cleanup is done
+ // at most every 5 seconds so that we don't always
+ // addLast(removeLast).
+ if (oldestTime > timeLimit - 5) {
+ return;
+ }
+
+ // and we remove the *enough* old ones (1 lifetime ago)
+ while (!entries.isEmpty()) {
+ AuthTimeWithHash removed = entries.removeLast();
+ if (removed.ctime >= timeLimit) {
+ entries.addLast(removed);
+ oldestTime = removed.ctime;
+ return;
}
}
- // It would be nice if LinkedList has a method called truncate(index).
- if (index > -1) {
- do {
- // remove expired timestamps from the list.
- entries.removeLast();
- } while(entries.size() > index);
- }
+
+ oldestTime = Integer.MIN_VALUE;
}
public boolean isEmpty() {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/MemoryCache.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/MemoryCache.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,9 @@
package sun.security.krb5.internal.rcache;
-import java.util.*;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import sun.security.krb5.internal.KerberosTime;
import sun.security.krb5.internal.KrbApErrException;
import sun.security.krb5.internal.ReplayCache;
@@ -48,31 +50,18 @@
private static final int lifespan = KerberosTime.getDefaultSkew();
private static final boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;
- private final Map<String,AuthList> content = new HashMap<>();
+ private final Map<String,AuthList> content = new ConcurrentHashMap<>();
@Override
public synchronized void checkAndStore(KerberosTime currTime, AuthTimeWithHash time)
throws KrbApErrException {
String key = time.client + "|" + time.server;
- AuthList rc = content.get(key);
+ content.computeIfAbsent(key, k -> new AuthList(lifespan))
+ .put(time, currTime);
if (DEBUG) {
System.out.println("MemoryCache: add " + time + " to " + key);
}
- if (rc == null) {
- rc = new AuthList(lifespan);
- rc.put(time, currTime);
- if (!rc.isEmpty()) {
- content.put(key, rc);
- }
- } else {
- if (DEBUG) {
- System.out.println("MemoryCache: Existing AuthList:\n" + rc);
- }
- rc.put(time, currTime);
- if (rc.isEmpty()) {
- content.remove(key);
- }
- }
+ // TODO: clean up AuthList entries with only expired AuthTimeWithHash objects.
}
public String toString() {
--- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -41,7 +41,6 @@
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
-import jdk.xml.internal.SecuritySupport;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
@@ -52,7 +51,7 @@
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
- * @LastModified: Nov 2017
+ * @LastModified: Feb 2018
*/
abstract public class ToStream extends SerializerBase {
@@ -138,8 +137,7 @@
* but this value can be set through the xsl:output
* extension attribute xalan:line-separator.
*/
- protected char[] m_lineSep =
- SecuritySupport.getSystemProperty("line.separator").toCharArray();
+ protected char[] m_lineSep = System.lineSeparator().toCharArray();
/**
* True if the the system line separator is to be used.
--- a/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
* This class contains utility methods for reading resources in the JAXP packages
*/
public class SecuritySupport {
- public final static String NEWLINE = getSystemProperty("line.separator", "\n");
+ public final static String NEWLINE = System.lineSeparator();
/**
* Cache for properties in java.home/conf/jaxp.properties
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -568,14 +568,14 @@
return hiddenSym;
}
- /** Is this symbol inherited into a given class?
+ /** Is this symbol accessible in a given class?
* PRE: If symbol's owner is a interface,
* it is already assumed that the interface is a superinterface
- * of given class.
+ * the given class.
* @param clazz The class for which we want to establish membership.
* This must be a subclass of the member's owner.
*/
- public boolean isInheritedIn(Symbol clazz, Types types) {
+ public final boolean isAccessibleIn(Symbol clazz, Types types) {
switch ((int)(flags_field & Flags.AccessFlags)) {
default: // error recovery
case PUBLIC:
@@ -603,6 +603,17 @@
}
}
+ /** Is this symbol inherited into a given class?
+ * PRE: If symbol's owner is a interface,
+ * it is already assumed that the interface is a superinterface
+ * of the given class.
+ * @param clazz The class for which we want to establish membership.
+ * This must be a subclass of the member's owner.
+ */
+ public boolean isInheritedIn(Symbol clazz, Types types) {
+ return isAccessibleIn(clazz, types);
+ }
+
/** The (variable or method) symbol seen as a member of given
* class type`site' (this might change the symbol's type).
* This is used exclusively for producing diagnostics.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Mon Feb 26 09:56:12 2018 +0100
@@ -304,7 +304,7 @@
@Override
List<JCLambda> rewrite(JCNewClass oldTree){
- JCMethodDecl md = (JCMethodDecl)decls(oldTree.def).head;
+ JCMethodDecl md = (JCMethodDecl)copier.copy(decls(oldTree.def).head);
List<JCVariableDecl> params = md.params;
JCBlock body = md.body;
JCLambda newTree = make.at(oldTree).Lambda(params, body);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Feb 26 09:56:12 2018 +0100
@@ -2193,8 +2193,7 @@
List<Type> argtypes = argtypesBuf.toList();
List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
- // If we have made no mistakes in the class type...
- if (clazztype.hasTag(CLASS)) {
+ if (clazztype.hasTag(CLASS) || clazztype.hasTag(ERROR)) {
// Enums may not be instantiated except implicitly
if ((clazztype.tsym.flags_field & Flags.ENUM) != 0 &&
(!env.tree.hasTag(VARDEF) ||
@@ -2381,7 +2380,8 @@
// If we already errored, be careful to avoid a further avalanche. ErrorType answers
// false for isInterface call even when the original type is an interface.
boolean implementing = clazztype.tsym.isInterface() ||
- clazztype.isErroneous() && clazztype.getOriginalType().tsym.isInterface();
+ clazztype.isErroneous() && !clazztype.getOriginalType().hasTag(NONE) &&
+ clazztype.getOriginalType().tsym.isInterface();
if (implementing) {
cdef.implementing = List.of(clazz);
@@ -2413,7 +2413,8 @@
finalargtypes = finalargtypes.map(deferredAttr.deferredCopier);
}
- clazztype = cdef.sym.type;
+ clazztype = clazztype.hasTag(ERROR) ? types.createErrorType(cdef.sym.type)
+ : cdef.sym.type;
Symbol sym = tree.constructor = rs.resolveConstructor(
tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes);
Assert.check(!sym.kind.isResolutionError());
@@ -5080,7 +5081,7 @@
*/
private Type dummyMethodType(JCMethodDecl md) {
Type restype = syms.unknownType;
- if (md != null && md.restype.hasTag(TYPEIDENT)) {
+ if (md != null && md.restype != null && md.restype.hasTag(TYPEIDENT)) {
JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype;
if (prim.typetag == VOID)
restype = syms.voidType;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -632,8 +632,7 @@
}
// Hidee must be accessible in hider's class.
- // The method isInheritedIn is poorly named: it checks only access.
- return hidee.isInheritedIn(hiderClass, types);
+ return hidee.isAccessibleIn(hiderClass, types);
}
@DefinedBy(Api.LANGUAGE_MODEL)
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Feb 26 09:56:12 2018 +0100
@@ -1673,6 +1673,8 @@
CAST,
EXPLICIT_LAMBDA,
IMPLICIT_LAMBDA,
+ IMPLICIT_LAMBDA_ALL_VAR,
+ BAD_LAMBDA,
PARENS
}
@@ -1681,9 +1683,92 @@
formalParameters(true) :
implicitParameters(hasParens);
+ if (explicitParams) {
+ LambdaClassfier lambdaClassfier = new LambdaClassfier();
+ for (JCVariableDecl param: params) {
+ if (param.vartype != null &&
+ isRestrictedLocalVarTypeName(param.vartype) &&
+ param.vartype.hasTag(TYPEARRAY)) {
+ log.error(DiagnosticFlag.SYNTAX, param.pos, Errors.VarNotAllowedArray);
+ }
+ if (param.vartype != null && param.name != names.empty) {
+ if (isRestrictedLocalVarTypeName(param.vartype)) {
+ lambdaClassfier.addImplicitVarParameter();
+ } else {
+ lambdaClassfier.addExplicitParameter();
+ }
+ }
+ if (param.vartype == null && param.name != names.empty ||
+ param.vartype != null && param.name == names.empty) {
+ lambdaClassfier.addImplicitParameter();
+ }
+ if (lambdaClassfier.result() == ParensResult.BAD_LAMBDA) {
+ break;
+ }
+ }
+ if (lambdaClassfier.diagFragment != null) {
+ log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassfier.diagFragment));
+ }
+ }
return lambdaExpressionOrStatementRest(params, pos);
}
+ class LambdaClassfier {
+ ParensResult kind; //ParensResult.EXPLICIT_LAMBDA;
+ Fragment diagFragment;
+ List<JCVariableDecl> params;
+
+ void addExplicitParameter() {
+ reduce(ParensResult.EXPLICIT_LAMBDA);
+ }
+
+ void addImplicitVarParameter() {
+ reduce(ParensResult.IMPLICIT_LAMBDA_ALL_VAR);
+ }
+
+ void addImplicitParameter() {
+ reduce(ParensResult.IMPLICIT_LAMBDA);
+ }
+
+ private void reduce(ParensResult newKind) {
+ if (kind == null) {
+ kind = newKind;
+ } else if (kind != newKind && kind != ParensResult.BAD_LAMBDA) {
+ ParensResult currentKind = kind;
+ kind = ParensResult.BAD_LAMBDA;
+ switch (currentKind) {
+ case EXPLICIT_LAMBDA:
+ if (newKind == ParensResult.IMPLICIT_LAMBDA) {
+ diagFragment = Fragments.ImplicitAndExplicitNotAllowed;
+ } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) {
+ diagFragment = Fragments.VarAndExplicitNotAllowed;
+ }
+ break;
+ case IMPLICIT_LAMBDA:
+ if (newKind == ParensResult.EXPLICIT_LAMBDA) {
+ diagFragment = Fragments.ImplicitAndExplicitNotAllowed;
+ } else if (newKind == ParensResult.IMPLICIT_LAMBDA_ALL_VAR) {
+ diagFragment = Fragments.VarAndImplicitNotAllowed;
+ }
+ break;
+ case IMPLICIT_LAMBDA_ALL_VAR:
+ if (newKind == ParensResult.EXPLICIT_LAMBDA) {
+ diagFragment = Fragments.VarAndExplicitNotAllowed;
+ } else if (newKind == ParensResult.IMPLICIT_LAMBDA) {
+ diagFragment = Fragments.VarAndImplicitNotAllowed;
+ }
+ break;
+ default:
+ throw new AssertionError("unexpected option for field kind");
+ }
+ }
+ }
+
+ ParensResult result() {
+ return kind;
+ }
+ }
+
JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
checkSourceLevel(Feature.LAMBDA);
accept(ARROW);
@@ -3044,7 +3129,21 @@
return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
}
} else {
- name = ident();
+ if (!lambdaParameter ||
+ LAX_IDENTIFIER.accepts(token.kind) ||
+ mods.flags != Flags.PARAMETER ||
+ mods.annotations.nonEmpty()) {
+ name = ident();
+ } else {
+ /** if it is a lambda parameter and the token kind is not an identifier,
+ * and there are no modifiers or annotations, then this means that the compiler
+ * supposed the lambda to be explicit but it can contain a mix of implicit,
+ * var or explicit parameters. So we assign the error name to the parameter name
+ * instead of issuing an error and analyze the lambda parameters as a whole at
+ * a higher level.
+ */
+ name = names.empty;
+ }
}
}
if ((mods.flags & Flags.VARARGS) != 0 &&
@@ -3947,7 +4046,7 @@
// need to distinguish between vararg annos and array annos
// look at typeAnnotationsPushedBack comment
this.permitTypeAnnotationsPushBack = true;
- JCExpression type = parseType();
+ JCExpression type = parseType(lambdaParameter);
this.permitTypeAnnotationsPushBack = false;
if (token.kind == ELLIPSIS) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Feb 26 09:56:12 2018 +0100
@@ -1229,6 +1229,20 @@
compiler.err.var.not.allowed.compound=\
''var'' is not allowed in a compound declaration
+# 0: fragment
+compiler.err.invalid.lambda.parameter.declaration=\
+ invalid lambda parameter declaration\n\
+ ({0})
+
+compiler.misc.implicit.and.explicit.not.allowed=\
+ cannot mix implicitly-typed and explicitly-typed parameters
+
+compiler.misc.var.and.explicit.not.allowed=\
+ cannot mix ''var'' and explicitly-typed parameters
+
+compiler.misc.var.and.implicit.not.allowed=\
+ cannot mix ''var'' and implicitly-typed parameters
+
compiler.misc.local.cant.infer.null=\
variable initializer is ''null''
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,7 @@
super(addr);
}
+ public boolean isArrayKlass() { return true; }
private static CIntField dimension;
private static MetadataField higherDimension;
private static MetadataField lowerDimension;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -339,24 +339,28 @@
}
// returns null, if not resolved.
- public InstanceKlass getFieldOrMethodKlassRefAt(int which) {
+ public Klass getFieldOrMethodKlassRefAt(int which) {
int refIndex = getFieldOrMethodAt(which);
int klassIndex = extractLowShortFromInt(refIndex);
- return (InstanceKlass) getKlassAt(klassIndex);
+ return getKlassAt(klassIndex);
}
// returns null, if not resolved.
public Method getMethodRefAt(int which) {
- InstanceKlass klass = getFieldOrMethodKlassRefAt(which);
+ Klass klass = getFieldOrMethodKlassRefAt(which);
if (klass == null) return null;
Symbol name = getNameRefAt(which);
Symbol sig = getSignatureRefAt(which);
- return klass.findMethod(name, sig);
+ // Consider the super class for arrays. (java.lang.Object)
+ if (klass.isArrayKlass()) {
+ klass = klass.getJavaSuper();
+ }
+ return ((InstanceKlass)klass).findMethod(name, sig);
}
// returns null, if not resolved.
public Field getFieldRefAt(int which) {
- InstanceKlass klass = getFieldOrMethodKlassRefAt(which);
+ InstanceKlass klass = (InstanceKlass)getFieldOrMethodKlassRefAt(which);
if (klass == null) return null;
Symbol name = getNameRefAt(which);
Symbol sig = getSignatureRefAt(which);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,6 +86,7 @@
}
public boolean isKlass() { return true; }
+ public boolean isArrayKlass() { return false; }
// Fields
private static AddressField javaMirror;
--- a/src/jdk.internal.le/share/classes/jdk/internal/jline/extra/EditingHistory.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.internal.le/share/classes/jdk/internal/jline/extra/EditingHistory.java Mon Feb 26 09:56:12 2018 +0100
@@ -367,11 +367,11 @@
return count;
}
- public List<String> currentSessionEntries() {
+ public List<String> entries(boolean currentSession) {
List<String> result = new ArrayList<>();
for (Entry e : fullHistory) {
- if (!(e.value() instanceof PersistentEntryMarker)) {
+ if (!currentSession || !(e.value() instanceof PersistentEntryMarker)) {
result.add(e.value().toString());
}
}
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Mon Feb 26 09:56:12 2018 +0100
@@ -80,8 +80,8 @@
* - handling of covariant overrides
* - handling of override of method found in multiple superinterfaces
* - convert type/method/field output to Java source like syntax, e.g.
- * instead of java/lang/Runtime.runFinalizersOnExit(Z)V
- * print void java.lang.Runtime.runFinalizersOnExit(boolean)
+ * instead of java/lang/Character.isJavaLetter(C)Z
+ * print void java.lang.Character.isJavaLetter(char)boolean
* - more example output in man page
* - more rigorous GNU style option parsing; use joptsimple?
*
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/internals.md Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/internals.md Mon Feb 26 09:56:12 2018 +0100
@@ -195,15 +195,14 @@
**EXAMPLE OUTPUT**
Given the following method declaration and annotation from the
-`java.lang.Runtime` class,
+`java.lang.Character` class,
- @Deprecated(since="1.2",
- forRemoval=true)
- public static void runFinalizersOnExit(boolean value)
+ @Deprecated(since="1.1")
+ public static boolean isJavaLetter(char ch)
the following line will be emitted from **jdeprscan -Xprint-csv**:
- METHOD,java/lang/Runtime,runFinalizersOnExit(Z)V,1.2,true
+ METHOD,java/lang/Character,isJavaLetter(C)Z,1.1,false
[RFC]: https://www.ietf.org/rfc/rfc4180.txt
--- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/readme.md Mon Feb 26 09:56:12 2018 +0100
@@ -1,6 +1,6 @@
<!--
-Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -134,30 +134,30 @@
The output is a report that lists program elements that use deprecated
APIs. Output is subject to change.
-Consider the following declarations from Java SE 9:
+Consider the following declarations:
// java.lang.Boolean
@Deprecated(since="9")
public Boolean(boolean value)
- // java.lang.Runtime
+ // java.lang.Thread
- @Deprecated(since="1.2", forRemoval=true)
- public static void runFinalizersOnExit(boolean value)
+ @Deprecated(since="1.5", forRemoval=true)
+ public void destroy()
Running **jdeprscan** over a class that calls these methods will result
in output something like the following:
class Example uses method java/lang/Boolean.<init>(Z)V deprecated
- class Example uses method java/lang/Runtime.runFinalizersOnExit(Z)V deprecated for removal
+ class Example uses method java/lang/Thread.destroy()V deprecated for removal
Running **jdeprscan** with the `--list` option will result in output
including something like the following:
...
@Deprecated(since="9") java.lang.Boolean(boolean)
- @Deprecated(since="1.2", forRemoval=true) void java.lang.Runtime.runFinalizersOnExit(boolean)
+ @Deprecated(since="1.5", forRemoval=true) void java.lang.Thread.destroy()
...
**NOTES**
--- a/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jdwp.agent/share/native/libdt_socket/socketTransport.c Mon Feb 26 09:56:12 2018 +0100
@@ -398,7 +398,7 @@
return instr;
}
- *mask = htonl(-1 << (32 - m));
+ *mask = htonl((uint32_t)(~0) << (32 - m));
return s;
}
--- a/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Mon Feb 26 09:56:12 2018 +0100
@@ -386,7 +386,7 @@
for (File file : options.jimages) {
if (!file.exists() || !file.isFile()) {
- throw TASK_HELPER.newBadArgs("err.not.a.jimage", file.getName());
+ throw TASK_HELPER.newBadArgs("err.not.a.jimage", file);
}
try (BasicImageReader reader = BasicImageReader.open(file.toPath())) {
@@ -431,6 +431,8 @@
}
}
}
+ } catch (IOException ioe) {
+ throw TASK_HELPER.newBadArgs("err.invalid.jimage", file, ioe.getMessage());
}
}
}
--- a/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Mon Feb 26 09:56:12 2018 +0100
@@ -95,6 +95,7 @@
err.missing.arg=no value given for {0}
err.not.a.dir=not a directory: {0}
err.not.a.jimage=not a jimage file: {0}
+err.invalid.jimage=Unable to open {0}: {1}
err.no.jimage=no jimage provided
err.option.unsupported={0} not supported: {1}
err.unknown.option=unknown option: {0}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java Mon Feb 26 09:56:12 2018 +0100
@@ -27,6 +27,7 @@
import java.util.Map;
import java.util.function.Predicate;
import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
@@ -49,7 +50,13 @@
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy((resource) -> {
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
- resource = predicate.test(resource.path()) ? resource : null;
+ boolean shouldExclude = !predicate.test(resource.path());
+ // do not allow filtering module-info.class to avoid mutating module graph.
+ if (shouldExclude &&
+ resource.path().equals("/" + resource.moduleName() + "/module-info.class")) {
+ throw new PluginException("Cannot exclude " + resource.path());
+ }
+ return shouldExclude? null : resource;
}
return resource;
}, out);
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Mon Feb 26 09:56:12 2018 +0100
@@ -151,8 +151,8 @@
}
@Override
- public Iterable<String> currentSessionHistory() {
- return history.currentSessionEntries();
+ public Iterable<String> history(boolean currentSession) {
+ return history.entries(currentSession);
}
@Override
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Mon Feb 26 09:56:12 2018 +0100
@@ -40,7 +40,7 @@
public abstract boolean interactiveOutput();
- public abstract Iterable<String> currentSessionHistory();
+ public abstract Iterable<String> history(boolean currentSession);
public abstract boolean terminalEditorRunning();
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon Feb 26 09:56:12 2018 +0100
@@ -1457,6 +1457,7 @@
static final CompletionProvider EMPTY_COMPLETION_PROVIDER = new FixedCompletionProvider();
private static final CompletionProvider SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all", "-start ", "-history");
private static final CompletionProvider SAVE_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all ", "-start ", "-history ");
+ private static final CompletionProvider HISTORY_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all");
private static final CompletionProvider SNIPPET_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all", "-start " );
private static final FixedCompletionProvider COMMAND_LINE_LIKE_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider(
"-class-path ", "-module-path ", "-add-modules ", "-add-exports ");
@@ -1657,6 +1658,11 @@
};
}
+ // /history command completion
+ private static CompletionProvider historyCompletion() {
+ return optionCompletion(HISTORY_OPTION_COMPLETION_PROVIDER);
+ }
+
// /reload command completion
private static CompletionProvider reloadCompletion() {
return optionCompletion(RELOAD_OPTIONS_COMPLETION_PROVIDER);
@@ -1781,8 +1787,8 @@
this::cmdReload,
reloadCompletion()));
registerCommand(new Command("/history",
- arg -> cmdHistory(),
- EMPTY_COMPLETION_PROVIDER));
+ this::cmdHistory,
+ historyCompletion()));
registerCommand(new Command("/debug",
this::cmdDebug,
EMPTY_COMPLETION_PROVIDER,
@@ -2423,9 +2429,14 @@
hardrb(key);
}
- private boolean cmdHistory() {
+ private boolean cmdHistory(String rawArgs) {
+ ArgTokenizer at = new ArgTokenizer("/history", rawArgs.trim());
+ at.allowedOptions("-all");
+ if (!checkOptionsAndRemainingInput(at)) {
+ return false;
+ }
cmdout.println();
- for (String s : input.currentSessionHistory()) {
+ for (String s : input.history(!at.hasOption("-all"))) {
// No number prefix, confusing with snippet ids
cmdout.printf("%s\n", s);
}
@@ -2935,7 +2946,7 @@
private boolean cmdList(String arg) {
if (arg.length() >= 2 && "-history".startsWith(arg)) {
- return cmdHistory();
+ return cmdHistory("");
}
Stream<Snippet> stream = argsOptionsToSnippets(state::snippets,
this::mainActive, arg, "/list");
@@ -3183,7 +3194,7 @@
CREATE, TRUNCATE_EXISTING, WRITE)) {
if (at.hasOption("-history")) {
// they want history (commands and snippets), ignore the snippet stream
- for (String s : input.currentSessionHistory()) {
+ for (String s : input.history(true)) {
writer.write(s);
writer.write("\n");
}
@@ -3862,7 +3873,7 @@
}
@Override
- public Iterable<String> currentSessionHistory() {
+ public Iterable<String> history(boolean currentSession) {
return Collections.emptyList();
}
--- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Mon Feb 26 09:56:12 2018 +0100
@@ -454,9 +454,14 @@
/env -add-modules com.greetings
help.history.summary = history of what you have typed
-help.history.args =
+help.history.args = [-all]
help.history =\
-Display the history of snippet and command input since this jshell tool was launched.
+Display the history of snippet and command input.\n\
+\n\
+/history\n\t\
+ List the history of snippet and command input since this jshell tool was launched\n\n\
+/history -all\n\t\
+ List all the history of snippet and command input from this and previous sessions
help.debug.summary = toggle debugging of the jshell tool
help.debug.args = [0][r][g][f][c][d][e]
--- a/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java Mon Feb 26 09:56:12 2018 +0100
@@ -87,6 +87,6 @@
@Override
String importLine(JShell state) {
- return "import static " + classFullName() + "." + name() + ";\n";
+ return "import static " + classFullName() + "." + name() + "; ";
}
}
--- a/src/jdk.jshell/share/classes/jdk/jshell/OuterWrapMap.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/OuterWrapMap.java Mon Feb 26 09:56:12 2018 +0100
@@ -64,7 +64,7 @@
private CompoundWrap wrappedInClass(String className, String imports, List<Wrap> wraps) {
List<Object> elems = new ArrayList<>(wraps.size() + 2);
- elems.add(imports +
+ elems.add(imports + "\n" +
"class " + className + " {\n");
elems.addAll(wraps);
elems.add("}\n");
--- a/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java Mon Feb 26 09:56:12 2018 +0100
@@ -79,9 +79,9 @@
@Override
String importLine(JShell state) {
- return "import static " + classFullName() + "." + name() + ";\n" +
+ return "import static " + classFullName() + "." + name() + "; " +
anonymousClasses.stream()
- .map(c -> "import static " + classFullName() + "." + c + ";\n")
+ .map(c -> "import static " + classFullName() + "." + c + "; ")
.collect(Collectors.joining());
}
--- a/src/jdk.management.agent/share/classes/sun/management/jdp/JdpController.java Tue Feb 20 21:46:02 2018 +0100
+++ b/src/jdk.management.agent/share/classes/sun/management/jdp/JdpController.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,19 +22,17 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package sun.management.jdp;
import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.UUID;
-
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import java.lang.UnsupportedOperationException;
-import sun.management.VMManagement;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.UUID;
/**
* JdpController is responsible to create and manage a broadcast loop.
--- a/test/TestCommon.gmk Tue Feb 20 21:46:02 2018 +0100
+++ b/test/TestCommon.gmk Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -173,6 +173,20 @@
endif
endif
+
+# Optionally create a CDS archive before running tests
+ifeq ($(GENERATE_CDS_ARCHIVE), true)
+ CDS_ARCHIVE_FILE := $(ABS_TEST_OUTPUT_DIR)/cds_archive.jsa
+
+ $(CDS_ARCHIVE_FILE): $(PRODUCT_HOME)
+ $(PRODUCT_HOME)/bin/java -XX:+UnlockDiagnosticVMOptions \
+ -XX:SharedArchiveFile=$(shell $(GETMIXEDPATH) "$(CDS_ARCHIVE_FILE)") -Xshare:dump
+
+ CDS_VM_ARGS := -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=$(shell $(GETMIXEDPATH) "$(CDS_ARCHIVE_FILE)")
+ JTREG_TEST_OPTIONS += $(addprefix -vmoption:, $(CDS_VM_ARGS))
+ TEST_PREREQS += $(CDS_ARCHIVE_FILE)
+endif
+
# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
ifdef JPRT_ARCHIVE_BUNDLE
ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
@@ -444,7 +458,7 @@
PHONY_LIST += jtreg_exists
# Run jtreg
-jtreg_tests: prep jtreg_exists $(PRODUCT_HOME)
+jtreg_tests: prep jtreg_exists $(PRODUCT_HOME) $(TEST_PREREQS)
( \
( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)"); \
export JT_HOME; \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/StoreMovedBeforeInfiniteLoop.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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 8197563
+ * @summary assert(is_Loop()) crash in PhaseIdealLoop::try_move_store_before_loop()
+ *
+ * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileOnly=StoreMovedBeforeInfiniteLoop::test StoreMovedBeforeInfiniteLoop
+ *
+ */
+
+public class StoreMovedBeforeInfiniteLoop {
+ public static void main(String[] args) {
+ field = -1;
+ test(new Object());
+ }
+
+ static int field;
+
+ static int constant() {
+ return 65;
+ }
+
+ private static int test(Object o) {
+ do {
+ if (field <= 0) {
+ return -109;
+ }
+ do {
+ field = 4;
+ } while (constant() >= 0);
+ } while (o == null);
+ return -109;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/ElfDecoder/TestElfDirectRead.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8193373
+ * @summary Test reading ELF info direct from underlaying file
+ * @requires (os.family == "linux")
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail TestElfDirectRead
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.JDKToolFinder;
+import sun.hotspot.WhiteBox;
+
+public class TestElfDirectRead {
+ public static void main(String args[]) throws Exception {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+ wb.disableElfSectionCache();
+ ProcessBuilder pb = new ProcessBuilder();
+ OutputAnalyzer output;
+ // Grab my own PID
+ String pid = Long.toString(ProcessTools.getProcessId());
+
+ pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail"});
+ output = new OutputAnalyzer(pb.start());
+ // This is a pre-populated stack frame, should always exist if can decode
+ output.shouldContain("MallocSiteTable::new_entry");
+ }
+}
+
--- a/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,39 +48,33 @@
TestCommon.testDump(appJar, TestCommon.list("Hello"));
// PASS: 1) runtime with classpath containing the one used in dump time
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar + File.pathSeparator + appJar2,
- "HelloMore");
- TestCommon.checkExec(output);
+ "HelloMore")
+ .assertNormalExit();
final String errorMessage1 = "Unable to use shared archive";
final String errorMessage2 = "shared class paths mismatch";
// FAIL: 2) runtime with classpath different from the one used in dump time
// (runtime has an extra jar file prepended to the class path)
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar2 + File.pathSeparator + appJar,
- "HelloMore");
- output.shouldContain(errorMessage1);
- output.shouldContain(errorMessage2);
- output.shouldHaveExitValue(1);
+ "HelloMore")
+ .assertAbnormalExit(errorMessage1, errorMessage2);
// FAIL: 3) runtime with classpath part of the one used in dump time
TestCommon.testDump(appJar + File.pathSeparator + appJar2,
TestCommon.list("Hello"));
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar2,
- "Hello");
- output.shouldContain(errorMessage1);
- output.shouldContain(errorMessage2);
- output.shouldHaveExitValue(1);
+ "Hello")
+ .assertAbnormalExit(errorMessage1, errorMessage2);
// FAIL: 4) runtime with same set of jar files in the classpath but
// with different order
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar2 + File.pathSeparator + appJar,
- "HelloMore");
- output.shouldContain(errorMessage1);
- output.shouldContain(errorMessage2);
- output.shouldHaveExitValue(1);
+ "HelloMore")
+ .assertAbnormalExit(errorMessage1, errorMessage2);
}
}
--- a/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,20 +62,13 @@
public void testBootClassPathMismatch() throws Exception {
String appJar = JarBuilder.getOrCreateHelloJar();
String appClasses[] = {"Hello"};
- OutputAnalyzer dumpOutput = TestCommon.dump(
+ TestCommon.dump(
appJar, appClasses, "-Xbootclasspath/a:" + appJar);
String testDir = TestCommon.getTestDir("newdir");
String otherJar = testDir + File.separator + "hello.jar";
- OutputAnalyzer execOutput = TestCommon.exec(
- appJar, "-verbose:class", "-Xbootclasspath/a:" + otherJar, "Hello");
- try {
- TestCommon.checkExec(execOutput, mismatchMessage);
- } catch (java.lang.RuntimeException re) {
- String cause = re.getMessage();
- if (!mismatchMessage.equals(cause)) {
- throw re;
- }
- }
+ TestCommon.run(
+ "-cp", appJar, "-verbose:class", "-Xbootclasspath/a:" + otherJar, "Hello")
+ .assertAbnormalExit(mismatchMessage);
}
/* Error should be detected if:
@@ -85,17 +78,10 @@
public void testBootClassPathMismatch2() throws Exception {
String appJar = JarBuilder.getOrCreateHelloJar();
String appClasses[] = {"Hello"};
- OutputAnalyzer dumpOutput = TestCommon.dump(appJar, appClasses);
- OutputAnalyzer execOutput = TestCommon.exec(
- appJar, "-verbose:class", "-Xbootclasspath/a:" + appJar, "Hello");
- try {
- TestCommon.checkExec(execOutput, mismatchMessage);
- } catch (java.lang.RuntimeException re) {
- String cause = re.getMessage();
- if (!mismatchMessage.equals(cause)) {
- throw re;
- }
- }
+ TestCommon.dump(appJar, appClasses);
+ TestCommon.run(
+ "-cp", appJar, "-verbose:class", "-Xbootclasspath/a:" + appJar, "Hello")
+ .assertAbnormalExit(mismatchMessage);
}
/* No error if:
@@ -105,13 +91,12 @@
public void testBootClassPathMatch() throws Exception {
String appJar = TestCommon.getTestJar("hello.jar");
String appClasses[] = {"Hello"};
- OutputAnalyzer dumpOutput = TestCommon.dump(
+ TestCommon.dump(
appJar, appClasses, "-Xbootclasspath/a:" + appJar);
- OutputAnalyzer execOutput = TestCommon.exec(
- appJar, "-verbose:class",
- "-Xbootclasspath/a:" + appJar, "Hello");
- TestCommon.checkExec(execOutput,
- "[class,load] Hello source: shared objects file");
+ TestCommon.run(
+ "-cp", appJar, "-verbose:class",
+ "-Xbootclasspath/a:" + appJar, "Hello")
+ .assertNormalExit("[class,load] Hello source: shared objects file");
}
private static void copyHelloToNewDir() throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,17 +76,17 @@
} else {
jarPathUpper = Paths.get(appJarUpper);
}
-
- out = TestCommon.exec(appJarUpper, "Hello", "-Xlog:class+path=info",
- "-Xlog:cds");
- if (TestCommon.isUnableToMap(out))
- return;
+ boolean isSameFile = Files.isSameFile(jarPath, jarPathUpper);
- if (Files.isSameFile(jarPath, jarPathUpper)) {
- TestCommon.checkExec(out, "Hello World");
- } else {
- out.shouldContain("shared class paths mismatch")
- .shouldHaveExitValue(1);
- }
- }
+ TestCommon.run("-cp", appJarUpper, "Hello", "-Xlog:class+path=info",
+ "-Xlog:cds")
+ .ifNoMappingFailure(output -> {
+ if (isSameFile) {
+ output.shouldContain("Hello World");
+ } else {
+ output.shouldContain("shared class paths mismatch");
+ output.shouldHaveExitValue(1);
+ }
+ });
+ }
}
--- a/test/hotspot/jtreg/runtime/appcds/ClassPathAttr.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/ClassPathAttr.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,29 +68,30 @@
"CpAttr4",
"CpAttr5"));
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "CpAttr1");
- TestCommon.checkExec(output);
+ "CpAttr1")
+ .assertNormalExit();
// Logging test for class+path.
- output = TestCommon.execCommon(
+ TestCommon.run(
"-Xlog:class+path",
"-cp", cp,
- "CpAttr1");
- if (!TestCommon.isUnableToMap(output)){
- output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
- output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
- }
+ "CpAttr1")
+ .assertNormalExit(output -> {
+ output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
+ output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
+ });
+
// Make sure aliased TraceClassPaths still works
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+TraceClassPaths",
"-cp", cp,
- "CpAttr1");
- if (!TestCommon.isUnableToMap(output)){
- output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
- output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
- }
+ "CpAttr1")
+ .assertNormalExit(output -> {
+ output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
+ output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
+ });
}
}
--- a/test/hotspot/jtreg/runtime/appcds/HelloExtTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/HelloExtTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,8 @@
/*
* @test
- * @summary a simple test for loading a class using the ext class loader in AppCDS
+ * @summary a simple test for loading a class using the platform class loader
+ * (which used to be called the "extension loader) in AppCDS
* @requires vm.cds
* @library /test/lib
* @modules java.base/jdk.internal.misc
@@ -53,19 +54,20 @@
TestCommon.list("org/omg/CORBA/ORB", "[Ljava/lang/Comparable;"),
bootClassPath, "-verbose:class", "--add-modules", "java.corba");
- OutputAnalyzer output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
- "-cp", appJar, bootClassPath, "-verbose:class", "--add-modules", "java.corba", "HelloExt");
-
String prefix = ".class.load. ";
String class_pattern = ".*LambdaForm[$]MH[/][0123456789].*";
String suffix = ".*source: shared objects file.*";
String pattern = prefix + class_pattern + suffix;
- output.shouldNotMatch(pattern);
+
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+ "-cp", appJar, bootClassPath, "-verbose:class", "--add-modules", "java.corba", "HelloExt")
+ .assertNormalExit(output -> output.shouldNotMatch(pattern));
+
- output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
- "-cp", appJar, bootClassPath, "-verbose:class",
- "-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary",
- "--add-modules", "java.corba", "HelloExt");
- output.shouldNotMatch(class_pattern);
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+ "-cp", appJar, bootClassPath, "-verbose:class",
+ "-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary",
+ "--add-modules", "java.corba", "HelloExt")
+ .assertNormalExit(output -> output.shouldNotMatch(class_pattern));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/IgnoreEmptyClassPaths.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/IgnoreEmptyClassPaths.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,12 +51,12 @@
TestCommon.testDump(cp_dump, TestCommon.list("Hello", "HelloMore"),
"-XX:+TraceClassPaths", "-XX:+IgnoreEmptyClassPaths");
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", cp_exec,
"-XX:+IgnoreEmptyClassPaths", // should affect classpath even if placed after the "-cp" argument
"-XX:+TraceClassPaths",
- "HelloMore");
- TestCommon.checkExec(output);
+ "HelloMore")
+ .assertNormalExit();
}
}
--- a/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,8 +59,7 @@
static void run(String[] extra_matches, String cp, String... args) throws Exception {
String[] opts = {"-cp", cp, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", use_whitebox_jar};
opts = TestCommon.concat(opts, args);
- OutputAnalyzer output = TestCommon.execCommon(opts);
- TestCommon.checkExec(output, extra_matches);
+ TestCommon.run(opts).assertNormalExit(extra_matches);
}
public static void main(String[] args) throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/OldClassTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/OldClassTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,11 +65,11 @@
OutputAnalyzer output = TestCommon.dump(jar, appClasses);
TestCommon.checkExecReturn(output, 0, true, "Pre JDK 1.5 class not supported by CDS");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", jar,
"-verbose:class",
- "Hello");
- TestCommon.checkExecReturn(output, 0, true, "Hello Unicode world (Old)");
+ "Hello")
+ .assertNormalExit("Hello Unicode world (Old)");
// CASE 2: if we exlcude old version of this class, we should not pick up
// the newer version of this class in a subsequent classpath element.
@@ -77,11 +77,11 @@
output = TestCommon.dump(classpath, appClasses);
TestCommon.checkExecReturn(output, 0, true, "Pre JDK 1.5 class not supported by CDS");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", classpath,
"-verbose:class",
- "Hello");
- TestCommon.checkExecReturn(output, 0, true, "Hello Unicode world (Old)");
+ "Hello")
+ .assertNormalExit("Hello Unicode world (Old)");
}
static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,81 +67,79 @@
TestCommon.testDump(cp, TestCommon.list("Hello"));
- OutputAnalyzer output;
-
log("Normal execution -- all the JAR paths should be checked");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 0, true, lastCheckMsg);
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-XX:+PrintSharedArchiveAndExit",
- "-XX:+PrintSharedDictionary"); // Test PrintSharedDictionary as well.
- check(output, 0, true, lastCheckMsg, "java.lang.Object");
+ "-XX:+PrintSharedDictionary") // Test PrintSharedDictionary as well.
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg, "java.lang.Object"));
log("Normal execution -- Make sure -version, help message and app main()\n" +
"class are not invoked. These are checked inside check().");
- output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-version");
- check(output, 0, true, lastCheckMsg);
+ TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-version")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
- output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-help");
- check(output, 0, true, lastCheckMsg);
+ TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-help")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
- output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello");
- check(output, 0, true, lastCheckMsg);
+ TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
log("Execution with simple errors -- with 'simple' errors like missing or modified\n" +
"JAR files, the VM should try to continue to print the remaining information.\n" +
"Use an invalid Boot CP -- all the JAR paths should be checked");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-Xbootclasspath/a:foo.jar",
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, ");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, "));
log("Use an App CP shorter than the one at dump time -- all the JAR paths should be checked");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", ".",
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: .");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: ."));
log("Use an invalid App CP -- all the JAR paths should be checked");
String invalidCP = "non-existing-dir" + File.pathSeparator + cp;
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", invalidCP,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP);
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP));
log("Changed modification time of hello.jar -- all the JAR paths should be checked");
(new File(appJar)).setLastModified(System.currentTimeMillis() + 2000);
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "[Timestamp mismatch]");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[Timestamp mismatch]"));
log("Even if hello.jar is out of date, we should still be able to print the dictionary.");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-XX:+PrintSharedArchiveAndExit",
- "-XX:+PrintSharedDictionary"); // Test PrintSharedDictionary as well.
- check(output, 1, true, lastCheckMsg, "java.lang.Object");
+ "-XX:+PrintSharedDictionary") // Test PrintSharedDictionary as well.
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "java.lang.Object"));
log("Remove hello.jar -- all the JAR paths should be checked");
(new File(appJar)).delete();
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "[Required classpath entry does not exist: " + appJar + "]");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[Required classpath entry does not exist: " + appJar + "]"));
log("Execution with major errors -- with 'major' errors like the JSA file\n" +
"is missing, we should stop immediately to avoid crashing the JVM.");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-XX:+PrintSharedArchiveAndExit",
- "-XX:SharedArchiveFile=./no-such-fileappcds.jsa");
- check(output, 1, false, lastCheckMsg);
+ "-XX:SharedArchiveFile=./no-such-fileappcds.jsa")
+ .ifNoMappingFailure(output -> check(output, 1, false, lastCheckMsg));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,10 +77,10 @@
OutputAnalyzer output;
// -Xshare:on
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
- "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper");
- TestCommon.checkExec(output, "Prohibited package name: java.lang");
+ "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper")
+ .assertNormalExit("Prohibited package name: java.lang");
// -Xshare:auto
output = TestCommon.execAuto(
--- a/test/hotspot/jtreg/runtime/appcds/SpecifySysLoaderProp.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/SpecifySysLoaderProp.java Mon Feb 26 09:56:12 2018 +0100
@@ -51,56 +51,49 @@
// (0) Baseline. Do not specify -Djava.system.class.loader
// The test class should be loaded from archive
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", appJar,
- "ReportMyLoader");
- TestCommon.checkExec(output,
- "[class,load] ReportMyLoader source: shared objects file",
- "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@");
+ "ReportMyLoader")
+ .assertNormalExit("[class,load] ReportMyLoader source: shared objects file",
+ "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@");
// (1) Try to execute the archive with -Djava.system.class.loader=no.such.Klass,
// it should fail
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar,
"-Djava.system.class.loader=no.such.Klass",
- "ReportMyLoader");
- try {
- output.shouldContain(warning);
- output.shouldContain("ClassNotFoundException: no.such.Klass");
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ "ReportMyLoader")
+ .assertAbnormalExit(output -> {
+ output.shouldContain(warning);
+ output.shouldContain("ClassNotFoundException: no.such.Klass");
+ });
// (2) Try to execute the archive with -Djava.system.class.loader=TestClassLoader,
// it should run, but AppCDS should be disabled
- output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", appJar,
"-Djava.system.class.loader=TestClassLoader",
- "ReportMyLoader");
- TestCommon.checkExec(output,
- "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@", //<-this is still printed because TestClassLoader simply delegates to Launcher$AppLoader, but ...
- "TestClassLoader.called = true", //<-but this proves that TestClassLoader was indeed called.
- "TestClassLoader: loadClass(\"ReportMyLoader\","); //<- this also proves that TestClassLoader was indeed called.
- try {
+ "ReportMyLoader")
+ .assertNormalExit("ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@", //<-this is still printed because TestClassLoader simply delegates to Launcher$AppLoader, but ...
+ "TestClassLoader.called = true", //<-but this proves that TestClassLoader was indeed called.
+ "TestClassLoader: loadClass(\"ReportMyLoader\",") //<- this also proves that TestClassLoader was indeed called.
+ .assertNormalExit(output -> {
output.shouldMatch(".class,load. TestClassLoader source: file:");
output.shouldMatch(".class,load. ReportMyLoader source: file:.*" + jarFileName);
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ });
// (3) Try to change the java.system.class.loader programmatically after
// the app's main method is executed. This should have no effect in terms of
// changing or switching the actual system class loader that's already in use.
- output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", appJar,
- "TrySwitchMyLoader");
- TestCommon.checkExec(output,
- "[class,load] ReportMyLoader source: shared objects file",
- "TrySwitchMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
- "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
- "TestClassLoader.called = false");
+ "TrySwitchMyLoader")
+ .assertNormalExit("[class,load] ReportMyLoader source: shared objects file",
+ "TrySwitchMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
+ "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
+ "TestClassLoader.called = false");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/TestCommon.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/TestCommon.java Mon Feb 26 09:56:12 2018 +0100
@@ -28,6 +28,7 @@
import jdk.test.lib.Platform;
import jdk.test.lib.cds.CDSOptions;
import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.cds.CDSTestUtils.Result;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import java.io.File;
@@ -191,6 +192,14 @@
return runWithArchive(opts);
}
+ // This is the new API for running a Java process with CDS enabled.
+ // See comments in the CDSTestUtils.Result class for how to use this method.
+ public static Result run(String... suffix) throws Exception {
+ AppCDSOptions opts = (new AppCDSOptions());
+ opts.addSuffix(suffix);
+ return new Result(opts, runWithArchive(opts));
+ }
+
public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
--- a/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -84,21 +84,22 @@
"/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
"/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar";
- longClassPath += ps + appJar;
+ String myCP = longClassPath + ps + appJar;
// Dump an archive with a specified JAR file in -classpath
- TestCommon.testDump(longClassPath, TestCommon.list("Hello"));
+ TestCommon.testDump(myCP, TestCommon.list("Hello"));
// Then try to execute the archive with a different classpath and with -XX:+TraceClassPaths.
// The diagnosis "expecting" app classpath trace should show the entire classpath.
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+TraceClassPaths",
"-cp", appJar,
- "Hello");
- output.shouldContain("Unable to use shared archive");
- output.shouldContain("shared class paths mismatch");
- // the "expecting" app classpath from -XX:+TraceClassPaths should not
- // be truncated
- output.shouldContain(longClassPath);
- output.shouldHaveExitValue(1);
+ "Hello")
+ .assertAbnormalExit(output -> {
+ output.shouldContain("Unable to use shared archive");
+ output.shouldContain("shared class paths mismatch");
+ // the "expecting" app classpath from -XX:+TraceClassPaths should not
+ // be truncated
+ output.shouldContain(myCP);
+ });
}
}
--- a/test/hotspot/jtreg/runtime/appcds/VerifierTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
static final String MAP_FAIL =
"shared archive file was created with less restrictive verification setting";
static final String VFY_ERR = "java.lang.VerifyError";
+ static final String PASS_RESULT = "Hi, how are you?";
enum Testset1Part {
A, B
@@ -110,12 +111,22 @@
TestCommon.testDump(jar, appClasses);
}
+ static void checkRuntimeOutput(OutputAnalyzer output, String expected) throws Exception {
+ output.shouldContain(expected);
+ if (expected.equals(PASS_RESULT) ||
+ expected.equals(VFY_ERR)) {
+ output.shouldHaveExitValue(0);
+ } else {
+ output.shouldNotHaveExitValue(0);
+ }
+ }
+
static void testset_1(String jar, String[] noAppClasses, String[] appClasses, Testset1Part part)
throws Exception
{
String config[][] = {
// {dump_list, dumptime_verification_setting,
- // runtime_verification_setting, runtime_output},
+ // runtime_verification_setting, expected_output_str},
// Dump app/ext with -Xverify:remote
{"app", VFY_REMOTE, VFY_REMOTE, VFY_ERR},
@@ -166,7 +177,7 @@
noAppClasses;
String dump_setting = config[i][1];
String runtime_setting = config[i][2];
- String runtime_output = config[i][3];
+ String expected_output_str = config[i][3];
System.out.println("Test case [" + i + "]: dumping " + config[i][0] +
" with " + dump_setting +
", run with " + runtime_setting);
@@ -178,17 +189,10 @@
"-Xms256m",
"-Xmx256m");
}
- OutputAnalyzer runtimeOutput = TestCommon.execCommon(
- "-cp", jar,
- runtime_setting,
- "VerifierTest0");
- try {
- runtimeOutput.shouldContain(runtime_output);
- } catch (RuntimeException re) {
- // Check if the failure is due to archive mapping failure.
- // If not, a RuntimeException will be thrown.
- runtimeOutput.shouldContain("Unable to use shared archive");
- }
+ TestCommon.run("-cp", jar,
+ runtime_setting,
+ "VerifierTest0")
+ .ifNoMappingFailure(output -> checkRuntimeOutput(output, expected_output_str));
prev_dump_setting = dump_setting;
}
}
@@ -204,10 +208,9 @@
"Hi$MyClass");
jar = TestCommon.getTestJar(jarName_hi + ".jar") + File.pathSeparator +
TestCommon.getTestJar(jarName_greet + ".jar");
- final String PASS_RESULT = "Hi, how are you?";
String config2[][] = {
// {dump_list, dumptime_verification_setting,
- // runtime_verification_setting, runtime_output},
+ // runtime_verification_setting, expected_output_str},
// Dump app/ext with -Xverify:remote
{"app", VFY_REMOTE, VFY_REMOTE, PASS_RESULT},
@@ -226,7 +229,7 @@
// config2[i][0] is always set to "app" in this test
String dump_setting = config2[i][1];
String runtime_setting = config2[i][2];
- String runtime_output = config2[i][3];
+ String expected_output_str = config2[i][3];
System.out.println("Test case [" + i + "]: dumping " + config2[i][0] +
" with " + dump_setting +
", run with " + runtime_setting);
@@ -237,19 +240,11 @@
// issue - assert failure when dumping archive with the -Xverify:all
"-Xms256m",
"-Xmx256m");
- OutputAnalyzer runtimeOutput = TestCommon.execCommon(
- "-cp", jar,
- runtime_setting,
- "Hi");
- try {
- runtimeOutput.shouldContain(runtime_output);
- } catch (RuntimeException re) {
- // Check if the failure is due to archive mapping failure.
- // If not, a RuntimeException will be thrown.
- runtimeOutput.shouldContain("Unable to use shared archive");
- }
+ TestCommon.run("-cp", jar,
+ runtime_setting,
+ "Hi")
+ .ifNoMappingFailure(output -> checkRuntimeOutput(output, expected_output_str));
}
-
}
static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {
@@ -279,7 +274,7 @@
MethodVisitor mv;
AnnotationVisitor av0;
- cw.visit(V1_6, ACC_SUPER, "UnverifiableBase", null, "java/lang/Object", null);
+ cw.visit(V1_8, ACC_SUPER, "UnverifiableBase", null, "java/lang/Object", null);
{
fv = cw.visitField(ACC_FINAL + ACC_STATIC, "x", "LVerifierTest;", null, null);
fv.visitEnd();
@@ -296,8 +291,7 @@
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
- //WAS mv.visitTypeInsn(NEW, "VerifierTest");
- mv.visitTypeInsn(NEW, "java/lang/Object");
+ mv.visitTypeInsn(NEW, "VerifierTest0");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "VerifierTest0", "<init>", "()V", false);
mv.visitFieldInsn(PUTSTATIC, "UnverifiableBase", "x", "LVerifierTest;");
@@ -305,6 +299,7 @@
mv.visitMaxs(2, 0);
mv.visitEnd();
}
+ addBadMethod(cw);
cw.visitEnd();
return cw.toByteArray();
@@ -317,7 +312,7 @@
MethodVisitor mv;
AnnotationVisitor av0;
- cw.visit(V1_6, ACC_ABSTRACT + ACC_INTERFACE, "UnverifiableIntf", null, "java/lang/Object", null);
+ cw.visit(V1_8, ACC_ABSTRACT + ACC_INTERFACE, "UnverifiableIntf", null, "java/lang/Object", null);
{
fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "x", "LVerifierTest0;", null, null);
@@ -326,8 +321,7 @@
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
- //WAS mv.visitTypeInsn(NEW, "VerifierTest");
- mv.visitTypeInsn(NEW, "java/lang/Object");
+ mv.visitTypeInsn(NEW, "VerifierTest0");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "VerifierTest0", "<init>", "()V", false);
mv.visitFieldInsn(PUTSTATIC, "UnverifiableIntf", "x", "LVerifierTest0;");
@@ -335,9 +329,18 @@
mv.visitMaxs(2, 0);
mv.visitEnd();
}
+ addBadMethod(cw);
cw.visitEnd();
return cw.toByteArray();
}
+ // Add a bad method to make the class fail verification.
+ static void addBadMethod(ClassWriter cw) throws Exception {
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "bad", "()V", null, null);
+ mv.visitCode();
+ mv.visitInsn(ARETURN); // java.lang.VerifyError: Operand stack underflow
+ mv.visitMaxs(2, 2);
+ mv.visitEnd();
+ }
}
--- a/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,11 +45,10 @@
TestCommon.testDump(appJar, TestCommon.list("Hello"));
// Then try to execute the archive without -classpath -- it should fail
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
/* "-cp", appJar, */ // <- uncomment this and the execution should succeed
- "Hello");
- output.shouldContain("Unable to use shared archive");
- output.shouldContain("shared class paths mismatch");
- output.shouldHaveExitValue(1);
+ "Hello")
+ .assertAbnormalExit("Unable to use shared archive",
+ "shared class paths mismatch");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/ArrayTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/ArrayTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,6 @@
}
String[] opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- output = TestCommon.execCommon(opts);
- TestCommon.checkExec(output);
+ TestCommon.run(opts).assertNormalExit();
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/CheckAnonymousClass.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/CheckAnonymousClass.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,9 +44,6 @@
TestCommon.dump(appJar, TestCommon.list("Hello", "org/omg/CORBA/ORB"),
"--add-modules", "java.corba", "-Xlog:class+load=info");
- OutputAnalyzer output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions",
- "-cp", appJar, "-Xlog:class+load=info", "--add-modules", "java.corba", "Hello");
-
String prefix = ".class.load. ";
// class name pattern like the following:
// jdk.internal.loader.BuiltinClassLoader$$Lambda$1/1816757085
@@ -55,20 +52,14 @@
String suffix = ".*source: shared objects file.*";
String pattern = prefix + class_pattern + suffix;
// during run time, anonymous classes shouldn't be loaded from the archive
- try {
- output.shouldNotMatch(pattern);
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions",
+ "-cp", appJar, "-Xlog:class+load=info", "--add-modules", "java.corba", "Hello")
+ .assertNormalExit(output -> output.shouldNotMatch(pattern));
// inspect the archive and make sure no anonymous class is in there
- output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions",
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions",
"-cp", appJar, "-Xlog:class+load=info", "-XX:+PrintSharedArchiveAndExit",
- "-XX:+PrintSharedDictionary", "--add-modules", "java.corba", "Hello");
- try {
- output.shouldNotMatch(class_pattern);
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ "-XX:+PrintSharedDictionary", "--add-modules", "java.corba", "Hello")
+ .assertNormalExit(output -> output.shouldNotMatch(class_pattern));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDump.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDump.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,13 +67,13 @@
TestCommon.testDump(appJar, TestCommon.list("Hello"),
extraArg, "-Xmx32m", gcLog);
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar,
"-Xmx32m",
"-XX:+PrintSharedSpaces",
gcLog,
- "Hello");
- TestCommon.checkExec(output);
+ "Hello")
+ .assertNormalExit();
}
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -113,7 +113,7 @@
"-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
}
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar,
bootClassPath,
"-Xmx32m",
@@ -124,8 +124,8 @@
"-XX:+WhiteBoxAPI",
"-XX:SharedReadOnlySize=30m",
gcLog,
- "GCSharedStringsDuringDumpWb");
- TestCommon.checkExec(output);
+ "GCSharedStringsDuringDumpWb")
+ .assertNormalExit();
}
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/AppClassInCP.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/AppClassInCP.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,13 +90,13 @@
String classPath = appJar + File.pathSeparator + classDir;
System.out.println("classPath: " + classPath);
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"-cp", classPath,
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
- "PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello");
- TestCommon.checkExec(output,
+ "PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello")
+ .assertNormalExit(
"I pass!",
"Hello!",
"Hello source: shared objects file");
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/CustomPackage.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/CustomPackage.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,12 +72,12 @@
"PatchMain", "javax.naming.myspi.NamingManager");
TestCommon.checkDump(output, "Preload Warning: Cannot find javax/naming/myspi/NamingManager");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.myspi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.myspi.NamingManager")
+ .assertNormalExit("I pass!");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,12 +72,12 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is not patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming2=" + moduleJar,
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- output.shouldNotContain("I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit(o -> o.shouldNotContain("I pass!"));
// Case 2: --patch-module specified for dump time but not for run time
System.out.println("Case 2: --patch-module specified for dump time but not for run time");
@@ -89,11 +89,11 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is not patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- output.shouldNotContain("I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit(o -> o.shouldNotContain("I pass!"));
// Case 3: --patch-module specified for run time but not for dump time
System.out.println("Case 3: --patch-module specified for run time but not for dump time");
@@ -104,12 +104,12 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass!");
// Case 4: mismatched --patch-module entry counts between dump time and run time
System.out.println("Case 4: mismatched --patch-module entry counts between dump time and run time");
@@ -121,12 +121,12 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"--patch-module=java.naming2=" + moduleJar,
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass!");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,10 +64,11 @@
"PatchMain", "java.lang.NewClass");
TestCommon.checkDump(output, "Loading classes to share");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.base=" + moduleJar,
- "PatchMain", "java.lang.NewClass");
- output.shouldContain("CDS is disabled when java.base module is patched");
+ "PatchMain", "java.lang.NewClass")
+ .assertAbnormalExit("Unable to use shared archive",
+ "CDS is disabled when java.base module is patched");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/Simple.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/Simple.java Mon Feb 26 09:56:12 2018 +0100
@@ -70,12 +70,12 @@
"PatchMain", "javax.naming.spi.NamingManager");
TestCommon.checkDump(output, "Loading classes to share");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass!");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/SubClassOfPatchedClass.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/SubClassOfPatchedClass.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,13 +92,13 @@
String classPath = appJar + File.pathSeparator + classDir;
System.out.println("classPath: " + classPath);
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"-cp", classPath,
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
- "PatchMain", "javax.naming.Reference", "mypackage.MyReference");
- TestCommon.checkExec(output,
+ "PatchMain", "javax.naming.Reference", "mypackage.MyReference")
+ .assertNormalExit(
"I pass!",
"MyReference source: file:");
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/TwoJars.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/TwoJars.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -89,12 +89,12 @@
"PatchMain", "javax.naming.spi.NamingManager");
TestCommon.checkDump(output, "Loading classes to share");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar2 + File.pathSeparator + moduleJar,
"-Xlog:class+load",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/DummyClassesInBootClassPath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/DummyClassesInBootClassPath.java Mon Feb 26 09:56:12 2018 +0100
@@ -70,10 +70,10 @@
}
String[] arguments = new String[argsList.size()];
arguments = argsList.toArray(arguments);
- OutputAnalyzer execOutput = TestCommon.execCommon(
+ Testcommon.run(
"--add-modules", "java.activation", "-Xbootclasspath/a:" + appJar,
- "DummyClassHelper", arguments[0], arguments[1]);
- checkOutput(execOutput, classNames);
+ "DummyClassHelper", arguments[0], arguments[1])
+ .assertNormalExit(output -> checkOutput(output, classNames));
JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
String whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
@@ -87,8 +87,8 @@
String[] opts = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
"--add-modules", "java.activation", bootClassPath, "-Xlog:class+path=trace",
"DummyClassHelper", arguments[0], arguments[1], arguments[2]};
- execOutput = TestCommon.execCommon(opts);
- checkOutput(execOutput, classNames);
+ Testcommon.run(opts)
+ .assertNormalExit(output -> checkOutput(output, classNames));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/EmptyClassInBootClassPath.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/EmptyClassInBootClassPath.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,16 +73,14 @@
argsList.add("useAppLoader");
String[] opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- OutputAnalyzer runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, "appLoader found method main");
+ TestCommon.run(opts).assertNormalExit("appLoader found method main");
// case 2: load class in bootclasspath using boot loader
argsList.remove(argsList.size() - 1);
argsList.add("useBootLoader");
opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+ TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
// case 3: load class in bootclasspath using app loader with '--limit-modules java.base'
argsList.add(0, "--limit-modules");
@@ -91,16 +89,13 @@
argsList.add("useAppLoader");
opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+ TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
// case 4: load class in bootclasspath using boot loader with '--limit-modules java.base'
argsList.remove(argsList.size() - 1);
argsList.add("useBootLoader");
opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
-
+ TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -113,10 +113,9 @@
log("runTestWithAppLoader(): testCaseId = %d", entry.testCaseId);
String params = TransformTestCommon.getAgentParams(entry, parent, child);
String agentParam = String.format("-javaagent:%s=%s", agentJar, params);
- out = TestCommon.execCommon("-Xlog:class+load=info", "-cp", appJar,
- agentParam, child);
-
- TransformTestCommon.checkResults(entry, out, parent, child);
+ TestCommon.run("-Xlog:class+load=info", "-cp", appJar,
+ agentParam, child)
+ .assertNormalExit(output -> TransformTestCommon.checkResults(entry, output, parent, child));
}
}
@@ -187,13 +186,13 @@
String agentParam = "-javaagent:" + agentJar + "=" +
TransformTestCommon.getAgentParams(entry, parent, child);
- out = TestCommon.execCommon("-Xlog:class+load=info",
- "-cp", appJar,
- "--add-opens=java.base/java.security=ALL-UNNAMED",
- agentParam,
- "CustomLoaderApp",
- customJar, loaderType, child);
- TransformTestCommon.checkResults(entry, out, parent, child);
+ TestCommon.run("-Xlog:class+load=info",
+ "-cp", appJar,
+ "--add-opens=java.base/java.security=ALL-UNNAMED",
+ agentParam,
+ "CustomLoaderApp",
+ customJar, loaderType, child)
+ .assertNormalExit(output -> TransformTestCommon.checkResults(entry, output, parent, child));
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/BadBSMUseTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8186211
+ * @summary CONSTANT_Dynamic_info structure's tries to use a BSM index whose signature is for an invokedynamic and vice versa.
+ * @requires os.arch != "sparcv9"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @compile CondyUsesIndyBSM.jcod
+ * @compile IndyUsesCondyBSM.jcod
+ * @run main/othervm -Xverify:all BadBSMUseTest
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+// BootstrapMethodError expected in each test case below.
+public class BadBSMUseTest {
+ public static void main(String args[]) throws Throwable {
+ // 1. Test a CONSTANT_Dynamic_info's bootstrap_method_attr_index points
+ // at a BSM meant for a CONSTANT_InvokeDynamic_info
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("CondyUsesIndyBSM");
+ OutputAnalyzer oa = new OutputAnalyzer(pb.start());
+ oa.shouldContain("In Indybsm target CallSite method foo");
+ oa.shouldContain("BootstrapMethodError: bootstrap method initialization exception");
+ oa.shouldHaveExitValue(1);
+
+ // 2. Test a CONSTANT_InvokeDynamic_info's bootstrap_method_attr_index points
+ // at a BSM meant for a CONSTANT_Dynamic_info
+ pb = ProcessTools.createJavaProcessBuilder("IndyUsesCondyBSM");
+ oa = new OutputAnalyzer(pb.start());
+ oa.shouldContain("In Condybsm");
+ oa.shouldContain("BootstrapMethodError: bootstrap method initialization exception");
+ oa.shouldHaveExitValue(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadBSMArrayTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8186211
+ * @summary CONSTANT_Dynamic_info structure present with various bad BSM index, BSM array attribute checks.
+ * @requires os.arch != "sparcv9"
+ * @compile CondyBadBSMIndex.jcod
+ * @compile CondyEmptyBSMArray1.jcod
+ * @compile CondyNoBSMArray.jcod
+ * @run main/othervm -Xverify:all CondyBadBSMArrayTest
+ */
+
+// Test that a CONSTANT_Dynamic_info structure present with the following issues:
+// 1. The CONSTANT_Dynamic_info structure's bootstrap_method_attr_index value is
+// an index outside of the array size.
+// 2. An empty BootstrapMethods Attribute array
+// 3. No BootstrapMethods Attribute array present.
+public class CondyBadBSMArrayTest {
+ public static void main(String args[]) throws Throwable {
+ // 1. The CONSTANT_Dynamic_info structure's bootstrap_method_attr_index is outside the array size
+ try {
+ Class newClass = Class.forName("CondyBadBSMIndex");
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!e.getMessage().contains("Short length on BootstrapMethods in class file")) {
+ throw new RuntimeException("ClassFormatError thrown, incorrect message");
+ }
+ System.out.println("Test CondyBadBSMIndex passed: " + e.getMessage());
+ } catch (Throwable e) {
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ }
+
+ // 2. An empty BootstrapMethods Attribute array - contains zero elements
+ try {
+ Class newClass = Class.forName("CondyEmptyBSMArray1");
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!e.getMessage().contains("Short length on BootstrapMethods in class file")) {
+ throw new RuntimeException("ClassFormatError thrown, incorrect message");
+ }
+ System.out.println("Test CondyEmptyBSMArray1 passed: " + e.getMessage());
+ } catch (Throwable e) {
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ }
+
+ // 3. No BootstrapMethods Attribute array present`
+ try {
+ Class newClass = Class.forName("CondyNoBSMArray");
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!e.getMessage().contains("Missing BootstrapMethods attribute in class file")) {
+ throw new RuntimeException("ClassFormatError thrown, incorrect message");
+ }
+ System.out.println("Test CondyNoBSMArray passed: " + e.getMessage());
+ } catch (Throwable e) {
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadBSMIndex.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_Dynamic_info whose bootstrap_method_attr_index is bogus.
+ * ClassFormatError expected.
+ */
+
+/*
+class CondyBadBSMIndex {
+ CondyBadBSMIndex() { }
+ public static Object m() {
+ // ldc Dynamic where the CONSTANT_Dynamic_info bootstrap_method_attr_index points at slot #5
+ // in the bootstrap_methods array, however, the bootstrap_methods array is composed of only 1 slot.
+ // Outcome -> java.lang.ClassFormatError: Short length on BootstrapMethods in class file CondyBadBSMIndex
+ return of ldc's Object;
+ public static void main(String[] args) { return; }
+}
+*/
+
+class CondyBadBSMIndex {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "java/lang/Object"; // #1
+ class #1; // #2
+ Utf8 "<init>"; // #3
+ Utf8 "()V"; // #4
+ NameAndType #3 #4; // #5
+ Method #2 #5; // #6
+ Utf8 "Code"; // #7
+ Utf8 "CondyBadBSMIndex"; // #8
+ class #8; // #9
+ Utf8 "bsm"; // #10
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #11
+ NameAndType #10 #11; // #12
+ Method #9 #12; // #13
+ MethodHandle 6b #13; // #14
+ Utf8 "name"; // #15
+ Utf8 "Ljava/lang/Object;"; // #16
+ NameAndType #15 #16; // #17
+ Dynamic 5s #17; // #18
+ Utf8 "m"; // #19
+ Utf8 "()Ljava/lang/Object;"; // #20
+ Utf8 "main"; // #21
+ Utf8 "([Ljava/lang/String;)V"; // #22
+ Utf8 "BootstrapMethods"; // #23
+ Utf8 "CondyBadBSMIndex"; // #24
+ class #24; // #25
+ } // Constant Pool
+
+ 0x0000; // access
+ #25;// this_cpx
+ #2;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #3; // name_cpx
+ #4; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70006B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #19; // name_cpx
+ #20; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0x1212B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #21; // name_cpx
+ #22; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 0; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0xB1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#23) { // BootstrapMethods
+ [] { // bootstrap_methods
+ { // bootstrap_method
+ #14; // bootstrap_method_ref
+ [] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ }
+ } // end BootstrapMethods
+ } // Attributes
+} // end class CondyBadBSMIndex
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadLDC.jasm Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a incorrect ldc instruction of a condy whose loadable
+ * constant is a double. VerifyError expected.
+ */
+
+class CondyBadLDC
+ version 55:0
+{
+
+
+public Method "<init>":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+
+public static Method intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;"
+ throws java/lang/Throwable
+ stack 4 locals 6
+{
+ aload_1;
+ astore 4;
+ iconst_m1;
+ istore 5;
+ aload 4;
+ invokevirtual Method java/lang/String.hashCode:"()I";
+ lookupswitch{ //11
+ -2001159796: L238;
+ -1538095928: L272;
+ -891985903: L255;
+ 66: L108;
+ 67: L124;
+ 68: L140;
+ 70: L156;
+ 73: L172;
+ 74: L188;
+ 83: L204;
+ 90: L221;
+ default: L286 };
+ L108: stack_frame_type append;
+ locals_map class java/lang/String, int;
+ aload 4;
+ ldc String "B";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_0;
+ istore 5;
+ goto L286;
+ L124: stack_frame_type same;
+ aload 4;
+ ldc String "C";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_1;
+ istore 5;
+ goto L286;
+ L140: stack_frame_type same;
+ aload 4;
+ ldc String "D";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_2;
+ istore 5;
+ goto L286;
+ L156: stack_frame_type same;
+ aload 4;
+ ldc String "F";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_3;
+ istore 5;
+ goto L286;
+ L172: stack_frame_type same;
+ aload 4;
+ ldc String "I";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_4;
+ istore 5;
+ goto L286;
+ L188: stack_frame_type same;
+ aload 4;
+ ldc String "J";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_5;
+ istore 5;
+ goto L286;
+ L204: stack_frame_type same;
+ aload 4;
+ ldc String "S";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 6;
+ istore 5;
+ goto L286;
+ L221: stack_frame_type same;
+ aload 4;
+ ldc String "Z";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 7;
+ istore 5;
+ goto L286;
+ L238: stack_frame_type same;
+ aload 4;
+ ldc String "nullRef";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 8;
+ istore 5;
+ goto L286;
+ L255: stack_frame_type same;
+ aload 4;
+ ldc String "string";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 9;
+ istore 5;
+ goto L286;
+ L272: stack_frame_type same;
+ aload 4;
+ ldc String "stringArray";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 10;
+ istore 5;
+ L286: stack_frame_type same;
+ iload 5;
+ tableswitch{ //0 to 10
+ 0: L348;
+ 1: L354;
+ 2: L360;
+ 3: L366;
+ 4: L372;
+ 5: L377;
+ 6: L383;
+ 7: L389;
+ 8: L402;
+ 9: L404;
+ 10: L407;
+ default: L422 };
+ L348: stack_frame_type same;
+ iload_3;
+ i2b;
+ invokestatic Method java/lang/Byte.valueOf:"(B)Ljava/lang/Byte;";
+ areturn;
+ L354: stack_frame_type same;
+ iload_3;
+ i2c;
+ invokestatic Method java/lang/Character.valueOf:"(C)Ljava/lang/Character;";
+ areturn;
+ L360: stack_frame_type same;
+ iload_3;
+ i2d;
+ invokestatic Method java/lang/Double.valueOf:"(D)Ljava/lang/Double;";
+ areturn;
+ L366: stack_frame_type same;
+ iload_3;
+ i2f;
+ invokestatic Method java/lang/Float.valueOf:"(F)Ljava/lang/Float;";
+ areturn;
+ L372: stack_frame_type same;
+ iload_3;
+ invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/Integer;";
+ areturn;
+ L377: stack_frame_type same;
+ iload_3;
+ i2l;
+ invokestatic Method java/lang/Long.valueOf:"(J)Ljava/lang/Long;";
+ areturn;
+ L383: stack_frame_type same;
+ iload_3;
+ i2s;
+ invokestatic Method java/lang/Short.valueOf:"(S)Ljava/lang/Short;";
+ areturn;
+ L389: stack_frame_type same;
+ iload_3;
+ ifle L397;
+ iconst_1;
+ goto L398;
+ L397: stack_frame_type same;
+ iconst_0;
+ L398: stack_frame_type stack1;
+ stack_map int;
+ invokestatic Method java/lang/Boolean.valueOf:"(Z)Ljava/lang/Boolean;";
+ areturn;
+ L402: stack_frame_type same;
+ aconst_null;
+ areturn;
+ L404: stack_frame_type same;
+ ldc String "string";
+ areturn;
+ L407: stack_frame_type same;
+ iconst_2;
+ anewarray class java/lang/String;
+ dup;
+ iconst_0;
+ ldc String "string";
+ aastore;
+ dup;
+ iconst_1;
+ ldc String "string";
+ aastore;
+ areturn;
+ L422: stack_frame_type same;
+ new class java/lang/BootstrapMethodError;
+ dup;
+ ldc String "Failure to generate a dynamic constant";
+ invokespecial Method java/lang/BootstrapMethodError."<init>":"(Ljava/lang/String;)V";
+ athrow;
+}
+
+public static Method D:"()D"
+ stack 2 locals 0
+{
+ // ldc of a double will yield a VerifyError, should be an ldc2_w instruction
+ ldc Dynamic REF_invokeStatic:CondyBadLDC.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":D:"D" int 2147483647;
+ dreturn;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+ stack 2 locals 1
+{
+ invokestatic Method D:"()D";
+ return;
+}
+
+} // end Class CondyBadLDC
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadLDC2_W.jasm Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a ldc2_w instruction of a condy which returns a loadable float
+ * constant. VerifyError expected.
+ */
+class CondyBadLDC2_W
+ version 55:0
+{
+
+public Method "<init>":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+
+public static Method intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;"
+ throws java/lang/Throwable
+ stack 4 locals 6
+{
+ aload_1;
+ astore 4;
+ iconst_m1;
+ istore 5;
+ aload 4;
+ invokevirtual Method java/lang/String.hashCode:"()I";
+ lookupswitch{ //11
+ -2001159796: L238;
+ -1538095928: L272;
+ -891985903: L255;
+ 66: L108;
+ 67: L124;
+ 68: L140;
+ 70: L156;
+ 73: L172;
+ 74: L188;
+ 83: L204;
+ 90: L221;
+ default: L286 };
+ L108: stack_frame_type append;
+ locals_map class java/lang/String, int;
+ aload 4;
+ ldc String "B";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_0;
+ istore 5;
+ goto L286;
+ L124: stack_frame_type same;
+ aload 4;
+ ldc String "C";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_1;
+ istore 5;
+ goto L286;
+ L140: stack_frame_type same;
+ aload 4;
+ ldc String "D";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_2;
+ istore 5;
+ goto L286;
+ L156: stack_frame_type same;
+ aload 4;
+ ldc String "F";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_3;
+ istore 5;
+ goto L286;
+ L172: stack_frame_type same;
+ aload 4;
+ ldc String "I";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_4;
+ istore 5;
+ goto L286;
+ L188: stack_frame_type same;
+ aload 4;
+ ldc String "J";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_5;
+ istore 5;
+ goto L286;
+ L204: stack_frame_type same;
+ aload 4;
+ ldc String "S";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 6;
+ istore 5;
+ goto L286;
+ L221: stack_frame_type same;
+ aload 4;
+ ldc String "Z";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 7;
+ istore 5;
+ goto L286;
+ L238: stack_frame_type same;
+ aload 4;
+ ldc String "nullRef";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 8;
+ istore 5;
+ goto L286;
+ L255: stack_frame_type same;
+ aload 4;
+ ldc String "string";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 9;
+ istore 5;
+ goto L286;
+ L272: stack_frame_type same;
+ aload 4;
+ ldc String "stringArray";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 10;
+ istore 5;
+ L286: stack_frame_type same;
+ iload 5;
+ tableswitch{ //0 to 10
+ 0: L348;
+ 1: L354;
+ 2: L360;
+ 3: L366;
+ 4: L372;
+ 5: L377;
+ 6: L383;
+ 7: L389;
+ 8: L402;
+ 9: L404;
+ 10: L407;
+ default: L422 };
+ L348: stack_frame_type same;
+ iload_3;
+ i2b;
+ invokestatic Method java/lang/Byte.valueOf:"(B)Ljava/lang/Byte;";
+ areturn;
+ L354: stack_frame_type same;
+ iload_3;
+ i2c;
+ invokestatic Method java/lang/Character.valueOf:"(C)Ljava/lang/Character;";
+ areturn;
+ L360: stack_frame_type same;
+ iload_3;
+ i2d;
+ invokestatic Method java/lang/Double.valueOf:"(D)Ljava/lang/Double;";
+ areturn;
+ L366: stack_frame_type same;
+ iload_3;
+ i2f;
+ invokestatic Method java/lang/Float.valueOf:"(F)Ljava/lang/Float;";
+ areturn;
+ L372: stack_frame_type same;
+ iload_3;
+ invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/Integer;";
+ areturn;
+ L377: stack_frame_type same;
+ iload_3;
+ i2l;
+ invokestatic Method java/lang/Long.valueOf:"(J)Ljava/lang/Long;";
+ areturn;
+ L383: stack_frame_type same;
+ iload_3;
+ i2s;
+ invokestatic Method java/lang/Short.valueOf:"(S)Ljava/lang/Short;";
+ areturn;
+ L389: stack_frame_type same;
+ iload_3;
+ ifle L397;
+ iconst_1;
+ goto L398;
+ L397: stack_frame_type same;
+ iconst_0;
+ L398: stack_frame_type stack1;
+ stack_map int;
+ invokestatic Method java/lang/Boolean.valueOf:"(Z)Ljava/lang/Boolean;";
+ areturn;
+ L402: stack_frame_type same;
+ aconst_null;
+ areturn;
+ L404: stack_frame_type same;
+ ldc String "string";
+ areturn;
+ L407: stack_frame_type same;
+ iconst_2;
+ anewarray class java/lang/String;
+ dup;
+ iconst_0;
+ ldc String "string";
+ aastore;
+ dup;
+ iconst_1;
+ ldc String "string";
+ aastore;
+ areturn;
+ L422: stack_frame_type same;
+ new class java/lang/BootstrapMethodError;
+ dup;
+ ldc String "Failure to generate a dynamic constant";
+ invokespecial Method java/lang/BootstrapMethodError."<init>":"(Ljava/lang/String;)V";
+ athrow;
+}
+
+public static Method F:"()F"
+ stack 1 locals 0
+{
+ // VerifyError, ldc2_w of a float, should be ldc
+ ldc2_w Dynamic REF_invokeStatic:CondyBadLDC2_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":F:"F" int 2147483647;
+ freturn;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+ stack 1 locals 1
+{
+ invokestatic Method F:"()F";
+ return;
+}
+
+} // end Class CondyBadLDC2_W
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadNameType.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_Dynamic_info structure whose name_and_type_index
+ * does not point at a CONSTANT_NameAndType_info structure. ClassFormatError expected.
+ */
+
+/*
+class CondyBadNameType {
+ CondyBadNameType() { }
+ public static Object m() {
+ // ldc Dynamic where the CONSTANT_Dynamic_info name_and_type_index erroneously points
+ // at a Utf8 instead of the expected CONSTANT_NameAndType.
+ // Outcome -> java.lang.ClassFormatError: Invalid constant pool index 16 in class file CondyBadNameType
+ return of ldc's Object;
+ public static void main(String[] args) { return; }
+}
+*/
+
+class CondyBadNameType {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "java/lang/Object"; // #1
+ class #1; // #2
+ Utf8 "<init>"; // #3
+ Utf8 "()V"; // #4
+ NameAndType #3 #4; // #5
+ Method #2 #5; // #6
+ Utf8 "Code"; // #7
+ Utf8 "CondyBadNameType"; // #8
+ class #8; // #9
+ Utf8 "bsm"; // #10
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #11
+ NameAndType #10 #11; // #12
+ Method #9 #12; // #13
+ MethodHandle 6b #13; // #14
+ Utf8 "name"; // #15
+ Utf8 "Ljava/lang/Object;"; // #16
+ NameAndType #15 #16; // #17
+ Dynamic 0s #16; // #18
+ Utf8 "m"; // #19
+ Utf8 "()Ljava/lang/Object;"; // #20
+ Utf8 "main"; // #21
+ Utf8 "([Ljava/lang/String;)V"; // #22
+ Utf8 "BootstrapMethods"; // #23
+ Utf8 "CondyBadNameType"; // #24
+ class #24; // #25
+ } // Constant Pool
+
+ 0x0000; // access
+ #25;// this_cpx
+ #2;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #3; // name_cpx
+ #4; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70006B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #19; // name_cpx
+ #20; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0x1212B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #21; // name_cpx
+ #22; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 0; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0xB1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#23) { // BootstrapMethods
+ [] { // bootstrap_methods
+ { // bootstrap_method
+ #14; // bootstrap_method_ref
+ [] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ }
+ } // end BootstrapMethods
+ } // Attributes
+} // end class CondyBadNameType
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyBadNameTypeTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8186211
+ * @summary CONSTANT_Dynamic_info structure's name_and_type_index item does not point at CONSANT_NameAndType_info
+ * @requires os.arch != "sparcv9"
+ * @compile CondyBadNameType.jcod
+ * @run main/othervm -Xverify:all CondyBadNameTypeTest
+ */
+
+// Test a CONSTANT_Dynamic_info structure's name_and_type_index points at a
+// constant pool NameAndType_info structure.
+public class CondyBadNameTypeTest {
+ public static void main(String args[]) throws Throwable {
+ try {
+ Class newClass = Class.forName("CondyBadNameType");
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!e.getMessage().contains("Invalid constant pool index")) {
+ throw new RuntimeException("ClassFormatError thrown, incorrect message");
+ }
+ System.out.println("Test CondyBadNameTypeTest passed: " + e.getMessage());
+ } catch (Throwable e) {
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyCFVCheck.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_Dynamic_info structure in a version 54 class file.
+ */
+
+/*
+class CondyCFVCheck {
+ CondyCondyCFVCheck() {}
+ public static Object m() {
+ // ldc Dynamic
+ // Outcome -> java.lang.ClassFormatError: Class file version does not support constant tag 17 in class file CondyCFVCheck
+ return of ldc's Object;
+ public static void main(String[] args) { return; }
+}
+*/
+
+class CondyCFVCheck {
+ 0xCAFEBABE;
+ 0; // minor version
+ 54; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "java/lang/Object"; // #1
+ class #1; // #2
+ Utf8 "<init>"; // #3
+ Utf8 "()V"; // #4
+ NameAndType #3 #4; // #5
+ Method #2 #5; // #6
+ Utf8 "Code"; // #7
+ Utf8 "CondyCFVCheck"; // #8
+ class #8; // #9
+ Utf8 "bsm"; // #10
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #11
+ NameAndType #10 #11; // #12
+ Method #9 #12; // #13
+ MethodHandle 6b #13; // #14
+ Utf8 "name"; // #15
+ Utf8 "Ljava/lang/Object;"; // #16
+ NameAndType #15 #16; // #17
+ Dynamic 0s #17; // #18
+ Utf8 "m"; // #19
+ Utf8 "()Ljava/lang/Object;"; // #20
+ Utf8 "main"; // #21
+ Utf8 "([Ljava/lang/String;)V"; // #22
+ Utf8 "BootstrapMethods"; // #23
+ Utf8 "CondyCFVCheck"; // #24
+ class #24; // #25
+ } // Constant Pool
+
+ 0x0000; // access
+ #25;// this_cpx
+ #2;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #3; // name_cpx
+ #4; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70006B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #19; // name_cpx
+ #20; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0x1212B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #21; // name_cpx
+ #22; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 0; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0xB1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#23) { // BootstrapMethods
+ [] { // bootstrap_methods
+ { // bootstrap_method
+ #14; // bootstrap_method_ref
+ [] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ }
+ } // end BootstrapMethods
+ } // Attributes
+} // end class CondyCFVCheck
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyCFVCheckTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8186211
+ * @summary CONSTANT_Dynamic_info structure present within an unsupported class file version.
+ * @requires os.arch != "sparcv9"
+ * @compile CondyCFVCheck.jcod
+ * @run main/othervm -Xverify:all CondyCFVCheckTest
+ */
+
+// Test a CONSTANT_Dynamic_info structure present within an unsupported class file version
+// yields a ClassFormatError.
+public class CondyCFVCheckTest {
+ public static void main(String args[]) throws Throwable {
+ try {
+ Class newClass = Class.forName("CondyCFVCheck");
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ } catch (java.lang.ClassFormatError e) {
+ if (!e.getMessage().contains("Class file version does not support constant tag 17 in class file")) {
+ throw new RuntimeException("ClassFormatError thrown, incorrect message");
+ }
+ System.out.println("Test CondyCFVCheckTest passed: " + e.getMessage());
+ } catch (Throwable e) {
+ throw new RuntimeException("Expected ClassFormatError exception not thrown");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyEmptyBSMArray1.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_Dynamic_info structure, but the BootstrapMethods Attribute
+ * contains bootstrap_methods array with 0 elements. ClassFormatError expected.
+ */
+
+/*
+class CondyEmptyBSMArray1 {
+ CondyEmptyBSMArray1() {}
+ public static Object m() {
+ // ldc Dynamic where the CONSTANT_Dynamic_info bootstrap_method_attr_index points to slot #0
+ // in the bootstrap_methods array, however the BootstrapMethods array is empty.
+ // Outcome -> java.lang.ClassFormatError: Short length on BootstrapMethods in class file CondyEmptyBSMArray1
+ return of ldc's Object;
+ public static void main(String[] args) { return; }
+}
+*/
+
+class CondyEmptyBSMArray1 {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "java/lang/Object"; // #1
+ class #1; // #2
+ Utf8 "<init>"; // #3
+ Utf8 "()V"; // #4
+ NameAndType #3 #4; // #5
+ Method #2 #5; // #6
+ Utf8 "Code"; // #7
+ Utf8 "CondyEmptyBSMArray1"; // #8
+ class #8; // #9
+ Utf8 "bsm"; // #10
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #11
+ NameAndType #10 #11; // #12
+ Method #9 #12; // #13
+ MethodHandle 6b #13; // #14
+ Utf8 "name"; // #15
+ Utf8 "Ljava/lang/Object;"; // #16
+ NameAndType #15 #16; // #17
+ Dynamic 0s #17; // #18
+ Utf8 "m"; // #19
+ Utf8 "()Ljava/lang/Object;"; // #20
+ Utf8 "main"; // #21
+ Utf8 "([Ljava/lang/String;)V"; // #22
+ Utf8 "BootstrapMethods"; // #23
+ Utf8 "CondyEmptyBSMArray1"; // #24
+ class #24; // #25
+ } // Constant Pool
+
+ 0x0000; // access
+ #25;// this_cpx
+ #2;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #3; // name_cpx
+ #4; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70006B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #19; // name_cpx
+ #20; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0x1212B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #21; // name_cpx
+ #22; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 0; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0xB1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#23) { // BootstrapMethods
+ [0] { // bootstrap_methods
+ }
+ } // end BootstrapMethods
+ } // Attributes
+} // end class CondyEmptyBSMArray1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyLDCTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8186211
+ * @summary Tests various ldc, ldc_w, ldc2_w instructions of CONSTANT_Dynamic.
+ * @requires os.arch != "sparcv9"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @compile CondyUseLDC_W.jasm
+ * @compile CondyBadLDC2_W.jasm
+ * @compile CondyBadLDC.jasm
+ * @run main/othervm -Xverify:all CondyLDCTest
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class CondyLDCTest {
+ public static void main(String args[]) throws Throwable {
+ // 1. Test a ldc_w instruction can be used with condy's which generate
+ // loadable constants of the following types: byte, char, short, float, integer, boolean.
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("CondyUseLDC_W");
+ OutputAnalyzer oa = new OutputAnalyzer(pb.start());
+ oa.shouldNotContain("VerifyError");
+ oa.shouldHaveExitValue(0);
+
+ // 2. Test ldc2_w of a condy which returns a dynamically generated
+ // float constant, generates a VerifyError.
+ pb = ProcessTools.createJavaProcessBuilder("CondyBadLDC2_W");
+ oa = new OutputAnalyzer(pb.start());
+ oa.shouldContain("java.lang.VerifyError: Illegal type at constant pool entry");
+ oa.shouldContain("CondyBadLDC2_W.F()F @0: ldc2_w");
+ oa.shouldHaveExitValue(1);
+
+ // 3. Test a ldc of a condy which returns a dynamically generated
+ // double constant, generates a VerifyError.
+ pb = ProcessTools.createJavaProcessBuilder("CondyBadLDC");
+ oa = new OutputAnalyzer(pb.start());
+ oa.shouldContain("java.lang.VerifyError: Illegal type at constant pool entry");
+ oa.shouldContain("CondyBadLDC.D()D @0: ldc");
+ oa.shouldHaveExitValue(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecial.jasm Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+super public class CondyNewInvokeSpecial
+ version 55:0
+{
+
+public Method "<init>":"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)V"
+ stack 3 locals 4
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
+ ldc String "In CondyNewInvokeSpecial <init> method";
+ invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
+ return;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+ stack 3 locals 1
+{
+ new class CondyNewInvokeSpecial;
+ dup;
+ ldc Dynamic REF_newInvokeSpecial:CondyNewInvokeSpecial."<init>":"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)V":CondyNewInvokeSpecial:"Ljava/lang/Object;";
+ return;
+}
+
+} // end Class CondyNewInvokeSpecial
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyNewInvokeSpecialTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8186211
+ * @summary Test CONSTANT_Dynamic where the BSM is invoked via a REF_newInvokeSpecial.
+ * @requires os.arch != "sparcv9"
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @compile CondyNewInvokeSpecial.jasm
+ * @run main/othervm -Xverify:all CondyNewInvokeSpecialTest
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class CondyNewInvokeSpecialTest {
+ public static void main(String args[]) throws Throwable {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("CondyNewInvokeSpecial");
+ OutputAnalyzer oa = new OutputAnalyzer(pb.start());
+ oa.shouldContain("In CondyNewInvokeSpecial <init> method");
+ oa.shouldHaveExitValue(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyNoBSMArray.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_Dynamic_info structure but the class file contains
+ * no BootstrapMethods Attribute array. ClassFormatError expected.
+ */
+
+/*
+class CondyNoBSMArray {
+ CondyNoBSMArray() {}
+ public static Object m() {
+ // ldc Dynamic where the CONSTANT_Dynamic_info bootstrap_method_attr_index points to slot #0
+ // in the bootstrap_methods array, however the BootstrapMethods array is non-existent.
+ // Outcome -> java.lang.ClassFormatError: Missing BootstrapMethods attribute in class file CondyNoBSMArray
+ return of ldc's Object;
+ public static void main(String[] args) { return; }
+}
+*/
+
+class CondyNoBSMArray {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "java/lang/Object"; // #1
+ class #1; // #2
+ Utf8 "<init>"; // #3
+ Utf8 "()V"; // #4
+ NameAndType #3 #4; // #5
+ Method #2 #5; // #6
+ Utf8 "Code"; // #7
+ Utf8 "CondyNoBSMArray"; // #8
+ class #8; // #9
+ Utf8 "bsm"; // #10
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #11
+ NameAndType #10 #11; // #12
+ Method #9 #12; // #13
+ MethodHandle 6b #13; // #14
+ Utf8 "name"; // #15
+ Utf8 "Ljava/lang/Object;"; // #16
+ NameAndType #15 #16; // #17
+ Dynamic 0s #17; // #18
+ Utf8 "m"; // #19
+ Utf8 "()Ljava/lang/Object;"; // #20
+ Utf8 "main"; // #21
+ Utf8 "([Ljava/lang/String;)V"; // #22
+ Utf8 "BootstrapMethods"; // #23
+ Utf8 "CondyNoBSMArray"; // #24
+ class #24; // #25
+ } // Constant Pool
+
+ 0x0000; // access
+ #25;// this_cpx
+ #2;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #3; // name_cpx
+ #4; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70006B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #19; // name_cpx
+ #20; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0x1212B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #21; // name_cpx
+ #22; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 0; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0xB1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ } // Attributes
+} // end class CondyNoBSMArray
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyUseLDC_W.jasm Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains ldc_w instructions of condy's who generate dynamic constants
+ * of the following types: byte, char, short, int, float, boolean.
+ */
+class CondyUseLDC_W
+ version 55:0
+{
+
+public Method "<init>":"()V"
+ stack 1 locals 1
+{
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+}
+
+public static Method intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;"
+ throws java/lang/Throwable
+ stack 4 locals 6
+{
+ aload_1;
+ astore 4;
+ iconst_m1;
+ istore 5;
+ aload 4;
+ invokevirtual Method java/lang/String.hashCode:"()I";
+ lookupswitch{ //11
+ -2001159796: L238;
+ -1538095928: L272;
+ -891985903: L255;
+ 66: L108;
+ 67: L124;
+ 68: L140;
+ 70: L156;
+ 73: L172;
+ 74: L188;
+ 83: L204;
+ 90: L221;
+ default: L286 };
+ L108: stack_frame_type append;
+ locals_map class java/lang/String, int;
+ aload 4;
+ ldc String "B";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_0;
+ istore 5;
+ goto L286;
+ L124: stack_frame_type same;
+ aload 4;
+ ldc String "C";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_1;
+ istore 5;
+ goto L286;
+ L140: stack_frame_type same;
+ aload 4;
+ ldc String "D";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_2;
+ istore 5;
+ goto L286;
+ L156: stack_frame_type same;
+ aload 4;
+ ldc String "F";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_3;
+ istore 5;
+ goto L286;
+ L172: stack_frame_type same;
+ aload 4;
+ ldc String "I";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_4;
+ istore 5;
+ goto L286;
+ L188: stack_frame_type same;
+ aload 4;
+ ldc String "J";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ iconst_5;
+ istore 5;
+ goto L286;
+ L204: stack_frame_type same;
+ aload 4;
+ ldc String "S";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 6;
+ istore 5;
+ goto L286;
+ L221: stack_frame_type same;
+ aload 4;
+ ldc String "Z";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 7;
+ istore 5;
+ goto L286;
+ L238: stack_frame_type same;
+ aload 4;
+ ldc String "nullRef";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 8;
+ istore 5;
+ goto L286;
+ L255: stack_frame_type same;
+ aload 4;
+ ldc String "string";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 9;
+ istore 5;
+ goto L286;
+ L272: stack_frame_type same;
+ aload 4;
+ ldc String "stringArray";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifeq L286;
+ bipush 10;
+ istore 5;
+ L286: stack_frame_type same;
+ iload 5;
+ tableswitch{ //0 to 10
+ 0: L348;
+ 1: L354;
+ 2: L360;
+ 3: L366;
+ 4: L372;
+ 5: L377;
+ 6: L383;
+ 7: L389;
+ 8: L402;
+ 9: L404;
+ 10: L407;
+ default: L422 };
+ L348: stack_frame_type same;
+ iload_3;
+ i2b;
+ invokestatic Method java/lang/Byte.valueOf:"(B)Ljava/lang/Byte;";
+ areturn;
+ L354: stack_frame_type same;
+ iload_3;
+ i2c;
+ invokestatic Method java/lang/Character.valueOf:"(C)Ljava/lang/Character;";
+ areturn;
+ L360: stack_frame_type same;
+ iload_3;
+ i2d;
+ invokestatic Method java/lang/Double.valueOf:"(D)Ljava/lang/Double;";
+ areturn;
+ L366: stack_frame_type same;
+ iload_3;
+ i2f;
+ invokestatic Method java/lang/Float.valueOf:"(F)Ljava/lang/Float;";
+ areturn;
+ L372: stack_frame_type same;
+ iload_3;
+ invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/Integer;";
+ areturn;
+ L377: stack_frame_type same;
+ iload_3;
+ i2l;
+ invokestatic Method java/lang/Long.valueOf:"(J)Ljava/lang/Long;";
+ areturn;
+ L383: stack_frame_type same;
+ iload_3;
+ i2s;
+ invokestatic Method java/lang/Short.valueOf:"(S)Ljava/lang/Short;";
+ areturn;
+ L389: stack_frame_type same;
+ iload_3;
+ ifle L397;
+ iconst_1;
+ goto L398;
+ L397: stack_frame_type same;
+ iconst_0;
+ L398: stack_frame_type stack1;
+ stack_map int;
+ invokestatic Method java/lang/Boolean.valueOf:"(Z)Ljava/lang/Boolean;";
+ areturn;
+ L402: stack_frame_type same;
+ aconst_null;
+ areturn;
+ L404: stack_frame_type same;
+ ldc String "string";
+ areturn;
+ L407: stack_frame_type same;
+ iconst_2;
+ anewarray class java/lang/String;
+ dup;
+ iconst_0;
+ ldc String "string";
+ aastore;
+ dup;
+ iconst_1;
+ ldc String "string";
+ aastore;
+ areturn;
+ L422: stack_frame_type same;
+ new class java/lang/BootstrapMethodError;
+ dup;
+ ldc String "Failure to generate a dynamic constant";
+ invokespecial Method java/lang/BootstrapMethodError."<init>":"(Ljava/lang/String;)V";
+ athrow;
+}
+
+public static Method B:"()B"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":B:"B" int 127;
+ ireturn;
+}
+
+public static Method C:"()C"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":C:"C" int 65535;
+ ireturn;
+}
+
+public static Method F:"()F"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":F:"F" int 2147483647;
+ freturn;
+}
+
+public static Method F_AsType:"()F"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":I:"F" int 2147483647;
+ freturn;
+}
+
+public static Method I:"()I"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":I:"I" int 2147483647;
+ ireturn;
+}
+
+public static Method S:"()S"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":S:"S" int 32767;
+ ireturn;
+}
+
+public static Method Z_F:"()Z"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":Z:"Z" int 0;
+ ireturn;
+}
+
+public static Method Z_T:"()Z"
+ stack 1 locals 0
+{
+ ldc_w Dynamic REF_invokeStatic:CondyUseLDC_W.intConversion:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;I)Ljava/lang/Object;":Z:"Z" int 1;
+ ireturn;
+}
+
+public static Method main:"([Ljava/lang/String;)V"
+ stack 8 locals 1
+{
+ invokestatic Method B:"()B";
+ invokestatic Method C:"()C";
+ invokestatic Method S:"()S";
+ invokestatic Method F:"()F";
+ invokestatic Method F_AsType:"()F";
+ invokestatic Method Z_F:"()Z";
+ invokestatic Method Z_T:"()Z";
+ invokestatic Method I:"()I";
+ return;
+}
+
+} // end Class CondyUseLDC_W
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/CondyUsesIndyBSM.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_Dynamic_info structure whose bootstrap_method_attr_index
+ * points to a BSM for an invokedynamic. Both the condy & indy point at element 0 in the
+ * bootstrap methods array. BootstrapMethodError expected.
+ */
+
+/*
+class CondyUsesIndyBSM {
+ CondyUsesIndyBSM() { }
+ public static Object Condybsm(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.Class) {
+ System.out.println("In Condybsm");
+ return String(0);
+ }
+ public static int foo() {
+ System.out.println("In Indybsm target CallSite method foo");
+ return 100;
+ }
+ public static MethodHandle MH_foo() {
+ // Constructs a MethodHandle for foo
+ Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(int.class);
+ return lookup.findStatic(CondyUsesIndyBSM.class, "foo", mt);
+ }
+ public static CallSite Indybsm(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.invoke.MethodType) {
+ return new CallSite(CondyUsesIndyBSM.MH_foo());
+ }
+ public static Object m() {
+ // invokedynamic where the BSM = slot #0 in the BootstrapMethods array is CondyUsesIndyBSM.Indybsm() -> succeeds
+ // ldc_w dynamic where the BSM = slot #0 in the BootstrapMethods array is CondyUsesIndyBSM.Indybsm() -> receives a BootstrapMethodError
+ return of ldc's Object;
+ }
+ public static void main(String[] args) {
+ CondyUsesIndyBSM.m();
+ return;
+ }
+
+BootstrapMethods:
+ 0: #70 REF_invokeStatic CondyUsesIndyBSM.Indybsm:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ 1: #75 REF_invokeStatic CondyUsesIndyBSM.Condybsm:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+ Method arguments:
+}
+*/
+
+class CondyUsesIndyBSM {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Utf8 "java/lang/Object"; // #1
+ class #1; // #2
+ Utf8 "<init>"; // #3
+ Utf8 "()V"; // #4
+ NameAndType #3 #4; // #5
+ Method #2 #5; // #6
+ Utf8 "Code"; // #7
+ Utf8 "java/lang/System"; // #8
+ class #8; // #9
+ Utf8 "out"; // #10
+ Utf8 "Ljava/io/PrintStream;"; // #11
+ NameAndType #10 #11; // #12
+ Field #9 #12; // #13
+ Utf8 "In Condybsm"; // #14
+ String #14; // #15
+ Utf8 "java/io/PrintStream"; // #16
+ class #16; // #17
+ Utf8 "println"; // #18
+ Utf8 "(Ljava/lang/String;)V"; // #19
+ NameAndType #18 #19; // #20
+ Method #17 #20; // #21
+ Utf8 "0"; // #22
+ String #22; // #23
+ Utf8 "Condybsm"; // #24
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #25
+ Utf8 "In Indybsm target CallSite method foo"; // #26
+ String #26; // #27
+ Utf8 "foo"; // #28
+ Utf8 "()I"; // #29
+ Utf8 "java/lang/invoke/MethodHandles"; // #30
+ class #30; // #31
+ Utf8 "lookup"; // #32
+ Utf8 "()Ljava/lang/invoke/MethodHandles$Lookup;"; // #33
+ NameAndType #32 #33; // #34
+ Method #31 #34; // #35
+ Utf8 "CondyUsesIndyBSM"; // #36
+ class #36; // #37
+ String #28; // #38
+ Utf8 "java/lang/Integer"; // #39
+ class #39; // #40
+ Utf8 "TYPE"; // #41
+ Utf8 "Ljava/lang/Class;"; // #42
+ NameAndType #41 #42; // #43
+ Field #40 #43; // #44
+ Utf8 "java/lang/invoke/MethodType"; // #45
+ class #45; // #46
+ Utf8 "methodType"; // #47
+ Utf8 "(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;"; // #48
+ NameAndType #47 #48; // #49
+ Method #46 #49; // #50
+ Utf8 "java/lang/invoke/MethodHandles$Lookup"; // #51
+ class #51; // #52
+ Utf8 "findStatic"; // #53
+ Utf8 "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;"; // #54
+ NameAndType #53 #54; // #55
+ Method #52 #55; // #56
+ Utf8 "MH_foo"; // #57
+ Utf8 "()Ljava/lang/invoke/MethodHandle;"; // #58
+ Utf8 "java/lang/invoke/ConstantCallSite"; // #59
+ class #59; // #60
+ NameAndType #57 #58; // #61
+ Method #37 #61; // #62
+ Utf8 "(Ljava/lang/invoke/MethodHandle;)V"; // #63
+ NameAndType #3 #63; // #64
+ Method #60 #64; // #65
+ Utf8 "Indybsm"; // #66
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; // #67
+ NameAndType #66 #67; // #68
+ Method #37 #68; // #69
+ MethodHandle 6b #69; // #70
+ NameAndType #28 #29; // #71
+ InvokeDynamic 0s #71; // #72
+ NameAndType #24 #25; // #73
+ Method #37 #73; // #74
+ MethodHandle 6b #74; // #75
+ Utf8 "name"; // #76
+ Utf8 "Ljava/lang/Object;"; // #77
+ NameAndType #76 #77; // #78
+ Dynamic 0s #78; // #79
+ Utf8 "m"; // #80
+ Utf8 "()Ljava/lang/Object;"; // #81
+ NameAndType #80 #81; // #82
+ Method #37 #82; // #83
+ Utf8 "main"; // #84
+ Utf8 "([Ljava/lang/String;)V"; // #85
+ Utf8 "BootstrapMethods"; // #86
+ Utf8 "CondyUsesIndyBSM"; // #87
+ class #87; // #88
+ } // Constant Pool
+
+ 0x0000; // access
+ #88;// this_cpx
+ #2;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #3; // name_cpx
+ #4; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70006B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #24; // name_cpx
+ #25; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 2; // max_stack
+ 3; // max_locals
+ Bytes[]{
+ 0xB2000D120FB60015;
+ 0x1217B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #28; // name_cpx
+ #29; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 2; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0xB2000D121BB60015;
+ 0x1064AC;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #57; // name_cpx
+ #58; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 4; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0xB8002312251226B2;
+ 0x002CB80032B60038;
+ 0xB0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #66; // name_cpx
+ #67; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 3; // max_stack
+ 3; // max_locals
+ Bytes[]{
+ 0xBB003C59B8003EB7;
+ 0x0041B0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #80; // name_cpx
+ #81; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 2; // max_stack
+ 0; // max_locals
+ Bytes[]{
+ 0xBA0048000013004F;
+ 0xB0;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #84; // name_cpx
+ #85; // sig_cpx
+ [] { // Attributes
+ Attr(#7) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0xB80053B1;
+ }
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#86) { // BootstrapMethods
+ [] { // bootstrap_methods
+ { // bootstrap_method
+ #70; // bootstrap_method_ref
+ [] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ ;
+ { // bootstrap_method
+ #75; // bootstrap_method_ref
+ [] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ }
+ } // end BootstrapMethods
+ } // Attributes
+} // end class CondyUsesIndyBSM
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/condy/IndyUsesCondyBSM.jcod Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+/*
+ * This test contains a CONSTANT_InvokeDynamic_info structure whose bootstrap_method_attr_index
+ * points to a BSM for an CONSTANT_Dynamic. Both the condy & indy point at element 0 in the
+ * bootstrap methods array. BootstrapMethodError expected.
+ */
+
+/*
+class IndyUsesCondyBSM {
+ IndyUsesCondyBSM() { }
+ public static Object Condybsm(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.Class) {
+ System.out.println("In Condybsm");
+ return String(0);
+ }
+ public static int foo() {
+ System.out.println("In Indybsm target CallSite method foo");
+ return 100;
+ }
+ public static MethodHandle MH_foo() {
+ // Constructs a MethodHandle for foo
+ Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(int.class);
+ return lookup.findStatic(IndyUsesCondyBSM.class, "foo", mt);
+ }
+ public static CallSite Indybsm(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.invoke.MethodType) {
+ return new CallSite(IndyUsesCondyBSM.MH_foo());
+ }
+ public static int m() {
+ // ldc_w dynamic where the BSM = slot #0 in the BootstrapMethods array is IndyUsesCondyBSM.Condybsm() -> succeeds
+ // invokedynamic where the BSM = slot #0 in the BootstrapMethods array is IndyUsesCondyBSM.Condybsm() -> receives a BootstrapMethodError
+ return Callsite.foo();
+ }
+ public static void main(String[] args) {
+ IndyUsesCondyBSM.m();
+ return;
+ }
+
+BootstrapMethods:
+ 0: #65 REF_invokeStatic IndyUsesCondyBSM.Condybsm:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+ Method arguments:
+ 1: #74 REF_invokeStatic IndyUsesCondyBSM.Indybsm:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+}
+*/
+
+class IndyUsesCondyBSM {
+ 0xCAFEBABE;
+ 0; // minor version
+ 55; // version
+ [88] { // Constant Pool
+ ; // first element is empty
+ String #48; // #1 at 0x0A
+ String #49; // #2 at 0x0D
+ String #56; // #3 at 0x10
+ String #58; // #4 at 0x13
+ class #51; // #5 at 0x16
+ Method #62 #20; // #6 at 0x19
+ InvokeDynamic 0s #53; // #7 at 0x1E
+ Method #5 #71; // #8 at 0x23
+ Method #26 #47; // #9 at 0x28
+ Field #21 #86; // #10 at 0x2D
+ Method #28 #75; // #11 at 0x32
+ Field #61 #82; // #12 at 0x37
+ Method #18 #36; // #13 at 0x3C
+ Method #29 #46; // #14 at 0x41
+ Method #57 #87; // #15 at 0x46
+ Method #5 #73; // #16 at 0x4B
+ Dynamic 0s #23; // #17 at 0x50
+ class #80; // #18 at 0x55
+ Utf8 "java/io/PrintStream"; // #19 at 0x58
+ NameAndType #81 #59; // #20 at 0x6E
+ class #85; // #21 at 0x73
+ Utf8 "java/lang/invoke/MethodType"; // #22 at 0x76
+ NameAndType #31 #77; // #23 at 0x94
+ Utf8 "m"; // #24 at 0x99
+ Utf8 "java/lang/invoke/MethodHandles$Lookup"; // #25 at 0x9D
+ class #19; // #26 at 0xC5
+ Utf8 "SourceFile"; // #27 at 0xC8
+ class #22; // #28 at 0xD5
+ class #25; // #29 at 0xD8
+ Utf8 "IndyUsesCondyBSM.jasm"; // #30 at 0xDB
+ Utf8 "name"; // #31 at 0xF3
+ Utf8 "Indybsm"; // #32 at 0xFA
+ Utf8 "findStatic"; // #33 at 0x0104
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"; // #34 at 0x0111
+ Utf8 "()Ljava/lang/invoke/MethodHandles$Lookup;"; // #35 at 0x0172
+ NameAndType #81 #66; // #36 at 0x019E
+ Utf8 "MH_foo"; // #37 at 0x01A3
+ Method #5 #84; // #38 at 0x01AC
+ Utf8 "Code"; // #39 at 0x01B1
+ Utf8 "lookup"; // #40 at 0x01B8
+ Utf8 "([Ljava/lang/String;)V"; // #41 at 0x01C1
+ Utf8 "out"; // #42 at 0x01DA
+ Utf8 "BootstrapMethods"; // #43 at 0x01E0
+ Utf8 "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;"; // #44 at 0x01F3
+ Utf8 "Ljava/lang/Class;"; // #45 at 0x0257
+ NameAndType #33 #44; // #46 at 0x026B
+ NameAndType #52 #63; // #47 at 0x0270
+ Utf8 "0"; // #48 at 0x0275
+ Utf8 "In Condybsm"; // #49 at 0x0279
+ Utf8 "java/lang/invoke/MethodHandles"; // #50 at 0x0287
+ Utf8 "IndyUsesCondyBSM"; // #51 at 0x02A8
+ Utf8 "println"; // #52 at 0x02BB
+ NameAndType #58 #67; // #53 at 0x02C5
+ Utf8 "java/lang/Object"; // #54 at 0x02CA
+ Utf8 "java/lang/System"; // #55 at 0x02DD
+ Utf8 "In Indybsm target CallSite method foo"; // #56 at 0x02F0
+ class #50; // #57 at 0x0318
+ Utf8 "foo"; // #58 at 0x031B
+ Utf8 "()V"; // #59 at 0x0321
+ Utf8 "()Ljava/lang/invoke/MethodHandle;"; // #60 at 0x0327
+ class #55; // #61 at 0x034B
+ class #54; // #62 at 0x034E
+ Utf8 "(Ljava/lang/String;)V"; // #63 at 0x0351
+ Utf8 "main"; // #64 at 0x0369
+ MethodHandle 6b #79; // #65 at 0x0370
+ Utf8 "(Ljava/lang/invoke/MethodHandle;)V"; // #66 at 0x0374
+ Utf8 "()I"; // #67 at 0x0399
+ Utf8 "(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;"; // #68 at 0x039F
+ Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; // #69 at 0x03D2
+ Utf8 "Condybsm"; // #70 at 0x0448
+ NameAndType #37 #60; // #71 at 0x0453
+ NameAndType #70 #34; // #72 at 0x0458
+ NameAndType #24 #67; // #73 at 0x045D
+ MethodHandle 6b #38; // #74 at 0x0462
+ NameAndType #78 #68; // #75 at 0x0466
+ Utf8 "Ljava/io/PrintStream;"; // #76 at 0x046B
+ Utf8 "Ljava/lang/Object;"; // #77 at 0x0483
+ Utf8 "methodType"; // #78 at 0x0498
+ Method #5 #72; // #79 at 0x04A5
+ Utf8 "java/lang/invoke/ConstantCallSite"; // #80 at 0x04AA
+ Utf8 "<init>"; // #81 at 0x04CE
+ NameAndType #42 #76; // #82 at 0x04D7
+ Utf8 "TYPE"; // #83 at 0x04DC
+ NameAndType #32 #69; // #84 at 0x04E3
+ Utf8 "java/lang/Integer"; // #85 at 0x04E8
+ NameAndType #83 #45; // #86 at 0x04FC
+ NameAndType #40 #35; // #87 at 0x0501
+ } // Constant Pool
+
+ 0x0000; // access [ ]
+ #5;// this_cpx
+ #62;// super_cpx
+
+ [0] { // Interfaces
+ } // Interfaces
+
+ [0] { // fields
+ } // fields
+
+ [7] { // methods
+ { // Member at 0x0512
+ 0x0001; // access
+ #81; // name_cpx
+ #59; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 17) { // Code at 0x051A
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[5]{
+ 0x2AB70006B1;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0531
+ 0x0009; // access
+ #70; // name_cpx
+ #34; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 23) { // Code at 0x0539
+ 2; // max_stack
+ 3; // max_locals
+ Bytes[11]{
+ 0xB2000C1202B60009;
+ 0x1201B0;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x0556
+ 0x0009; // access
+ #58; // name_cpx
+ #67; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 23) { // Code at 0x055E
+ 2; // max_stack
+ 0; // max_locals
+ Bytes[11]{
+ 0xB2000C1203B60009;
+ 0x1064AC;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x057B
+ 0x0009; // access
+ #37; // name_cpx
+ #60; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 29) { // Code at 0x0583
+ 4; // max_stack
+ 0; // max_locals
+ Bytes[17]{
+ 0xB8000F12051204B2;
+ 0x000AB8000BB6000E;
+ 0xB0;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x05A6
+ 0x0009; // access
+ #32; // name_cpx
+ #69; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 23) { // Code at 0x05AE
+ 3; // max_stack
+ 3; // max_locals
+ Bytes[11]{
+ 0xBB001259B80008B7;
+ 0x000DB0;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x05CB
+ 0x0009; // access
+ #24; // name_cpx
+ #67; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 21) { // Code at 0x05D3
+ 2; // max_stack
+ 0; // max_locals
+ Bytes[9]{
+ 0x130011BA00070000;
+ 0xAC;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member at 0x05EE
+ 0x0009; // access
+ #64; // name_cpx
+ #41; // sig_cpx
+ [1] { // Attributes
+ Attr(#39, 16) { // Code at 0x05F6
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[4]{
+ 0xB80010B1;
+ }
+ [0] { // Traps
+ } // end Traps
+ [0] { // Attributes
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [2] { // Attributes
+ Attr(#27, 2) { // SourceFile at 0x060E
+ #30;
+ } // end SourceFile
+ ;
+ Attr(#43, 10) { // BootstrapMethods at 0x0616
+ [2] { // bootstrap_methods
+ { // bootstrap_method
+ #65; // bootstrap_method_ref
+ [0] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ ;
+ { // bootstrap_method
+ #74; // bootstrap_method_ref
+ [0] { // bootstrap_arguments
+ } // bootstrap_arguments
+ } // bootstrap_method
+ }
+ } // end BootstrapMethods
+ } // Attributes
+} // end class IndyUsesCondyBSM
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest-s390x Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,7 @@
+FROM s390x/ubuntu
+
+COPY /jdk /jdk
+
+ENV JAVA_HOME=/jdk
+
+CMD ["/bin/bash"]
--- a/test/hotspot/jtreg/runtime/containers/docker/TestCPUSets.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/containers/docker/TestCPUSets.java Mon Feb 26 09:56:12 2018 +0100
@@ -26,6 +26,7 @@
* @test
* @summary Test JVM's awareness of cpu sets (cpus and mems)
* @requires docker.support
+ * @requires (os.arch != "s390x")
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -85,8 +85,7 @@
"frame size:"));
} else {
expStrMap.put(cmdStr, List.of(
- "In interpreter codelet",
- "invoke return entry points"));
+ "In interpreter codelet"));
}
test.run(theApp.getPid(), cmds, expStrMap, null);
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
private Process toolProcess;
- public void ClhsdbLauncher() {
+ public ClhsdbLauncher() {
toolProcess = null;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintAll.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import jdk.test.lib.apps.LingeredApp;
+
+/*
+ * @test
+ * @bug 8175384
+ * @summary Test clhsdb 'printall' command
+ * @library /test/lib
+ * @run main/othervm/timeout=2400 -Xmx1g ClhsdbPrintAll
+ */
+
+public class ClhsdbPrintAll {
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Starting ClhsdbPrintAll test");
+
+ LingeredAppWithEnum theApp = null;
+ try {
+ ClhsdbLauncher test = new ClhsdbLauncher();
+
+ theApp = new LingeredAppWithEnum();
+ LingeredApp.startApp(null, theApp);
+ System.out.println("Started LingeredAppWithEnum with pid " + theApp.getPid());
+
+ List<String> cmds = List.of("printall");
+
+ Map<String, List<String>> expStrMap = new HashMap<>();
+ Map<String, List<String>> unExpStrMap = new HashMap<>();
+ expStrMap.put("printall", List.of(
+ "aload_0",
+ "Constant Pool of",
+ "public static void main(java.lang.String[])",
+ "Bytecode",
+ "[enum] class Song [signature Ljava/lang/Enum<LSong;>;]",
+ "Method java.lang.Object clone()",
+ "public static Song[] values()",
+ "invokevirtual",
+ "checkcast",
+ "Field Song HAVANA",
+ "Exception Table",
+ "invokedynamic"));
+ unExpStrMap.put("printall", List.of(
+ "cannot be cast to"));
+ test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap);
+ } catch (Exception ex) {
+ throw new RuntimeException("Test ERROR " + ex, ex);
+ } finally {
+ LingeredApp.stopApp(theApp);
+ }
+ System.out.println("Test PASSED");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithEnum.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.apps.LingeredApp;
+
+enum Song {
+ HALL_OF_FAME,
+ HAVANA
+};
+
+public class LingeredAppWithEnum extends LingeredApp {
+
+ public static void main(String args[]) {
+ for (Song s : Song.values()) {
+ System.out.println ("song " + s);
+ }
+ LingeredApp.main(args);
+ }
+ }
--- a/test/hotspot/jtreg/testlibrary/jittester/conf/exclude.methods.lst Tue Feb 20 21:46:02 2018 +0100
+++ b/test/hotspot/jtreg/testlibrary/jittester/conf/exclude.methods.lst Mon Feb 26 09:56:12 2018 +0100
@@ -12,7 +12,6 @@
java/lang/String::format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)
java/lang/System::exit(I)
java/lang/System::inheritedChannel()
-java/lang/System::runFinalizersOnExit(Z)
java/util/AbstractSet::toString()
java/util/HashSet::toString()
java/lang/RuntimeException::setStackTrace([Ljava/lang/StackTraceElement;)
--- a/test/jdk/ProblemList.txt Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/ProblemList.txt Mon Feb 26 09:56:12 2018 +0100
@@ -282,6 +282,9 @@
java/lang/String/nativeEncoding/StringPlatformChars.java 8182569 windows-all,solaris-all
+java/lang/invoke/condy/CondyRepeatFailedResolution.java 8197944 windows-all
+java/lang/invoke/condy/CondyReturnPrimitiveTest.java 8197944 windows-all
+
############################################################################
# jdk_instrument
@@ -464,9 +467,8 @@
tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all
-tools/jimage/JImageExtractTest.java 8170120 generic-all
-tools/jimage/JImageListTest.java 8170120 generic-all
-tools/jimage/JImageVerifyTest.java 8170120 generic-all
+tools/jimage/JImageExtractTest.java 8198405 windows-all
+tools/jimage/JImageListTest.java 8198405 windows-all
############################################################################
@@ -482,6 +484,8 @@
com/sun/jdi/sde/SourceDebugExtensionTest.java 8158066 windows-all
+com/sun/jdi/NashornPopFrameTest.java 8187143 generic-all
+
############################################################################
# jdk_time
--- a/test/jdk/com/sun/jdi/AllLineLocations.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/com/sun/jdi/AllLineLocations.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @summary Test ReferenceType.allLineLocations
* @author Gordon Hirsch
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g RefTypes.java
* @run build AllLineLocations
*
@@ -39,26 +39,22 @@
import java.util.List;
-public class AllLineLocations extends JDIScaffold {
- final String[] args;
+public class AllLineLocations extends TestScaffold {
public static void main(String args[]) throws Exception {
new AllLineLocations(args).startTests();
}
AllLineLocations(String args[]) {
- super();
- this.args = args;
+ super(args);
}
protected void runTests() throws Exception {
- connect(args);
- waitForVMStart();
/*
* Get to a point where the classes are loaded.
*/
- BreakpointEvent bp = resumeTo("RefTypes", "loadClasses", "()V");
+ BreakpointEvent bp = startTo("RefTypes", "loadClasses", "()V");
stepOut(bp.thread());
/*
@@ -220,6 +216,6 @@
System.out.println("AbstractAndNative: passed");
// Allow application to complete
- resumeToVMDeath();
+ resumeToVMDisconnect();
}
}
--- a/test/jdk/com/sun/jdi/ClassesByName.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/com/sun/jdi/ClassesByName.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
* loaded class list can be found with classesByName..
* @author Robert Field
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g HelloWorld.java
* @run build ClassesByName
*
@@ -41,21 +41,18 @@
import java.util.List;
import java.util.Iterator;
-public class ClassesByName extends JDIScaffold {
- final String[] args;
+public class ClassesByName extends TestScaffold {
public static void main(String args[]) throws Exception {
new ClassesByName(args).startTests();
}
ClassesByName(String args[]) throws Exception {
- super();
- this.args = args;
+ super(args);
}
protected void runTests() throws Exception {
- connect(args);
- waitForVMStart();
+ startUp("ClassesByName");
List all = vm().allClasses();
for (Iterator it = all.iterator(); it.hasNext(); ) {
@@ -71,6 +68,6 @@
}
// Allow application to complete
- resumeToVMDeath();
+ resumeToVMDisconnect();
}
}
--- a/test/jdk/com/sun/jdi/FilterMatch.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/com/sun/jdi/FilterMatch.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @summary addClassFilter("Foo") acts like "Foo*"
* @author Robert Field/Jim Holmlund
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g HelloWorld.java
* @run driver FilterMatch
*/
@@ -46,105 +46,95 @@
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
-public class FilterMatch extends JDIScaffold {
+public class FilterMatch extends TestScaffold {
- static boolean listenCalled;
+ EventSet eventSet = null;
+ boolean stepCompleted = false;
public static void main(String args[]) throws Exception {
- new FilterMatch().startTests();
- }
-
- public FilterMatch() {
- super();
+ new FilterMatch(args).startTests();
}
- private void listen() {
- TargetAdapter adapter = new TargetAdapter() {
- EventSet set = null;
-
- public boolean eventSetReceived(EventSet set) {
- this.set = set;
- return false;
- }
-
- // This gets called if all filters match.
- public boolean stepCompleted(StepEvent event) {
- listenCalled = true;
- System.out.println("listen: line#=" + event.location().lineNumber()
- + " event=" + event);
- // disable the step and then run to completion
- StepRequest str= (StepRequest)event.request();
- str.disable();
- set.resume();
- return false;
- }
- };
- listenCalled = false;
- addListener(adapter);
+ public FilterMatch(String args[]) {
+ super(args);
}
protected void runTests() throws Exception {
- String[] args = new String[2];
- args[0] = "-connect";
- args[1] = "com.sun.jdi.CommandLineLaunch:main=HelloWorld";
+ /*
+ * Get to the top of HelloWorld main() to determine referenceType and mainThread
+ */
+ BreakpointEvent bpe = startToMain("HelloWorld");
+ ReferenceType referenceType = (ClassType)bpe.location().declaringType();
+ mainThread = bpe.thread();
+ EventRequestManager requestManager = vm().eventRequestManager();
- connect(args);
- waitForVMStart();
-
- // VM has started, but hasn't started running the test program yet.
- EventRequestManager requestManager = vm().eventRequestManager();
- ReferenceType referenceType = resumeToPrepareOf("HelloWorld").referenceType();
+ Location loc = findLocation(referenceType, 3);
+ BreakpointRequest bpRequest = requestManager.createBreakpointRequest(loc);
- // The debuggee is stopped
- // I don't think we really have to set a bkpt and then do a step,
- // we should just be able to do a step. Problem is the
- // createStepRequest call needs a thread and I don't know
- // yet where to get one other than from the bkpt handling :-(
- Location location = findLocation(referenceType, 3);
- BreakpointRequest request
- = requestManager.createBreakpointRequest(location);
+ try {
+ addListener(this);
+ } catch (Exception ex){
+ ex.printStackTrace();
+ failure("failure: Could not add listener");
+ throw new Exception("FilterMatch: failed");
+ }
- request.enable();
+ bpRequest.enable();
- // This does a resume, so we shouldn't come back to it until
- // the debuggee has run and hit the bkpt.
- BreakpointEvent event = (BreakpointEvent)waitForRequestedEvent(request);
-
- // The bkpt was hit; remove it.
- requestManager.deleteEventRequest(request); // remove BP
-
- StepRequest request1 = requestManager.createStepRequest(event.thread(),
+ StepRequest stepRequest = requestManager.createStepRequest(mainThread,
StepRequest.STEP_LINE,StepRequest.STEP_OVER);
// These patterns all match HelloWorld. Since they all match, our
// listener should get called and the test will pass. If any of them
// are erroneously determined to _not_ match, then our listener will
// not get called and the test will fail.
- request1.addClassFilter("*");
+ stepRequest.addClassFilter("*");
- request1.addClassFilter("H*");
- request1.addClassFilter("He*");
- request1.addClassFilter("HelloWorld*");
+ stepRequest.addClassFilter("H*");
+ stepRequest.addClassFilter("He*");
+ stepRequest.addClassFilter("HelloWorld*");
- request1.addClassFilter("*d");
- request1.addClassFilter("*ld");
- request1.addClassFilter("*HelloWorld");
+ stepRequest.addClassFilter("*d");
+ stepRequest.addClassFilter("*ld");
+ stepRequest.addClassFilter("*HelloWorld");
- request1.addClassFilter("HelloWorld");
+ stepRequest.addClassFilter("HelloWorld");
// As a test, uncomment this line and the test should fail.
- //request1.addClassFilter("x");
+ //stepRequest.addClassFilter("x");
- request1.enable();
- listen();
+ stepRequest.enable();
vm().resume();
- waitForVMDeath();
+ waitForVMDisconnect();
- if ( !listenCalled){
+ if (!stepCompleted) {
throw new Exception( "Failed: Event filtered out.");
}
System.out.println( "Passed: Event not filtered out.");
}
+
+ // **************** event handlers **************
+
+ public void eventSetReceived(EventSet set) {
+ this.eventSet = set;
+ }
+
+ // This gets called if all filters match.
+ public void stepCompleted(StepEvent event) {
+ stepCompleted = true;
+ System.out.println("StepEvent at" + event.location());
+ // disable the step and then run to completion
+ StepRequest str = (StepRequest)event.request();
+ str.disable();
+ eventSet.resume();
+ }
+
+ public void breakpointReached(BreakpointEvent event) {
+ System.out.println("BreakpointEvent at" + event.location());
+ BreakpointRequest bpr = (BreakpointRequest)event.request();
+ // The bkpt was hit; disable it.
+ bpr.disable();
+ }
}
--- a/test/jdk/com/sun/jdi/FilterNoMatch.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/com/sun/jdi/FilterNoMatch.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
* @summary addClassFilter("Foo") acts like "Foo*"
* @author Robert Field/Jim Holmlund
*
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
* @run compile -g HelloWorld.java
* @run driver FilterNoMatch
*/
@@ -44,119 +44,108 @@
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
-public class FilterNoMatch extends JDIScaffold {
+public class FilterNoMatch extends TestScaffold {
- static boolean listenCalled;
+ EventSet eventSet = null;
+ boolean stepCompleted = false;
public static void main(String args[]) throws Exception {
- new FilterNoMatch().startTests();
- }
-
- public FilterNoMatch() {
- super();
+ new FilterNoMatch(args).startTests();
}
- private void listen() {
- TargetAdapter adapter = new TargetAdapter() {
- EventSet set = null;
-
- public boolean eventSetReceived(EventSet set) {
- this.set = set;
- return false;
- }
-
- // This gets called if no patterns match. If any
- // pattern is erroneously matched, then this method
- // will not get called.
- public boolean stepCompleted(StepEvent event) {
- listenCalled = true;
- System.out.println("listen: line#=" + event.location().lineNumber()
- + " event=" + event);
- // disable the step and then run to completion
- StepRequest str= (StepRequest)event.request();
- str.disable();
- set.resume();
- return false;
- }
- };
- listenCalled = false;
- addListener(adapter);
+ public FilterNoMatch(String args[]) {
+ super(args);
}
protected void runTests() throws Exception {
- String[] args = new String[2];
- args[0] = "-connect";
- args[1] = "com.sun.jdi.CommandLineLaunch:main=HelloWorld";
-
- connect(args);
- waitForVMStart();
-
+ /*
+ * Get to the top of HelloWorld main() to determine referenceType and mainThread
+ */
+ BreakpointEvent bpe = startToMain("HelloWorld");
+ ReferenceType referenceType = (ClassType)bpe.location().declaringType();
+ mainThread = bpe.thread();
// VM has started, but hasn't started running the test program yet.
EventRequestManager requestManager = vm().eventRequestManager();
- ReferenceType referenceType = resumeToPrepareOf("HelloWorld").referenceType();
- // The debuggee is stopped
- // I don't think we really have to set a bkpt and then do a step,
- // we should just be able to do a step. Problem is the
- // createStepRequest call needs a thread and I don't know
- // yet where to get one other than from the bkpt handling :-(
Location location = findLocation(referenceType, 3);
- BreakpointRequest request
- = requestManager.createBreakpointRequest(location);
+ BreakpointRequest bpRequest = requestManager.createBreakpointRequest(location);
- request.enable();
-
- // This does a resume, so we shouldn't come back to it until
- // the debuggee has run and hit the bkpt.
- BreakpointEvent event = (BreakpointEvent)waitForRequestedEvent(request);
+ try {
+ addListener(this);
+ } catch (Exception ex){
+ ex.printStackTrace();
+ failure("failure: Could not add listener");
+ throw new Exception("FilterNoMatch: failed");
+ }
- // The bkpt was hit; remove it.
- requestManager.deleteEventRequest(request);
+ bpRequest.enable();
- StepRequest request1 = requestManager.createStepRequest(event.thread(),
+ StepRequest stepRequest = requestManager.createStepRequest(mainThread,
StepRequest.STEP_LINE,StepRequest.STEP_OVER);
-
// We have to filter out all these so that they don't cause the
// listener to be called.
- request1.addClassExclusionFilter("java.*");
- request1.addClassExclusionFilter("javax.*");
- request1.addClassExclusionFilter("sun.*");
- request1.addClassExclusionFilter("com.sun.*");
- request1.addClassExclusionFilter("com.oracle.*");
- request1.addClassExclusionFilter("oracle.*");
- request1.addClassExclusionFilter("jdk.internal.*");
+ stepRequest.addClassExclusionFilter("java.*");
+ stepRequest.addClassExclusionFilter("javax.*");
+ stepRequest.addClassExclusionFilter("sun.*");
+ stepRequest.addClassExclusionFilter("com.sun.*");
+ stepRequest.addClassExclusionFilter("com.oracle.*");
+ stepRequest.addClassExclusionFilter("oracle.*");
+ stepRequest.addClassExclusionFilter("jdk.internal.*");
// We want our listener to be called if a pattern does not match.
// So, here we want patterns that do not match HelloWorld.
// If any pattern here erroneously matches, then our listener
// will not get called and the test will fail.
- request1.addClassExclusionFilter("H");
- request1.addClassExclusionFilter("HelloWorl");
- request1.addClassExclusionFilter("HelloWorldx");
- request1.addClassExclusionFilter("xHelloWorld");
+ stepRequest.addClassExclusionFilter("H");
+ stepRequest.addClassExclusionFilter("HelloWorl");
+ stepRequest.addClassExclusionFilter("HelloWorldx");
+ stepRequest.addClassExclusionFilter("xHelloWorld");
- request1.addClassExclusionFilter("*elloWorldx");
- request1.addClassExclusionFilter("*elloWorl");
- request1.addClassExclusionFilter("*xHelloWorld");
- request1.addClassExclusionFilter("elloWorld*");
- request1.addClassExclusionFilter("HelloWorldx*");
- request1.addClassExclusionFilter("xHelloWorld*");
+ stepRequest.addClassExclusionFilter("*elloWorldx");
+ stepRequest.addClassExclusionFilter("*elloWorl");
+ stepRequest.addClassExclusionFilter("*xHelloWorld");
+ stepRequest.addClassExclusionFilter("elloWorld*");
+ stepRequest.addClassExclusionFilter("HelloWorldx*");
+ stepRequest.addClassExclusionFilter("xHelloWorld*");
// As a test, uncomment this line and this test should fail.
- //request1.addClassExclusionFilter("*elloWorld");
-
+ //stepRequest.addClassExclusionFilter("*elloWorld");
- request1.enable();
- listen();
+ stepRequest.enable();
vm().resume();
- waitForVMDeath();
+ waitForVMDisconnect();
- if ( !listenCalled){
+ if (!stepCompleted) {
throw new Exception( "Failed: .");
}
System.out.println( "Passed: ");
}
+
+ // **************** event handlers **************
+
+ public void eventSetReceived(EventSet set) {
+ this.eventSet = set;
+ }
+
+ // This gets called if no patterns match. If any
+ // pattern is erroneously matched, then this method
+ // will not get called.
+ public void stepCompleted(StepEvent event) {
+ stepCompleted = true;
+ System.out.println("StepEvent at" + event.location());
+ // disable the step and then run to completion
+ StepRequest str = (StepRequest)event.request();
+ str.disable();
+ eventSet.resume();
+ }
+
+ public void breakpointReached(BreakpointEvent event) {
+ System.out.println("BreakpointEvent at" + event.location());
+ BreakpointRequest bpr = (BreakpointRequest)event.request();
+ // The bkpt was hit; disable it.
+ bpr.disable();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/NashornPopFrameTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8187143
+ * @summary JDI crash in ~BufferBlob::MethodHandles adapters
+ *
+ * @run build TestScaffold VMConnection TargetListener TargetAdapter
+ * @run compile -g NashornPopFrameTest.java
+ * @run driver NashornPopFrameTest
+ */
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import javax.script.*;
+
+import java.io.PrintStream;
+
+
+// The debuggee, creates and uses a Nashorn engine to evaluate a simple script.
+
+// The debugger tries to set a breakpoint in Nashorn internal DEBUGGER method.
+// When the breakpoint is reached, it looks for stack frame whose method's
+// declaring type name starts with jdk.nashorn.internal.scripts.Script$.
+// (nashorn dynamically generated classes)
+// It then pops stack frames using the ThreadReference.popFrames() call, up to
+// and including the above stackframe.
+// The execution of the debuggee application is resumed after the needed
+// frames have been popped.
+
+class ScriptDebuggee {
+ public final static int BKPT_LINE = 74;
+ static ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
+ static public String failReason = null;
+
+ static void doit() throws Exception {
+ System.out.println("Debugee: started!");
+ String script =
+ "function f() {\r\n" +
+ " debugger;\r\n" +
+ " debugger;\r\n" +
+ "}\r\n" +
+ "f();";
+ try {
+ engine.eval(script);
+ } catch (Exception ex) {
+ failReason = "ScriptDebuggee failed: Exception in engine.eval(): "
+ + ex.toString();
+ ex.printStackTrace();
+ }
+ System.out.println("Debugee: finished!"); // BKPT_LINE
+ }
+
+ public static void main(String[] args) throws Exception {
+ doit();
+ }
+}
+
+/********** test program **********/
+
+public class NashornPopFrameTest extends TestScaffold {
+ static PrintStream out = System.out;
+ static boolean breakpointReached = false;
+ String debuggeeFailReason = null;
+ ClassType targetClass;
+ ThreadReference mainThread;
+ BreakpointRequest bkptRequest;
+
+ NashornPopFrameTest(String args[]) {
+ super(args);
+ }
+
+ public static void main(String[] args) throws Exception {
+ NashornPopFrameTest nashornPopFrameTest = new NashornPopFrameTest(args);
+ nashornPopFrameTest.startTests();
+ }
+
+ /********** test core **********/
+
+ protected void runTests() throws Exception {
+ /*
+ * Get to the top of main() to determine targetClass and mainThread
+ */
+ BreakpointEvent bpe = startToMain("ScriptDebuggee");
+ targetClass = (ClassType)bpe.location().declaringType();
+ out.println("Agent: runTests: after startToMain()");
+
+ mainThread = bpe.thread();
+ EventRequestManager erm = vm().eventRequestManager();
+
+ Location loc = findLocation(targetClass, ScriptDebuggee.BKPT_LINE);
+
+ try {
+ addListener(this);
+ } catch (Exception ex){
+ ex.printStackTrace();
+ failure("Failed: Could not add listener");
+ throw new Exception("NashornPopFrameTest: failed with Exception in AddListener");
+ }
+
+ pauseAtDebugger(vm());
+ bkptRequest = erm.createBreakpointRequest(loc);
+ bkptRequest.enable();
+
+ vm().resume();
+
+ try {
+ listen(vm());
+ } catch (Exception exp) {
+ exp.printStackTrace();
+ failure("Failed: Caught Exception while Listening");
+ throw new Exception("NashornPopFrameTest: failed with Exception in listen()");
+ }
+
+ // Debugger continues to run until it receives a VMdisconnect event either because
+ // the Debuggee crashed / got exception / finished successfully.
+ while (!vmDisconnected) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ee) {
+ }
+ }
+
+ removeListener(this);
+
+ if (breakpointReached) {
+ if (debuggeeFailReason != null) {
+ failure(debuggeeFailReason);
+ }
+ } else {
+ failure("Expected breakpoint in ScriptDebuggee:" +
+ ScriptDebuggee.BKPT_LINE + " was not reached");
+ }
+ if (testFailed) {
+ throw new Exception("NashornPopFrameTest: failed");
+ }
+ out.println("NashornPopFrameTest: passed");
+ }
+
+ private static void pauseAtDebugger(VirtualMachine vm) throws AbsentInformationException {
+ for (ReferenceType t : vm.allClasses()) pauseAtDebugger(t);
+ }
+
+ // Set a breakpoint in Nashorn internal DEBUGGER method.
+ private static void pauseAtDebugger(ReferenceType t) throws AbsentInformationException {
+ if (!t.name().endsWith(".ScriptRuntime")) {
+ return;
+ }
+ for (Location l : t.allLineLocations()) {
+ if (!l.method().name().equals("DEBUGGER")) continue;
+ BreakpointRequest bkptReq = t.virtualMachine().eventRequestManager().createBreakpointRequest(l);
+ out.println("Setting breakpoint for " + l);
+ bkptReq.enable();
+ break;
+ }
+ }
+
+ private static void listen(VirtualMachine vm) throws Exception {
+ EventQueue eventQueue = vm.eventQueue();
+ EventSet es = eventQueue.remove();
+ if (es != null) {
+ handle(es);
+ }
+ }
+
+ // Handle event when breakpoint is reached
+ private static void handle(EventSet eventSet) throws Exception {
+ out.println("Agent handle(): started");
+ for (Event event : eventSet) {
+ if (event instanceof BreakpointEvent) {
+ findFrameAndPop(event);
+ }
+ }
+ eventSet.resume();
+ out.println("Agent handle(): finished");
+ }
+
+ private static void findFrameAndPop(Event event) throws Exception {
+ ThreadReference thread = ((BreakpointEvent) event).thread();
+ out.println("Agent: handling Breakpoint " + " at " +
+ ((BreakpointEvent) event).location() +
+ " in thread: " + thread);
+ StackFrame sf = findScriptFrame(thread);
+ if (sf != null) {
+ out.println("Thread Pop Frame on StackFrame = " + sf);
+ thread.popFrames(sf);
+ }
+ }
+
+ // Find stack frame whose method's declaring type name starts with
+ // jdk.nashorn.internal.scripts.Script$ and return that frame
+ private static StackFrame findScriptFrame(ThreadReference t) throws IncompatibleThreadStateException {
+ for (int i = 0; i < t.frameCount(); i++) {
+ StackFrame sf = t.frame(i);
+ String typeName = sf.location().method().declaringType().name();
+ if (typeName.startsWith("jdk.nashorn.internal.scripts.Script$")) {
+ out.println("Agent: in findScriptFrame: TypeName = " + typeName);
+ return sf;
+ }
+ }
+ throw new RuntimeException("no script frame");
+ }
+
+ static int bkptCount = 0;
+
+ /********** event handlers **********/
+
+ public void breakpointReached(BreakpointEvent event) {
+ ThreadReference thread = ((BreakpointEvent) event).thread();
+ String locStr = "" + ((BreakpointEvent) event).location();
+ out.println("Agent: BreakpointEvent #" + (bkptCount++) +
+ " at " + locStr + " in thread: " + thread);
+ if (locStr.equals("ScriptDebuggee:" + ScriptDebuggee.BKPT_LINE)) {
+ breakpointReached = true;
+ Field failReasonField = targetClass.fieldByName("failReason");
+ Value failReasonVal = targetClass.getValue(failReasonField);
+ if (failReasonVal != null) {
+ debuggeeFailReason = ((StringReference)failReasonVal).value();
+ }
+ bkptRequest.disable();
+ }
+ }
+
+ public void eventSetComplete(EventSet set) {
+ set.resume();
+ }
+
+ public void vmDisconnected(VMDisconnectEvent event) {
+ println("Agent: Got VMDisconnectEvent");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/io/File/UserDirChangedTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8194154
+ @summary Test changing property user.dir on impacting getCanonicalPath
+ @run main/othervm UserDirChangedTest
+ */
+
+import java.io.File;
+
+public class UserDirChangedTest {
+ public static void main(String[] args) throws Exception {
+ String keyUserDir = "user.dir";
+ String userDirNew = "/home/a/b/c/";
+ String fileName = "./a";
+
+ String userDir = System.getProperty(keyUserDir);
+ File file = new File(fileName);
+ String canFilePath = file.getCanonicalPath();
+
+ // now reset user.dir, this will cause crash on linux without bug 8194154 fixed.
+ System.setProperty(keyUserDir, userDirNew);
+ String newCanFilePath = file.getCanonicalPath();
+ System.out.format("%24s %48s%n", "Canonical Path = ", canFilePath);
+ System.out.format("%24s %48s%n", "new Canonical Path = ", newCanFilePath);
+ if (!canFilePath.equals(newCanFilePath)) {
+ throw new RuntimeException("Changing property user.dir should have no effect on getCanonicalPath");
+ }
+ }
+}
--- a/test/jdk/java/io/FileInputStream/UnreferencedFISClosesFd.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/io/FileInputStream/UnreferencedFISClosesFd.java Mon Feb 26 09:56:12 2018 +0100
@@ -41,7 +41,14 @@
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayDeque;
import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.sun.management.UnixOperatingSystemMXBean;
@@ -161,6 +168,7 @@
long fdCount = getFdCount();
System.out.printf("final count of open file descriptors: %d%n", fdCount);
if (fdCount != fdCount0) {
+ listProcFD();
throw new AssertionError("raw fd count wrong: expected: " + fdCount0
+ ", actual: " + fdCount);
}
@@ -266,4 +274,27 @@
}
return 0;
}
+
+ /**
+ * Method to list the open file descriptors (if supported by the 'lsof' command).
+ */
+ static void listProcFD() {
+ List<String> lsofDirs = List.of("/usr/bin", "/usr/sbin");
+ Optional<Path> lsof = lsofDirs.stream()
+ .map(s -> Paths.get(s, "lsof"))
+ .filter(f -> Files.isExecutable(f))
+ .findFirst();
+ lsof.ifPresent(exe -> {
+ try {
+ System.out.printf("Open File Descriptors:%n");
+ long pid = ProcessHandle.current().pid();
+ ProcessBuilder pb = new ProcessBuilder(exe.toString(), "-p", Integer.toString((int) pid));
+ pb.inheritIO();
+ Process p = pb.start();
+ p.waitFor(10, TimeUnit.SECONDS);
+ } catch (IOException | InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ });
+ }
}
--- a/test/jdk/java/lang/Runtime/shutdown/Basic.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/lang/Runtime/shutdown/Basic.java Mon Feb 26 09:56:12 2018 +0100
@@ -49,12 +49,13 @@
static Runtime rt = Runtime.getRuntime();
static PrintStream out = System.out;
+ // Expect that no finalizer is invoked at exit
@DataProvider(name = "testcase")
public Object[][] getTestCase() {
return new Object[][] {
- { "fallThrough", 0, "h1", "f1" },
- { "exit0", 0, "h1", "f1" },
- { "exit0NoHook", 0, "", "f1" },
+ { "fallThrough", 0, "h1", "" },
+ { "exit0", 0, "h1", "" },
+ { "exit0NoHook", 0, "", "" },
{ "exit1", 1, "h1", "" },
{ "exit1NoHook", 1, "", "" },
{ "halt", 0, "", "" },
@@ -112,19 +113,16 @@
public static void fallThrough() throws Exception {
rt.addShutdownHook(new Hook("h1"));
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
}
public static void exit0() throws Exception {
rt.addShutdownHook(new Hook("h1"));
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
rt.exit(0);
}
public static void exit0NoHook() throws Exception {
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
rt.exit(0);
}
@@ -132,13 +130,11 @@
public static void exit1() throws Exception {
rt.addShutdownHook(new Hook("h1"));
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
rt.exit(1);
}
public static void exit1NoHook() throws Exception {
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
rt.exit(1);
}
@@ -146,13 +142,11 @@
rt.addShutdownHook(new Hook("h1") {
public void go() { rt.halt(1); }});
Fin f = new Fin("f1") { public void go() { rt.halt(1); }};
- rt.runFinalizersOnExit(true);
rt.halt(0);
}
public static void haltNoHook() throws Exception {
Fin f = new Fin("f1") { public void go() { rt.halt(1); }};
- rt.runFinalizersOnExit(true);
rt.halt(0);
}
@@ -160,7 +154,6 @@
rt.addShutdownHook(new Hook("h1") {
public void go() { rt.halt(0); }});
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
rt.exit(1);
}
@@ -191,52 +184,9 @@
rt.exit(1);
}
-
- /* The following two methods are provided for manual testing only.
- * Neither test is suitable for being run from within the harness.
- */
-
- public static void awt() throws Exception {
- final Frame f = new Frame();
- final TextArea ta = new TextArea();
- Fin fx = new Fin("f1");
- rt.runFinalizersOnExit(true);
- rt.addShutdownHook(new Hook("h1") {
- public void go() {
- ta.setText("Hooked!");
- out.println("Hooked!");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException x) { }
- ta.append("\nSleep 1");
- out.println("Sleep 1");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException x) { }
- ta.append("\nSleep 2");
- out.println("Sleep 2");
- }});
- f.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- out.println("Closing...");
- ta.setText("Closing...");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException x) { }
- f.dispose();
- rt.exit(42);
- }});
- ta.setText("Terminate me!");
- f.add(ta);
- f.pack();
- f.show();
- Thread.sleep(10000);
- }
-
/* For INT, HUP, TERM */
public static void stall() throws Exception {
Fin f = new Fin("f1");
- rt.runFinalizersOnExit(true);
rt.addShutdownHook(new Hook("h1"));
out.print("Type ^C now: ");
out.flush();
--- a/test/jdk/java/lang/System/ExitFinalizersAndJIT.java Tue Feb 20 21:46:02 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, 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 4119554
- @summary runFinalizersOnExit(true) causes JIT to be unloaded and
- crashes the VM. Interim fix for 1.2 beta4 -- don't unload
- native libraries loaded by system classes.
- @run main/othervm ExitFinalizersAndJIT
-*/
-
-public class ExitFinalizersAndJIT {
- public static void main(String[] args) throws Exception {
- System.runFinalizersOnExit(true);
- }
-}
--- a/test/jdk/java/lang/System/finalization/FinExit.java Tue Feb 20 21:46:02 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 1998, 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 4116016
- @summary Ensure that finalizers are not invoked more than once when on-exit
- finalization is enabled and a finalizer invokes System.exit after
- System.exit has already been invoked
- @build FinExit
- @run shell FinExit.sh
- */
-
-
-public class FinExit {
-
- boolean finalized = false;
-
- public void finalize() {
- if (finalized) {
- System.out.println("2");
- } else {
- finalized = true;
- System.out.println("1");
- System.exit(0);
- }
- }
-
- public static void main(String[] args) throws Exception {
- System.runFinalizersOnExit(true);
- Object o = new FinExit();
- System.exit(0);
- }
-
-}
--- a/test/jdk/java/lang/System/finalization/FinExit.sh Tue Feb 20 21:46:02 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#! /bin/sh
-
-#
-# Copyright (c) 1998, 2010, 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.
-#
-
-#
-
-# We only want the first character, Windows might add CRLF
-x=`$TESTJAVA/bin/java ${TESTVMOPTS} -cp "$TESTCLASSES" FinExit | cut -c1`
-echo $x
-if [ "x$x" != "x1" ]; then
- echo On-exit finalizer invoked twice
- exit 1
-else
- exit 0
-fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/CallerSensitiveAccess.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8196830
+ * @modules java.base/jdk.internal.reflect
+ * @run testng/othervm --illegal-access=deny CallerSensitiveAccess
+ * @summary Check Lookup findVirtual, findStatic and unreflect behavior with
+ * caller sensitive methods with focus on AccessibleObject.setAccessible
+ */
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.InaccessibleObjectException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.internal.reflect.CallerSensitive;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.NoInjection;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class CallerSensitiveAccess {
+
+ /**
+ * Caller sensitive methods in APIs exported by java.base.
+ */
+ @DataProvider(name = "callerSensitiveMethods")
+ static Object[][] callerSensitiveMethods() {
+ return callerSensitiveMethods(Object.class.getModule())
+ .map(m -> new Object[] { m, shortDescription(m) })
+ .toArray(Object[][]::new);
+ }
+
+ /**
+ * Using publicLookup, attempt to use findVirtual or findStatic to obtain a
+ * method handle to a caller sensitive method.
+ */
+ @Test(dataProvider = "callerSensitiveMethods",
+ expectedExceptions = IllegalAccessException.class)
+ public void testPublicLookupFind(@NoInjection Method method, String desc) throws Exception {
+ Lookup lookup = MethodHandles.publicLookup();
+ Class<?> refc = method.getDeclaringClass();
+ String name = method.getName();
+ MethodType mt = MethodType.methodType(method.getReturnType(), method.getParameterTypes());
+ if (Modifier.isStatic(method.getModifiers())) {
+ lookup.findStatic(refc, name, mt);
+ } else {
+ lookup.findVirtual(refc, name, mt);
+ }
+ }
+
+ /**
+ * Using publicLookup, attempt to use unreflect to obtain a method handle to a
+ * caller sensitive method.
+ */
+ @Test(dataProvider = "callerSensitiveMethods",
+ expectedExceptions = IllegalAccessException.class)
+ public void testPublicLookupUnreflect(@NoInjection Method method, String desc) throws Exception {
+ MethodHandles.publicLookup().unreflect(method);
+ }
+
+
+ // -- Test method handles to setAccessible --
+
+ private int aField;
+
+ Field accessibleField() {
+ try {
+ return getClass().getDeclaredField("aField");
+ } catch (NoSuchFieldException e) {
+ fail();
+ return null;
+ }
+ }
+
+ Field inaccessibleField() {
+ try {
+ return String.class.getDeclaredField("hash");
+ } catch (NoSuchFieldException e) {
+ fail();
+ return null;
+ }
+ }
+
+ void findAndInvokeSetAccessible(Class<? extends AccessibleObject> refc, Field f) throws Throwable {
+ MethodType mt = MethodType.methodType(void.class, boolean.class);
+ MethodHandle mh = MethodHandles.lookup().findVirtual(refc, "setAccessible", mt);
+ mh.invoke(f, true); // may throw InaccessibleObjectException
+ assertTrue(f.isAccessible());
+ }
+
+ void unreflectAndInvokeSetAccessible(Method m, Field f) throws Throwable {
+ assertTrue(m.getName().equals("setAccessible"));
+ assertFalse(Modifier.isStatic(m.getModifiers()));
+ MethodHandle mh = MethodHandles.lookup().unreflect(m);
+ mh.invoke(f, true); // may throw InaccessibleObjectException
+ assertTrue(f.isAccessible());
+ }
+
+ /**
+ * Create a method handle to setAccessible and use it to suppress access to an
+ * accessible member.
+ */
+ @Test
+ public void testSetAccessible1() throws Throwable {
+ findAndInvokeSetAccessible(AccessibleObject.class, accessibleField());
+ }
+ @Test
+ public void testSetAccessible2() throws Throwable {
+ findAndInvokeSetAccessible(Field.class, accessibleField());
+ }
+ @Test
+ public void testSetAccessible3() throws Throwable {
+ Method m = AccessibleObject.class.getMethod("setAccessible", boolean.class);
+ unreflectAndInvokeSetAccessible(m, accessibleField());
+ }
+ @Test
+ public void testSetAccessible4() throws Throwable {
+ Method m = Field.class.getMethod("setAccessible", boolean.class);
+ unreflectAndInvokeSetAccessible(m, accessibleField());
+ }
+
+ /**
+ * Create a method handle to setAccessible and attempt to use it to suppress
+ * access to an inaccessible member.
+ */
+ @Test(expectedExceptions = InaccessibleObjectException.class)
+ public void testSetAccessible5() throws Throwable {
+ findAndInvokeSetAccessible(AccessibleObject.class, inaccessibleField());
+ }
+ @Test(expectedExceptions = InaccessibleObjectException.class)
+ public void testSetAccessible6() throws Throwable {
+ findAndInvokeSetAccessible(Field.class, inaccessibleField());
+ }
+ @Test(expectedExceptions = InaccessibleObjectException.class)
+ public void testSetAccessible7() throws Throwable {
+ Method m = AccessibleObject.class.getMethod("setAccessible", boolean.class);
+ unreflectAndInvokeSetAccessible(m, inaccessibleField());
+ }
+ @Test(expectedExceptions = InaccessibleObjectException.class)
+ public void testSetAccessible8() throws Throwable {
+ Method m = Field.class.getMethod("setAccessible", boolean.class);
+ unreflectAndInvokeSetAccessible(m, inaccessibleField());
+ }
+
+
+ // -- Test sub-classes of AccessibleObject --
+
+ /**
+ * Custom AccessibleObject objects. One class overrides setAccessible, the other
+ * does not override this method.
+ */
+ @DataProvider(name = "customAccessibleObjects")
+ static Object[][] customAccessibleObjectClasses() {
+ return new Object[][] { { new S1() }, { new S2() } };
+ }
+ public static class S1 extends AccessibleObject { }
+ public static class S2 extends AccessibleObject {
+ @Override
+ public void setAccessible(boolean flag) {
+ super.setAccessible(flag);
+ }
+ }
+
+ void findAndInvokeSetAccessible(Lookup lookup, AccessibleObject obj) throws Throwable {
+ MethodType mt = MethodType.methodType(void.class, boolean.class);
+ MethodHandle mh = lookup.findVirtual(obj.getClass(), "setAccessible", mt);
+ mh.invoke(obj, true);
+ assertTrue(obj.isAccessible());
+ }
+
+ void unreflectAndInvokeSetAccessible(Lookup lookup, AccessibleObject obj) throws Throwable {
+ Method m = obj.getClass().getMethod("setAccessible", boolean.class);
+ MethodHandle mh = lookup.unreflect(m);
+ mh.invoke(obj, true);
+ assertTrue(obj.isAccessible());
+ }
+
+ /**
+ * Using publicLookup, create a method handle to setAccessible and invoke it
+ * on a custom AccessibleObject object.
+ */
+ @Test(expectedExceptions = IllegalAccessException.class)
+ public void testPublicLookupSubclass1() throws Throwable {
+ // S1 does not override setAccessible
+ findAndInvokeSetAccessible(MethodHandles.publicLookup(), new S1());
+ }
+ @Test
+ public void testPublicLookupSubclass2() throws Throwable {
+ // S2 overrides setAccessible
+ findAndInvokeSetAccessible(MethodHandles.publicLookup(), new S2());
+ }
+ @Test(expectedExceptions = IllegalAccessException.class)
+ public void testPublicLookupSubclass3() throws Throwable {
+ // S1 does not override setAccessible
+ unreflectAndInvokeSetAccessible(MethodHandles.publicLookup(), new S1());
+ }
+ @Test
+ public void testPublicLookupSubclass4() throws Throwable {
+ // S2 overrides setAccessible
+ unreflectAndInvokeSetAccessible(MethodHandles.publicLookup(), new S2());
+ }
+
+ /**
+ * Using a full power lookup, create a method handle to setAccessible and
+ * invoke it on a custom AccessibleObject object.
+ */
+ @Test(dataProvider = "customAccessibleObjects")
+ public void testLookupSubclass1(AccessibleObject obj) throws Throwable {
+ findAndInvokeSetAccessible(MethodHandles.lookup(), obj);
+ }
+ @Test(dataProvider = "customAccessibleObjects")
+ public void testLookupSubclass2(AccessibleObject obj) throws Throwable {
+ unreflectAndInvokeSetAccessible(MethodHandles.lookup(), obj);
+ }
+
+ /**
+ * Using a full power lookup, create a method handle to setAccessible on a
+ * sub-class of AccessibleObject and then attempt to invoke it on a Field object.
+ */
+ @Test(dataProvider = "customAccessibleObjects",
+ expectedExceptions = ClassCastException.class)
+ public void testLookupSubclass3(AccessibleObject obj) throws Throwable {
+ MethodType mt = MethodType.methodType(void.class, boolean.class);
+ Lookup lookup = MethodHandles.lookup();
+ MethodHandle mh = lookup.findVirtual(obj.getClass(), "setAccessible", mt);
+ mh.invoke(accessibleField(), true); // should throw ClassCastException
+ }
+
+ /**
+ * Using a full power lookup, use unreflect to create a method handle to
+ * setAccessible on a sub-class of AccessibleObject, then attempt to invoke
+ * it on a Field object.
+ */
+ @Test
+ public void testLookupSubclass4() throws Throwable {
+ // S1 does not override setAccessible
+ Method m = S1.class.getMethod("setAccessible", boolean.class);
+ assertTrue(m.getDeclaringClass() == AccessibleObject.class);
+ MethodHandle mh = MethodHandles.lookup().unreflect(m);
+ Field f = accessibleField();
+ mh.invoke(f, true);
+ assertTrue(f.isAccessible());
+ }
+ @Test(expectedExceptions = InaccessibleObjectException.class)
+ public void testLookupSubclass5() throws Throwable {
+ // S1 does not override setAccessible
+ Method m = S1.class.getMethod("setAccessible", boolean.class);
+ assertTrue(m.getDeclaringClass() == AccessibleObject.class);
+ MethodHandle mh = MethodHandles.lookup().unreflect(m);
+ mh.invoke(inaccessibleField(), true); // should throw InaccessibleObjectException
+ }
+ @Test(expectedExceptions = ClassCastException.class)
+ public void testLookupSubclass6() throws Throwable {
+ // S2 overrides setAccessible
+ Method m = S2.class.getMethod("setAccessible", boolean.class);
+ assertTrue(m.getDeclaringClass() == S2.class);
+ MethodHandle mh = MethodHandles.lookup().unreflect(m);
+ mh.invoke(accessibleField(), true); // should throw ClassCastException
+ }
+ @Test(expectedExceptions = ClassCastException.class)
+ public void testLookupSubclass7() throws Throwable {
+ // S2 overrides setAccessible
+ Method m = S2.class.getMethod("setAccessible", boolean.class);
+ assertTrue(m.getDeclaringClass() == S2.class);
+ MethodHandle mh = MethodHandles.lookup().unreflect(m);
+ mh.invoke(inaccessibleField(), true); // should throw ClassCastException
+ }
+
+
+ // -- supporting methods --
+
+ /**
+ * Returns a stream of all caller sensitive methods on public classes in packages
+ * exported by a named module.
+ */
+ static Stream<Method> callerSensitiveMethods(Module module) {
+ assert module.isNamed();
+ ModuleReference mref = module.getLayer().configuration()
+ .findModule(module.getName())
+ .orElseThrow(() -> new RuntimeException())
+ .reference();
+ // find all ".class" resources in the module
+ // transform the resource name to a class name
+ // load every class in the exported packages
+ // return the caller sensitive methods of the public classes
+ try (ModuleReader reader = mref.open()) {
+ return reader.list()
+ .filter(rn -> rn.endsWith(".class"))
+ .map(rn -> rn.substring(0, rn.length() - 6)
+ .replace('/', '.'))
+ .filter(cn -> module.isExported(packageName(cn)))
+ .map(cn -> Class.forName(module, cn))
+ .filter(refc -> refc != null
+ && Modifier.isPublic(refc.getModifiers()))
+ .map(refc -> callerSensitiveMethods(refc))
+ .flatMap(List::stream);
+ } catch (IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ }
+
+ static String packageName(String cn) {
+ int last = cn.lastIndexOf('.');
+ if (last > 0) {
+ return cn.substring(0, last);
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Returns a list of the caller sensitive methods directly declared by the given
+ * class.
+ */
+ static List<Method> callerSensitiveMethods(Class<?> refc) {
+ return Arrays.stream(refc.getDeclaredMethods())
+ .filter(m -> m.isAnnotationPresent(CallerSensitive.class))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Returns a short description of the given method for tracing purposes.
+ */
+ static String shortDescription(Method m) {
+ var sb = new StringBuilder();
+ sb.append(m.getDeclaringClass().getName());
+ sb.append('.');
+ sb.append(m.getName());
+ sb.append('(');
+ StringJoiner sj = new StringJoiner(",");
+ for (Class<?> parameterType : m.getParameterTypes()) {
+ sj.add(parameterType.getTypeName());
+ }
+ sb.append(sj);
+ sb.append(')');
+ return sb.toString();
+ }
+}
--- a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java Mon Feb 26 09:56:12 2018 +0100
@@ -25,7 +25,7 @@
* @test
* @bug 8186211
* @summary Test basic invocation of multiple ldc's of the same dynamic constant that fail resolution
- * @requires os.arch == "x86_64"
+ * @requires os.arch != "sparcv9"
* @library /lib/testlibrary/bytecode /java/lang/invoke/common
* @build jdk.experimental.bytecode.BasicClassBuilder
* @run testng CondyRepeatFailedResolution
--- a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -25,7 +25,7 @@
* @test
* @bug 8186046
* @summary Test for condy BSMs returning primitive values or null
- * @requires os.arch == "x86_64"
+ * @requires os.arch != "sparcv9"
* @library /lib/testlibrary/bytecode
* @build jdk.experimental.bytecode.BasicClassBuilder
* @run testng CondyReturnPrimitiveTest
--- a/test/jdk/java/lang/invoke/condy/CondyWrongType.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/lang/invoke/condy/CondyWrongType.java Mon Feb 26 09:56:12 2018 +0100
@@ -25,7 +25,7 @@
* @test
* @bug 8186046
* @summary Test bootstrap methods returning the wrong type
- * @requires os.arch == "x86_64"
+ * @requires os.arch != "sparcv9"
* @library /lib/testlibrary/bytecode /java/lang/invoke/common
* @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.InstructionHelper
* @run testng CondyWrongType
--- a/test/jdk/java/util/Currency/PropertiesTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/util/Currency/PropertiesTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,8 @@
bug7102969();
} else if (args.length == 1 && args[0].equals("bug8157138")) {
bug8157138();
+ } else if (args.length == 1 && args[0].equals("bug8190904")) {
+ bug8190904();
} else {
System.err.println("Usage: java PropertiesTest -d <dumpfile>");
System.err.println(" java PropertiesTest -c <beforedump> <afterdump> <propsfile>");
@@ -118,8 +120,9 @@
for (String key: keys) {
String val = p.getProperty(key);
try {
- if (countOccurrences(val, ',') == 3 && !isPastCutoverDate(val)) {
- System.out.println("Skipping since date is in future");
+ if (val.chars().map(c -> c == ',' ? 1 : 0).sum() >= 3
+ && !isPastCutoverDate(val)) {
+ System.out.println("Skipping " + key + " since date is in future");
continue; // skip since date in future (no effect)
}
} catch (ParseException pe) {
@@ -130,6 +133,13 @@
System.out.printf("Testing key: %s, val: %s... ", key, val);
System.out.println("AfterVal is : " + afterVal);
+ if (afterVal == null) {
+ System.out.println("Testing key " + key + " is ignored"
+ + " because of the inconsistent numeric code and/or"
+ + " dfd for the given currency code: "+val);
+ continue;
+ }
+
Matcher m = propertiesPattern.matcher(val.toUpperCase(Locale.ROOT));
if (!m.find()) {
// format is not recognized.
@@ -166,22 +176,24 @@
System.out.printf("Success!\n");
}
if (!after.isEmpty()) {
- StringBuilder sb = new StringBuilder()
- .append("Currency data replacement failed. Unnecessary modification was(were) made for the following currencies:\n");
+
keys = after.stringPropertyNames();
for (String key : keys) {
- sb.append(" country: ")
- .append(key)
- .append(" currency: ")
- .append(after.getProperty(key))
- .append("\n");
+ String modified = after.getProperty(key);
+ if(!p.containsValue(modified)) {
+ throw new RuntimeException("Unnecessary modification was"
+ + " made to county: "+ key + " with currency value:"
+ + " " + modified);
+ } else {
+ System.out.println(key + " modified by an entry in"
+ + " currency.properties with currency value "
+ + modified);
+ }
}
- throw new RuntimeException(sb.toString());
}
}
private static void bug7102969() {
-
// check the correct overriding of special case entries
Currency cur = Currency.getInstance(new Locale("", "JP"));
if (!cur.getCurrencyCode().equals("ABC")) {
@@ -248,6 +260,41 @@
}
+ private static void bug8190904() {
+ // should throw IllegalArgumentException as currency code
+ // does not exist as valid ISO 4217 code and failed to load
+ // from currency.properties file because of inconsistent numeric/dfd
+ try {
+ Currency.getInstance("MCC");
+ throw new RuntimeException("[FAILED: Should throw"
+ + " IllegalArgumentException for invalid currency code]");
+ } catch (IllegalArgumentException ex) {
+ // expected to throw IllegalArgumentException
+ }
+
+ // should keep the XOF instance as XOF,952,0, as the XOF entries in
+ // currency.properties IT=XOF,952,1, XY=XOF,955,0 are ignored because
+ // of inconsistency in numeric code and/or dfd
+ checkCurrencyInstance("XOF", 952, 0);
+ // property entry "AS=USD,841,2" should change all occurences
+ // of USD with USD,841,2
+ checkCurrencyInstance("USD", 841, 2);
+ }
+
+ /**
+ * Test the numeric code and fraction of the Currency instance obtained
+ * by given currencyCode, with the expected numericCode and fraction
+ */
+ private static void checkCurrencyInstance(String currencyCode,
+ int numericCode, int fraction) {
+ Currency cur = Currency.getInstance(currencyCode);
+ if (cur.getNumericCode() != numericCode
+ || cur.getDefaultFractionDigits() != fraction) {
+ throw new RuntimeException("[FAILED: Incorrect numeric code or"
+ + " dfd for currency code: " + currencyCode + "]");
+ }
+ }
+
private static boolean isPastCutoverDate(String s)
throws IndexOutOfBoundsException, NullPointerException, ParseException {
String dateString = s.substring(s.lastIndexOf(',')+1, s.length()).trim();
@@ -263,13 +310,4 @@
}
}
- private static int countOccurrences(String value, char match) {
- int count = 0;
- for (char c : value.toCharArray()) {
- if (c == match) {
- ++count;
- }
- }
- return count;
- }
}
--- a/test/jdk/java/util/Currency/PropertiesTest.sh Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/util/Currency/PropertiesTest.sh Mon Feb 26 09:56:12 2018 +0100
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
# @test
# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 7102969
-# 8157138
+# 8157138 8190904
# @summary tests the capability of replacing the currency data with user
# specified currency properties file
# @build PropertiesTest
@@ -124,6 +124,11 @@
${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug8157138
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+# run bug8190904 test
+echo ''
+${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug8190904
+if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+
# Cleanup
rm -rf $WRITABLEJDK
--- a/test/jdk/java/util/Currency/currency.properties Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/util/Currency/currency.properties Mon Feb 26 09:56:12 2018 +0100
@@ -26,5 +26,9 @@
MG=MGG,990,10
MX=SSS,493,2,2001-01-01-00-00-00
PE=EUR ,978 ,2, 20399-01-01T00:00:00
-MG=MGG,990,10
=euR,111,2, 2099-01-01-00-00-00
+MR=MCC,556,7
+IT=XOF,952,1
+XY=XOF,955,0
+AS=USD,841,2
+CY=CYP,822,2
--- a/test/jdk/java/util/Formatter/FormatLocale.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/java/util/Formatter/FormatLocale.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,12 @@
/**
* @test
- * @bug 8146156 8159548
+ * @bug 8146156 8159548 8060094
* @modules jdk.localedata
* @summary test whether uppercasing follows Locale.Category.FORMAT locale.
+ * Also test whether the uppercasing uses the locale specified to the
+ * Formatter API.
+ *
* @run main/othervm FormatLocale
*/
@@ -38,7 +41,6 @@
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
-import java.util.Locale.Category;
import java.util.TimeZone;
import java.util.stream.IntStream;
@@ -50,40 +52,81 @@
"%S",
"%S",
"%TB",
- "%G");
+ "%G",
+ "%C");
+
static final List<Object> src = List.of(
"Turkish",
"Turkish",
LocalDate.of(2016, Month.APRIL, 1),
- Float.valueOf(100_000_000));
+ Float.valueOf(100_000_000),
+ 'i');
+
+ static final List<Locale> defaultLocale = List.of(
+ Locale.ENGLISH,
+ TURKISH,
+ TURKISH,
+ Locale.FRANCE,
+ TURKISH);
+
static final List<Locale> formatLocale = List.of(
- Locale.ENGLISH,
- TURKISH,
- TURKISH,
- Locale.FRANCE);
- static final List<String> expected = List.of(
- "TURKISH",
- "TURK\u0130SH",
- "N\u0130SAN",
- "1,00000E+08");
+ TURKISH,
+ Locale.ENGLISH,
+ Locale.FRANCE,
+ Locale.ENGLISH,
+ Locale.ENGLISH);
+
+ static final List<String> expectedWithDefaultLocale = List.of(
+ "TURKISH",
+ "TURK\u0130SH",
+ "N\u0130SAN",
+ "1,00000E+08",
+ "\u0130");
+
+ static final List<String> expectedWithFormatLocale = List.of(
+ "TURK\u0130SH",
+ "TURKISH",
+ "AVRIL",
+ "1.00000E+08",
+ "I");
static void formatLocaleTest() {
StringBuilder sb = new StringBuilder();
+ // checks whether upper casing follows Locale.Category.FORMAT locale
IntStream.range(0, src.size()).forEach(i -> {
sb.setLength(0);
- Locale.setDefault(Locale.Category.FORMAT, formatLocale.get(i));
+ Locale.setDefault(Locale.Category.FORMAT, defaultLocale.get(i));
new Formatter(sb).format(conversions.get(i), src.get(i));
- if (!sb.toString().equals(expected.get(i))) {
+ if (!sb.toString().equals(expectedWithDefaultLocale.get(i))) {
throw new RuntimeException(
- "Wrong uppercasing with Formatter.format(" +
- "\"" + conversions.get(i) + "\"" +
- ") in locale "
- + formatLocale.get(i) +
- ". Expected: " + expected.get(i) +
- " Returned: " + sb.toString());
+ "Wrong uppercasing while using Formatter.format(" +
+ "\"" + conversions.get(i) + "\"" +
+ ") with the default locale: '"
+ + defaultLocale.get(i) +
+ "'. Expected: " + expectedWithDefaultLocale.get(i) +
+ " Returned: " + sb.toString());
}
});
+
+ // checks whether upper casing uses the locale set during creation of
+ // Formatter instance, instead of the default locale
+ IntStream.range(0, src.size()).forEach(i -> {
+ sb.setLength(0);
+ Locale.setDefault(Locale.Category.FORMAT, defaultLocale.get(i));
+ new Formatter(sb, formatLocale.get(i)).format(conversions.get(i),
+ src.get(i));
+ if (!sb.toString().equals(expectedWithFormatLocale.get(i))) {
+ throw new RuntimeException(
+ "Wrong uppercasing while using Formatter.format(" +
+ "\"" + conversions.get(i) + "\"" +
+ ") with the locale specified during instance" +
+ " creation: '" + formatLocale.get(i) +
+ "'. Expected: " + expectedWithFormatLocale.get(i) +
+ " Returned: " + sb.toString());
+ }
+ });
+
}
static void nullLocaleTest() {
--- a/test/jdk/jdk/internal/jline/extra/HistoryTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/jdk/internal/jline/extra/HistoryTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8178821
+ * @bug 8178821 8198670
* @summary Test Completion
* @modules jdk.internal.le/jdk.internal.jline
* jdk.internal.le/jdk.internal.jline.console
@@ -133,16 +133,27 @@
complete.set(true); history.add("/*current2*/");
complete.set(true); history.add("/*current3*/");
- assertEquals(history.currentSessionEntries(), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/"));
+ assertEquals(history.entries(true), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/"));
+ assertEquals(history.entries(false), Arrays.asList(
+ "void test() {",
+ " System.err.println(1);",
+ "}",
+ "/exit",
+ "void test() { /*changed*/",
+ " System.err.println(2);",
+ "} /*changed*/",
+ "{",
+ "}",
+ "/*current1*/", "/*current2*/", "/*current3*/"), history.entries(false).toString());
history.remove(0);
- assertEquals(history.currentSessionEntries(), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/"));
+ assertEquals(history.entries(true), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/"));
while (history.size() > 2)
history.remove(0);
- assertEquals(history.currentSessionEntries(), Arrays.asList("/*current2*/", "/*current3*/"));
+ assertEquals(history.entries(true), Arrays.asList("/*current2*/", "/*current3*/"));
for (int i = 0; i < MemoryHistory.DEFAULT_MAX_SIZE * 2; i++) {
complete.set(true); history.add("/exit");
--- a/test/jdk/tools/jimage/JImageExtractTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/tools/jimage/JImageExtractTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -154,8 +154,10 @@
Path tmp = Files.createTempDirectory(Paths.get("."), getClass().getName());
Files.createFile(Paths.get(tmp.toString(), ".not_empty"));
jimage("extract", "--dir", tmp.toString(), getImagePath())
- .assertFailure()
- .assertShowsError();
+ .assertSuccess()
+ .resultChecker(r -> {
+ assertTrue(r.output.isEmpty(), "Output is not expected");
+ });
}
public void testExtractToFile() throws IOException {
--- a/test/jdk/tools/jimage/JImageListTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/tools/jimage/JImageListTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -57,7 +57,7 @@
.map(s -> s.substring(s.indexOf(':') + 1).trim())
.collect(Collectors.toList());
assertTrue(modules.size() > 0, "Image contains at least one module.");
- assertTrue(modules.indexOf("java.base") > 0, "Module java.base found.");
+ assertTrue(modules.contains("java.base"), "Module java.base found.");
});
}
@@ -88,7 +88,7 @@
.map(s -> s.substring(s.indexOf(':') + 1).trim())
.collect(Collectors.toList());
assertTrue(modules.size() > 0, "Image contains at least one module.");
- assertTrue(modules.indexOf("java.base") > 0, "Module java.base found.");
+ assertTrue(modules.contains("java.base"), "Module java.base found.");
Set<String> entries = Stream.of(lines)
.filter(s -> { return !s.startsWith("Module: ") && !s.startsWith("Offset"); })
--- a/test/jdk/tools/jlink/JLinkTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jdk/tools/jlink/JLinkTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -43,6 +43,7 @@
* @test
* @summary Test image creation
* @bug 8189777
+ * @bug 8194922
* @author Jean-Francois Denise
* @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g)
* @library ../lib
@@ -276,6 +277,15 @@
helper.checkImage(imageDir, moduleName, res, null);
}
+ // module-info.class should not be excluded
+ {
+ String[] userOptions = { "--exclude-resources", "/jdk_8194922/module-info.class" };
+ String moduleName = "jdk_8194922";
+ helper.generateDefaultJModule(moduleName);
+ helper.generateDefaultImage(userOptions, moduleName).
+ assertFailure("Cannot exclude /jdk_8194922/module-info.class");
+ }
+
// default compress
{
testCompress(helper, "compresscmdcomposite2", "--compress", "2");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jlink/plugins/ExcludeModuleInfoTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8194922
+ * @summary jlink --exclude-resources should never exclude module-info.class
+ * @modules jdk.jlink/jdk.tools.jlink.internal
+ * jdk.jlink/jdk.tools.jlink.internal.plugins
+ * jdk.jlink/jdk.tools.jlink.plugin
+ * @run main ExcludeModuleInfoTest
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.tools.jlink.internal.ResourcePoolManager;
+
+import jdk.tools.jlink.internal.plugins.ExcludePlugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+
+public class ExcludeModuleInfoTest {
+
+ public static void main(String[] args) throws Exception {
+ new ExcludeModuleInfoTest().test();
+ }
+
+ public void test() throws Exception {
+ check("**.class", "/mymodule/module-info.class");
+ check("/java.base/module-info.class", "/java.base/module-info.class");
+ }
+
+ public void check(String s, String sample) throws Exception {
+ Map<String, String> prop = new HashMap<>();
+ prop.put(ExcludePlugin.NAME, s);
+ ExcludePlugin excludePlugin = new ExcludePlugin();
+ excludePlugin.configure(prop);
+ ResourcePoolManager resourcesMgr = new ResourcePoolManager();
+ ResourcePoolEntry resource = ResourcePoolEntry.create(sample, new byte[0]);
+ resourcesMgr.add(resource);
+ ResourcePoolManager resultMgr = new ResourcePoolManager();
+ try {
+ excludePlugin.transform(resourcesMgr.resourcePool(),
+ resultMgr.resourcePoolBuilder());
+ throw new AssertionError(sample + " exclusion should have resulted in exception");
+ } catch (PluginException pe) {
+ System.err.println("Got exception as expected: " + pe);
+ pe.printStackTrace();
+ }
+ }
+}
--- a/test/jtreg-ext/requires/VMProps.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/jtreg-ext/requires/VMProps.java Mon Feb 26 09:56:12 2018 +0100
@@ -352,9 +352,9 @@
* @return true if docker is supported in a given environment
*/
protected String dockerSupport() {
- // currently docker testing is only supported for Linux-x64 and Linux-ppc64le
+ // currently docker testing is only supported for Linux-x64, Linux-s390x and Linux-ppc64le
String arch = System.getProperty("os.arch");
- if (! (Platform.isLinux() && (Platform.isX64() || arch.equals("ppc64le")))) {
+ if (! (Platform.isLinux() && (Platform.isX64() || Platform.isS390x() || arch.equals("ppc64le")))) {
return "false";
}
--- a/test/langtools/jdk/jshell/CommandCompletionTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/jdk/jshell/CommandCompletionTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8144095 8164825 8169818 8153402 8165405 8177079 8178013 8167554
+ * @bug 8144095 8164825 8169818 8153402 8165405 8177079 8178013 8167554 8166232
* @summary Test Command Completion
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -124,6 +124,14 @@
}
@Test
+ public void testHistory() {
+ test(false, new String[] {"--no-startup"},
+ a -> assertCompletion(a, "/hi|", false, "/history "),
+ a -> assertCompletion(a, "/history |", false, "-all")
+ );
+ }
+
+ @Test
public void testDrop() {
test(false, new String[] {"--no-startup"},
a -> assertCompletion(a, "/d|", false, "/drop "),
--- a/test/langtools/jdk/jshell/CompletionSuggestionTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/jdk/jshell/CompletionSuggestionTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8131025 8141092 8153761 8145263 8131019 8175886 8176184 8176241 8176110 8177466
+ * @bug 8131025 8141092 8153761 8145263 8131019 8175886 8176184 8176241 8176110 8177466 8197439
* @summary Test Completion and Documentation
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -661,6 +661,10 @@
assertCompletion("CharSequence r = |", true);
}
+ public void testCompletionInAnonymous() {
+ assertCompletionIncludesExcludes("new Undefined() { int i = \"\".l|", Set.of("length()"), Set.of());
+ }
+
@BeforeMethod
public void setUp() {
super.setUp();
--- a/test/langtools/jdk/jshell/JdiBogusHostListenExecutionControlTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/jdk/jshell/JdiBogusHostListenExecutionControlTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8169519 8168615
+ * @bug 8169519 8168615 8176474
* @summary Tests for JDI connector failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @run testng JdiBogusHostListenExecutionControlTest
@@ -40,7 +40,9 @@
public class JdiBogusHostListenExecutionControlTest {
private static final String EXPECTED_ERROR =
- "Launching JShell execution engine threw: Failed remote listen: java.net.SocketException: Unresolved address @ com.sun.jdi.SocketListe";
+ "Launching JShell execution engine threw: Failed remote listen:";
+ private static final String EXPECTED_LOCATION =
+ "@ com.sun.jdi.SocketListen";
public void badOptionListenTest() {
try {
@@ -50,7 +52,10 @@
.executionEngine("jdi:hostname(BattyRumbleBuckets-Snurfle-99-Blip)")
.build();
} catch (IllegalStateException ex) {
- assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
+ assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR),
+ ex.getMessage() + "\nExpected: " + EXPECTED_ERROR);
+ assertTrue(ex.getMessage().contains(EXPECTED_LOCATION),
+ ex.getMessage() + "\nExpected: " + EXPECTED_LOCATION);
return;
}
fail("Expected IllegalStateException");
--- a/test/langtools/jdk/jshell/StartOptionTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/jdk/jshell/StartOptionTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -230,7 +230,7 @@
startCo(s -> {
assertTrue(s.split("\n").length >= 5, "Not enough help-extra lines: " + s);
assertTrue(s.contains("--add-exports"), "Expected --add-exports: " + s);
- assertTrue(s.contains("--execution"), "Expected --add-exports: " + s);
+ assertTrue(s.contains("--execution"), "Expected --execution: " + s);
assertFalse(s.contains("Welcome"), "Unexpected start: " + s);
}, opt);
}
--- a/test/langtools/jdk/jshell/ToolBasicTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/jdk/jshell/ToolBasicTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 8174796 8174797 8175304 8167554 8180508
+ * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 8174796 8174797 8175304 8167554 8180508 8166232
* @summary Tests for Basic tests for REPL tool
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -652,6 +652,10 @@
public void testHistoryReference() {
test(false, new String[]{"--no-startup"},
+ a -> assertCommand(a, "System.err.println(99)", "", "", null, "", "99\n"),
+ a -> assertCommand(a, "/exit", "")
+ );
+ test(false, new String[]{"--no-startup"},
a -> assertCommand(a, "System.err.println(1)", "", "", null, "", "1\n"),
a -> assertCommand(a, "System.err.println(2)", "", "", null, "", "2\n"),
a -> assertCommand(a, "/-2", "System.err.println(1)", "", null, "", "1\n"),
@@ -661,6 +665,16 @@
"System.err.println(2)\n" +
"System.err.println(1)\n" +
"/history\n"),
+ a -> assertCommand(a, "/history -all",
+ "/debug 0\n" +
+ "System.err.println(99)\n" +
+ "/exit\n" +
+ "/debug 0\n" +
+ "System.err.println(1)\n" +
+ "System.err.println(2)\n" +
+ "System.err.println(1)\n" +
+ "/history\n" +
+ "/history -all\n"),
a -> assertCommand(a, "/-2", "System.err.println(2)", "", null, "", "2\n"),
a -> assertCommand(a, "/!", "System.err.println(2)", "", null, "", "2\n"),
a -> assertCommand(a, "/2", "System.err.println(2)", "", null, "", "2\n"),
--- a/test/langtools/jdk/jshell/ToolSimpleTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/jdk/jshell/ToolSimpleTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797 8177079 8180508 8177466 8172154 8192979 8191842
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797 8177079 8180508 8177466 8172154 8192979 8191842 8198573
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -793,4 +793,15 @@
(a) -> assertCommandOutputContains(a, "/vars list", "| List<<anonymous class extending Object>> list = ")
);
}
+
+ // This is mainly interesting in the TestLocalSimpleTest case (8198573)
+ @Test
+ public void testUpdateFalsePositive() {
+ test(
+ a -> assertClass(a, "class A { int a() { int error = 0; return error; } }", "class", "A"),
+ a -> assertVariable(a, "A", "a", "new A()", "A@.+"),
+ a -> assertVariable(a, "int", "error", "4711", "4711"),
+ a -> assertCommandOutputContains(a, "a", "A@")
+ );
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8198502.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8198502
+ * @summary Exception at runtime due to lambda analyzer reattributes live AST
+ * @run compile -XDfind=lambda T8198502.java
+ * @run main T8198502
+ */
+
+public class T8198502 {
+
+ public static void main(String... args) {
+ new T8198502().run();
+ }
+
+ private void run() {
+ Base b = new Base() {
+ public void run() {
+ test(this);
+ }
+ };
+ b.run();
+ }
+
+ private static void test(T8198502 t) {
+ throw new AssertionError("Should not be invoked!");
+ }
+
+ private static void test(Base b) {
+ //ok to invoke
+ }
+
+ public static interface Base {
+ void run();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/analyzer/AnonymousInAnonymous.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8197439
+ * @summary Check anonymous class in anonymous class, where the nested one becomes
+ * unresolvable with lambda conversion.
+ * @compile -XDfind=lambda -Werror AnonymousInAnonymous.java
+ */
+
+public class AnonymousInAnonymous {
+ static void s(I1 i) {}
+ static {
+ s(
+ new I1() {
+ public I2 get() {
+ return new I2() {
+ };
+ }
+ });
+ }
+ public static interface I1 {
+ public static class I2 { }
+ public I2 get();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/BracketsNotAllowedImplicitLambda.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// key: compiler.err.var.not.allowed.array
+
+import java.util.function.*;
+
+class BracketsNotAllowedImplicitLambda {
+ BiFunction<String[], String, String> f = (var s1[], var s2) -> s2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/ExplicitImplicitLambda.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// key: compiler.err.invalid.lambda.parameter.declaration
+// key: compiler.misc.implicit.and.explicit.not.allowed
+
+import java.util.function.*;
+
+class ExplicitImplicitLambda {
+ IntBinaryOperator f = (int x, y) -> x + y;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/VarAllOrNothing.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// key: compiler.err.invalid.lambda.parameter.declaration
+// key: compiler.misc.var.and.implicit.not.allowed
+
+import java.util.function.*;
+
+class VarAllOrNothing {
+ IntBinaryOperator f = (x, var y) -> x + y;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/VarExplicitLambda.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// key: compiler.err.invalid.lambda.parameter.declaration
+// key: compiler.misc.var.and.explicit.not.allowed
+
+import java.util.function.*;
+
+class VarExplicitLambda {
+ IntBinaryOperator f = (int x, var y) -> x + y;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/VarNotAllowedExplicitLambda.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// key: compiler.err.invalid.lambda.parameter.declaration
+// key: compiler.misc.var.and.explicit.not.allowed
+
+class VarNotAllowedExplicitLambda {
+ F f = (String s, var v)->{};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/failover/PostAttrConstructor.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8197439
+ * @summary Ensure that constructors don't cause crash in Attr.postAttr
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.comp
+ * jdk.compiler/com.sun.tools.javac.tree
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.tools.*;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.comp.Attr;
+import com.sun.tools.javac.tree.JCTree;
+
+public class PostAttrConstructor {
+
+ static class JavaSource extends SimpleJavaFileObject {
+
+ final static String source =
+ "class C {\n" +
+ " public C() {}\n" +
+ "}";
+
+ JavaSource() {
+ super(URI.create("myfo:/C.java"), JavaFileObject.Kind.SOURCE);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ public static void main(String... args) throws IOException {
+ new PostAttrConstructor().run();
+ }
+
+ void run() throws IOException {
+ File destDir = new File("classes"); destDir.mkdir();
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ JavaSource source = new JavaSource();
+ JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, null, null,
+ Arrays.asList("-d", destDir.getPath()),
+ null,
+ Arrays.asList(source));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+ Attr attr = Attr.instance(ct.getContext());
+ attr.postAttr((JCTree) cut);
+ }
+
+}
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg05.out Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg05.out Mon Feb 26 09:56:12 2018 +0100
@@ -7,21 +7,13 @@
Neg05.java:26:43: compiler.err.improperly.formed.type.inner.raw.param
Neg05.java:27:56: compiler.err.improperly.formed.type.inner.raw.param
Neg05.java:29:48: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:29:35: compiler.err.cant.apply.symbol: kindname.constructor, , V, java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:30:59: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:30:46: compiler.err.cant.apply.symbol: kindname.constructor, , V, java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:31:44: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:31:31: compiler.err.cant.apply.symbol: kindname.constructor, , V, java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:32:57: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:32:44: compiler.err.cant.apply.symbol: kindname.constructor, , V, java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:34:49: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:34:36: compiler.err.cant.apply.symbol: kindname.constructor, , V,Z, java.lang.String,java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:35:59: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:35:46: compiler.err.cant.apply.symbol: kindname.constructor, , V,Z, java.lang.String,java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:36:44: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:36:31: compiler.err.cant.apply.symbol: kindname.constructor, , V,Z, java.lang.String,java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:37:57: compiler.err.improperly.formed.type.inner.raw.param
-Neg05.java:37:44: compiler.err.cant.apply.symbol: kindname.constructor, , V,Z, java.lang.String,java.lang.String, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.inconvertible.types: java.lang.String, V))
Neg05.java:41:37: compiler.err.improperly.formed.type.inner.raw.param
Neg05.java:41:44: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V, Neg05.Foo<V>, Neg05<?>.Foo<java.lang.String>))
Neg05.java:42:47: compiler.err.improperly.formed.type.inner.raw.param
@@ -54,4 +46,4 @@
Neg05.java:58:40: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<?>))
Neg05.java:59:46: compiler.err.improperly.formed.type.inner.raw.param
Neg05.java:59:53: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg05.Foo), (compiler.misc.infer.no.conforming.instance.exists: V,Z, Neg05.Foo<V>, Neg05<?>.Foo<? super java.lang.String>))
-56 errors
+48 errors
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg06.out Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg06.out Mon Feb 26 09:56:12 2018 +0100
@@ -1,6 +1,4 @@
Neg06.java:18:36: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.IFoo), (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
-Neg06.java:18:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.anonymous.class: java.lang.Object, Neg06.ISuperFoo<java.lang.String>)
Neg06.java:19:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
Neg06.java:20:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
-Neg06.java:20:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.anonymous.class: <any>, Neg06.CSuperFoo<java.lang.String>)
-5 errors
+3 errors
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg18.out Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg18.out Mon Feb 26 09:56:12 2018 +0100
@@ -1,3 +1,2 @@
Neg18.java:14:21: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: pkg.Neg18_01), (compiler.misc.inaccessible.varargs.type: pkg.Neg18_01.PkgPrivate, kindname.class, Neg18))
-Neg18.java:14:9: compiler.err.cant.apply.symbol: kindname.constructor, , pkg.Neg18_01.PkgPrivate[], compiler.misc.no.args, kindname.class, compiler.misc.anonymous.class: <any>, (compiler.misc.inaccessible.varargs.type: pkg.Neg18_01.PkgPrivate, kindname.class, Neg18)
-2 errors
+1 error
--- a/test/langtools/tools/javac/lambda/LambdaParserTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/tools/javac/lambda/LambdaParserTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
*/
import java.io.IOException;
+import java.util.Arrays;
import combo.ComboInstance;
import combo.ComboParameter;
@@ -105,26 +106,44 @@
}
}
+ enum SourceKind {
+ SOURCE_9("9"),
+ SOURCE_10("10");
+
+ String sourceNumber;
+
+ SourceKind(String sourceNumber) {
+ this.sourceNumber = sourceNumber;
+ }
+ }
+
enum LambdaParameterKind implements ComboParameter {
- IMPLICIT(""),
- EXPLIICT_SIMPLE("A"),
- EXPLIICT_SIMPLE_ARR1("A[]"),
- EXPLIICT_SIMPLE_ARR2("A[][]"),
- EXPLICIT_VARARGS("A..."),
- EXPLICIT_GENERIC1("A<X>"),
- EXPLICIT_GENERIC2("A<? extends X, ? super Y>"),
- EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>..."),
- EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]"),
- EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]");
+
+ IMPLICIT_1("", ExplicitKind.IMPLICIT),
+ IMPLICIT_2("var", ExplicitKind.IMPLICIT_VAR),
+ EXPLIICT_SIMPLE("A", ExplicitKind.EXPLICIT),
+ EXPLIICT_SIMPLE_ARR1("A[]", ExplicitKind.EXPLICIT),
+ EXPLIICT_SIMPLE_ARR2("A[][]", ExplicitKind.EXPLICIT),
+ EXPLICIT_VARARGS("A...", ExplicitKind.EXPLICIT),
+ EXPLICIT_GENERIC1("A<X>", ExplicitKind.EXPLICIT),
+ EXPLICIT_GENERIC2("A<? extends X, ? super Y>", ExplicitKind.EXPLICIT),
+ EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>...", ExplicitKind.EXPLICIT),
+ EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]", ExplicitKind.EXPLICIT),
+ EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]", ExplicitKind.EXPLICIT);
+
+ enum ExplicitKind {
+ IMPLICIT,
+ IMPLICIT_VAR,
+ EXPLICIT;
+ }
String parameterType;
+ ExplicitKind explicitKind;
- LambdaParameterKind(String parameterType) {
+
+ LambdaParameterKind(String parameterType, ExplicitKind ekind) {
this.parameterType = parameterType;
- }
-
- boolean explicit() {
- return this != IMPLICIT;
+ this.explicitKind = ekind;
}
boolean isVarargs() {
@@ -136,12 +155,23 @@
public String expand(String optParameter) {
return parameterType;
}
+
+ ExplicitKind explicitKind(SourceKind sk) {
+ switch (explicitKind) {
+ case IMPLICIT_VAR:
+ return (sk == SourceKind.SOURCE_9) ?
+ ExplicitKind.EXPLICIT : ExplicitKind.IMPLICIT_VAR;
+ default:
+ return explicitKind;
+ }
+ }
}
enum ModifierKind implements ComboParameter {
NONE(""),
FINAL("final"),
- PUBLIC("public");
+ PUBLIC("public"),
+ ANNO("@A");
String modifier;
@@ -152,7 +182,8 @@
boolean compatibleWith(LambdaParameterKind pk) {
switch (this) {
case PUBLIC: return false;
- case FINAL: return pk != LambdaParameterKind.IMPLICIT;
+ case ANNO:
+ case FINAL: return pk != LambdaParameterKind.IMPLICIT_1;
case NONE: return true;
default: throw new AssertionError("Invalid modifier kind " + this);
}
@@ -208,6 +239,7 @@
new ComboTestHelper<LambdaParserTest>()
.withFilter(LambdaParserTest::redundantTestFilter)
.withFilter(LambdaParserTest::badImplicitFilter)
+ .withDimension("SOURCE", (x, sk) -> x.sk = sk, SourceKind.values())
.withDimension("LAMBDA", (x, lk) -> x.lk = lk, LambdaKind.values())
.withDimension("NAME", (x, name) -> x.pn = name, LambdaParameterName.values())
.withArrayDimension("TYPE", (x, type, idx) -> x.pks[idx] = type, 2, LambdaParameterKind.values())
@@ -221,6 +253,7 @@
ModifierKind[] mks = new ModifierKind[2];
LambdaKind lk;
LambdaParameterName pn;
+ SourceKind sk;
boolean badImplicitFilter() {
return !(mks[0] != ModifierKind.NONE && lk.isShort());
@@ -240,13 +273,15 @@
return true;
}
- String template = "class Test {\n" +
- " SAM s = #{EXPR};\n" +
- "}";
+ String template = "@interface A { }\n" +
+ "class Test {\n" +
+ " SAM s = #{EXPR};\n" +
+ "}";
@Override
public void doWork() throws IOException {
newCompilationTask()
+ .withOptions(Arrays.asList("-source", sk.sourceNumber))
.withSourceFromTemplate(template)
.parse(this::check);
}
@@ -256,7 +291,7 @@
(lk.arity() > 1 && !mks[1].compatibleWith(pks[1]));
if (lk.arity() == 2 &&
- (pks[0].explicit() != pks[1].explicit() ||
+ (pks[0].explicitKind(sk) != pks[1].explicitKind(sk) ||
pks[0].isVarargs())) {
errorExpected = true;
}
--- a/test/langtools/tools/javac/lvti/ParserTest.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/tools/javac/lvti/ParserTest.java Mon Feb 26 09:56:12 2018 +0100
@@ -60,7 +60,7 @@
List<? extends var> l2; //error
List<? super var> l3; //error
try {
- Function<var, String> f = (var x2) -> ""; //error
+ Function<var, String> f = (var x2) -> ""; //ok
} catch (var ex) { } //error
}
--- a/test/langtools/tools/javac/lvti/ParserTest.out Tue Feb 20 21:46:02 2018 +0100
+++ b/test/langtools/tools/javac/lvti/ParserTest.out Mon Feb 26 09:56:12 2018 +0100
@@ -18,8 +18,7 @@
ParserTest.java:60:24: compiler.err.var.not.allowed.here
ParserTest.java:61:22: compiler.err.var.not.allowed.here
ParserTest.java:63:22: compiler.err.var.not.allowed.here
-ParserTest.java:63:40: compiler.err.var.not.allowed.here
ParserTest.java:64:18: compiler.err.var.not.allowed.here
ParserTest.java:68:35: compiler.err.var.not.allowed.here
ParserTest.java:69:22: compiler.err.var.not.allowed.here
-24 errors
+23 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/processing/model/util/elements/hides/C.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+public class C implements I {
+ public static class IC {}
+ public static int f = 0;
+ public static void m() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/processing/model/util/elements/hides/Hides.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8034933
+ * @summary Elements hides does not work correctly with interface methods
+ * @library /tools/javac/lib
+ * @modules java.compiler
+ * jdk.compiler
+ * @build JavacTestingAbstractProcessor Hides
+ * @compile -processor Hides -proc:only C.java I.java
+ */
+
+import java.util.Set;
+import java.util.List;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+
+import static javax.lang.model.util.ElementFilter.*;
+
+public class Hides extends JavacTestingAbstractProcessor {
+
+ VariableElement getField(TypeElement te) {
+ List<VariableElement> fields = fieldsIn(te.getEnclosedElements());
+ if (fields.size() != 1) {
+ throw new AssertionError("Expected only one field in: " + te);
+ }
+ return fields.get(0);
+ }
+
+ ExecutableElement getMethod(TypeElement te) {
+ List<ExecutableElement> methods = methodsIn(te.getEnclosedElements());
+ if (methods.size() != 1) {
+ throw new AssertionError("Expected only one method in: " + te);
+ }
+ return methods.get(0);
+ }
+
+ TypeElement getIC(TypeElement te) {
+ List<TypeElement> ics = typesIn(te.getEnclosedElements());
+ if (ics.size() != 1) {
+ throw new AssertionError("Expected only one inner class in: " + te);
+ }
+ return ics.get(0);
+ }
+
+ public boolean process(Set<? extends TypeElement> tes,
+ RoundEnvironment round) {
+ if (round.processingOver())
+ return true;
+
+ TypeElement klass = null;
+ TypeElement intfc = null;
+
+ for (TypeElement te : typesIn(round.getRootElements())) {
+ switch (te.getKind()) {
+ case INTERFACE:
+ intfc = te;
+ break;
+ case CLASS:
+ klass = te;
+ break;
+ default:
+ throw new AssertionError("don't know what this is: " + te);
+ }
+ }
+
+ for (Element e : klass.getEnclosedElements()) {
+ switch (e.getKind()) {
+ case FIELD:
+ check(e, getField(intfc));
+ break;
+ case METHOD:
+ check(e, getMethod(intfc));
+ break;
+ case CLASS:
+ check(e, getIC(intfc));
+ default:
+ break;
+ }
+ }
+
+ if (!status)
+ throw new Error("Test fails");
+ return true;
+ }
+ boolean status = true;
+
+ String getFQN(Element e) {
+ return e.getEnclosingElement() + "." + e;
+ }
+
+ void check(Element e1, Element e2) {
+ if (eltUtils.hides(e1, e2)) {
+ System.err.println("Pass: " + getFQN(e1) + " hides: " + getFQN(e2));
+ } else {
+ System.err.println("Fail: Expected: " + getFQN(e1) + " to hide: " + getFQN(e2));
+ status = false;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/processing/model/util/elements/hides/I.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+interface I {
+ public static class IC {}
+ public static int f = 0;
+ public static void m() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/resolve/BrokenAnonymous.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8197439
+ * @summary Ensuring that unresolvable anonymous class is still attributed.
+ * @modules jdk.compiler
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.tools.*;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.*;
+
+public class BrokenAnonymous {
+
+ static class JavaSource extends SimpleJavaFileObject {
+
+ final static String source =
+ "class C {\n" +
+ " Object o1 = new Undef1() {" +
+ " int i = 0;\n" +
+ " int m(int j) { return i + j; }\n" +
+ " }\n" +
+ " Object o2 = new Undef2<>() {" +
+ " int i = 0;\n" +
+ " int m(int j) { return i + j; }\n" +
+ " }\n" +
+ "}";
+
+ JavaSource() {
+ super(URI.create("myfo:/C.java"), JavaFileObject.Kind.SOURCE);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ public static void main(String... args) throws IOException {
+ new BrokenAnonymous().run();
+ }
+
+ void run() throws IOException {
+ File destDir = new File("classes"); destDir.mkdir();
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ JavaSource source = new JavaSource();
+ JavacTask ct = (JavacTask)tool.getTask(null, null, null,
+ Arrays.asList("-d", destDir.getPath()),
+ null,
+ Arrays.asList(source));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+ Trees trees = Trees.instance(ct);
+ ct.analyze();
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void visitVariable(VariableTree node, Void p) {
+ verifyElementType();
+ return super.visitVariable(node, p);
+ }
+ @Override
+ public Void visitMethod(MethodTree node, Void p) {
+ verifyElementType();
+ return super.visitMethod(node, p);
+ }
+ @Override
+ public Void visitIdentifier(IdentifierTree node, Void p) {
+ verifyElementType();
+ return super.visitIdentifier(node, p);
+ }
+ private void verifyElementType() {
+ TreePath tp = getCurrentPath();
+ assertNotNull(trees.getElement(tp));
+ assertNotNull(trees.getTypeMirror(tp));
+ }
+ }.scan(cut, null);
+ }
+
+ private void assertNotNull(Object obj) {
+ if (obj == null) {
+ throw new AssertionError("Unexpected null value.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.java Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8198512
+ * @summary compiler support for local-variable syntax for lambda parameters
+ * @compile/fail/ref=VarInImplicitLambdaNegTest01.out -XDrawDiagnostics VarInImplicitLambdaNegTest01.java
+ */
+
+import java.util.function.*;
+
+class VarInImplicitLambdaNegTest01 {
+ IntBinaryOperator f1 = (x, var y) -> x + y; // error implicit and var
+ IntBinaryOperator f2 = (var x, y) -> x + y; // error var and implicit
+ IntBinaryOperator f3 = (int x, var y) -> x + y; // error var and explicit
+ IntBinaryOperator f4 = (int x, y) -> x + y; // error explicit and implicit
+
+ BiFunction<String[], String, String> f5 = (var s1[], var s2) -> s2; // error var and array
+ BiFunction<Function<String, String>, String, String> f = (Function<String, String> s1, String s2) -> s2; // ok
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.out Mon Feb 26 09:56:12 2018 +0100
@@ -0,0 +1,6 @@
+VarInImplicitLambdaNegTest01.java:11:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:12:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:13:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.explicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:14:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:16:52: compiler.err.var.not.allowed.array
+5 errors
--- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,160 @@
// This class contains common test utilities for testing CDS
public class CDSTestUtils {
+ public interface Checker {
+ public void check(OutputAnalyzer output) throws Exception;
+ }
+
+ /*
+ * INTRODUCTION
+ *
+ * When testing various CDS functionalities, we need to launch JVM processes
+ * using a "launch method" (such as TestCommon.run), and analyze the results of these
+ * processes.
+ *
+ * While typical jtreg tests would use OutputAnalyzer in such cases, due to the
+ * complexity of CDS failure modes, we have added the CDSTestUtils.Result class
+ * to make the analysis more convenient and less error prone.
+ *
+ * A Java process can end in one of the following 4 states:
+ *
+ * 1: Unexpected error - such as JVM crashing. In this case, the "launch method"
+ * will throw a RuntimeException.
+ * 2: Mapping Failure - this happens when the OS (intermittently) fails to map the
+ * CDS archive, normally caused by Address Space Layout Randomization.
+ * We usually treat this as "pass".
+ * 3: Normal Exit - the JVM process has finished without crashing, and the exit code is 0.
+ * 4: Abnormal Exit - the JVM process has finished without crashing, and the exit code is not 0.
+ *
+ * In most test cases, we need to check the JVM process's output in cases 3 and 4. However, we need
+ * to make sure that our test code is not confused by case 2.
+ *
+ * For example, a JVM process is expected to print the string "Hi" and exit with 0. With the old
+ * CDSTestUtils.runWithArchive API, the test may be written as this:
+ *
+ * OutputAnalyzer out = CDSTestUtils.runWithArchive(args);
+ * out.shouldContain("Hi");
+ *
+ * However, if the JVM process fails with mapping failure, the string "Hi" will not be in the output,
+ * and your test case will fail intermittently.
+ *
+ * Instead, the test case should be written as
+ *
+ * CCDSTestUtils.run(args).assertNormalExit("Hi");
+ *
+ * EXAMPLES/HOWTO
+ *
+ * 1. For simple substring matching:
+ *
+ * CCDSTestUtils.run(args).assertNormalExit("Hi");
+ * CCDSTestUtils.run(args).assertNormalExit("a", "b", "x");
+ * CCDSTestUtils.run(args).assertAbnormalExit("failure 1", "failure2");
+ *
+ * 2. For more complex output matching: using Lambda expressions
+ *
+ * CCDSTestUtils.run(args)
+ * .assertNormalExit(output -> output.shouldNotContain("this should not be printed");
+ * CCDSTestUtils.run(args)
+ * .assertAbnormalExit(output -> {
+ * output.shouldNotContain("this should not be printed");
+ * output.shouldHaveExitValue(123);
+ * });
+ *
+ * 3. Chaining several checks:
+ *
+ * CCDSTestUtils.run(args)
+ * .assertNormalExit(output -> output.shouldNotContain("this should not be printed")
+ * .assertNormalExit("should have this", "should have that");
+ *
+ * 4. [Rare use case] if a test sometimes exit normally, and sometimes abnormally:
+ *
+ * CCDSTestUtils.run(args)
+ * .ifNormalExit("ths string is printed when exiting with 0")
+ * .ifAbNormalExit("ths string is printed when exiting with 1");
+ *
+ * NOTE: you usually don't want to write your test case like this -- it should always
+ * exit with the same exit code. (But I kept this API because some existing test cases
+ * behave this way -- need to revisit).
+ */
+ public static class Result {
+ private final OutputAnalyzer output;
+ private final CDSOptions options;
+ private final boolean hasMappingFailure;
+ private final boolean hasAbnormalExit;
+ private final boolean hasNormalExit;
+
+ public Result(CDSOptions opts, OutputAnalyzer out) throws Exception {
+ options = opts;
+ output = out;
+ hasMappingFailure = CDSTestUtils.checkCommonExecExceptions(output);
+ hasAbnormalExit = (!hasMappingFailure) && (output.getExitValue() != 0);
+ hasNormalExit = (!hasMappingFailure) && (output.getExitValue() == 0);
+
+ if (hasNormalExit) {
+ if ("on".equals(options.xShareMode) && output.getStderr().contains("java version")) {
+ // "-showversion" is always passed in the command-line by the execXXX methods.
+ // During normal exit, we require that the VM to show that sharing was enabled.
+ output.shouldContain("sharing");
+ }
+ }
+ }
+
+ public Result assertNormalExit(Checker checker) throws Exception {
+ if (!hasMappingFailure) {
+ checker.check(output);
+ output.shouldHaveExitValue(0);
+ }
+ return this;
+ }
+
+ public Result assertAbnormalExit(Checker checker) throws Exception {
+ if (!hasMappingFailure) {
+ checker.check(output);
+ output.shouldNotHaveExitValue(0);
+ }
+ return this;
+ }
+
+ public Result ifNormalExit(Checker checker) throws Exception {
+ if (hasNormalExit) {
+ checker.check(output);
+ }
+ return this;
+ }
+
+ public Result ifAbnormalExit(Checker checker) throws Exception {
+ if (hasAbnormalExit) {
+ checker.check(output);
+ }
+ return this;
+ }
+
+ public Result ifNoMappingFailure(Checker checker) throws Exception {
+ if (!hasMappingFailure) {
+ checker.check(output);
+ }
+ return this;
+ }
+
+
+ public Result assertNormalExit(String... matches) throws Exception {
+ if (!hasMappingFailure) {
+ checkMatches(output, matches);
+ output.shouldHaveExitValue(0);
+ }
+ return this;
+ }
+
+ public Result assertAbnormalExit(String... matches) throws Exception {
+ if (!hasMappingFailure) {
+ checkMatches(output, matches);
+ output.shouldNotHaveExitValue(0);
+ }
+
+ return this;
+ }
+ }
+
// Specify this property to copy sdandard output of the child test process to
// the parent/main stdout of the test.
// By default such output is logged into a file, and is copied into the main stdout.
@@ -119,7 +273,7 @@
// of exceptions and common errors.
// Exception e argument - an exception to be re-thrown if none of the common
// exceptions match. Pass null if you wish not to re-throw any exception.
- public static void checkCommonExecExceptions(OutputAnalyzer output, Exception e)
+ public static boolean checkCommonExecExceptions(OutputAnalyzer output, Exception e)
throws Exception {
if (output.getStdout().contains("http://bugreport.java.com/bugreport/crash.jsp")) {
throw new RuntimeException("Hotspot crashed");
@@ -128,7 +282,7 @@
throw new RuntimeException("Test Failed");
}
if (output.getOutput().contains("shared class paths mismatch")) {
- throw new RuntimeException("shared class paths mismatch");
+// throw new RuntimeException("shared class paths mismatch");
}
if (output.getOutput().contains("Unable to unmap shared space")) {
throw new RuntimeException("Unable to unmap shared space");
@@ -139,11 +293,17 @@
// and can be random (see ASLR).
if (isUnableToMap(output)) {
System.out.println(UnableToMapMsg);
- return;
+ return true;
}
- if (e != null)
+ if (e != null) {
throw e;
+ }
+ return false;
+ }
+
+ public static boolean checkCommonExecExceptions(OutputAnalyzer output) throws Exception {
+ return checkCommonExecExceptions(output, null);
}
@@ -176,6 +336,12 @@
return false;
}
+ public static Result run(String... cliPrefix) throws Exception {
+ CDSOptions opts = new CDSOptions();
+ opts.setArchiveName(getDefaultArchiveName());
+ opts.addPrefix(cliPrefix);
+ return new Result(opts, runWithArchive(opts));
+ }
// Execute JVM with CDS archive, specify command line args suffix
public static OutputAnalyzer runWithArchive(String... cliPrefix)
@@ -246,7 +412,7 @@
return output;
}
- checkExtraMatches(output, extraMatches);
+ checkMatches(output, extraMatches);
return output;
}
@@ -260,13 +426,13 @@
}
output.shouldHaveExitValue(expectedExitValue);
- checkExtraMatches(output, extraMatches);
+ checkMatches(output, extraMatches);
return output;
}
- public static OutputAnalyzer checkExtraMatches(OutputAnalyzer output,
- String... extraMatches) throws Exception {
- for (String match : extraMatches) {
+ public static OutputAnalyzer checkMatches(OutputAnalyzer output,
+ String... matches) throws Exception {
+ for (String match : matches) {
output.shouldContain(match);
}
return output;
--- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java Mon Feb 26 09:56:12 2018 +0100
@@ -161,7 +161,7 @@
Files.copy(dockerfile, buildDir.resolve("Dockerfile"));
// Build the docker
- execute("docker", "build", buildDir.toString(), "--no-cache", "--tag", imageName)
+ execute("docker", "build", "--no-cache", "--tag", imageName, buildDir.toString())
.shouldHaveExitValue(0)
.shouldContain("Successfully built");
}
--- a/test/lib/sun/hotspot/WhiteBox.java Tue Feb 20 21:46:02 2018 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java Mon Feb 26 09:56:12 2018 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -541,4 +541,6 @@
public native boolean isContainerized();
public native void printOsInfo();
+ // Decoder
+ public native void disableElfSectionCache();
}