# HG changeset patch # User prr # Date 1519162249 28800 # Node ID ca29679eafe5d217c14e0ffeaa327afb3020f149 # Parent 6dc5e0cdb44c2598aaa34d32dd23e3a0a9d3fede# Parent b75c9e2e3b1fe6be1a947f1f6a565bc10e5c5b09 Merge diff -r 6dc5e0cdb44c -r ca29679eafe5 make/Images.gmk --- 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) diff -r 6dc5e0cdb44c -r ca29679eafe5 make/Main.gmk --- 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 -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) diff -r 6dc5e0cdb44c -r ca29679eafe5 make/autoconf/basics.m4 --- 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) diff -r 6dc5e0cdb44c -r ca29679eafe5 make/autoconf/spec.gmk.in --- 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@ diff -r 6dc5e0cdb44c -r ca29679eafe5 make/common/MakeBase.gmk --- 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)? && \ diff -r 6dc5e0cdb44c -r ca29679eafe5 make/devkit/createSolarisDevkit.sh --- 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 " - -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 diff -r 6dc5e0cdb44c -r ca29679eafe5 make/devkit/createSolarisDevkit12.4.sh --- /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 " + +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 diff -r 6dc5e0cdb44c -r ca29679eafe5 make/devkit/createSolarisDevkit12.6.sh --- /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 " + +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 diff -r 6dc5e0cdb44c -r ca29679eafe5 make/gensrc/Gensrc-jdk.internal.vm.compiler.gmk --- 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; \ diff -r 6dc5e0cdb44c -r ca29679eafe5 make/mapfiles/libjava/mapfile-vers --- 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; diff -r 6dc5e0cdb44c -r ca29679eafe5 make/scripts/compare.sh --- 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 diff -r 6dc5e0cdb44c -r ca29679eafe5 make/scripts/compare_exceptions.sh.incl --- 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 diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/classes/java/lang/Runtime.java --- 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(); } /** diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/classes/java/lang/invoke/BootstrapMethodInvoker.java --- 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 diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java --- 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}, diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/classes/java/lang/ref/Reference.java --- 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(); + } }); } diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/classes/java/util/Locale.java --- 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)*)
* country (extension)*
* - * 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)*)
* country (extension)*
* - * 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. diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/classes/jdk/internal/misc/JavaLangRefAccess.java --- 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(); } diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/share/native/libjava/Runtime.c --- 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) { diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/windows/classes/java/net/TwoStacksPlainSocketImpl.java --- 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; diff -r 6dc5e0cdb44c -r ca29679eafe5 src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c --- 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"); diff -r 6dc5e0cdb44c -r ca29679eafe5 src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java --- 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 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 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); } diff -r 6dc5e0cdb44c -r ca29679eafe5 src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- 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'' diff -r 6dc5e0cdb44c -r ca29679eafe5 src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java --- 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()); } } } diff -r 6dc5e0cdb44c -r ca29679eafe5 src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties --- 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} diff -r 6dc5e0cdb44c -r ca29679eafe5 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java --- 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); diff -r 6dc5e0cdb44c -r ca29679eafe5 src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java --- 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; } diff -r 6dc5e0cdb44c -r ca29679eafe5 test/jdk/ProblemList.txt --- 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 ############################################################################ diff -r 6dc5e0cdb44c -r ca29679eafe5 test/jdk/tools/jimage/JImageExtractTest.java --- 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 { diff -r 6dc5e0cdb44c -r ca29679eafe5 test/jdk/tools/jimage/JImageListTest.java --- 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 entries = Stream.of(lines) .filter(s -> { return !s.startsWith("Module: ") && !s.startsWith("Offset"); }) diff -r 6dc5e0cdb44c -r ca29679eafe5 test/jdk/tools/jlink/JLinkTest.java --- 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"); diff -r 6dc5e0cdb44c -r ca29679eafe5 test/jdk/tools/jlink/plugins/ExcludeModuleInfoTest.java --- /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 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(); + } + } +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/diags/examples/BracketsNotAllowedImplicitLambda.java --- /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 f = (var s1[], var s2) -> s2; +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/diags/examples/ExplicitImplicitLambda.java --- /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; +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/diags/examples/VarAllOrNothing.java --- /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; +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/diags/examples/VarExplicitLambda.java --- /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; +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/diags/examples/VarNotAllowedExplicitLambda.java --- /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)->{}; +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/lambda/8131742/T8131742.out --- 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 diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/lambda/LambdaParserTest.java --- 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"), - EXPLICIT_GENERIC2("A"), - EXPLICIT_GENERIC2_VARARGS("A..."), - EXPLICIT_GENERIC2_ARR1("A[]"), - EXPLICIT_GENERIC2_ARR2("A[][]"); + + 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", ExplicitKind.EXPLICIT), + EXPLICIT_GENERIC2("A", ExplicitKind.EXPLICIT), + EXPLICIT_GENERIC2_VARARGS("A...", ExplicitKind.EXPLICIT), + EXPLICIT_GENERIC2_ARR1("A[]", ExplicitKind.EXPLICIT), + EXPLICIT_GENERIC2_ARR2("A[][]", 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() .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; } diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/lvti/ParserTest.java --- 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 l2; //error List l3; //error try { - Function f = (var x2) -> ""; //error + Function f = (var x2) -> ""; //ok } catch (var ex) { } //error } diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/lvti/ParserTest.out --- 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 diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/parser/extend/TrialParser.java --- 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; } diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.java --- /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 f5 = (var s1[], var s2) -> s2; +} diff -r 6dc5e0cdb44c -r ca29679eafe5 test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.out --- /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