--- a/make/Images.gmk Fri Feb 16 16:18:55 2018 -0800
+++ b/make/Images.gmk Tue Feb 20 13:30:49 2018 -0800
@@ -134,18 +134,22 @@
$(call DependOnVariable, JDK_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jdk jimage
$(RM) -r $(JDK_IMAGE_DIR)
- $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
- $(JLINK_JDK_EXTRA_OPTS) \
- --output $(JDK_IMAGE_DIR)
+ $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jdk, \
+ $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
+ $(JLINK_JDK_EXTRA_OPTS) \
+ --output $(JDK_IMAGE_DIR) \
+ )
$(TOUCH) $@
$(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre jimage
$(RM) -r $(JRE_IMAGE_DIR)
- $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
- $(JLINK_JRE_EXTRA_OPTS) \
- --output $(JRE_IMAGE_DIR)
+ $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre, \
+ $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
+ --output $(JRE_IMAGE_DIR) \
+ )
$(TOUCH) $@
@@ -153,27 +157,33 @@
$(call DependOnVariable, JRE_COMPACT1_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre compact1 jimage
$(RM) -r $(JRE_COMPACT1_IMAGE_DIR)
- $(JLINK_TOOL) --add-modules $(JRE_COMPACT1_MODULES_LIST) \
- $(JLINK_JRE_EXTRA_OPTS) \
- --output $(JRE_COMPACT1_IMAGE_DIR)
+ $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre_compact1, \
+ $(JLINK_TOOL) --add-modules $(JRE_COMPACT1_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
+ --output $(JRE_COMPACT1_IMAGE_DIR) \
+ )
$(TOUCH) $@
$(JRE_COMPACT2_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_COMPACT2_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre compact2 jimage
$(RM) -r $(JRE_COMPACT2_IMAGE_DIR)
- $(JLINK_TOOL) --add-modules $(JRE_COMPACT2_MODULES_LIST) \
- $(JLINK_JRE_EXTRA_OPTS) \
- --output $(JRE_COMPACT2_IMAGE_DIR)
+ $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre_compact2, \
+ $(JLINK_TOOL) --add-modules $(JRE_COMPACT2_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
+ --output $(JRE_COMPACT2_IMAGE_DIR) \
+ )
$(TOUCH) $@
$(JRE_COMPACT3_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_COMPACT3_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre compact3 jimage
$(RM) -r $(JRE_COMPACT3_IMAGE_DIR)
- $(JLINK_TOOL) --add-modules $(JRE_COMPACT3_MODULES_LIST) \
- $(JLINK_JRE_EXTRA_OPTS) \
- --output $(JRE_COMPACT3_IMAGE_DIR)
+ $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/images/jre_compact3, \
+ $(JLINK_TOOL) --add-modules $(JRE_COMPACT3_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
+ --output $(JRE_COMPACT3_IMAGE_DIR) \
+ )
$(TOUCH) $@
TOOL_JRE_TARGETS := $(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE)
--- a/make/Main.gmk Fri Feb 16 16:18:55 2018 -0800
+++ b/make/Main.gmk Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/make/autoconf/basics.m4 Tue Feb 20 13:30:49 2018 -0800
@@ -258,16 +258,12 @@
if test "x$READLINK_TESTED" != yes; then
# On MacOSX there is a readlink tool with a different
# purpose than the GNU readlink tool. Check the found readlink.
- ISGNU=`$READLINK --version 2>&1 | $GREP GNU`
- if test "x$ISGNU" = x; then
- # A readlink that we do not know how to use.
- # Are there other non-GNU readlinks out there?
- READLINK_TESTED=yes
- READLINK=
- fi
+ READLINK_ISGNU=`$READLINK --version 2>&1 | $GREP GNU`
+ # If READLINK_ISGNU is empty, then it's a non-GNU readlink. Don't use it.
+ READLINK_TESTED=yes
fi
- if test "x$READLINK" != x; then
+ if test "x$READLINK" != x && "x$READLINK_ISGNU" != x; then
$1=`$READLINK -f [$]$1`
else
# Save the current directory for restoring afterwards
@@ -494,6 +490,7 @@
BASIC_REQUIRE_PROGS(MV, mv)
BASIC_REQUIRE_PROGS(NAWK, [nawk gawk awk])
BASIC_REQUIRE_PROGS(PRINTF, printf)
+ BASIC_REQUIRE_PROGS(READLINK, [greadlink readlink])
BASIC_REQUIRE_PROGS(RM, rm)
BASIC_REQUIRE_PROGS(RMDIR, rmdir)
BASIC_REQUIRE_PROGS(SH, sh)
@@ -525,7 +522,6 @@
# These are not required on all platforms
BASIC_PATH_PROGS(CYGPATH, cygpath)
- BASIC_PATH_PROGS(READLINK, [greadlink readlink])
BASIC_PATH_PROGS(DF, df)
BASIC_PATH_PROGS(CPIO, [cpio bsdcpio])
BASIC_PATH_PROGS(NICE, nice)
--- a/make/autoconf/spec.gmk.in Fri Feb 16 16:18:55 2018 -0800
+++ b/make/autoconf/spec.gmk.in Tue Feb 20 13:30:49 2018 -0800
@@ -685,6 +685,7 @@
PANDOC:=@FIXPATH@ @PANDOC@
PATCH:=@PATCH@
PRINTF:=@PRINTF@
+READLINK:=@READLINK@
RM:=@RM@
RMDIR:=@RMDIR@
SED:=@SED@
--- a/make/common/MakeBase.gmk Fri Feb 16 16:18:55 2018 -0800
+++ b/make/common/MakeBase.gmk Tue Feb 20 13:30:49 2018 -0800
@@ -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
@@ -545,8 +545,18 @@
define install-file
$(call MakeTargetDir)
$(RM) '$(call DecodeSpace, $@)'
- $(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'
- if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then $(XATTR) -cs '$(call DecodeSpace, $@)'; fi
+ # Work around a weirdness with cp on Macosx. When copying a symlink, if
+ # the target of the link is write protected (e.g. 444), cp will add
+ # write permission for the user on the target file (644). Avoid this by
+ # using ln to create a new link instead.
+ if [ -h '$(call DecodeSpace, $<)' ]; then \
+ $(LN) -s "`$(READLINK) '$(call DecodeSpace, $<)'`" '$(call DecodeSpace, $@)'; \
+ else \
+ $(CP) -fRP '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \
+ fi
+ if [ -n "`$(XATTR) -ls '$(call DecodeSpace, $@)'`" ]; then \
+ $(XATTR) -cs '$(call DecodeSpace, $@)'; \
+ fi
endef
else
define install-file
@@ -1000,6 +1010,7 @@
# Param 2 - The command to run
ExecuteWithLog = \
$(call LogCmdlines, Exececuting: [$(strip $2)]) \
+ $(call MakeDir, $(dir $(strip $1))) \
$(call WriteFile, $2, $(strip $1).cmdline) \
( $(strip $2) > >($(TEE) $(strip $1).log) 2> >($(TEE) $(strip $1).log >&2) || \
( exitcode=$(DOLLAR)? && \
--- a/make/devkit/createSolarisDevkit.sh Fri Feb 16 16:18:55 2018 -0800
+++ /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 Tue Feb 20 13:30:49 2018 -0800
@@ -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 Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/make/mapfiles/libjava/mapfile-vers Tue Feb 20 13:30:49 2018 -0800
@@ -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/make/scripts/compare.sh Fri Feb 16 16:18:55 2018 -0800
+++ b/make/scripts/compare.sh Tue Feb 20 13:30:49 2018 -0800
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2012, 2016, 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
@@ -94,7 +94,7 @@
$SED -e '/[<>] \* from.*\.idl/d' \
-e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
-e '/[<>] .*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d' \
- -e '/[<>] \*.*[0-9]\{4\} [0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \
+ -e '/[<>] \*.*[0-9]\{4\} \(at \)*[0-9][0-9]*:[0-9]\{2\}:[0-9]\{2\}.*/d' \
-e '/\/\/ Generated from input file.*/d' \
-e '/\/\/ This file was generated AUTOMATICALLY from a template file.*/d' \
-e '/\/\/ java GenerateCharacter.*/d')
@@ -102,9 +102,12 @@
# Ignore date strings in class files.
# Anonymous lambda classes get randomly assigned counters in their names.
if test "x$SUFFIX" = "xclass"; then
- if [ "$NAME" = "SystemModules.class" ]; then
- # The SystemModules.class is not comparable. The way it is generated is
- # too random. It can even be of different size for no apparent reason.
+ if [ "$NAME" = "SystemModules\$all.class" ] \
+ || [ "$NAME" = "SystemModules\$default.class" ]; then
+ # The SystemModules\$*.classes are not comparable as they contain the
+ # module hashes which would require a whole other level of
+ # reproducible builds to get reproducible. There is also random
+ # order of map initialization.
TMP=""
elif [ "$NAME" = "module-info.class" ]; then
# The module-info.class have several issues with random ordering of
@@ -654,7 +657,6 @@
# pdb files.
PDB_DIRS="$(ls -d \
{$OTHER,$THIS}/support/modules_{cmds,libs}/{*,*/*} \
- {$OTHER,$THIS}/support/demos/image/jvmti/*/lib \
{$OTHER,$THIS}/support/native/java.base/java_objs \
)"
export _NT_SYMBOL_PATH="$(echo $PDB_DIRS | tr ' ' ';')"
@@ -1001,6 +1003,12 @@
-o -name '*.dll' -o -name '*.obj' -o -name '*.o' -o -name '*.a' \
-o -name '*.cpl' \) | $SORT | $FILTER)
+ # On macos, filter out the dSYM debug symbols files as they are also
+ # named *.dylib.
+ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
+ LIBS=$(echo "$LIBS" | $GREP -v '\.dSYM/')
+ fi
+
if [ -n "$LIBS" ]; then
echo Libraries...
print_binary_diff_header
@@ -1041,7 +1049,7 @@
-o -name '*.jfc' -o -name '*.dat' -o -name 'release' -o -name '*.dir'\
-o -name '*.sym' -o -name '*.idl' -o -name '*.h' -o -name '*.access' \
-o -name '*.template' -o -name '*.policy' -o -name '*.security' \
- -o -name 'COPYRIGHT' -o -name '*.1' \
+ -o -name 'COPYRIGHT' -o -name '*.1' -o -name '*.debuginfo' \
-o -name 'classlist' \) | $SORT | $FILTER)
fi
@@ -1219,7 +1227,7 @@
STRIP_ALL=false
fi
-COMPARE_ROOT=/tmp/cimages.$USER
+COMPARE_ROOT=$OUTPUTDIR/compare-support
if [ "$CLEAN_OUTPUT" = "true" ]; then
echo Cleaning old output in $COMPARE_ROOT.
$RM -rf $COMPARE_ROOT
--- a/make/scripts/compare_exceptions.sh.incl Fri Feb 16 16:18:55 2018 -0800
+++ b/make/scripts/compare_exceptions.sh.incl Tue Feb 20 13:30:49 2018 -0800
@@ -428,8 +428,13 @@
./bin/xjc.exe
"
+ SORT_SYMBOLS="
+ ./bin/fontmanager.dll
+ "
+
ACCEPTED_DIS_DIFF="
./bin/jabswitch.exe
+ ./bin/fontmanager.dll
"
if [ "$OPENJDK_TARGET_CPU" = "x86" ]; then
--- a/src/java.base/share/classes/java/lang/Runtime.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/classes/java/lang/Runtime.java Tue Feb 20 13:30:49 2018 -0800
@@ -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;
@@ -702,9 +704,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 +723,7 @@
* @see java.lang.Object#finalize()
*/
public void runFinalization() {
- runFinalization0();
+ SharedSecrets.getJavaLangRefAccess().runFinalization();
}
/**
--- a/src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java Tue Feb 20 13:30:49 2018 -0800
@@ -116,8 +116,24 @@
argv[0], argv[1]);
break;
case 3:
- result = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2]);
+ // Special case the LambdaMetafactory::metafactory BSM
+ //
+ // By invoking exactly, we can avoid generating a number of
+ // classes on first (and subsequent) lambda initialization,
+ // most of which won't be shared with other invoke uses.
+ MethodType bsmType = bootstrapMethod.type();
+ if (isLambdaMetafactoryIndyBSM(bsmType)) {
+ result = (CallSite)bootstrapMethod
+ .invokeExact(caller, name, (MethodType)type, (MethodType)argv[0],
+ (MethodHandle)argv[1], (MethodType)argv[2]);
+ } else if (isLambdaMetafactoryCondyBSM(bsmType)) {
+ result = bootstrapMethod
+ .invokeExact(caller, name, (Class<?>)type, (MethodType)argv[0],
+ (MethodHandle)argv[1], (MethodType)argv[2]);
+ } else {
+ result = bootstrapMethod.invoke(caller, name, type,
+ argv[0], argv[1], argv[2]);
+ }
break;
case 4:
result = bootstrapMethod.invoke(caller, name, type,
@@ -175,6 +191,30 @@
}
}
+ 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);
+
+ /**
+ * @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 Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java Tue Feb 20 13:30:49 2018 -0800
@@ -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/ref/Reference.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/classes/java/lang/ref/Reference.java Tue Feb 20 13:30:49 2018 -0800
@@ -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/util/Locale.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/classes/java/util/Locale.java Tue Feb 20 13:30:49 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -1946,9 +1946,10 @@
* script (country(, extension)*)<br>
* country (extension)*<br>
* </blockquote>
- * depending on which fields are specified in the locale. If the
- * language, script, country, and variant fields are all empty,
- * this function returns the empty string.
+ * depending on which fields are specified in the locale. The field
+ * separator in the above parentheses, denoted as a comma character, may
+ * be localized depending on the locale. If the language, script, country,
+ * and variant fields are all empty, this function returns the empty string.
*
* @return The name of the locale appropriate to display.
*/
@@ -1971,9 +1972,10 @@
* script (country(, extension)*)<br>
* country (extension)*<br>
* </blockquote>
- * depending on which fields are specified in the locale. If the
- * language, script, country, and variant fields are all empty,
- * this function returns the empty string.
+ * depending on which fields are specified in the locale. The field
+ * separator in the above parentheses, denoted as a comma character, may
+ * be localized depending on the locale. If the language, script, country,
+ * and variant fields are all empty, this function returns the empty string.
*
* @param inLocale The locale for which to retrieve the display name.
* @return The name of the locale appropriate to display.
--- a/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java Tue Feb 20 13:30:49 2018 -0800
@@ -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/native/libjava/Runtime.c Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/share/native/libjava/Runtime.c Tue Feb 20 13:30:49 2018 -0800
@@ -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/windows/classes/java/net/TwoStacksPlainSocketImpl.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java Tue Feb 20 13:30:49 2018 -0800
@@ -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
@@ -29,42 +29,13 @@
import sun.net.ResourceManager;
/*
- * This class defines the plain SocketImpl that is used for all
- * Windows version lower than Vista. It adds support for IPv6 on
- * these platforms where available.
- *
- * For backward compatibility Windows platforms that do not have IPv6
- * support also use this implementation, and fd1 gets set to null
- * during socket creation.
+ * This class defines the plain SocketImpl that is used when
+ * the System property java.net.preferIPv4Stack is set to true.
*
* @author Chris Hegarty
*/
-class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl
-{
- /* second fd, used for ipv6 on windows only.
- * fd1 is used for listeners and for client sockets at initialization
- * until the socket is connected. Up to this point fd always refers
- * to the ipv4 socket and fd1 to the ipv6 socket. After the socket
- * becomes connected, fd always refers to the connected socket
- * (either v4 or v6) and fd1 is closed.
- *
- * For ServerSockets, fd always refers to the v4 listener and
- * fd1 the v6 listener.
- */
- private FileDescriptor fd1;
-
- /*
- * Needed for ipv6 on windows because we need to know
- * if the socket is bound to ::0 or 0.0.0.0, when a caller
- * asks for it. Otherwise we don't know which socket to ask.
- */
- private InetAddress anyLocalBoundAddr = null;
-
- /* to prevent starvation when listening on two sockets, this is
- * is used to hold the id of the last socket we accepted on.
- */
- private int lastfd = -1;
+class TwoStacksPlainSocketImpl extends AbstractPlainSocketImpl {
// true if this socket is exclusively bound
private final boolean exclusiveBind;
@@ -85,43 +56,11 @@
exclusiveBind = exclBind;
}
- /**
- * Creates a socket with a boolean that specifies whether this
- * is a stream socket (true) or an unconnected UDP socket (false).
- */
- protected synchronized void create(boolean stream) throws IOException {
- fd1 = new FileDescriptor();
- try {
- super.create(stream);
- } catch (IOException e) {
- fd1 = null;
- throw e;
- }
- }
-
- /**
- * Binds the socket to the specified address of the specified local port.
- * @param address the address
- * @param port the port
- */
- protected synchronized void bind(InetAddress address, int lport)
- throws IOException
- {
- super.bind(address, lport);
- if (address.isAnyLocalAddress()) {
- anyLocalBoundAddr = address;
- }
- }
-
public Object getOption(int opt) throws SocketException {
if (isClosedOrPending()) {
throw new SocketException("Socket Closed");
}
if (opt == SO_BINDADDR) {
- if (fd != null && fd1 != null ) {
- /* must be unbound or else bound to anyLocal */
- return anyLocalBoundAddr;
- }
InetAddressContainer in = new InetAddressContainer();
socketGetOption(opt, in);
return in.addr;
@@ -161,7 +100,7 @@
@Override
protected void close() throws IOException {
synchronized(fdLock) {
- if (fd != null || fd1 != null) {
+ if (fd != null) {
if (!stream) {
ResourceManager.afterUdpClose();
}
@@ -172,7 +111,6 @@
closePending = true;
socketClose();
fd = null;
- fd1 = null;
return;
} else {
/*
@@ -191,39 +129,11 @@
}
}
- @Override
- void reset() throws IOException {
- if (fd != null || fd1 != null) {
- socketClose();
- }
- fd = null;
- fd1 = null;
- super.reset();
- }
-
- /*
- * Return true if already closed or close is pending
- */
- @Override
- public boolean isClosedOrPending() {
- /*
- * Lock on fdLock to ensure that we wait if a
- * close is in progress.
- */
- synchronized (fdLock) {
- if (closePending || (fd == null && fd1 == null)) {
- return true;
- } else {
- return false;
- }
- }
- }
-
/* Native methods */
static native void initProto();
- native void socketCreate(boolean isServer) throws IOException;
+ native void socketCreate(boolean stream) throws IOException;
native void socketConnect(InetAddress address, int port, int timeout)
throws IOException;
--- a/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Fri Feb 16 16:18:55 2018 -0800
+++ b/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Tue Feb 20 13:30:49 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, 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,14 +37,12 @@
static jfieldID IO_fd_fdID;
jfieldID psi_fdID;
-jfieldID psi_fd1ID;
jfieldID psi_addressID;
jfieldID psi_portID;
jfieldID psi_localportID;
jfieldID psi_timeoutID;
jfieldID psi_trafficClassID;
jfieldID psi_serverSocketID;
-jfieldID psi_lastfdID;
/*
* the level of the TCP protocol for setsockopt and getsockopt
@@ -62,15 +60,6 @@
return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
-static int getFD1(JNIEnv *env, jobject this) {
- jobject fdObj = (*env)->GetObjectField(env, this, psi_fd1ID);
-
- if (fdObj == NULL) {
- return -1;
- }
- return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-}
-
/*
* The initProto function is called whenever TwoStacksPlainSocketImpl is
@@ -90,15 +79,11 @@
psi_fdID = (*env)->GetFieldID(env, cls , "fd", "Ljava/io/FileDescriptor;");
CHECK_NULL(psi_fdID);
- psi_fd1ID =(*env)->GetFieldID(env, cls , "fd1", "Ljava/io/FileDescriptor;");
- CHECK_NULL(psi_fd1ID);
psi_addressID = (*env)->GetFieldID(env, cls, "address",
"Ljava/net/InetAddress;");
CHECK_NULL(psi_addressID);
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
CHECK_NULL(psi_portID);
- psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
- CHECK_NULL(psi_lastfdID);
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
CHECK_NULL(psi_localportID);
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
@@ -120,8 +105,8 @@
JNIEXPORT void JNICALL
Java_java_net_TwoStacksPlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
jboolean stream) {
- jobject fdObj, fd1Obj;
- int fd, fd1;
+ jobject fdObj;
+ int fd;
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
@@ -139,30 +124,6 @@
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, FALSE);
(*env)->SetIntField(env, fdObj, IO_fd_fdID, (int)fd);
}
- if (ipv6_available()) {
- fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
-
- if (IS_NULL(fd1Obj)) {
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
- NET_SocketClose(fd);
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "null fd1 object");
- return;
- }
- fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
- if (fd1 == -1) {
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
- NET_SocketClose(fd);
- NET_ThrowCurrent(env, "create");
- return;
- } else {
- /* Set socket attribute so it is not passed to any child process */
- SetHandleInformation((HANDLE)(UINT_PTR)fd1, HANDLE_FLAG_INHERIT, FALSE);
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
- }
- } else {
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
- }
}
/*
@@ -182,16 +143,10 @@
/* family and localport are int fields of iaObj */
int family;
- jint fd = -1, fd1 = -1;
+ jint fd = -1;
jint len;
- int ipv6_supported = ipv6_available();
- /* fd initially points to the IPv4 socket and fd1 to the IPv6 socket
- * If we want to connect to IPv6 then we swap the two sockets/objects
- * This way, fd is always the connected socket, and fd1 always gets closed.
- */
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
SOCKETADDRESS sa;
@@ -203,10 +158,6 @@
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
- if (ipv6_supported && !IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- }
-
if (IS_NULL(iaObj)) {
JNU_ThrowNullPointerException(env, "inet address argument is null.");
return;
@@ -218,35 +169,15 @@
}
family = sa.sa.sa_family;
- if (family == AF_INET6) {
- if (!ipv6_supported) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Protocol family not supported");
- return;
- } else {
- if (fd1 == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Destination unreachable");
- return;
- }
- /* close the v4 socket, and set fd to be the v6 socket */
- (*env)->SetObjectField(env, this, psi_fdID, fd1Obj);
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
- NET_SocketClose(fd);
- fd = fd1; fdObj = fd1Obj;
- }
- } else {
- if (fd1 != -1) {
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
- NET_SocketClose(fd1);
- }
- if (fd == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "Destination unreachable");
- return;
- }
+ if (family != AF_INET) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ "Protocol family not supported");
}
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
+ if (fd == -1) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ "Destination unreachable");
+ return;
+ }
if (timeout <= 0) {
connect_res = connect(fd, &sa.sa, sizeof(SOCKETADDRESS));
@@ -388,10 +319,9 @@
jboolean exclBind) {
/* fdObj is the FileDescriptor field on this */
- jobject fdObj, fd1Obj;
+ jobject fdObj;
/* fd is an int field on fdObj */
- int fd, fd1 = -1, len = 0;
- int ipv6_supported = ipv6_available();
+ int fd, len = 0;
/* family is an int field of iaObj */
int family;
@@ -400,25 +330,21 @@
SOCKETADDRESS sa;
fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
family = getInetAddress_family(env, iaObj);
- if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
+ if (family != java_net_InetAddress_IPv4) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Protocol family not supported");
return;
}
- if (IS_NULL(fdObj) || (ipv6_supported && IS_NULL(fd1Obj))) {
+ if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
} else {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- if (ipv6_supported) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- }
}
if (IS_NULL(iaObj)) {
JNU_ThrowNullPointerException(env, "inet address argument");
@@ -429,42 +355,7 @@
JNI_FALSE) != 0) {
return;
}
- if (ipv6_supported) {
- struct ipv6bind v6bind;
- v6bind.addr = &sa.sa;
- v6bind.ipv4_fd = fd;
- v6bind.ipv6_fd = fd1;
- rv = NET_BindV6(&v6bind, exclBind);
- if (rv != -1) {
- /* check if the fds have changed */
- if (v6bind.ipv4_fd != fd) {
- fd = v6bind.ipv4_fd;
- if (fd == -1) {
- /* socket is closed. */
- (*env)->SetObjectField(env, this, psi_fdID, NULL);
- } else {
- /* socket was re-created */
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
- }
- }
- if (v6bind.ipv6_fd != fd1) {
- fd1 = v6bind.ipv6_fd;
- if (fd1 == -1) {
- /* socket is closed. */
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
- } else {
- /* socket was re-created */
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, fd1);
- }
- }
- } else {
- /* NET_BindV6() closes both sockets upon a failure */
- (*env)->SetObjectField(env, this, psi_fdID, NULL);
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
- }
- } else {
- rv = NET_WinBind(fd, &sa, len, exclBind);
- }
+ rv = NET_WinBind(fd, &sa, len, exclBind);
if (rv == -1) {
NET_ThrowCurrent(env, "NET_Bind");
@@ -482,7 +373,7 @@
int len = sizeof(SOCKETADDRESS);
u_short port;
- if (getsockname(sa.sa.sa_family == AF_INET ? fd : fd1, &sa.sa, &len) == -1) {
+ if (getsockname(fd, &sa.sa, &len) == -1) {
NET_ThrowCurrent(env, "getsockname in plain socketBind");
return;
}
@@ -505,14 +396,13 @@
{
/* this FileDescriptor fd field */
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
jobject address;
/* fdObj's int fd field */
- int fd = INVALID_SOCKET, fd1 = INVALID_SOCKET;
+ int fd = INVALID_SOCKET;
SOCKETADDRESS addr;
int addrlen;
- if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
+ if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"socket closed");
return;
@@ -521,10 +411,6 @@
if (!IS_NULL(fdObj)) {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
- /* Listen on V4 if address type is v4 or if v6 and address is ::0.
- * Listen on V6 if address type is v6 or if v4 and address is 0.0.0.0.
- * In cases, where we listen on one space only, we close the other socket.
- */
address = (*env)->GetObjectField(env, this, psi_addressID);
if (IS_NULL(address)) {
JNU_ThrowNullPointerException(env, "socket address");
@@ -535,27 +421,15 @@
return;
}
- if (addr.sa.sa_family == AF_INET || IN6ADDR_ISANY(&addr.sa6)) {
+ if (addr.sa.sa_family == AF_INET) {
/* listen on v4 */
if (listen(fd, count) == -1) {
NET_ThrowCurrent(env, "listen failed");
}
} else {
- NET_SocketClose (fd);
+ NET_SocketClose(fd);
(*env)->SetObjectField(env, this, psi_fdID, NULL);
}
- if (ipv6_available() && !IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- if (addr.sa.sa_family == AF_INET6 || addr.sa4.sin_addr.s_addr == INADDR_ANY) {
- /* listen on v6 */
- if (listen(fd1, count) == -1) {
- NET_ThrowCurrent(env, "listen failed");
- }
- } else {
- NET_SocketClose (fd1);
- (*env)->SetObjectField(env, this, psi_fd1ID, NULL);
- }
- }
}
/*
@@ -571,35 +445,31 @@
jint port;
jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
/* the FileDescriptor field on socket */
jobject socketFdObj;
- /* cache the Inet4/6Address classes */
+ /* cache the Inet4 class */
static jclass inet4Cls;
- static jclass inet6Cls;
/* the InetAddress field on socket */
jobject socketAddressObj;
/* the fd int field on fdObj */
- jint fd=-1, fd1=-1;
+ jint fd=-1;
SOCKETADDRESS sa;
jint len;
+ int ret;
- if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
+ if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return;
}
- if (!IS_NULL(fdObj)) {
- fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
- }
- if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- }
+
+ fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
if (IS_NULL(socket)) {
JNU_ThrowNullPointerException(env, "socket is null");
return;
@@ -611,72 +481,26 @@
JNU_ThrowNullPointerException(env, "socket address or fd obj");
return;
}
- if (fd != -1 && fd1 != -1) {
- fd_set rfds;
- struct timeval t, *tP=&t;
- int lastfd, res, fd2;
- FD_ZERO(&rfds);
- FD_SET(fd,&rfds);
- FD_SET(fd1,&rfds);
- if (timeout) {
- t.tv_sec = timeout/1000;
- t.tv_usec = (timeout%1000)*1000;
- } else {
- tP = NULL;
- }
- res = select (fd, &rfds, NULL, NULL, tP);
- if (res == 0) {
+
+ len = sizeof(struct sockaddr_in);
+ if (timeout) {
+ ret = NET_Timeout(fd, timeout);
+ if (ret == 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
"Accept timed out");
return;
- } else if (res == 1) {
- fd2 = FD_ISSET(fd, &rfds)? fd: fd1;
- } else if (res == 2) {
- /* avoid starvation */
- lastfd = (*env)->GetIntField(env, this, psi_lastfdID);
- if (lastfd != -1) {
- fd2 = lastfd==fd? fd1: fd;
- } else {
- fd2 = fd;
- }
- (*env)->SetIntField(env, this, psi_lastfdID, fd2);
- } else {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "select failed");
+ } else if (ret == -1) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ /* REMIND: SOCKET CLOSED PROBLEM */
+/* NET_ThrowCurrent(env, "Accept failed"); */
+ return;
+ } else if (ret == -2) {
+ JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
+ "operation interrupted");
return;
}
- if (fd2 == fd) { /* v4 */
- len = sizeof(struct sockaddr_in);
- } else {
- len = sizeof(struct sockaddr_in6);
- }
- fd = fd2;
- } else {
- int ret;
- if (fd1 != -1) {
- fd = fd1;
- len = sizeof(struct sockaddr_in6);
- } else {
- len = sizeof(struct sockaddr_in);
- }
- if (timeout) {
- ret = NET_Timeout(fd, timeout);
- if (ret == 0) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
- "Accept timed out");
- return;
- } else if (ret == -1) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
- /* REMIND: SOCKET CLOSED PROBLEM */
- /* NET_ThrowCurrent(env, "Accept failed"); */
- return;
- } else if (ret == -2) {
- JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
- "operation interrupted");
- return;
- }
- }
}
+
fd = accept(fd, &sa.sa, &len);
if (fd < 0) {
/* REMIND: SOCKET CLOSED PROBLEM */
@@ -692,65 +516,40 @@
SetHandleInformation((HANDLE)(UINT_PTR)fd, HANDLE_FLAG_INHERIT, 0);
(*env)->SetIntField(env, socketFdObj, IO_fd_fdID, fd);
- if (sa.sa.sa_family == AF_INET) {
- if (inet4Cls == NULL) {
- jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
- if (c != NULL) {
- inet4Cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- }
+ if (sa.sa.sa_family != AF_INET) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ "Protocol family not supported");
+ return;
+ }
- /*
- * fill up the remote peer port and address in the new socket structure
- */
- if (inet4Cls != NULL) {
- socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
- } else {
- socketAddressObj = NULL;
+ if (inet4Cls == NULL) {
+ jclass c = (*env)->FindClass(env, "java/net/Inet4Address");
+ if (c != NULL) {
+ inet4Cls = (*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
}
- if (socketAddressObj == NULL) {
- /*
- * FindClass or NewObject failed so close connection and
- * exist (there will be a pending exception).
- */
- NET_SocketClose(fd);
- return;
- }
+ }
- setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
- setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
- (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
+ /*
+ * fill up the remote peer port and address in the new socket structure
+ */
+ if (inet4Cls != NULL) {
+ socketAddressObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
} else {
- /* AF_INET6 -> Inet6Address */
- if (inet6Cls == 0) {
- jclass c = (*env)->FindClass(env, "java/net/Inet6Address");
- if (c != NULL) {
- inet6Cls = (*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- }
- }
+ socketAddressObj = NULL;
+ }
+ if (socketAddressObj == NULL) {
+ /*
+ * FindClass or NewObject failed so close connection and
+ * exit (there will be a pending exception).
+ */
+ NET_SocketClose(fd);
+ return;
+ }
- if (inet6Cls != NULL) {
- socketAddressObj = (*env)->NewObject(env, inet6Cls, ia6_ctrID);
- } else {
- socketAddressObj = NULL;
- }
- if (socketAddressObj == NULL) {
- /*
- * FindClass or NewObject failed so close connection and
- * exist (there will be a pending exception).
- */
- NET_SocketClose(fd);
- return;
- }
- setInet6Address_ipaddress(env, socketAddressObj, (char *)&sa.sa6.sin6_addr);
- setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv6);
- setInet6Address_scopeid(env, socketAddressObj, sa.sa6.sin6_scope_id);
-
- }
- /* fields common to AF_INET and AF_INET6 */
-
+ setInetAddress_addr(env, socketAddressObj, ntohl(sa.sa4.sin_addr.s_addr));
+ setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
+ (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
port = ntohs ((u_short)GET_PORT(&sa));
(*env)->SetIntField(env, socket, psi_portID, (int)port);
port = (*env)->GetIntField(env, this, psi_localportID);
@@ -795,10 +594,9 @@
jboolean useDeferredClose) {
jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
- jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
- jint fd=-1, fd1=-1;
+ jint fd=-1;
- if (IS_NULL(fdObj) && IS_NULL(fd1Obj)) {
+ if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"socket already closed");
return;
@@ -806,17 +604,10 @@
if (!IS_NULL(fdObj)) {
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
}
- if (!IS_NULL(fd1Obj)) {
- fd1 = (*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
- }
if (fd != -1) {
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
NET_SocketClose(fd);
}
- if (fd1 != -1) {
- (*env)->SetIntField(env, fd1Obj, IO_fd_fdID, -1);
- NET_SocketClose(fd1);
- }
}
/*
@@ -831,7 +622,7 @@
Java_java_net_TwoStacksPlainSocketImpl_socketNativeSetOption
(JNIEnv *env, jobject this, jint cmd, jboolean on, jobject value)
{
- int fd, fd1;
+ int fd;
int level = 0, optname = 0, optlen = 0;
union {
int i;
@@ -843,8 +634,7 @@
* Get SOCKET and check that it hasn't been closed
*/
fd = getFD(env, this);
- fd1 = getFD1(env, this);
- if (fd < 0 && fd1 < 0) {
+ if (fd < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
return;
}
@@ -901,12 +691,6 @@
return;
}
}
- if (fd1 != -1) {
- if (setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
- sizeof(timeout)) < 0) {
- NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
- }
- }
}
return;
}
@@ -980,12 +764,6 @@
NET_ThrowCurrent(env, "setsockopt");
}
}
-
- if (fd1 != -1) {
- if (NET_SetSockOpt(fd1, level, optname, (void *)&optval, optlen) < 0) {
- NET_ThrowCurrent(env, "setsockopt");
- }
- }
}
@@ -998,7 +776,7 @@
Java_java_net_TwoStacksPlainSocketImpl_socketGetOption
(JNIEnv *env, jobject this, jint opt, jobject iaContainerObj)
{
- int fd, fd1;
+ int fd;
int level = 0, optname = 0, optlen = 0;
union {
int i;
@@ -1009,18 +787,12 @@
* Get SOCKET and check it hasn't been closed
*/
fd = getFD(env, this);
- fd1 = getFD1(env, this);
memset((char *)&optval, 0, sizeof(optval));
- if (fd < 0 && fd1 < 0) {
+ if (fd < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
return -1;
}
- if (fd < 0) {
- fd = fd1;
- }
-
- /* For IPv6, we assume both sockets have the same setting always */
/*
* SO_BINDADDR isn't a socket option
@@ -1035,13 +807,6 @@
memset((char *)&sa, 0, len);
- if (fd == -1) {
- /* must be an IPV6 only socket. Case where both sockets are != -1
- * is handled in java
- */
- fd = getFD1 (env, this);
- }
-
if (getsockname(fd, &sa.sa, &len) < 0) {
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Error getting socket name");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Feb 20 13:30:49 2018 -0800
@@ -43,11 +43,10 @@
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.Error;
import com.sun.tools.javac.util.JCDiagnostic.Warning;
+import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
-import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
@@ -290,9 +289,31 @@
/** Skip forward until a suitable stop token is found.
*/
- protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
+ protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement, boolean stopAtLambdaBody) {
while (true) {
switch (token.kind) {
+ case ARROW:
+ if (stopAtLambdaBody) {
+ //find end of lambda expression; this could be either a comma or an rparen (if in method context),
+ //or a semi colon (if in assignment context).
+ int depth = 0;
+ while (true) {
+ switch (token.kind) {
+ case EOF:
+ case LBRACE: depth++; break;
+ case RBRACE: depth--; break;
+ case COMMA:
+ case RPAREN:
+ case SEMI:
+ if (depth == 0) {
+ return;
+ }
+ break;
+ }
+ nextToken();
+ }
+ }
+ break;
case SEMI:
nextToken();
return;
@@ -1076,7 +1097,8 @@
break;
case LPAREN:
if (typeArgs == null && (mode & EXPR) != 0) {
- ParensResult pres = analyzeParens();
+ LambdaClassfier lambdaClassifier = new LambdaClassfier();
+ ParensResult pres = analyzeParens(lambdaClassifier);
switch (pres) {
case CAST:
accept(LPAREN);
@@ -1095,9 +1117,15 @@
mode = EXPR;
JCExpression t1 = term3();
return F.at(pos).TypeCast(t, t1);
+ case BAD_LAMBDA:
+ Assert.checkNonNull(lambdaClassifier.diagFragment);
+ t = syntaxError(pos, List.nil(), Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment));
+ skip(false, false, false, false, true);
+ break;
case IMPLICIT_LAMBDA:
case EXPLICIT_LAMBDA:
- t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos);
+ case IMPLICIT_LAMBDA_ALL_VAR:
+ t = lambdaExpressionOrStatement(true, pres != ParensResult.IMPLICIT_LAMBDA, pos);
break;
default: //PARENS
accept(LPAREN);
@@ -1509,15 +1537,17 @@
* matching '>' and see if the subsequent terminal is either '.' or '::'.
*/
@SuppressWarnings("fallthrough")
- ParensResult analyzeParens() {
+ ParensResult analyzeParens(LambdaClassfier lambdaClassifier) {
int depth = 0;
boolean type = false;
outer: for (int lookahead = 0 ; ; lookahead++) {
- TokenKind tk = S.token(lookahead).kind;
+ Token lookaheadToken = S.token(lookahead);
+ TokenKind tk = lookaheadToken.kind;
switch (tk) {
case COMMA:
type = true;
- case EXTENDS: case SUPER: case DOT: case AMP:
+ break;
+ case FINAL: case EXTENDS: case SUPER: case DOT: case AMP:
//skip
break;
case QUES:
@@ -1534,7 +1564,8 @@
return ParensResult.CAST;
} else if (peekToken(lookahead, LAX_IDENTIFIER)) {
//Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
- return ParensResult.EXPLICIT_LAMBDA;
+ lambdaClassifier.addExplicitParameter();
+ lookahead++; //skip Identifier
}
break;
case LPAREN:
@@ -1547,24 +1578,29 @@
}
break;
case RPAREN:
- // if we have seen something that looks like a type,
- // then it's a cast expression
- if (type) return ParensResult.CAST;
- // otherwise, disambiguate cast vs. parenthesized expression
- // based on subsequent token.
- switch (S.token(lookahead + 1).kind) {
- /*case PLUSPLUS: case SUBSUB: */
- case BANG: case TILDE:
- case LPAREN: case THIS: case SUPER:
- case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
- case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
- case TRUE: case FALSE: case NULL:
- case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
- case BYTE: case SHORT: case CHAR: case INT:
- case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
- return ParensResult.CAST;
- default:
- return ParensResult.PARENS;
+ if (peekToken(lookahead, ARROW)) {
+ //this is a lambda
+ return lambdaClassifier.result();
+ } else {
+ // if we have seen something that looks like a type,
+ // then it's a cast expression
+ if (type) return ParensResult.CAST;
+ // otherwise, disambiguate cast vs. parenthesized expression
+ // based on subsequent token.
+ switch (S.token(lookahead + 1).kind) {
+ /*case PLUSPLUS: case SUBSUB: */
+ case BANG: case TILDE:
+ case LPAREN: case THIS: case SUPER:
+ case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
+ case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
+ case TRUE: case FALSE: case NULL:
+ case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
+ case BYTE: case SHORT: case CHAR: case INT:
+ case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
+ return ParensResult.CAST;
+ default:
+ return ParensResult.PARENS;
+ }
}
case UNDERSCORE:
case ASSERT:
@@ -1572,17 +1608,23 @@
case IDENTIFIER:
if (peekToken(lookahead, LAX_IDENTIFIER)) {
// Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
- return ParensResult.EXPLICIT_LAMBDA;
- } else if (peekToken(lookahead, RPAREN, ARROW)) {
- // Identifier, ')' '->' -> implicit lambda
- return ParensResult.IMPLICIT_LAMBDA;
+ if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) &&
+ lookaheadToken.name() == names.var) {
+ lambdaClassifier.addImplicitVarParameter();
+ } else {
+ lambdaClassifier.addExplicitParameter();
+ }
+ lookahead++; //skip Identifier
+ } else if ((!type && peekToken(lookahead, COMMA)) || peekToken(lookahead, RPAREN)) {
+ lambdaClassifier.addImplicitParameter();
}
type = false;
break;
- case FINAL:
case ELLIPSIS:
- //those can only appear in explicit lambdas
- return ParensResult.EXPLICIT_LAMBDA;
+ //those can only appear in explicit, non-var, lambdas
+ lambdaClassifier.addExplicitParameter();
+ lookahead++; //skip Identifier
+ break;
case MONKEYS_AT:
type = true;
lookahead += 1; //skip '@'
@@ -1614,7 +1656,9 @@
case LBRACKET:
if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
// '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
- return ParensResult.EXPLICIT_LAMBDA;
+ lambdaClassifier.addExplicitParameter();
+ lookahead += 2; //skip ']' Identifier
+ break;
} else if (peekToken(lookahead, RBRACKET, RPAREN) ||
peekToken(lookahead, RBRACKET, AMP)) {
// '[', ']', ')' -> cast
@@ -1643,12 +1687,15 @@
// '>', '&' -> cast
return ParensResult.CAST;
} else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
- peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
- peekToken(lookahead, ELLIPSIS)) {
+ peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW)) {
// '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
// '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
+ lambdaClassifier.addExplicitParameter();
+ lookahead++; //skip Identifier
+ break;
+ } else if (peekToken(lookahead, ELLIPSIS)) {
// '>', '...' -> explicit lambda
- return ParensResult.EXPLICIT_LAMBDA;
+ break; //this is handled in the outer switch
}
//it looks a type, but could still be (i) a cast to generic type,
//(ii) an unbound method reference or (iii) an explicit lambda
@@ -1666,6 +1713,61 @@
}
}
+ class LambdaClassfier {
+ ParensResult kind;
+ Fragment diagFragment;
+
+ 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;
+ }
+ }
+
/** Accepts all identifier-like tokens */
protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
@@ -1673,7 +1775,15 @@
CAST,
EXPLICIT_LAMBDA,
IMPLICIT_LAMBDA,
- PARENS
+ IMPLICIT_LAMBDA_ALL_VAR,
+ BAD_LAMBDA,
+ PARENS;
+ }
+
+ enum BAD_LAMBDA_KIND {
+ EXPLICIT_AND_VAR,
+ IMPLICIT_AND_VAR,
+ EXPLICIT_AND_IMPLICIT,
}
JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
@@ -1896,6 +2006,9 @@
List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
if (token.kind == LBRACKET) {
+ if (t == null) {
+ log.error(token.pos, Errors.VarNotAllowedArray);
+ }
int pos = token.pos;
nextToken();
t = bracketsOptCont(t, pos, nextLevelAnnotations);
@@ -2294,7 +2407,7 @@
if (token.pos == lastErrPos)
return stats.toList();
if (token.pos <= endPosTable.errorEndPos) {
- skip(false, true, true, true);
+ skip(false, true, true, true, false);
lastErrPos = token.pos;
}
stats.addAll(stat);
@@ -3133,7 +3246,7 @@
while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(checkForImports, false, false, false);
+ skip(checkForImports, false, false, false, false);
if (token.kind == EOF)
break;
}
@@ -3270,7 +3383,7 @@
defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
} else {
log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.ExpectedStr("'" + names.with + "'"));
- skip(false, false, false, false);
+ skip(false, false, false, false, false);
}
} else if (token.name() == names.uses) {
nextToken();
@@ -3475,7 +3588,7 @@
false));
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(false, true, true, false);
+ skip(false, true, true, false, false);
}
}
}
@@ -3537,7 +3650,7 @@
accept(LBRACE);
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(false, true, false, false);
+ skip(false, true, false, false, false);
if (token.kind == LBRACE)
nextToken();
}
@@ -3546,7 +3659,7 @@
defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(false, true, true, false);
+ skip(false, true, true, false, false);
}
}
accept(RBRACE);
@@ -3713,7 +3826,7 @@
accept(SEMI);
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(false, true, false, false);
+ skip(false, true, false, false, false);
if (token.kind == LBRACE) {
body = block();
}
@@ -3947,7 +4060,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) {
@@ -3964,6 +4077,10 @@
}
typeAnnotationsPushedBack = List.nil();
}
+ if (lambdaParameter && isRestrictedLocalVarTypeName(type)) {
+ //implicit lambda parameter type (with 'var')
+ type = null;
+ }
return variableDeclaratorId(mods, type, lambdaParameter);
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Feb 16 16:18:55 2018 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Feb 20 13:30:49 2018 -0800
@@ -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.jlink/share/classes/jdk/tools/jimage/JImageTask.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java Tue Feb 20 13:30:49 2018 -0800
@@ -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/jshell/ReplParser.java Fri Feb 16 16:18:55 2018 -0800
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java Tue Feb 20 13:30:49 2018 -0800
@@ -104,7 +104,7 @@
while (token.kind != EOF) {
if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(true, false, false, false);
+ skip(true, false, false, false, false);
if (token.kind == EOF) {
break;
}
--- a/test/jdk/ProblemList.txt Fri Feb 16 16:18:55 2018 -0800
+++ b/test/jdk/ProblemList.txt Tue Feb 20 13:30:49 2018 -0800
@@ -464,9 +464,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
############################################################################
--- a/test/jdk/tools/jimage/JImageExtractTest.java Fri Feb 16 16:18:55 2018 -0800
+++ b/test/jdk/tools/jimage/JImageExtractTest.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/test/jdk/tools/jimage/JImageListTest.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/test/jdk/tools/jlink/JLinkTest.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Tue Feb 20 13:30:49 2018 -0800
@@ -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();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/BracketsNotAllowedImplicitLambda.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Tue Feb 20 13:30:49 2018 -0800
@@ -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 Tue Feb 20 13:30:49 2018 -0800
@@ -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 Tue Feb 20 13:30:49 2018 -0800
@@ -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 Tue Feb 20 13:30:49 2018 -0800
@@ -0,0 +1,31 @@
+/*
+ * 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
+ * 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)->{};
+}
--- a/test/langtools/tools/javac/lambda/8131742/T8131742.out Fri Feb 16 16:18:55 2018 -0800
+++ b/test/langtools/tools/javac/lambda/8131742/T8131742.out Tue Feb 20 13:30:49 2018 -0800
@@ -1,4 +1,4 @@
-T8131742.java:8:38: compiler.err.expected3: ',', ')', '['
+T8131742.java:8:31: compiler.err.expected: ')'
T8131742.java:8:39: compiler.err.this.as.identifier
-T8131742.java:8:43: compiler.err.expected: ';'
+T8131742.java:8:43: compiler.err.expected: token.identifier
3 errors
--- a/test/langtools/tools/javac/lambda/LambdaParserTest.java Fri Feb 16 16:18:55 2018 -0800
+++ b/test/langtools/tools/javac/lambda/LambdaParserTest.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/test/langtools/tools/javac/lvti/ParserTest.java Tue Feb 20 13:30:49 2018 -0800
@@ -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 Fri Feb 16 16:18:55 2018 -0800
+++ b/test/langtools/tools/javac/lvti/ParserTest.out Tue Feb 20 13:30:49 2018 -0800
@@ -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
--- a/test/langtools/tools/javac/parser/extend/TrialParser.java Fri Feb 16 16:18:55 2018 -0800
+++ b/test/langtools/tools/javac/parser/extend/TrialParser.java Tue Feb 20 13:30:49 2018 -0800
@@ -104,7 +104,7 @@
while (token.kind != EOF) {
if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
// error recovery
- skip(true, false, false, false);
+ skip(true, false, false, false, false);
if (token.kind == EOF) {
break;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.java Tue Feb 20 13:30:49 2018 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8194892
+ * @summary add 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;
+ IntBinaryOperator f2 = (var x, y) -> x + y;
+ IntBinaryOperator f3 = (int x, var y) -> x + y;
+ IntBinaryOperator f4 = (int x, y) -> x + y;
+
+ BiFunction<String[], String, String> f5 = (var s1[], var s2) -> s2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.out Tue Feb 20 13:30:49 2018 -0800
@@ -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:54: compiler.err.var.not.allowed.array
+5 errors